package service import ( "errors" "fmt" "time" "accounting-app/internal/models" "accounting-app/internal/repository" ) // Service layer errors for allocation records var ( ErrAllocationRecordNotFound = errors.New("allocation record not found") ) // AllocationRecordService handles business logic for allocation records type AllocationRecordService struct { repo *repository.AllocationRecordRepository } // NewAllocationRecordService creates a new AllocationRecordService instance func NewAllocationRecordService(repo *repository.AllocationRecordRepository) *AllocationRecordService { return &AllocationRecordService{ repo: repo, } } // GetAllocationRecord retrieves an allocation record by ID func (s *AllocationRecordService) GetAllocationRecord(userID uint, id uint) (*models.AllocationRecord, error) { record, err := s.repo.GetByID(userID, id) if err != nil { if errors.Is(err, repository.ErrAllocationRecordNotFound) { return nil, ErrAllocationRecordNotFound } return nil, fmt.Errorf("failed to get allocation record: %w", err) } return record, nil } // GetAllAllocationRecords retrieves all allocation records func (s *AllocationRecordService) GetAllAllocationRecords(userID uint) ([]models.AllocationRecord, error) { records, err := s.repo.GetAll(userID) if err != nil { return nil, fmt.Errorf("failed to get allocation records: %w", err) } return records, nil } // GetAllocationRecordsByRule retrieves all allocation records for a specific rule func (s *AllocationRecordService) GetAllocationRecordsByRule(userID uint, ruleID uint) ([]models.AllocationRecord, error) { records, err := s.repo.GetByRuleID(userID, ruleID) if err != nil { return nil, fmt.Errorf("failed to get allocation records by rule: %w", err) } return records, nil } // GetAllocationRecordsBySourceAccount retrieves all allocation records for a specific source account func (s *AllocationRecordService) GetAllocationRecordsBySourceAccount(userID uint, accountID uint) ([]models.AllocationRecord, error) { records, err := s.repo.GetBySourceAccountID(userID, accountID) if err != nil { return nil, fmt.Errorf("failed to get allocation records by source account: %w", err) } return records, nil } // GetAllocationRecordsByDateRange retrieves allocation records within a date range func (s *AllocationRecordService) GetAllocationRecordsByDateRange(userID uint, startDate, endDate time.Time) ([]models.AllocationRecord, error) { records, err := s.repo.GetByDateRange(userID, startDate, endDate) if err != nil { return nil, fmt.Errorf("failed to get allocation records by date range: %w", err) } return records, nil } // GetRecentAllocationRecords retrieves the most recent allocation records func (s *AllocationRecordService) GetRecentAllocationRecords(userID uint, limit int) ([]models.AllocationRecord, error) { if limit <= 0 { limit = 10 } records, err := s.repo.GetRecent(userID, limit) if err != nil { return nil, fmt.Errorf("failed to get recent allocation records: %w", err) } return records, nil } // DeleteAllocationRecord deletes an allocation record by ID func (s *AllocationRecordService) DeleteAllocationRecord(userID uint, id uint) error { err := s.repo.Delete(userID, id) if err != nil { if errors.Is(err, repository.ErrAllocationRecordNotFound) { return ErrAllocationRecordNotFound } return fmt.Errorf("failed to delete allocation record: %w", err) } return nil } // GetStatistics retrieves statistics for allocation records func (s *AllocationRecordService) GetStatistics(userID uint) (map[string]interface{}, error) { stats, err := s.repo.GetStatistics(userID) if err != nil { return nil, fmt.Errorf("failed to get allocation statistics: %w", err) } return stats, nil }