apskel-pos-backend/internal/processor/voucher_processor.go
Aditya Siregar b37d21d366 Revert "fix backend"
This reverts commit afa8782eb2f450e232d169d58ea308537fb474e1.
2025-09-16 19:31:14 +07:00

157 lines
4.6 KiB
Go

package processor
import (
"apskel-pos-be/internal/mappers"
"apskel-pos-be/internal/models"
"apskel-pos-be/internal/repository"
"context"
"fmt"
"math/rand"
"time"
)
type VoucherProcessor struct {
voucherRepo *repository.VoucherRepository
}
func NewVoucherProcessor(voucherRepo *repository.VoucherRepository) *VoucherProcessor {
return &VoucherProcessor{
voucherRepo: voucherRepo,
}
}
// GetRandomVouchersForSpin retrieves random vouchers for spin feature
func (p *VoucherProcessor) GetRandomVouchersForSpin(ctx context.Context, req *models.ListVouchersForSpinRequest) (*models.ListVouchersForSpinResponse, error) {
// Set default limit if not provided
limit := req.Limit
if limit <= 0 {
limit = 10 // Default limit
}
if limit > 50 {
limit = 50 // Max limit
}
// Get random vouchers from repository
vouchers, err := p.voucherRepo.GetRandomVouchers(ctx, limit)
if err != nil {
return nil, fmt.Errorf("failed to get random vouchers: %w", err)
}
// Convert to spin response format
voucherResponses := make([]models.VoucherSpinResponse, len(vouchers))
for i, voucher := range vouchers {
voucherResponses[i] = *mappers.VoucherEntityToSpinResponse(&voucher)
}
return &models.ListVouchersForSpinResponse{
Vouchers: voucherResponses,
Count: len(voucherResponses),
}, nil
}
// GetVoucherByID retrieves a voucher by ID
func (p *VoucherProcessor) GetVoucherByID(ctx context.Context, voucherID int64) (*models.VoucherResponse, error) {
voucher, err := p.voucherRepo.GetByID(ctx, voucherID)
if err != nil {
return nil, fmt.Errorf("voucher not found: %w", err)
}
return mappers.VoucherEntityToResponse(voucher), nil
}
// GetVoucherByCode retrieves a voucher by voucher code
func (p *VoucherProcessor) GetVoucherByCode(ctx context.Context, voucherCode string) (*models.VoucherResponse, error) {
voucher, err := p.voucherRepo.GetByVoucherCode(ctx, voucherCode)
if err != nil {
return nil, fmt.Errorf("voucher not found: %w", err)
}
return mappers.VoucherEntityToResponse(voucher), nil
}
// ListVouchers retrieves vouchers with pagination
func (p *VoucherProcessor) ListVouchers(ctx context.Context, page, limit int) (*models.PaginatedVoucherResponse, error) {
offset := (page - 1) * limit
vouchers, total, err := p.voucherRepo.List(ctx, offset, limit)
if err != nil {
return nil, fmt.Errorf("failed to list vouchers: %w", err)
}
// Convert to response format
voucherResponses := make([]models.VoucherResponse, len(vouchers))
for i, voucher := range vouchers {
voucherResponses[i] = *mappers.VoucherEntityToResponse(&voucher)
}
totalPages := int((total + int64(limit) - 1) / int64(limit))
return &models.PaginatedVoucherResponse{
Data: voucherResponses,
TotalCount: int(total),
Page: page,
Limit: limit,
TotalPages: totalPages,
}, nil
}
// GetRandomVouchersByRows retrieves random vouchers organized into rows
func (p *VoucherProcessor) GetRandomVouchersByRows(ctx context.Context, req *models.ListVouchersByRowsRequest) (*models.ListVouchersByRowsResponse, error) {
// Set default values if not provided
rows := req.Rows
if rows <= 0 {
rows = 4 // Default to 4 rows
}
if rows > 10 {
rows = 10 // Max 10 rows
}
// Get random vouchers organized by rows
voucherRows, err := p.voucherRepo.GetRandomVouchersByRows(ctx, rows, req.WinnerNumber)
if err != nil {
return nil, fmt.Errorf("failed to get random vouchers by rows: %w", err)
}
// Convert to response format and select winners
responseRows := make([]models.VoucherRow, len(voucherRows))
totalVouchers := 0
for i, row := range voucherRows {
vouchers := make([]models.VoucherSpinResponse, len(row))
// Select a random winner from this row if there are vouchers
if len(row) > 0 {
// Select random winner
rand.Seed(time.Now().UnixNano() + int64(i)) // Add row index for different seed
winnerIndex := rand.Intn(len(row))
// Mark as winner in database
err := p.voucherRepo.MarkAsWinner(ctx, row[winnerIndex].ID)
if err != nil {
// Log error but continue - don't fail the entire request
fmt.Printf("Failed to mark voucher %d as winner: %v\n", row[winnerIndex].ID, err)
} else {
// Update the voucher object to reflect the change
row[winnerIndex].IsWinner = true
}
}
// Convert all vouchers to response format
for j, voucher := range row {
vouchers[j] = *mappers.VoucherEntityToSpinResponse(&voucher)
}
responseRows[i] = models.VoucherRow{
RowNumber: i + 1, // Row numbers start from 1
Vouchers: vouchers,
}
totalVouchers += len(row)
}
return &models.ListVouchersByRowsResponse{
Rows: responseRows,
TotalRows: len(responseRows),
TotalVouchers: totalVouchers,
}, nil
}