79 lines
1.9 KiB
Go
79 lines
1.9 KiB
Go
|
|
package service
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"database/sql"
|
||
|
|
"fmt"
|
||
|
|
|
||
|
|
"boc/repository"
|
||
|
|
)
|
||
|
|
|
||
|
|
// SalesService handles business logic for sales operations
|
||
|
|
type SalesService struct {
|
||
|
|
repo *repository.SalesRepository
|
||
|
|
db *sql.DB
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewSalesService(db *sql.DB) *SalesService {
|
||
|
|
return &SalesService{
|
||
|
|
repo: repository.NewSalesRepository(db),
|
||
|
|
db: db,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ListDeals returns all deals filtered by status
|
||
|
|
func (s *SalesService) ListDeals(ctx context.Context, status string) ([]repository.Deal, error) {
|
||
|
|
return s.repo.ListDeals(ctx, status)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetDeal returns a single deal by ID
|
||
|
|
func (s *SalesService) GetDeal(ctx context.Context, id string) (*repository.Deal, error) {
|
||
|
|
return s.repo.GetDeal(ctx, id)
|
||
|
|
}
|
||
|
|
|
||
|
|
// CreateDeal creates a new deal with validation
|
||
|
|
func (s *SalesService) CreateDeal(ctx context.Context, d *repository.Deal) error {
|
||
|
|
if d.Name == "" {
|
||
|
|
return fmt.Errorf("deal name is required")
|
||
|
|
}
|
||
|
|
if d.CustomerID == "" {
|
||
|
|
return fmt.Errorf("customer ID is required")
|
||
|
|
}
|
||
|
|
if d.Value <= 0 {
|
||
|
|
return fmt.Errorf("deal value must be positive")
|
||
|
|
}
|
||
|
|
if d.Status == "" {
|
||
|
|
d.Status = "open"
|
||
|
|
}
|
||
|
|
if d.Stage == "" {
|
||
|
|
d.Stage = "discovery"
|
||
|
|
}
|
||
|
|
if d.Currency == "" {
|
||
|
|
d.Currency = "USD"
|
||
|
|
}
|
||
|
|
return s.repo.CreateDeal(ctx, d)
|
||
|
|
}
|
||
|
|
|
||
|
|
// UpdateDeal updates an existing deal
|
||
|
|
func (s *SalesService) UpdateDeal(ctx context.Context, id string, d *repository.Deal) error {
|
||
|
|
if d.Name == "" {
|
||
|
|
return fmt.Errorf("deal name is required")
|
||
|
|
}
|
||
|
|
return s.repo.UpdateDeal(ctx, id, d)
|
||
|
|
}
|
||
|
|
|
||
|
|
// ListProducts returns all active products
|
||
|
|
func (s *SalesService) ListProducts(ctx context.Context) ([]repository.Product, error) {
|
||
|
|
return s.repo.ListProducts(ctx)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetMRR calculates monthly recurring revenue
|
||
|
|
func (s *SalesService) GetMRR(ctx context.Context) (float64, error) {
|
||
|
|
return s.repo.GetMRR(ctx)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetARR calculates annual recurring revenue
|
||
|
|
func (s *SalesService) GetARR(ctx context.Context) (float64, error) {
|
||
|
|
return s.repo.GetARR(ctx)
|
||
|
|
}
|