@@ -1,228 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"apskel-pos-be/internal/entities"
|
||||
"context"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type VoucherRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewVoucherRepository(db *gorm.DB) *VoucherRepository {
|
||||
return &VoucherRepository{db: db}
|
||||
}
|
||||
|
||||
func (r *VoucherRepository) Create(ctx context.Context, voucher *entities.Voucher) error {
|
||||
return r.db.WithContext(ctx).Create(voucher).Error
|
||||
}
|
||||
|
||||
func (r *VoucherRepository) GetByID(ctx context.Context, id int64) (*entities.Voucher, error) {
|
||||
var voucher entities.Voucher
|
||||
err := r.db.WithContext(ctx).Where("id = ?", id).First(&voucher).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &voucher, nil
|
||||
}
|
||||
|
||||
func (r *VoucherRepository) GetByVoucherCode(ctx context.Context, voucherCode string) (*entities.Voucher, error) {
|
||||
var voucher entities.Voucher
|
||||
err := r.db.WithContext(ctx).Where("voucher_code = ?", voucherCode).First(&voucher).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &voucher, nil
|
||||
}
|
||||
|
||||
func (r *VoucherRepository) List(ctx context.Context, offset, limit int) ([]entities.Voucher, int64, error) {
|
||||
var vouchers []entities.Voucher
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(ctx)
|
||||
|
||||
if err := query.Model(&entities.Voucher{}).Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
err := query.Offset(offset).Limit(limit).Find(&vouchers).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return vouchers, total, nil
|
||||
}
|
||||
|
||||
func (r *VoucherRepository) GetRandomVouchers(ctx context.Context, limit int) ([]entities.Voucher, error) {
|
||||
var vouchers []entities.Voucher
|
||||
|
||||
// First, get the total count
|
||||
var total int64
|
||||
if err := r.db.WithContext(ctx).Model(&entities.Voucher{}).Count(&total).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if total == 0 {
|
||||
return vouchers, nil
|
||||
}
|
||||
|
||||
// If we have fewer vouchers than requested, return all
|
||||
if int(total) <= limit {
|
||||
err := r.db.WithContext(ctx).Find(&vouchers).Error
|
||||
return vouchers, err
|
||||
}
|
||||
|
||||
// Generate random offsets to get random vouchers
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
usedOffsets := make(map[int]bool)
|
||||
|
||||
for len(vouchers) < limit && len(usedOffsets) < int(total) {
|
||||
offset := rand.Intn(int(total))
|
||||
if usedOffsets[offset] {
|
||||
continue
|
||||
}
|
||||
usedOffsets[offset] = true
|
||||
|
||||
var voucher entities.Voucher
|
||||
err := r.db.WithContext(ctx).Offset(offset).Limit(1).First(&voucher).Error
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
vouchers = append(vouchers, voucher)
|
||||
}
|
||||
|
||||
return vouchers, nil
|
||||
}
|
||||
|
||||
func (r *VoucherRepository) GetRandomVouchersByRows(ctx context.Context, rows int, winnerNumber *int) ([][]entities.Voucher, error) {
|
||||
var allVouchers []entities.Voucher
|
||||
var err error
|
||||
|
||||
// First, try to get vouchers based on winner_number parameter
|
||||
if winnerNumber != nil {
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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, 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 {
|
||||
// Return empty rows if no vouchers available
|
||||
return make([][]entities.Voucher, rows), nil
|
||||
}
|
||||
|
||||
// Shuffle the vouchers for randomness
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
rand.Shuffle(len(allVouchers), func(i, j int) {
|
||||
allVouchers[i], allVouchers[j] = allVouchers[j], allVouchers[i]
|
||||
})
|
||||
|
||||
// Calculate vouchers per row (distribute evenly)
|
||||
vouchersPerRow := len(allVouchers) / rows
|
||||
if vouchersPerRow == 0 {
|
||||
vouchersPerRow = 1 // At least 1 voucher per row
|
||||
}
|
||||
|
||||
// Organize vouchers into rows
|
||||
voucherRows := make([][]entities.Voucher, rows)
|
||||
voucherIndex := 0
|
||||
|
||||
for i := 0; i < rows; i++ {
|
||||
// Calculate how many vouchers this row should have
|
||||
remainingRows := rows - i
|
||||
remainingVouchers := len(allVouchers) - voucherIndex
|
||||
|
||||
// Distribute remaining vouchers evenly among remaining rows
|
||||
rowSize := remainingVouchers / remainingRows
|
||||
if remainingVouchers%remainingRows > 0 {
|
||||
rowSize++
|
||||
}
|
||||
|
||||
// Ensure we don't exceed available vouchers
|
||||
if voucherIndex+rowSize > len(allVouchers) {
|
||||
rowSize = len(allVouchers) - voucherIndex
|
||||
}
|
||||
|
||||
// Create the row
|
||||
if voucherIndex < len(allVouchers) {
|
||||
endIdx := voucherIndex + rowSize
|
||||
if endIdx > len(allVouchers) {
|
||||
endIdx = len(allVouchers)
|
||||
}
|
||||
voucherRows[i] = allVouchers[voucherIndex:endIdx]
|
||||
voucherIndex = endIdx
|
||||
} else {
|
||||
voucherRows[i] = []entities.Voucher{} // Empty row
|
||||
}
|
||||
}
|
||||
|
||||
return voucherRows, nil
|
||||
}
|
||||
|
||||
func (r *VoucherRepository) Update(ctx context.Context, voucher *entities.Voucher) error {
|
||||
return r.db.WithContext(ctx).Save(voucher).Error
|
||||
}
|
||||
|
||||
func (r *VoucherRepository) Delete(ctx context.Context, id int64) error {
|
||||
return r.db.WithContext(ctx).Delete(&entities.Voucher{}, id).Error
|
||||
}
|
||||
|
||||
func (r *VoucherRepository) MarkAsWinner(ctx context.Context, id int64) error {
|
||||
return r.db.WithContext(ctx).Model(&entities.Voucher{}).Where("id = ?", id).Update("is_winner", true).Error
|
||||
}
|
||||
Reference in New Issue
Block a user