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

124 lines
4.2 KiB
Go

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
}