2025-06-06 21:14:28 +07:00

141 lines
4.5 KiB
Go

package repository
import (
"enaklo-pos-be/internal/common/logger"
"enaklo-pos-be/internal/common/mycontext"
"enaklo-pos-be/internal/entity"
"fmt"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
)
type UndianRepo interface {
GetUndianEventByID(ctx mycontext.Context, id int64) (*entity.UndianEventDB, error)
GetActiveUndianEvents(ctx mycontext.Context) ([]*entity.UndianEventDB, error)
GetActiveUndianEventsWithPrizes(ctx mycontext.Context, customerID int64) ([]*entity.UndianEventDB, error)
GetCustomerVouchersByEventIDs(ctx mycontext.Context, customerID int64, eventIDs []int64) ([]*entity.UndianVoucherDB, error)
CreateUndianVouchers(ctx mycontext.Context, vouchers []*entity.UndianVoucherDB) error
GetNextVoucherSequence(ctx mycontext.Context) (int64, error)
GetNextVoucherSequenceBatch(ctx mycontext.Context, count int) (int64, error)
}
type undianRepository struct {
db *gorm.DB
}
func NewUndianRepository(db *gorm.DB) UndianRepo {
return &undianRepository{
db: db,
}
}
func (r *undianRepository) GetUndianEventByID(ctx mycontext.Context, id int64) (*entity.UndianEventDB, error) {
event := new(entity.UndianEventDB)
if err := r.db.WithContext(ctx).First(event, id).Error; err != nil {
logger.ContextLogger(ctx).Error("error when get undian event by id", zap.Error(err))
return nil, err
}
return event, nil
}
func (r *undianRepository) GetActiveUndianEvents(ctx mycontext.Context) ([]*entity.UndianEventDB, error) {
var events []*entity.UndianEventDB
now := time.Now()
if err := r.db.WithContext(ctx).
Where("status = 'active' AND start_date <= ? AND end_date >= ?", now, now).
Order("created_at DESC").
Find(&events).Error; err != nil {
logger.ContextLogger(ctx).Error("error when get active undian events", zap.Error(err))
return nil, err
}
return events, nil
}
func (r *undianRepository) GetActiveUndianEventsWithPrizes(ctx mycontext.Context, customerID int64) ([]*entity.UndianEventDB, error) {
var events []*entity.UndianEventDB
now := time.Now()
query := r.db.WithContext(ctx).
Preload("Prizes", func(db *gorm.DB) *gorm.DB {
return db.Order("rank ASC")
}).
Where("status = 'active' AND start_date <= ? AND end_date >= ?", now, now).
Order("created_at DESC")
// If customer ID is provided, preload only that customer's vouchers
if customerID > 0 {
query = query.Preload("Vouchers", func(db *gorm.DB) *gorm.DB {
return db.Where("customer_id = ?", customerID).Order("created_at ASC")
})
} else {
// If no customer ID, don't load any vouchers (or load all if needed)
query = query.Preload("Vouchers", func(db *gorm.DB) *gorm.DB {
return db.Where("1 = 0") // This loads no vouchers
})
}
if err := query.Find(&events).Error; err != nil {
logger.ContextLogger(ctx).Error("error when get active undian events with prizes",
zap.Int64("customerID", customerID),
zap.Error(err))
return nil, err
}
return events, nil
}
func (r *undianRepository) GetCustomerVouchersByEventIDs(ctx mycontext.Context, customerID int64, eventIDs []int64) ([]*entity.UndianVoucherDB, error) {
var vouchers []*entity.UndianVoucherDB
if err := r.db.WithContext(ctx).
Where("customer_id = ? AND undian_event_id IN ?", customerID, eventIDs).
Order("undian_event_id ASC, created_at ASC").
Find(&vouchers).Error; err != nil {
logger.ContextLogger(ctx).Error("error when get customer vouchers by event IDs",
zap.Int64("customerID", customerID),
zap.Int64s("eventIDs", eventIDs),
zap.Error(err))
return nil, err
}
return vouchers, nil
}
func (r *undianRepository) CreateUndianVouchers(ctx mycontext.Context, vouchers []*entity.UndianVoucherDB) error {
err := r.db.WithContext(ctx).Create(&vouchers).Error
if err != nil {
logger.ContextLogger(ctx).Error("error when create undian vouchers", zap.Error(err))
return err
}
return nil
}
func (r *undianRepository) GetNextVoucherSequence(ctx mycontext.Context) (int64, error) {
var sequence int64
err := r.db.WithContext(ctx).Raw("SELECT nextval('voucher_sequence')").Scan(&sequence).Error
if err != nil {
logger.ContextLogger(ctx).Error("error when get next voucher sequence", zap.Error(err))
return 0, err
}
return sequence, nil
}
func (r *undianRepository) GetNextVoucherSequenceBatch(ctx mycontext.Context, count int) (int64, error) {
var startSequence int64
query := fmt.Sprintf("SELECT nextval('voucher_sequence') + %d - %d", count-1, count-1)
err := r.db.WithContext(ctx).Raw(query).Scan(&startSequence).Error
if err != nil {
logger.ContextLogger(ctx).Error("error when get batch voucher sequence", zap.Error(err))
return 0, err
}
return startSequence, nil
}