package service import ( "context" "errors" "strings" "financeiro-carvalho/internal/model" "financeiro-carvalho/internal/repository" ) var ( ErrInvalidTransactionType = errors.New("type must be 'income' or 'expense'") ErrTransactionEmptyDesc = errors.New("description is required") ErrTransactionInvalidAmount = errors.New("amount must be greater than zero") ) type TransactionService struct { repo repository.ManualTransactionRepository } func NewTransactionService(repo repository.ManualTransactionRepository) *TransactionService { return &TransactionService{repo: repo} } func (s *TransactionService) List(ctx context.Context, month string) ([]model.Transaction, error) { txs, err := s.repo.List(ctx, month) if txs == nil { return []model.Transaction{}, err } return txs, err } func (s *TransactionService) Create(ctx context.Context, t model.Transaction) (*model.Transaction, error) { if err := validateTransaction(t); err != nil { return nil, err } t.Description = strings.TrimSpace(t.Description) return s.repo.Create(ctx, t) } func (s *TransactionService) Update(ctx context.Context, t model.Transaction) (*model.Transaction, error) { if err := validateTransaction(t); err != nil { return nil, err } t.Description = strings.TrimSpace(t.Description) out, err := s.repo.Update(ctx, t) if errors.Is(err, repository.ErrNotFound) { return nil, errors.New("transaction not found") } return out, err } func (s *TransactionService) Delete(ctx context.Context, id int) error { err := s.repo.Delete(ctx, id) if errors.Is(err, repository.ErrNotFound) { return errors.New("transaction not found") } return err } func (s *TransactionService) DeleteByMonth(ctx context.Context, month string) (int, error) { return s.repo.DeleteByMonth(ctx, month) } func validateTransaction(t model.Transaction) error { if strings.TrimSpace(t.Description) == "" { return ErrTransactionEmptyDesc } if t.Amount <= 0 { return ErrTransactionInvalidAmount } if t.Type != "income" && t.Type != "expense" { return ErrInvalidTransactionType } return nil }