130 lines
3.7 KiB
Go
130 lines
3.7 KiB
Go
|
|
package repository
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"fmt"
|
||
|
|
|
||
|
|
"apskel-pos-be/internal/entities"
|
||
|
|
|
||
|
|
"gorm.io/gorm"
|
||
|
|
)
|
||
|
|
|
||
|
|
type RewardRepository interface {
|
||
|
|
Create(ctx context.Context, reward *entities.Reward) error
|
||
|
|
GetByID(ctx context.Context, id string) (*entities.Reward, error)
|
||
|
|
List(ctx context.Context, req *entities.ListRewardsRequest) ([]entities.Reward, int64, error)
|
||
|
|
Update(ctx context.Context, reward *entities.Reward) error
|
||
|
|
Delete(ctx context.Context, id string) error
|
||
|
|
UpdateStock(ctx context.Context, id string, newStock int) error
|
||
|
|
GetByRewardType(ctx context.Context, rewardType entities.RewardType) ([]entities.Reward, error)
|
||
|
|
}
|
||
|
|
|
||
|
|
type rewardRepository struct {
|
||
|
|
db *gorm.DB
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewRewardRepository(db *gorm.DB) RewardRepository {
|
||
|
|
return &rewardRepository{
|
||
|
|
db: db,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *rewardRepository) Create(ctx context.Context, reward *entities.Reward) error {
|
||
|
|
if err := r.db.WithContext(ctx).Create(reward).Error; err != nil {
|
||
|
|
return fmt.Errorf("failed to create reward: %w", err)
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *rewardRepository) GetByID(ctx context.Context, id string) (*entities.Reward, error) {
|
||
|
|
var reward entities.Reward
|
||
|
|
if err := r.db.WithContext(ctx).Where("id = ?", id).First(&reward).Error; err != nil {
|
||
|
|
if err == gorm.ErrRecordNotFound {
|
||
|
|
return nil, fmt.Errorf("reward not found")
|
||
|
|
}
|
||
|
|
return nil, fmt.Errorf("failed to get reward: %w", err)
|
||
|
|
}
|
||
|
|
return &reward, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *rewardRepository) List(ctx context.Context, req *entities.ListRewardsRequest) ([]entities.Reward, int64, error) {
|
||
|
|
var rewards []entities.Reward
|
||
|
|
var total int64
|
||
|
|
|
||
|
|
query := r.db.WithContext(ctx).Model(&entities.Reward{})
|
||
|
|
|
||
|
|
// Apply filters
|
||
|
|
if req.Search != "" {
|
||
|
|
query = query.Where("name ILIKE ?", "%"+req.Search+"%")
|
||
|
|
}
|
||
|
|
|
||
|
|
if req.RewardType != "" {
|
||
|
|
query = query.Where("reward_type = ?", req.RewardType)
|
||
|
|
}
|
||
|
|
|
||
|
|
if req.MinPoints != nil {
|
||
|
|
query = query.Where("cost_points >= ?", *req.MinPoints)
|
||
|
|
}
|
||
|
|
|
||
|
|
if req.MaxPoints != nil {
|
||
|
|
query = query.Where("cost_points <= ?", *req.MaxPoints)
|
||
|
|
}
|
||
|
|
|
||
|
|
if req.HasStock != nil {
|
||
|
|
if *req.HasStock {
|
||
|
|
query = query.Where("stock > 0 OR stock IS NULL")
|
||
|
|
} else {
|
||
|
|
query = query.Where("stock <= 0")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Count total records
|
||
|
|
if err := query.Count(&total).Error; err != nil {
|
||
|
|
return nil, 0, fmt.Errorf("failed to count rewards: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Apply pagination
|
||
|
|
if req.Page > 0 && req.Limit > 0 {
|
||
|
|
offset := (req.Page - 1) * req.Limit
|
||
|
|
query = query.Offset(offset).Limit(req.Limit)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Apply sorting
|
||
|
|
query = query.Order("created_at DESC")
|
||
|
|
|
||
|
|
if err := query.Find(&rewards).Error; err != nil {
|
||
|
|
return nil, 0, fmt.Errorf("failed to list rewards: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
return rewards, total, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *rewardRepository) Update(ctx context.Context, reward *entities.Reward) error {
|
||
|
|
if err := r.db.WithContext(ctx).Save(reward).Error; err != nil {
|
||
|
|
return fmt.Errorf("failed to update reward: %w", err)
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *rewardRepository) Delete(ctx context.Context, id string) error {
|
||
|
|
if err := r.db.WithContext(ctx).Where("id = ?", id).Delete(&entities.Reward{}).Error; err != nil {
|
||
|
|
return fmt.Errorf("failed to delete reward: %w", err)
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *rewardRepository) UpdateStock(ctx context.Context, id string, newStock int) error {
|
||
|
|
if err := r.db.WithContext(ctx).Model(&entities.Reward{}).Where("id = ?", id).Update("stock", newStock).Error; err != nil {
|
||
|
|
return fmt.Errorf("failed to update reward stock: %w", err)
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *rewardRepository) GetByRewardType(ctx context.Context, rewardType entities.RewardType) ([]entities.Reward, error) {
|
||
|
|
var rewards []entities.Reward
|
||
|
|
if err := r.db.WithContext(ctx).Where("reward_type = ?", rewardType).Find(&rewards).Error; err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to get rewards by type: %w", err)
|
||
|
|
}
|
||
|
|
return rewards, nil
|
||
|
|
}
|