photum/backend/internal/finance/service.go
NANDO9322 e78de535c1 feat: implementação do financeiro e suporte a múltiplas funções
Este commit introduz o módulo financeiro completo e refatora o sistema de profissionais para suportar múltiplas funções, corrigindo a contabilização e validação de equipes.

Principais alterações:

- **Módulo Financeiro:**
  - Criação da tabela `financial_transactions` e queries associadas.
  - Implementação do backend (Handler/Service) para gerenciar transações.
  - Nova página [Finance.tsx](cci:7://file:///c:/Projetos/photum/frontend/pages/Finance.tsx:0:0-0:0) com listagem, edição, filtros avançados e agrupamento por FOT.
  - Correção na busca de FOTs e formatação de datas.

- **Gestão de Equipe e Profissionais:**
  - Refatoração para suportar múltiplas funções por profissional (Backend & Frontend).
  - Atualização do [Dashboard](cci:1://file:///c:/Projetos/photum/frontend/pages/Dashboard.tsx:31:0-1663:2) e [EventTable](cci:1://file:///c:/Projetos/photum/frontend/components/EventTable.tsx:28:0-659:2) para contabilizar corretamente profissionais (Fotografo, Cinegrafista, Recepcionista) verificando a lista de funções.
  - Implementação de validação de cota no aceite de convites (bloqueia se a equipe da função específica já estiver completa).
  - Ajuste visual nos indicadores de "Equipe Completa" e contadores de faltantes na listagem de eventos.

- **Geral:**
  - Atualização da documentação Swagger.
  - Ajustes de tipagem e migrações de banco de dados.
2026-01-15 18:07:39 -03:00

111 lines
3.4 KiB
Go

package finance
import (
"context"
"photum-backend/internal/db/generated"
"github.com/jackc/pgx/v5/pgtype"
)
type Service struct {
queries *generated.Queries
}
func NewService(queries *generated.Queries) *Service {
return &Service{queries: queries}
}
func (s *Service) Create(ctx context.Context, params generated.CreateTransactionParams) (generated.FinancialTransaction, error) {
txn, err := s.queries.CreateTransaction(ctx, params)
if err != nil {
return generated.FinancialTransaction{}, err
}
if params.FotID.Valid {
_ = s.updateFotExpenses(ctx, params.FotID)
}
return txn, nil
}
func (s *Service) Update(ctx context.Context, params generated.UpdateTransactionParams) (generated.FinancialTransaction, error) {
txn, err := s.queries.UpdateTransaction(ctx, params)
if err != nil {
return generated.FinancialTransaction{}, err
}
// Recalculate for the new FOT (if changed, we should technically recalc old one too, but simpler for now)
if params.FotID.Valid {
_ = s.updateFotExpenses(ctx, params.FotID)
}
return txn, nil
}
func (s *Service) Delete(ctx context.Context, id pgtype.UUID) error {
// First fetch to get FotID
txn, err := s.queries.GetTransaction(ctx, id)
if err != nil {
return err
}
err = s.queries.DeleteTransaction(ctx, id)
if err != nil {
return err
}
if txn.FotID.Valid {
_ = s.updateFotExpenses(ctx, txn.FotID)
}
return nil
}
func (s *Service) ListByFot(ctx context.Context, fotID pgtype.UUID) ([]generated.FinancialTransaction, error) {
return s.queries.ListTransactionsByFot(ctx, fotID)
}
func (s *Service) ListAll(ctx context.Context) ([]generated.ListTransactionsRow, error) {
return s.queries.ListTransactions(ctx)
}
func (s *Service) AutoFillSearch(ctx context.Context, fotNumber int32) (generated.GetCadastroFotByFotJoinRow, error) {
return s.queries.GetCadastroFotByFotJoin(ctx, fotNumber)
}
func (s *Service) ListFotEvents(ctx context.Context, fotID pgtype.UUID) ([]generated.ListAgendasByFotRow, error) {
return s.queries.ListAgendasByFot(ctx, fotID)
}
func (s *Service) SearchProfessionals(ctx context.Context, query string) ([]generated.SearchProfissionaisRow, error) {
return s.queries.SearchProfissionais(ctx, pgtype.Text{String: query, Valid: true})
}
func (s *Service) SearchProfessionalsByFunction(ctx context.Context, query string, functionName string) ([]generated.SearchProfissionaisByFunctionRow, error) {
return s.queries.SearchProfissionaisByFunction(ctx, generated.SearchProfissionaisByFunctionParams{
Column1: pgtype.Text{String: query, Valid: true}, // $1 - Name
Nome: functionName, // $2 - Function Name
})
}
func (s *Service) GetStandardPrice(ctx context.Context, eventName string, serviceName string) (pgtype.Numeric, error) {
// serviceName here is the Function Name (e.g. Fotógrafo)
return s.queries.GetStandardPrice(ctx, generated.GetStandardPriceParams{
Nome: eventName, // $1 - Event Name
Nome_2: serviceName, // $2 - Function Name
})
}
func (s *Service) SearchFot(ctx context.Context, query string) ([]generated.SearchFotRow, error) {
return s.queries.SearchFot(ctx, pgtype.Text{String: query, Valid: true})
}
func (s *Service) updateFotExpenses(ctx context.Context, fotID pgtype.UUID) error {
total, err := s.queries.SumTotalByFot(ctx, fotID)
if err != nil {
return err
}
return s.queries.UpdateCadastroFotGastos(ctx, generated.UpdateCadastroFotGastosParams{
ID: fotID,
GastosCaptacao: total,
})
}