// Package service provides business logic for the application package service import ( "accounting-app/internal/models" "accounting-app/internal/repository" "errors" ) // Template service errors var ( ErrTemplateNotFound = errors.New("template not found") ErrInvalidTemplate = errors.New("invalid template data") ) // TemplateInput represents input for creating/updating a template type TemplateInput struct { Name string `json:"name" binding:"required"` Amount float64 `json:"amount"` Type models.TransactionType `json:"type" binding:"required"` CategoryID uint `json:"category_id" binding:"required"` AccountID uint `json:"account_id" binding:"required"` Currency models.Currency `json:"currency"` Note string `json:"note"` SortOrder int `json:"sort_order"` } // TemplateService handles business logic for transaction templates type TemplateService struct { templateRepo *repository.TemplateRepository categoryRepo *repository.CategoryRepository accountRepo *repository.AccountRepository } // NewTemplateService creates a new TemplateService instance func NewTemplateService( templateRepo *repository.TemplateRepository, categoryRepo *repository.CategoryRepository, accountRepo *repository.AccountRepository, ) *TemplateService { return &TemplateService{ templateRepo: templateRepo, categoryRepo: categoryRepo, accountRepo: accountRepo, } } // CreateTemplate creates a new transaction template func (s *TemplateService) CreateTemplate(userID uint, input TemplateInput) (*models.TransactionTemplate, error) { if _, err := s.categoryRepo.GetByID(userID, input.CategoryID); err != nil { return nil, errors.New("category not found") } if _, err := s.accountRepo.GetByID(userID, input.AccountID); err != nil { return nil, errors.New("account not found") } currency := input.Currency if currency == "" { currency = models.CurrencyCNY } template := &models.TransactionTemplate{ UserID: &userID, Name: input.Name, Amount: input.Amount, Type: input.Type, CategoryID: input.CategoryID, AccountID: input.AccountID, Currency: currency, Note: input.Note, SortOrder: input.SortOrder, } if err := s.templateRepo.Create(template); err != nil { return nil, err } return s.templateRepo.GetByID(userID, template.ID) } // GetTemplate retrieves a template by ID func (s *TemplateService) GetTemplate(userID uint, id uint) (*models.TransactionTemplate, error) { template, err := s.templateRepo.GetByID(userID, id) if err != nil { if errors.Is(err, repository.ErrTemplateNotFound) { return nil, ErrTemplateNotFound } return nil, err } return template, nil } // GetAllTemplates retrieves all templates for a user func (s *TemplateService) GetAllTemplates(userID uint) ([]models.TransactionTemplate, error) { return s.templateRepo.GetAll(userID) } // UpdateTemplate updates a template func (s *TemplateService) UpdateTemplate(userID uint, id uint, input TemplateInput) (*models.TransactionTemplate, error) { template, err := s.templateRepo.GetByID(userID, id) if err != nil { if errors.Is(err, repository.ErrTemplateNotFound) { return nil, ErrTemplateNotFound } return nil, err } if _, err := s.categoryRepo.GetByID(userID, input.CategoryID); err != nil { return nil, errors.New("category not found") } if _, err := s.accountRepo.GetByID(userID, input.AccountID); err != nil { return nil, errors.New("account not found") } template.Name = input.Name template.Amount = input.Amount template.Type = input.Type template.CategoryID = input.CategoryID template.AccountID = input.AccountID if input.Currency != "" { template.Currency = input.Currency } template.Note = input.Note template.SortOrder = input.SortOrder if err := s.templateRepo.Update(template); err != nil { return nil, err } return s.templateRepo.GetByID(userID, id) } // DeleteTemplate deletes a template func (s *TemplateService) DeleteTemplate(userID uint, id uint) error { err := s.templateRepo.Delete(userID, id) if errors.Is(err, repository.ErrTemplateNotFound) { return ErrTemplateNotFound } return err } // UpdateSortOrder updates the sort order of templates func (s *TemplateService) UpdateSortOrder(userID uint, ids []uint) error { return s.templateRepo.UpdateSortOrder(userID, ids) }