package repository import ( "apskel-pos-be/internal/entities" "context" "fmt" "time" "github.com/google/uuid" "gorm.io/gorm" ) type OmsetTrackerRepository struct { db *gorm.DB } func NewOmsetTrackerRepository(db *gorm.DB) *OmsetTrackerRepository { return &OmsetTrackerRepository{db: db} } func (r *OmsetTrackerRepository) Create(ctx context.Context, omsetTracker *entities.OmsetTracker) error { return r.db.WithContext(ctx).Create(omsetTracker).Error } func (r *OmsetTrackerRepository) GetByID(ctx context.Context, id uuid.UUID) (*entities.OmsetTracker, error) { var omsetTracker entities.OmsetTracker err := r.db.WithContext(ctx).Preload("Game").Where("id = ?", id).First(&omsetTracker).Error if err != nil { return nil, err } return &omsetTracker, nil } func (r *OmsetTrackerRepository) List(ctx context.Context, offset, limit int, search, periodType string, gameID *uuid.UUID, from, to *time.Time, sortBy, sortOrder string) ([]entities.OmsetTracker, int64, error) { var omsetTrackers []entities.OmsetTracker var total int64 query := r.db.WithContext(ctx).Preload("Game") if search != "" { searchTerm := "%" + search + "%" query = query.Joins("LEFT JOIN games ON omset_tracker.game_id = games.id"). Where("games.name ILIKE ?", searchTerm) } if periodType != "" { query = query.Where("period_type = ?", periodType) } if gameID != nil { query = query.Where("game_id = ?", *gameID) } if from != nil { query = query.Where("period_start >= ?", *from) } if to != nil { query = query.Where("period_end <= ?", *to) } if err := query.Model(&entities.OmsetTracker{}).Count(&total).Error; err != nil { return nil, 0, err } if sortBy != "" { if sortOrder == "" { sortOrder = "asc" } query = query.Order(fmt.Sprintf("omset_tracker.%s %s", sortBy, sortOrder)) } else { query = query.Order("omset_tracker.period_start DESC") } err := query.Offset(offset).Limit(limit).Find(&omsetTrackers).Error if err != nil { return nil, 0, err } return omsetTrackers, total, nil } func (r *OmsetTrackerRepository) Update(ctx context.Context, omsetTracker *entities.OmsetTracker) error { return r.db.WithContext(ctx).Save(omsetTracker).Error } func (r *OmsetTrackerRepository) Delete(ctx context.Context, id uuid.UUID) error { return r.db.WithContext(ctx).Delete(&entities.OmsetTracker{}, id).Error } func (r *OmsetTrackerRepository) AddOmset(ctx context.Context, periodType entities.PeriodType, periodStart, periodEnd time.Time, amount int64, gameID *uuid.UUID) error { return r.db.WithContext(ctx).Model(&entities.OmsetTracker{}). Where("period_type = ? AND period_start = ? AND period_end = ? AND game_id = ?", periodType, periodStart, periodEnd, gameID). Update("total", gorm.Expr("total + ?", amount)).Error } func (r *OmsetTrackerRepository) GetOrCreatePeriod(ctx context.Context, periodType entities.PeriodType, periodStart, periodEnd time.Time, gameID *uuid.UUID) (*entities.OmsetTracker, error) { var omsetTracker entities.OmsetTracker err := r.db.WithContext(ctx).Preload("Game"). Where("period_type = ? AND period_start = ? AND period_end = ? AND game_id = ?", periodType, periodStart, periodEnd, gameID). First(&omsetTracker).Error if err == nil { return &omsetTracker, nil } if err != gorm.ErrRecordNotFound { return nil, err } // Create new period newOmsetTracker := &entities.OmsetTracker{ PeriodType: periodType, PeriodStart: periodStart, PeriodEnd: periodEnd, Total: 0, GameID: gameID, } err = r.Create(ctx, newOmsetTracker) if err != nil { return nil, err } return newOmsetTracker, nil } func (r *OmsetTrackerRepository) GetPeriodSummary(ctx context.Context, periodType entities.PeriodType, from, to time.Time) (map[string]interface{}, error) { var summary map[string]interface{} query := r.db.WithContext(ctx).Model(&entities.OmsetTracker{}). Select("SUM(total) as total_omset, COUNT(*) as period_count"). Where("period_type = ?", periodType) if !from.IsZero() { query = query.Where("period_start >= ?", from) } if !to.IsZero() { query = query.Where("period_end <= ?", to) } err := query.Scan(&summary).Error if err != nil { return nil, err } return summary, nil }