@@ -6,6 +6,8 @@ import (
|
||||
"apskel-pos-be/internal/repository"
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type VoucherProcessor struct {
|
||||
@@ -117,59 +119,20 @@ func (p *VoucherProcessor) GetRandomVouchersByRows(ctx context.Context, req *mod
|
||||
for i, row := range voucherRows {
|
||||
vouchers := make([]models.VoucherSpinResponse, len(row))
|
||||
|
||||
// Select a winner from this row if there are vouchers
|
||||
// Select a random winner from this row if there are vouchers
|
||||
if len(row) > 0 {
|
||||
var winnerIndex int
|
||||
|
||||
if req.WinnerNumber != nil {
|
||||
// If winner_number is specified, try to find a voucher with that winner_number
|
||||
// that is not already a winner, otherwise select any non-winner
|
||||
winnerIndex = -1
|
||||
for j, voucher := range row {
|
||||
if voucher.WinnerNumber == *req.WinnerNumber && !voucher.IsWinner {
|
||||
winnerIndex = j
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If no voucher with specified winner_number found, select any non-winner
|
||||
if winnerIndex == -1 {
|
||||
for j, voucher := range row {
|
||||
if !voucher.IsWinner {
|
||||
winnerIndex = j
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If still no non-winner found, select any voucher
|
||||
if winnerIndex == -1 {
|
||||
winnerIndex = 0
|
||||
}
|
||||
} else {
|
||||
// If no winner_number specified, select any non-winner, otherwise any voucher
|
||||
winnerIndex = -1
|
||||
for j, voucher := range row {
|
||||
if !voucher.IsWinner {
|
||||
winnerIndex = j
|
||||
break
|
||||
}
|
||||
}
|
||||
if winnerIndex == -1 {
|
||||
winnerIndex = 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 if not already a winner
|
||||
if !row[winnerIndex].IsWinner {
|
||||
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
|
||||
}
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,42 +102,64 @@ func (r *VoucherRepository) GetRandomVouchersByRows(ctx context.Context, rows in
|
||||
var allVouchers []entities.Voucher
|
||||
var err error
|
||||
|
||||
// Get all non-winner vouchers (regardless of winner_number)
|
||||
nonWinnerQuery := r.db.WithContext(ctx).Where("is_winner = ?", false)
|
||||
err = nonWinnerQuery.Find(&allVouchers).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If winner_number is provided, also include vouchers with that specific winner_number
|
||||
// (even if they're already winners, to have a pool to select from)
|
||||
// First, try to get vouchers based on winner_number parameter
|
||||
if winnerNumber != nil {
|
||||
var winnerNumberVouchers []entities.Voucher
|
||||
winnerQuery := r.db.WithContext(ctx).Where("winner_number = ?", *winnerNumber)
|
||||
err = winnerQuery.Find(&winnerNumberVouchers).Error
|
||||
// If winner_number is provided, filter by it and exclude already won vouchers
|
||||
query := r.db.WithContext(ctx).Where("winner_number = ? AND is_winner = ?", *winnerNumber, false)
|
||||
err = query.Find(&allVouchers).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Merge the two lists, avoiding duplicates
|
||||
existingIDs := make(map[int64]bool)
|
||||
for _, voucher := range allVouchers {
|
||||
existingIDs[voucher.ID] = true
|
||||
}
|
||||
|
||||
for _, voucher := range winnerNumberVouchers {
|
||||
if !existingIDs[voucher.ID] {
|
||||
allVouchers = append(allVouchers, voucher)
|
||||
// If no vouchers found for the specified winner_number, fallback to winner_number = 0
|
||||
if len(allVouchers) == 0 {
|
||||
fallbackQuery := r.db.WithContext(ctx).Where("winner_number = ? AND is_winner = ?", 0, false)
|
||||
err = fallbackQuery.Find(&allVouchers).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If still no vouchers found, get any vouchers available as fallback
|
||||
if len(allVouchers) == 0 {
|
||||
err = r.db.WithContext(ctx).Find(&allVouchers).Error
|
||||
// If still no vouchers found, try without is_winner filter for winner_number = 0
|
||||
if len(allVouchers) == 0 {
|
||||
fallbackQuery2 := r.db.WithContext(ctx).Where("winner_number = ?", 0)
|
||||
err = fallbackQuery2.Find(&allVouchers).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// If still no vouchers found, get any vouchers available
|
||||
if len(allVouchers) == 0 {
|
||||
err = r.db.WithContext(ctx).Find(&allVouchers).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If winner_number is not provided, use default winner_number = 0 and exclude already won vouchers
|
||||
query := r.db.WithContext(ctx).Where("winner_number = ? AND is_winner = ?", 0, false)
|
||||
err = query.Find(&allVouchers).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If no vouchers found, try without is_winner filter for winner_number = 0
|
||||
if len(allVouchers) == 0 {
|
||||
fallbackQuery := r.db.WithContext(ctx).Where("winner_number = ?", 0)
|
||||
err = fallbackQuery.Find(&allVouchers).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// If still no vouchers found, get any vouchers available
|
||||
if len(allVouchers) == 0 {
|
||||
err = r.db.WithContext(ctx).Find(&allVouchers).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(allVouchers) == 0 {
|
||||
|
||||
Reference in New Issue
Block a user