package undian import ( "enaklo-pos-be/internal/common/logger" "enaklo-pos-be/internal/common/mycontext" "enaklo-pos-be/internal/entity" "github.com/pkg/errors" "go.uber.org/zap" ) type Service interface { GetUndianList(ctx mycontext.Context, customerID int64) (*entity.UndianListResponse, error) GetActiveUndianEvents(ctx mycontext.Context) ([]*entity.UndianEventDB, error) } type Repository 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 undianSvc struct { repo Repository } func New(repo Repository) Service { return &undianSvc{ repo: repo, } } func (s *undianSvc) GetUndianList(ctx mycontext.Context, customerID int64) (*entity.UndianListResponse, error) { events, err := s.repo.GetActiveUndianEventsWithPrizes(ctx, customerID) if err != nil { logger.ContextLogger(ctx).Error("failed to get active undian events with prizes", zap.Int64("customerID", customerID), zap.Error(err)) return nil, errors.Wrap(err, "failed to get active undian events with prizes") } if len(events) == 0 { return &entity.UndianListResponse{ Events: []*entity.UndianEventResponse{}, }, nil } // Build response eventResponses := make([]*entity.UndianEventResponse, 0, len(events)) for _, event := range events { voucherResponses := make([]*entity.UndianVoucherResponse, 0, len(event.Vouchers)) for _, voucher := range event.Vouchers { voucherResponse := &entity.UndianVoucherResponse{ ID: voucher.ID, VoucherCode: voucher.VoucherCode, VoucherNumber: voucher.VoucherNumber, IsWinner: voucher.IsWinner, PrizeRank: voucher.PrizeRank, WonAt: voucher.WonAt, CreatedAt: voucher.CreatedAt, } voucherResponses = append(voucherResponses, voucherResponse) } // Convert prizes to response format prizeResponses := make([]*entity.UndianPrizeResponse, 0, len(event.Prizes)) for _, prize := range event.Prizes { prizeResponse := &entity.UndianPrizeResponse{ ID: prize.ID, Rank: prize.Rank, PrizeName: prize.PrizeName, PrizeValue: prize.PrizeValue, PrizeDescription: prize.PrizeDescription, PrizeType: prize.PrizeType, PrizeImageURL: prize.PrizeImageURL, WinningVoucherID: prize.WinningVoucherID, WinnerUserID: prize.WinnerUserID, Amount: prize.Amount, } prizeResponses = append(prizeResponses, prizeResponse) } eventResponse := &entity.UndianEventResponse{ ID: event.ID, Title: event.Title, Description: event.Description, ImageURL: event.ImageURL, Status: event.Status, StartDate: event.StartDate, EndDate: event.EndDate, DrawDate: event.DrawDate, MinimumPurchase: event.MinimumPurchase, DrawCompleted: event.DrawCompleted, DrawCompletedAt: event.DrawCompletedAt, TermsConditions: event.TermsAndConditions, Prefix: event.Prefix, CreatedAt: event.CreatedAt, UpdatedAt: event.UpdatedAt, VoucherCount: len(voucherResponses), // Fixed: use voucherResponses instead of eventVouchers Vouchers: voucherResponses, // Fixed: use voucherResponses instead of eventVouchers Prizes: prizeResponses, } eventResponses = append(eventResponses, eventResponse) } return &entity.UndianListResponse{ Events: eventResponses, }, nil } func (s *undianSvc) GetActiveUndianEvents(ctx mycontext.Context) ([]*entity.UndianEventDB, error) { events, err := s.repo.GetActiveUndianEvents(ctx) if err != nil { logger.ContextLogger(ctx).Error("failed to get active undian events", zap.Error(err)) return nil, errors.Wrap(err, "failed to get active undian events") } return events, nil }