This commit is contained in:
2026-01-25 21:59:00 +08:00
parent 7fd537bef3
commit 4cad3f0250
118 changed files with 30473 additions and 0 deletions

View File

@@ -0,0 +1,143 @@
// 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)
}