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

293 lines
9.3 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 CampaignProcessor interface {
CreateCampaign(ctx context.Context, req *contract.CreateCampaignRequest) (*models.CampaignResponse, error)
GetCampaign(ctx context.Context, id string) (*models.CampaignResponse, error)
ListCampaigns(ctx context.Context, req *contract.ListCampaignsRequest) (*models.ListCampaignsResponse, error)
UpdateCampaign(ctx context.Context, req *contract.UpdateCampaignRequest) (*models.CampaignResponse, error)
DeleteCampaign(ctx context.Context, id string) error
GetActiveCampaigns(ctx context.Context) ([]models.CampaignResponse, error)
GetCampaignsForApp(ctx context.Context) ([]models.CampaignResponse, error)
}
type campaignProcessor struct {
campaignRepo repository.CampaignRepository
}
func NewCampaignProcessor(campaignRepo repository.CampaignRepository) CampaignProcessor {
return &campaignProcessor{
campaignRepo: campaignRepo,
}
}
func (p *campaignProcessor) CreateCampaign(ctx context.Context, req *contract.CreateCampaignRequest) (*models.CampaignResponse, error) {
// Convert request to entity
entity := mappers.ToCampaignEntity(req)
if entity == nil {
return nil, fmt.Errorf("invalid request data")
}
// Create in repository
if err := p.campaignRepo.Create(ctx, entity); err != nil {
return nil, fmt.Errorf("failed to create campaign: %w", err)
}
// Convert entity to response
response := mappers.ToCampaignResponse(entity)
return response, nil
}
func (p *campaignProcessor) GetCampaign(ctx context.Context, id string) (*models.CampaignResponse, error) {
// Get from repository
entity, err := p.campaignRepo.GetByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("failed to get campaign: %w", err)
}
if entity == nil {
return nil, fmt.Errorf("campaign not found")
}
// Convert entity to response
response := mappers.ToCampaignResponse(entity)
return response, nil
}
func (p *campaignProcessor) ListCampaigns(ctx context.Context, req *contract.ListCampaignsRequest) (*models.ListCampaignsResponse, error) {
// Convert request to entity request
entityReq := &entities.ListCampaignsRequest{
Page: req.Page,
Limit: req.Limit,
Search: req.Search,
Type: req.Type,
IsActive: req.IsActive,
ShowOnApp: req.ShowOnApp,
StartDate: req.StartDate,
EndDate: req.EndDate,
}
// Get from repository
entities, total, err := p.campaignRepo.List(ctx, entityReq)
if err != nil {
return nil, fmt.Errorf("failed to list campaigns: %w", err)
}
// Convert entities to response
campaigns := mappers.ToCampaignResponseSlice(entities)
response := &models.ListCampaignsResponse{
Campaigns: campaigns,
Total: total,
Page: req.Page,
Limit: req.Limit,
}
return response, nil
}
func (p *campaignProcessor) UpdateCampaign(ctx context.Context, req *contract.UpdateCampaignRequest) (*models.CampaignResponse, error) {
// Convert request to entity
entity := mappers.ToCampaignEntityFromUpdate(req)
if entity == nil {
return nil, fmt.Errorf("invalid request data")
}
// Update in repository
if err := p.campaignRepo.Update(ctx, entity); err != nil {
return nil, fmt.Errorf("failed to update campaign: %w", err)
}
// Get updated entity
updatedEntity, err := p.campaignRepo.GetByID(ctx, req.ID.String())
if err != nil {
return nil, fmt.Errorf("failed to get updated campaign: %w", err)
}
// Convert entity to response
response := mappers.ToCampaignResponse(updatedEntity)
return response, nil
}
func (p *campaignProcessor) DeleteCampaign(ctx context.Context, id string) error {
// Delete from repository
if err := p.campaignRepo.Delete(ctx, id); err != nil {
return fmt.Errorf("failed to delete campaign: %w", err)
}
return nil
}
func (p *campaignProcessor) GetActiveCampaigns(ctx context.Context) ([]models.CampaignResponse, error) {
// Get from repository
entities, err := p.campaignRepo.GetActiveCampaigns(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get active campaigns: %w", err)
}
// Convert entities to response
campaigns := mappers.ToCampaignResponseSlice(entities)
return campaigns, nil
}
func (p *campaignProcessor) GetCampaignsForApp(ctx context.Context) ([]models.CampaignResponse, error) {
// Get from repository
entities, err := p.campaignRepo.GetCampaignsForApp(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get campaigns for app: %w", err)
}
// Convert entities to response
campaigns := mappers.ToCampaignResponseSlice(entities)
return campaigns, nil
}
// Campaign Rule Processor
type CampaignRuleProcessor interface {
CreateCampaignRule(ctx context.Context, req *contract.CreateCampaignRuleRequest) (*models.CampaignRuleResponse, error)
GetCampaignRule(ctx context.Context, id string) (*models.CampaignRuleResponse, error)
ListCampaignRules(ctx context.Context, req *contract.ListCampaignRulesRequest) (*models.ListCampaignRulesResponse, error)
UpdateCampaignRule(ctx context.Context, req *contract.UpdateCampaignRuleRequest) (*models.CampaignRuleResponse, error)
DeleteCampaignRule(ctx context.Context, id string) error
GetCampaignRulesByCampaignID(ctx context.Context, campaignID string) ([]models.CampaignRuleResponse, error)
}
type campaignRuleProcessor struct {
campaignRuleRepo repository.CampaignRuleRepository
}
func NewCampaignRuleProcessor(campaignRuleRepo repository.CampaignRuleRepository) CampaignRuleProcessor {
return &campaignRuleProcessor{
campaignRuleRepo: campaignRuleRepo,
}
}
func (p *campaignRuleProcessor) CreateCampaignRule(ctx context.Context, req *contract.CreateCampaignRuleRequest) (*models.CampaignRuleResponse, error) {
// Convert request to entity
entity := &entities.CampaignRule{
CampaignID: req.CampaignID,
RuleType: entities.RuleType(req.RuleType),
ConditionValue: req.ConditionValue,
RewardType: entities.CampaignRewardType(req.RewardType),
RewardValue: req.RewardValue,
RewardSubtype: (*entities.RewardSubtype)(req.RewardSubtype),
RewardRefID: req.RewardRefID,
Metadata: req.Metadata,
}
// Create in repository
if err := p.campaignRuleRepo.Create(ctx, entity); err != nil {
return nil, fmt.Errorf("failed to create campaign rule: %w", err)
}
// Convert entity to response
response := mappers.ToCampaignRuleResponse(entity)
return response, nil
}
func (p *campaignRuleProcessor) GetCampaignRule(ctx context.Context, id string) (*models.CampaignRuleResponse, error) {
// Get from repository
entity, err := p.campaignRuleRepo.GetByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("failed to get campaign rule: %w", err)
}
if entity == nil {
return nil, fmt.Errorf("campaign rule not found")
}
// Convert entity to response
response := mappers.ToCampaignRuleResponse(entity)
return response, nil
}
func (p *campaignRuleProcessor) ListCampaignRules(ctx context.Context, req *contract.ListCampaignRulesRequest) (*models.ListCampaignRulesResponse, error) {
// Convert request to entity request
entityReq := &entities.ListCampaignRulesRequest{
Page: req.Page,
Limit: req.Limit,
CampaignID: req.CampaignID,
RuleType: req.RuleType,
RewardType: req.RewardType,
}
// Get from repository
entities, total, err := p.campaignRuleRepo.List(ctx, entityReq)
if err != nil {
return nil, fmt.Errorf("failed to list campaign rules: %w", err)
}
// Convert entities to response
rules := mappers.ToCampaignRuleResponseSlice(entities)
response := &models.ListCampaignRulesResponse{
Rules: rules,
Total: total,
Page: req.Page,
Limit: req.Limit,
}
return response, nil
}
func (p *campaignRuleProcessor) UpdateCampaignRule(ctx context.Context, req *contract.UpdateCampaignRuleRequest) (*models.CampaignRuleResponse, error) {
// Convert request to entity
entity := &entities.CampaignRule{
ID: req.ID,
CampaignID: req.CampaignID,
RuleType: entities.RuleType(req.RuleType),
ConditionValue: req.ConditionValue,
RewardType: entities.CampaignRewardType(req.RewardType),
RewardValue: req.RewardValue,
RewardSubtype: (*entities.RewardSubtype)(req.RewardSubtype),
RewardRefID: req.RewardRefID,
Metadata: req.Metadata,
}
// Update in repository
if err := p.campaignRuleRepo.Update(ctx, entity); err != nil {
return nil, fmt.Errorf("failed to update campaign rule: %w", err)
}
// Get updated entity
updatedEntity, err := p.campaignRuleRepo.GetByID(ctx, req.ID.String())
if err != nil {
return nil, fmt.Errorf("failed to get updated campaign rule: %w", err)
}
// Convert entity to response
response := mappers.ToCampaignRuleResponse(updatedEntity)
return response, nil
}
func (p *campaignRuleProcessor) DeleteCampaignRule(ctx context.Context, id string) error {
// Delete from repository
if err := p.campaignRuleRepo.Delete(ctx, id); err != nil {
return fmt.Errorf("failed to delete campaign rule: %w", err)
}
return nil
}
func (p *campaignRuleProcessor) GetCampaignRulesByCampaignID(ctx context.Context, campaignID string) ([]models.CampaignRuleResponse, error) {
// Get from repository
entities, err := p.campaignRuleRepo.GetByCampaignID(ctx, campaignID)
if err != nil {
return nil, fmt.Errorf("failed to get campaign rules by campaign ID: %w", err)
}
// Convert entities to response
rules := mappers.ToCampaignRuleResponseSlice(entities)
return rules, nil
}