niki/donate_app/service/service.go

91 lines
2.2 KiB
Go

package service
import (
"context"
"errors"
"time"
"git.gocasts.ir/ebhomengo/niki/campaign/entity"
"git.gocasts.ir/ebhomengo/niki/repository"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
"git.gocasts.ir/ebhomengo/niki/types"
)
type CampaignService struct {
repo repository.CampaignRepository
}
type CampaignServiceInterface interface {
CreateCampaign(ctx context.Context, req CampaignRepository) (types.ID, error)
}
// NewCampaignService creates a new campaign service
func NewCampaignService(
repo repository.CampaignRepository,
participantRepo repository.CampaignParticipantRepository,
) *CampaignService {
return &CampaignService{
repo: repo,
participantRepo: participantRepo,
}
}
// CreateCampaign creates a new campaign
func (s *CampaignService) CreateCampaign(ctx context.Context, req CreateCampaignRequest) (types.ID, error) {
const Op = "service.campaign.create_campaign"
// Business Logic: Validation
if req.Title == "" {
return 0, richerror.New(Op).WithErr(errors.New("title is required"))
}
if req.GoalAmount <= 0 {
return 0, richerror.New(Op).WithErr(errors.New("goal_amount must be greater than 0"))
}
if req.AdminID == 0 {
return 0, richerror.New(Op).WithErr(errors.New("admin_id is required"))
}
// Business Logic: Validate status
validStatuses := map[string]bool{
"draft": true,
"active": true,
"completed": true,
"cancelled": true,
}
if !validStatuses[req.Status] {
return 0, richerror.New(Op).WithErr(errors.New("invalid status"))
}
// Create campaign entity
campaign := entity.Campaign{
Title: req.Title,
Description: req.Description,
GoalAmount: req.GoalAmount,
RaisedAmount: 0, // Initially 0
Status: entity.CampaignStatus(req.Status),
DeadlineAt: req.DeadlineAt,
AdminID: req.AdminID,
CreatedAt: time.Now(),
}
// Call repository
campaignID, err := s.repo.CreateCampaign(ctx, campaign)
if err != nil {
return 0, richerror.New(Op).WithErr(err)
}
return campaignID, nil
}