# Módulo Financeiro

## Objetivo

O módulo financeiro controla contas a receber, contas a pagar, honorários, despesas, parcelas e pagamentos do escritório. Todos os registros são isolados por `office_id` e vinculados obrigatoriamente a um cliente.

O vínculo com processo jurídico será acrescentado quando o módulo de processos estiver disponível. Esta entrega não cria uma referência sem integridade para uma tabela que ainda não existe.

## Princípios adotados

- valores monetários são armazenados em **centavos inteiros**;
- nenhum cálculo usa `float` ou `double`;
- pagamentos são históricos e não são sobrescritos;
- exclusão de pagamento significa **estorno auditável**;
- lançamentos cancelados usam soft delete;
- parcelas e pagamentos permanecem no banco para auditoria;
- consultas de outro escritório retornam `404`;
- alterações compostas usam transações;
- pagamentos bloqueiam a parcela no banco durante o cálculo do saldo.

## Estrutura de dados

### `financial_categories`

Categorias de receita e despesa do escritório.

Tipos:

- `income`: somente contas a receber;
- `expense`: somente contas a pagar;
- `both`: pode ser usada nos dois tipos.

Uma categoria com histórico financeiro não pode ser apagada. Ela deve ser desativada com `is_active=false`.

### `financial_entries`

Representa o lançamento principal.

Tipos:

- `receivable`: conta a receber;
- `payable`: conta a pagar.

Origens:

- `contractual_fee`: honorário contratual;
- `success_fee`: honorário de êxito ou sucumbência;
- `expense`: despesa;
- `other`: outra origem.

Status:

- `pending`;
- `partially_paid`;
- `paid`;
- `overdue`;
- `canceled`.

O status não é informado pelo frontend. Ele é recalculado pela API com base nas parcelas, pagamentos e vencimentos.

### `financial_installments`

Cada lançamento possui pelo menos uma parcela. O somatório das parcelas deve ser exatamente igual a `total_amount_cents`.

A API distribui diferenças de divisão inteira entre as primeiras parcelas. Exemplo: R$ 100,00 em três parcelas gera `3334`, `3333` e `3333` centavos.

### `financial_payments`

Cada pagamento pertence a uma parcela e ao lançamento correspondente.

O endpoint de exclusão não remove a linha. Ele preenche:

- `reversed_at`;
- `reversed_by_user_id`;
- `reversal_reason`.

Após o estorno, os saldos e status da parcela e do lançamento são recalculados.

### `financial_entry_document`

Relaciona documentos privados do GED com lançamentos financeiros. O documento e o lançamento precisam pertencer ao mesmo escritório e ao mesmo cliente.

## Cálculo do lançamento

```text
total_amount_cents =
    amount_cents
    + interest_amount_cents
    + fine_amount_cents
    - discount_amount_cents
```

O resultado deve ser maior que zero.

```text
balance_amount_cents = total_amount_cents - paid_amount_cents
```

O pagamento de uma parcela nunca pode ultrapassar `balance_amount_cents`.

## Parcelamento automático

Na criação, o frontend pode informar:

```json
{
  "installments_count": 3,
  "first_due_date": "2026-08-10",
  "installment_interval_months": 1
}
```

Também pode enviar uma agenda manual:

```json
{
  "installments": [
    {"due_date": "2026-08-10", "amount_cents": 30000},
    {"due_date": "2026-09-10", "amount_cents": 70000}
  ]
}
```

Não é permitido enviar os dois formatos ao mesmo tempo.

A agenda completa pode ser substituída em:

```http
POST /api/v1/financial-entries/{entry}/installments
```

A substituição é bloqueada depois que existir um pagamento ativo.

## Endpoints

### Categorias

```http
GET    /api/v1/financial-categories
POST   /api/v1/financial-categories
PUT    /api/v1/financial-categories/{category}
DELETE /api/v1/financial-categories/{category}
```

### Lançamentos

```http
GET    /api/v1/financial-entries
POST   /api/v1/financial-entries
GET    /api/v1/financial-entries/{entry}
PUT    /api/v1/financial-entries/{entry}
DELETE /api/v1/financial-entries/{entry}
```

`{entry}` recebe o UUID público.

### Parcelas e pagamentos

```http
GET    /api/v1/financial-entries/{entry}/installments
POST   /api/v1/financial-entries/{entry}/installments
POST   /api/v1/financial-installments/{installment}/payments
DELETE /api/v1/financial-payments/{payment}
```

`{installment}` e `{payment}` recebem UUID.

### Documentos financeiros

```http
POST   /api/v1/financial-entries/{entry}/documents/{document}
DELETE /api/v1/financial-entries/{entry}/documents/{document}
```

O arquivo continua sendo gerenciado pelo GED. Estes endpoints apenas criam ou removem o vínculo financeiro.

## Filtros

`GET /financial-entries` aceita:

- `search`;
- `client_id`;
- `category_id`;
- `type`;
- `origin`;
- `status`;
- `due_from` e `due_to`;
- `issued_from` e `issued_to`;
- `per_page`, limitado a 100.

A busca inclui descrição, número do documento, nome do cliente e CPF/CNPJ normalizado.

## Permissões

```text
finance.view
finance.create
finance.update
finance.delete
finance.payments.create
finance.payments.delete
finance.categories.manage
```

Distribuição inicial:

- `admin`: acesso completo;
- `financeiro`: acesso completo;
- `advogado-senior`: consulta;
- `advogado-junior`: sem acesso financeiro por padrão;
- `estagiario`: sem acesso financeiro por padrão.

A distribuição pode ser alterada pelo administrador do sistema.

## Alterações após pagamento

Depois que um pagamento é registrado, a API bloqueia mudanças que alterariam o histórico financeiro:

- cliente;
- tipo do lançamento;
- valor principal;
- desconto;
- juros;
- multa;
- agenda de parcelas.

Campos descritivos e a categoria compatível ainda podem ser atualizados.

## Vencimentos

Os status vencidos são atualizados quando os lançamentos ou parcelas são consultados e sempre que ocorre pagamento, estorno ou alteração de agenda.

Uma fase futura poderá adicionar uma rotina agendada para materializar esses status antes da geração de notificações e relatórios automáticos.

## Auditoria e exclusão

- pagamentos nunca são apagados;
- estornos exigem justificativa;
- lançamentos usam soft delete;
- parcelas permanecem para preservar o histórico;
- documentos continuam privados no GED;
- usuários responsáveis por criação, atualização, pagamento, estorno e cancelamento são registrados.

## Integração futura com processos

Quando o módulo processual for entregue, uma migration posterior adicionará `legal_case_id` com chave estrangeira. Não foi criada uma coluna sem constraint nesta etapa para evitar referências órfãs.
