voucher
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user