feat(#37): módulo de cartão de crédito com faturas mensais
- Migration 011: closing_day/due_day em accounts + tabela credit_bills - CreditBillService: cria/atualiza fatura corrente on-demand no GET /accounts - Widget FATURA ATUAL no dashboard com total e botão PAGAR - AccountsView: campos closing_day/due_day para contas credit + painel fatura - Dashboard: current_bills lista faturas não pagas de todos os cartões Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
@@ -27,12 +27,13 @@ type AccountRepo interface {
|
||||
}
|
||||
|
||||
type AccountService struct {
|
||||
repo repository.AccountRepoWithYield
|
||||
cdiSvc *CDIYieldService
|
||||
repo repository.AccountRepoWithYield
|
||||
cdiSvc *CDIYieldService
|
||||
billSvc *CreditBillService
|
||||
}
|
||||
|
||||
func NewAccountService(repo repository.AccountRepoWithYield, cdiSvc *CDIYieldService) *AccountService {
|
||||
return &AccountService{repo: repo, cdiSvc: cdiSvc}
|
||||
func NewAccountService(repo repository.AccountRepoWithYield, cdiSvc *CDIYieldService, billSvc *CreditBillService) *AccountService {
|
||||
return &AccountService{repo: repo, cdiSvc: cdiSvc, billSvc: billSvc}
|
||||
}
|
||||
|
||||
func (s *AccountService) validate(in model.AccountInput) error {
|
||||
@@ -45,22 +46,44 @@ func (s *AccountService) validate(in model.AccountInput) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// List returns accounts, applying CDI yield on-demand for cdi-type accounts.
|
||||
// List returns accounts, applying CDI yield on-demand and attaching current bill for credit accounts.
|
||||
func (s *AccountService) List(ctx context.Context) ([]model.Account, error) {
|
||||
accounts, err := s.repo.List(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
yieldApplied := false
|
||||
for i := range accounts {
|
||||
if accounts[i].YieldType == "cdi" {
|
||||
// Apply CDI yield — errors are non-fatal (BCB API may be unavailable)
|
||||
_ = s.cdiSvc.ApplyYield(ctx, &accounts[i])
|
||||
yieldApplied = true
|
||||
}
|
||||
}
|
||||
|
||||
// Re-fetch after yield transactions may have been created to get updated balances
|
||||
return s.repo.List(ctx)
|
||||
if yieldApplied {
|
||||
accounts, err = s.repo.List(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for i := range accounts {
|
||||
if accounts[i].Type == "credit" {
|
||||
closing, due := 1, 10
|
||||
if accounts[i].ClosingDay != nil {
|
||||
closing = *accounts[i].ClosingDay
|
||||
}
|
||||
if accounts[i].DueDay != nil {
|
||||
due = *accounts[i].DueDay
|
||||
}
|
||||
_ = s.billSvc.EnsureCurrentBill(ctx, accounts[i].ID, closing, due)
|
||||
bill, _ := s.billSvc.GetCurrent(ctx, accounts[i].ID)
|
||||
accounts[i].CurrentBill = bill
|
||||
}
|
||||
}
|
||||
|
||||
return accounts, nil
|
||||
}
|
||||
|
||||
func (s *AccountService) Create(ctx context.Context, in model.AccountInput) (*model.Account, error) {
|
||||
|
||||
Reference in New Issue
Block a user