apskel-pos-backend/internal/processor/reward_processor.go
Aditya Siregar 155016dec8 Add Campaign
2025-09-17 23:55:11 +07:00

150 lines
4.4 KiB
Go

package processor
import (
"context"
"fmt"
"apskel-pos-be/internal/contract"
"apskel-pos-be/internal/entities"
"apskel-pos-be/internal/mappers"
"apskel-pos-be/internal/models"
"apskel-pos-be/internal/repository"
)
type RewardProcessor interface {
CreateReward(ctx context.Context, req *contract.CreateRewardRequest) (*models.RewardResponse, error)
GetReward(ctx context.Context, id string) (*models.RewardResponse, error)
ListRewards(ctx context.Context, req *contract.ListRewardsRequest) (*models.ListRewardsResponse, error)
UpdateReward(ctx context.Context, req *contract.UpdateRewardRequest) (*models.RewardResponse, error)
DeleteReward(ctx context.Context, id string) error
UpdateRewardStock(ctx context.Context, id string, newStock int) error
GetRewardsByType(ctx context.Context, rewardType string) ([]models.RewardResponse, error)
}
type rewardProcessor struct {
rewardRepo repository.RewardRepository
}
func NewRewardProcessor(rewardRepo repository.RewardRepository) RewardProcessor {
return &rewardProcessor{
rewardRepo: rewardRepo,
}
}
func (p *rewardProcessor) CreateReward(ctx context.Context, req *contract.CreateRewardRequest) (*models.RewardResponse, error) {
// Convert request to entity
entity := mappers.ToRewardEntity(req)
if entity == nil {
return nil, fmt.Errorf("invalid request data")
}
// Create in repository
if err := p.rewardRepo.Create(ctx, entity); err != nil {
return nil, fmt.Errorf("failed to create reward: %w", err)
}
// Convert entity to response
response := mappers.ToRewardResponse(entity)
return response, nil
}
func (p *rewardProcessor) GetReward(ctx context.Context, id string) (*models.RewardResponse, error) {
// Get from repository
entity, err := p.rewardRepo.GetByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("failed to get reward: %w", err)
}
if entity == nil {
return nil, fmt.Errorf("reward not found")
}
// Convert entity to response
response := mappers.ToRewardResponse(entity)
return response, nil
}
func (p *rewardProcessor) ListRewards(ctx context.Context, req *contract.ListRewardsRequest) (*models.ListRewardsResponse, error) {
// Convert request to entity request
entityReq := &entities.ListRewardsRequest{
Page: req.Page,
Limit: req.Limit,
Search: req.Search,
RewardType: req.RewardType,
MinPoints: req.MinPoints,
MaxPoints: req.MaxPoints,
HasStock: req.HasStock,
}
// Get from repository
entities, total, err := p.rewardRepo.List(ctx, entityReq)
if err != nil {
return nil, fmt.Errorf("failed to list rewards: %w", err)
}
// Convert entities to response
rewards := mappers.ToRewardResponseSlice(entities)
response := &models.ListRewardsResponse{
Rewards: rewards,
Total: total,
Page: req.Page,
Limit: req.Limit,
}
return response, nil
}
func (p *rewardProcessor) UpdateReward(ctx context.Context, req *contract.UpdateRewardRequest) (*models.RewardResponse, error) {
// Convert request to entity
entity := mappers.ToRewardEntityFromUpdate(req)
if entity == nil {
return nil, fmt.Errorf("invalid request data")
}
// Update in repository
if err := p.rewardRepo.Update(ctx, entity); err != nil {
return nil, fmt.Errorf("failed to update reward: %w", err)
}
// Get updated entity
updatedEntity, err := p.rewardRepo.GetByID(ctx, req.ID.String())
if err != nil {
return nil, fmt.Errorf("failed to get updated reward: %w", err)
}
// Convert entity to response
response := mappers.ToRewardResponse(updatedEntity)
return response, nil
}
func (p *rewardProcessor) DeleteReward(ctx context.Context, id string) error {
// Delete from repository
if err := p.rewardRepo.Delete(ctx, id); err != nil {
return fmt.Errorf("failed to delete reward: %w", err)
}
return nil
}
func (p *rewardProcessor) UpdateRewardStock(ctx context.Context, id string, newStock int) error {
// Update stock in repository
if err := p.rewardRepo.UpdateStock(ctx, id, newStock); err != nil {
return fmt.Errorf("failed to update reward stock: %w", err)
}
return nil
}
func (p *rewardProcessor) GetRewardsByType(ctx context.Context, rewardType string) ([]models.RewardResponse, error) {
// Get from repository
entities, err := p.rewardRepo.GetByRewardType(ctx, entities.RewardType(rewardType))
if err != nil {
return nil, fmt.Errorf("failed to get rewards by type: %w", err)
}
// Convert entities to response
rewards := mappers.ToRewardResponseSlice(entities)
return rewards, nil
}