# Documentação técnica — Módulo financeiro (NF, parcelas, vendas, pedidos)

**Índice geral dos documentos:** **`Doc_INDICE.md`**.

**Dashboards** (visão geral, **DFC**, **DRE gerencial**, financeiro legado/KPIs, **extrato** de parcelas quitadas): **`Doc_Modulo_Dashboards.md`**. Classificação DRE/DFC no catálogo: **`Doc_Modulo_Produto_Servico.md`**.

Quase todas as entidades financeiras listadas abaixo são filtradas por **tenant** via `TenantScope` (direto em `idtenant` ou via `empresa.idtenant`). Detalhes: **`Doc_Modulo_Tenant.md`**.

**Assinatura SaaS** (planos, cadastro externo, Pagar.me, NF de onboarding, tela “Minha assinatura”): **`Doc_Modulo_Planos_Assinatura_Pagamento.md`**.

Este documento descreve o fluxo de dados, as tabelas envolvidas e as regras de negócio inferidas a partir dos controllers em `app/Http/Controllers/Admin/` (`NfController`, `NfParcelaController`, `VendaController`, `PedidoController`, `NfParcelaCreditoController`, `NfParcelaDebitoController`, `ContratoController`, `EventoController`, `CartaoCreditoController`, `TransferenciaController`, `ConciliacaoAgenciaController`) e dos models/serviços correlatos (`Nf`, `NfParcela`, `NfItem`, `Evento`, `Contrato`, `CartaoCredito`, `CartaoFatura`, `NfParcelaService`, `NfService`, `ContratoService`, `FluxoService`, `PedidoService`, `CartaoFaturaService`, `ConciliacaoAgenciaService`).

---

## 1. Fluxo principal de dados

### 1.1 Entidade central: `nf` (model `App\Models\Nf`)

A tabela **`nf`** concentra três “papéis” distintos, discriminados por **`tipo`** e **`saida`** (conforme scopes do model):

| Contexto   | `tipo` | `saida` | Significado no código                          | Controller principal      |
|-----------|--------|---------|------------------------------------------------|---------------------------|
| Compra    | `D`    | (não `P`/`V` no scope compra) | Despesa / nota de entrada              | `NfController` (rotas “compras”) |
| Venda     | `C`    | `V`     | Receita / venda                                | `VendaController`         |
| Pedido    | `C`    | `P`     | Pedido (itens solicitáveis, veículo, etc.)     | `PedidoController`        |

**Relacionamentos financeiros diretos:**

- **`nfitem`**: itens da nota (quantidades, valores unitários e total por linha).
- **`nfparcela`**: parcelas de pagamento/recebimento vinculadas à NF.

**Campo operacional PDV:** **`idcaixa`** (nullable, FK lógica à tabela **`caixas`**) — preenchido nas vendas concluídas pelo **PDV** quando o operador tem caixa aberto; usado para totalizar vendas no resumo do menu caixa. Demais origens de NF tendem a deixar `null`. Detalhes: **`Doc_Modulo_PDV.md`**.

Fluxo resumido:

1. **Criação da NF** — registro em `nf` com empresa, pessoa, forma de pagamento, agência (quando aplicável), datas, `qtdparcela`, `status`, totais.
2. **Itens** — inclusão/edição em `nfitem`; em compras pode haver importação textual ou vínculo com XML/NFe e `ProdutoFornecedorMap`.
3. **Conclusão da NF** — ao alterar `nf.status` para **`CONCLUÍDO`** (compras/vendas) ou **`CONCLUÍDO`** (pedidos), o sistema **gera ou ajusta parcelas** em `nfparcela` (regras diferem por controller; ver seção 3).
4. **Liquidação de parcelas** — alteração do status da parcela para **`QUITADO`** dispara movimentação de **saldo da agência** via `NfParcelaService` quando existe `idagencia` (e, nos fluxos de crédito/débito dedicados, validações extras).
5. **Listagens financeiras** — `NfParcelaCreditoController` e `NfParcelaDebitoController` filtram parcelas por **`nfparcela.tipo`** (`C` = crédito/receita, `D` = débito/despesa) e excluem NFs de pedido (`scopeNaoPedido`).

### 1.2 Parcelas genéricas (`NfParcelaController`)

- Lista parcelas com `NaoPedido()` e `status != INATIVO`.
- **Edição (`update`)**: ao mudar status para/de **`QUITADO`**, chama `NfParcelaService::concluirParcela` / `estornarParcela` conforme `nfparcela.tipo === 'C'` (crédito) ou `'D'` (débito), **somente se `idagencia` estiver definido**.

### 1.3 Crédito e débito (`NfParcelaCreditoController` / `NfParcelaDebitoController`)

- **Crédito**: parcelas com `tipo = 'C'` (associadas tipicamente a vendas / recebimentos).
- **Débito**: parcelas com `tipo = 'D'` (despesas / pagamentos a fornecedor).
- Integração com **`FluxoService`**: módulos `nfparcela_credito` e `nfparcela_debito` para transições de fluxo (`idfluxostatus`), histórico e, nas transições para/de status equivalente a **quitado**, reaplicam a mesma lógica de saldo que o `NfParcelaService` (via `aplicarRegrasPorModulo`). *Catálogo de status, transições configuráveis, cores de botões/badges e diferença para barras de progresso fixas: **`Doc_Modulo_Status_Fluxo_Cores.md`**.*
- **`NfParcelaDebitoController::update`**: se não houver agência, a transação é revertida e retorna erro orientando seleção de agência.

### 1.4 Transferência de mercadoria (`VendaController`)

Fluxo especial: venda com `transferencia = true` gera, no `update`, uma NF de **compra** na empresa destino (`tipo = 'D'`, `saida = 'N'`), replica itens (com criação de `ProdutoServico` na empresa destino se necessário) e cria parcelas na NF de entrada com `status = 'ATIVO'` e campos `saldoinicial` / `saldoatual` preenchidos a partir da agência (lógica paralela ao serviço de quitação).

### 1.4.1 Transferência entre contas (`TransferenciaController`)

Há um fluxo **separado** de transferência bancária/caixa entre agências em `App\Http\Controllers\Admin\TransferenciaController`:

- Cria **2 NFs vinculadas por `transferkey`** na mesma transação:
  - operação de **débito** (`tipo = 'D'`, `saida = 'N'`) na agência de saída;
  - operação de **crédito** (`tipo = 'C'`, `saida = 'V'`) na agência de entrada.
- Cria produto/serviço padrão **"Transferência entre contas"** (`ProdutoServico`) e `TipoProdutoServico` "Movimentação" quando necessário.
- Para cada NF criada, gera:
  - `nfitem` com centro de custo (`idgrupoitem`) informado no formulário;
  - `nfparcela` única com `datatransacao` na data da transferência.
- Atualiza saldo da agência imediatamente (`decrementarSaldo` na origem / `incrementarSaldo` no destino).

**Observação importante:** neste controller a parcela é gravada com `status = 'CONCLUÍDO'` (não `QUITADO`), diferente de outras rotinas financeiras; validar padronização de status conforme `nfparcela_credito`/`nfparcela_debito`.

**Rotas admin** (`routes/web.php`, prefixo `admin/transferencias`):

| Método / rota | Nome | Uso |
|---------------|------|-----|
| `resource transferencias` | `admin.transferencias.*` | CRUD |
| `GET transferencias/procurar` | `admin.transferencias.search` | Listagem filtrada |
| `GET transferencias/fetch` | `admin.transferencias.fetch` | AJAX |
| `GET transferencias/detalhes/{transferkey}` | `admin.transferencias.detalhes` | Par débito/crédito |
| `POST transferencias/{transferkey}/concluir` | `admin.transferencias.concluir` | Conclusão da operação |

### 1.5 Sincronização venda ↔ eventos (`VendaController::sincronizaEvento`)

Com **`nf.status = PENDENTE`**, ao **criar ou atualizar** a venda, o sistema executa `sincronizaEvento`: busca **eventos elegíveis** do cliente (`idcliente`), exclui cancelados, aplica filtros de `idnfitem` e de vínculo com outras NFs ativas, e para cada evento cria um **`nfitem`** na venda e grava **`evento.idnfitem`**. O cálculo de quantidade/valor usa **`TimeTracking`** (se o tipo tiver timetracking) ou janela **data/hora início–fim** e regras de `eventotipo` (`qtd`, valores do próprio evento vs `produtoservico.valorvenda`).

**Importante:** esse fluxo é **orientado à NF de venda** (controller de vendas), **não** ao ato de “concluir” o evento na tela de agenda. Ou seja, não há *listener* no `Evento` que dispare atualização de compra/venda automaticamente no código analisado.

### 1.6 Evento ↔ NF de **compra** (`NfController`) e conclusão de evento

**Pergunta frequente: ao concluir um evento, o `NfController` faz algo?**

**Não.** No `NfController` não existe ramo que reaja a `evento.status` (por exemplo `CONCLUÍDO`) nem que crie/atualize NF de compra por causa do evento.

Interações reais **compra × evento** no código atual:

| Onde | O que acontece |
|------|----------------|
| `NfController::edit` | Trecho que carregaria `Evento` para o fornecedor/cliente da compra está **comentado** (não há lista de eventos ativa nesse fluxo). |
| `NfController::update` | **Nenhuma** referência a `Evento` — parcelas e itens não dependem de conclusão de agenda. |
| `NfController::removeitem` | Ao excluir um `nfitem`, executa **`Evento::where('idnfitem', ...)->update(['idnfitem' => null])`**, para não deixar evento apontando para item removido. |

Ou seja: na **compra**, o vínculo financeiro com evento é **mínimo** (só desvinculação na exclusão de item). A geração de receita a partir de agenda está no fluxo de **venda** (seção 1.5).

### 1.7 `EventoController` e `PedidoService` (código legado / inativo)

Em `EventoController::update`, a chamada a **`PedidoService::sincronizaPedidoEvento($evento)`** está **comentada**. O método `sincronizaPedidoEvento` em `App\Services\PedidoService` contém lógica condicionada a **`$evento->status === 'CONCLUÍDO'`** para criar/vincular NF de pedido, porém o arquivo ainda inclui **`die`/`dd`** e não constitui fluxo utilizável em produção no estado atual.

**Conclusão para documentação:** **concluir um evento** na UI de eventos **não** aciona, por si só, `NfController` nem um serviço estável de NF; o único fluxo ativo e explícito evento→`nfitem` analisado aqui é **`VendaController::sincronizaEvento`** quando a **venda** permanece **`PENDENTE`** e é salva.

### 1.8 Contratos, recorrência e geração automática de NF

*Rotas administrativas, validações de cadastro, itens/veículos, comando Artisan e detalhes do `ContratoController`: **`Doc_Modulo_Contrato.md`**.*

Fluxo **paralelo** ao de compra/venda/pedido manual: **`contrato`** define periodicidade de cobrança e, ao ser processado, gera **`nf`** já vinculada ao contrato (`nf.idcontrato`), com itens copiados de **`contratoitem`** e parcelas via **`NfService`**.

**Gatilho principal:** em **`ContratoController::update`**, se existirem `datainiciorecorrencia`, `recorrencia` e `diavencimento`, o código entra num laço (até **24** iterações, proteção contra loop) enquanto **`Contrato::getProximaDataRecorrencia()`** retornar data: chama **`ContratoService::processarRecorrencias($contrato)`**.

**`ContratoService::processarRecorrencias`:**

- Loop interno (até **32** iterações): obtém o próximo vencimento com `getProximaDataRecorrencia()`; se nulo, encerra.
- Cria NF com **`NfService::store($contrato, $vencimento)`** (receita `tipo = C` e despesa `tipo = D` usam o mesmo serviço).
- Gera parcelas com **`NfService::handleParcels`** e itens com **`NfService::storeNfItem`** (todos os itens do contrato, não só o primeiro — o serviço lista `ContratoItem::where('idcontrato', ...)->get()`).
- Atualiza **`contrato.dataultimarecorrencia`** com a data do período faturado e persiste; no próximo ciclo o método de data pode avançar para cobranças em atraso (*catch-up*).

**`NfService::store` (resumo):**

- Preenche **`nf.idcontrato`** (rastreio de origem e atualização em lote de NFs “em andamento”), **`idpessoa`**, empresa, tipo produto/serviço, forma de pagamento, agência, totais/desconto a partir do contrato.
- **`status = CONCLUÍDO`**, **`qtdparcela = 1`**, **`saida`**: `V` se contrato `tipo = C` (receita), senão `N` (compra).
- Vencimento/entrada: data calculada pelo contrato ou *fallback* pelo dia do mês (`diavencimento`); ajuste para **dia útil anterior** (sábado/domingo) em **`ajustarParaDiaUtilAnterior`** — regra **diferente** da de `NfController`/`VendaController` na parcelamento manual (ver seção 3.1).

**`NfService::handleParcels`:** com NF **`CONCLUÍDO`**, cria parcelas em `nfparcela` **somente se ainda não existir nenhuma** para aquele `idnf` (no cenário atual, em geral **uma** parcela por NF gerada).

**Recorrência no model `Contrato`:** valores `recorrencia`: `semanal`, `mensal`, `trimestral`, `semestral`, `anual`. **`antecedencia`** (dias) antecipa a “abertura” da janela de faturamento em relação ao vencimento. **`datafimrecorrencia`** limita o período; fora de `[datainiciorecorrencia, datafimrecorrencia]` não gera.

**Pós-edição do contrato:** se houver NFs do contrato com parcelas **não quitadas**, o `update` pode retornar flags para modal; a rota **`atualizarNfsEmAndamento`** recalcula `totalnf`/`valornf`/`descontonf`, propaga forma de pagamento e agência, redistribui valor entre parcelas pendentes e alinha datas de vencimento ao **`diavencimento`** do contrato.

### 1.9 Pessoa no financeiro (“contato” comercial)

Não existe, no fluxo analisado, entidade separada **“contato”** tipo CRM: o terceiro da operação é sempre **`pessoa`** (`idpessoa` em **`nf`**, **`nfparcela`** e **`contrato`**). Endereço exibido em contrato pode ser duplicado em colunas do próprio **`contrato`** (`cep`, `endereco`, etc.) para documentos, sem substituir o cadastro de **`pessoa`**.

*Cadastro por tipo (cliente, fornecedor, funcionário, representante), usuários e permissões: **`Doc_Modulo_Pessoa_Usuario.md`***.

### 1.10 Cartão de crédito corporativo e fatura mensal automática

Fluxo dedicado em `App\Http\Controllers\Admin\CartaoCreditoController`:

- CRUD de **`cartao_credito`** com vínculo a:
  - `idempresa` (escopo tenant),
  - `idpessoa` (portador, restrito a colaborador/funcionário),
  - `idagencia` (conta padrão para pagamento).
- Ao criar/editar cartão ativo, o sistema chama **`CartaoFaturaService`** para garantir competências mensais (histórico + futuro) em **`cartao_fatura`**.
- As faturas têm status:
  - **`ABERTA`**: antes da data de fechamento;
  - **`FECHADA`**: após fechamento;
  - **`PAGA`**: após baixa por pagamento de fatura.
- O valor da fatura é recalculado com base em parcelas de despesas do cartão (`nfparcela` / `nf`) por competência.

#### 1.10.1 Vínculo técnico da compra/parcela com fatura

No lançamento de despesa com cartão:

- `nf.idcartao_credito` e `nfparcela.idcartao_credito` armazenam o cartão;
- `nf.idcartao_fatura` e `nfparcela.idcartao_fatura` armazenam a fatura da competência;
- o vínculo da competência é resolvido automaticamente por data de vencimento (`CartaoFaturaService::obterOuCriarFaturaPorData`).

Isso permite auditoria direta em listagens de compras e contas a pagar por “Origem” e “Fatura”.

### 1.11 Origem da parcela / NF (contrato vs recorrência SaaS)

Coluna **Origem** (badge ou sigla de 3 letras) nas telas:

- **Vendas** e **Compras** (`Nf::badgeOrigemHtml`)
- **Contas a receber** / **Contas a pagar** (`NfParcela::badgeOrigemHtml`)
- **Extrato / movimentação** (`badgeOrigemSiglaHtml` no partial `lista-nf-parcela-movimentacao`)

Lógica central em **`NfParcela::tipoOrigemParaNf()`**:

| Condição | Constante | Label | Sigla |
|----------|-----------|-------|-------|
| NF de transferência entre contas | `TRANSFERENCIA` | Transferência | TRF |
| `nf.idcontrato` + `contrato.modalidade = RECORRENCIA` | `RECORRENCIA` | Recorrência | REC |
| `nf.idcontrato` + `contrato.modalidade = CONTRATO` | `CONTRATO` | Contrato | CTO |
| `idcartao_credito` na parcela ou NF | `CARTAO` | Cartão | CAR |
| Demais casos | `NORMAL` | Normal | NOR |

Assinaturas SaaS provisionadas por `AssinaturaContratoService` geram NFs com `idcontrato` apontando para registro **`RECORRENCIA`**; contratos comerciais cadastrados em `admin/contratos` exibem **Contrato (CTO)**.

Ver também **`Doc_Modulo_Contrato.md`** § 6.1 e **`Doc_Modulo_Assinatura_Contrato.md`**.

#### 1.10.2 Pagamento de fatura sem poluir DRE

Ao pagar fatura no módulo de cartões:

- cria `nf` de transferência com **`saida = 'T'`** e `tipo = 'D'`;
- cria `nfparcela` de débito quitada e aplica baixa de saldo via `NfParcelaService`;
- tenta marcar a fatura da competência como **`PAGA`** quando o valor pago cobre o total.

Blindagem gerencial:

- consultas gerenciais em `DashboardFinanceiroController`, `DfcHierarquiaService` e `DreHierarquiaService` usam **`Nf::paraDemonstrativoGerencial()`** (`P`, `T`, `transferkey`). A **visão geral** (`DashboardController`) continua excluindo só `P`/`T` — saldo e projeções refletem movimento real de caixa, inclusive transferências entre contas.

#### 1.10.3 Rotas admin de cartão

Prefixo `admin/cartao-credito`: `resource`, `procurar`, `fetch`, `dashboard` (menu Painéis → Cartões de Crédito), `cadastros`, `POST {cartao}/pagar-fatura`.

Faturas mensais também garantidas pelo comando agendado **`cartao:faturas-gerar`** — **`Doc_Jobs_e_Agendamento.md`** § 5.

#### 1.10.4 Dashboard de cartões (visão gerencial por período)

O módulo possui dashboard dedicado em `CartaoCreditoController@dashboard` (menu em **Meus Módulos**) e mantém o CRUD em `CartaoCreditoController@index` (menu de **Cadastros**).

Regras de filtro e leitura:

- O dashboard usa período por `data_vencimento` da fatura (`cartao_fatura.data_vencimento`), com padrão no mês atual quando não houver filtro explícito.
- Todos os widgets devem respeitar o mesmo recorte de período e o `TenantScope` (por `idempresa`).
- Filtros suportados: `idempresa`, `idcartao_credito`, `data_vencimento` (between).

KPIs do topo (quitado x não quitado):

- **Total Vencido no Período**: soma de `cartao_fatura.valor_total` no recorte.
- **Total Pago no Período**: soma de `cartao_fatura.valor_total` com `status = 'PAGA'`.
- **Em Aberto no Período**: soma de `cartao_fatura.valor_total` com `status IN ('ABERTA','FECHADA')`.
- **Índice de Quitação (%)**: `Total Pago / Total Vencido * 100`.

Indicadores operacionais adicionais:

- **Consumo de limite por cartão**: consumo agregado no período / limite do cartão, com alerta visual em `>= 80%`.
- **Timeline de vencimentos**: lista por cartão com valor e situação:
  - `Paga` (status `PAGA`);
  - `A pagar` / `Em aberto` (status `FECHADA`/`ABERTA`);
  - `Atrasada` (vencida e não `PAGA`).
- **Maiores despesas por categoria** e **Top portadores** usam parcelas vinculadas a cartão (`nfparcela.idcartao_credito`) no mesmo recorte.

### 1.11 Conciliação de agência (`ConciliacaoAgenciaService`)

Trava financeira por **conta/agência**: campo **`agencia.conciliado_ate`** (data até a qual o período está fechado).

| Comportamento | Detalhe |
|---------------|---------|
| **Quitar / estornar parcela** | `NfParcelaService` chama `assertPodeQuitarOuEstornar` — bloqueia se `datatransacao` ≤ `conciliado_ate` (`ConciliacaoTravadaException`) |
| **Editar NF** | `NfController` / `VendaController` usam `assertPodeEditarNf` — impede alterar compra/venda/pedido com parcelas quitadas em datas já conciliadas |
| **Conciliar** | `ConciliacaoAgenciaController@conciliar` — avança `conciliado_ate`; grava **`ConciliacaoAgenciaHistorico`** |
| **Reabrir** | `reabrir` com motivo e auditoria; rota de detalhe `auditoria-reabertura` |

Rotas HTTP: **`Doc_Modulo_Dashboards.md`** § 13. Extrato pode exibir estado de conciliação por agência (`DashboardMovimentacaoController`).

---

## 2. Tabelas do banco afetadas

### 2.1 Núcleo financeiro da NF

| Tabela        | Uso principal |
|---------------|----------------|
| **`nf`**      | Cabeçalho: valores, status, tipo/saída, vínculos a empresa, pessoa, agência, forma de pagamento, veículo (pedidos), **`idcontrato`** (origem contrato), **`idcartao_credito`** e **`idcartao_fatura`** (origem cartão/fatura), etc. |
| **`nfitem`**  | Itens: `qtd`, `valorun`, `valoritem`, `idprodserv`, empresa, grupo/item opcional. |
| **`nfparcela`** | Parcelas: `valor`, vencimentos, `status`, `tipo` (C/D), `idagencia`, `idformapagamento`, **`idcartao_credito`**, **`idcartao_fatura`**, `saldoinicial`, `saldoatual`, `datatransacao`, `idfluxostatus`, etc. |

### 2.1.1 Núcleo de cartão/fatura

| Tabela | Uso principal |
|--------|---------------|
| **`cartao_credito`** | Cadastro do cartão corporativo (portador, conta padrão, bandeira, final, fechamento/vencimento, status). |
| **`cartao_fatura`** | Competências mensais por cartão (`YYYY-MM`), datas de fechamento/vencimento, valor consolidado e status (`ABERTA`/`FECHADA`/`PAGA`). |

### 2.2 Caixa / saldo

| Tabela      | Uso principal |
|-------------|----------------|
| **`agencia`** | Conta/caixa por **`idempresa`**: `nome`, dados bancários (`nagencia`, `nconta`, `noperacao`), **`chavepix`**, **`padrao`**, **`saldoinicial`** / **`saldoatual`**. O **`saldoatual`** é movimentado pelo **`NfParcelaService`** na quitação/estorno de parcelas com **`idagencia`**. Cadastro: **`AgenciaController`** — ao criar, normaliza `saldoinicial` (formato BR) e chama **`incrementarSaldo`** com esse valor para inicializar `saldoatual`. Ver **§ 2.4.5** para observações de implementação. |

### 2.3 Cadastros e referências frequentes

| Tabela / entidade | Uso |
|-------------------|-----|
| **`empresa`**     | Filtro tenant (via `TenantScope` nos models), joins nas buscas de parcelas. |
| **`pessoa`**      | Cliente/fornecedor (e outros papéis no cadastro) referenciado por `idpessoa` na NF, parcelas e contrato; equivale ao “contato” da operação financeira. |
| **`contrato`**    | Acordo com `idpessoa`, valores, `recorrencia`, janelas de cobrança, forma/agência; gera NFs via `ContratoService`/`NfService`. |
| **`contratoitem`**| Linhas espelhadas em `nfitem` quando a NF é gerada pelo contrato. |
| **`formapagamento`** | NF e parcelas; vendas propagam `idformapagamento` e `idagencia` para todas as parcelas no `update`. Ver **§ 2.4.2**. |
| **`finalidade_fiscal`** | Finalidade de emissão (código + descrição) por tenant; ligada a **`produtoservico.idfinalidade_fiscal`**. Ver **§ 2.4.1**. |
| **`cfops`** | CFOP (entrada/saída, destino, flags estoque/financeiro); **`nf.idcfop`** (e `cfop_codigo` no fillable). Ver **§ 2.4.3**. |
| **`codigos_tributacao_nacional`** | Códigos LC 116 / NFS-e; **`produtoservico.id_codigo_tributacao_nacional`**. Catálogo **global** (sem `TenantScope`); pode integrar **catálogo padrão do sistema** — **`Doc_Modulo_Catalogo_Padrao.md`**. Ver **§ 2.4.4**. |
| **`produtoservico`** | Itens de venda/compra; em compras, atualização de `valorcompra` ao editar item; campos fiscais opcionais (finalidade, CTN, código municipal). |
| **`item`**, **`grupoitem`** | Compras: itens genéricos e importação. |
| **`evento`** | Coluna **`idnfitem`**: aponta para o item da NF gerado na sincronização de venda; limpa em `NfController::removeitem`. Status do evento **não** dispara lógica em `NfController`. |
| **`eventotipo`**, **`timetracking`** | Usados em `VendaController::sincronizaEvento` para preço, quantidade e duração. |
| **`veiculo`**     | Pedidos e vendas quando aplicável. |
| **`tipoprodutoservico`** (model `TipoProdutoServico`) | Classificação da NF. |
| **`produtofornecedormap`** | Compras: vínculo XML ↔ produto interno. |
| **NFe/XML** (`nfnfe` / relação `Nf::nfnfe`) | Compras: itens importados do XML. |

### 2.4 Cadastros auxiliares fiscais e de pagamento (controllers admin)

Estes cadastros alimentam **NF**, **parcelas** e **produto/serviço**; ficam no menu de cadastros (ex.: forma de pagamento, agências, CFOP, finalidade, código de tributação nacional).

#### 2.4.1 Finalidade fiscal (`finalidade_fiscal` / `FinalidadeFiscal`)

- **Escopo:** `TenantScope` + **`idtenant`** no `store` (`session('selectedTenant')` ou `auth()->user()->tenant`).
- **Campos:** `codigo`, `descricao`, `status` (ATIVO/INATIVO).
- **Uso:** relacionamento **`ProdutoServico::finalidadeFiscal`** (`idfinalidade_fiscal`) para parametrizar emissão conforme produto.
- **Seed:** novos tenants recebem finalidades via **`FinalidadeFiscalSeeder`** no **`TenantObserver`** (ver **`Doc_Modulo_Tenant.md`**); em seguida **`provisionarTenant`** aplica o catálogo padrão (**`Doc_Modulo_Catalogo_Padrao.md`**).
- **Catálogo padrão:** pode ser marcada como padrão do sistema no tenant mestre; exclusão no tenant vira `EXCLUIDO` se não estiver em uso em `prodserv`.
- **Controller:** `FinalidadeFiscalController` — CRUD, busca por código/descrição.

#### 2.4.2 Forma de pagamento (`formapagamento` / `FormaPagamento`)

- **Escopo:** `TenantScope`; **`idtenant`** preenchido com **`auth()->user()->idtenant`** no `store`.
- **Campos:** `formapagamento` (nome), `status`, **`idfluxostatus`**, **`pdv`** (`S`/`N`) — fluxo único por tenant (**módulo `formapagamento`**: `ATIVO` ↔ `INATIVO`, sem variação por tipo); scopes **`habilitadoPdv()`** e **`ativa()`**.
- **Uso:** **`nf.idformapagamento`** e **`nfparcela.idformapagamento`**; vendas replicam forma (e agência) para todas as parcelas ao concluir.
- **Controller:** `FormaPagamentoController` — CRUD, transições via **`FluxoService`**, `fetch`, toggle de status na listagem (AJAX), toggle `pdv` no `update`.
- **PDV:** formas com **`pdv = S`** alimentam o modal **`PagamentoComponent`** na tela **`/PDV`**; detalhes em **`Doc_Modulo_PDV.md`**.

#### 2.4.3 CFOP (`cfops` / `CFOP`)

- **Escopo:** **sem** `TenantScope` — tabela **compartilhada** entre tenants (catálogo nacional).
- **Campos:** `codigo` (único, até 4 caracteres), `descricao`, **`tipo`** (`E` entrada / `S` saída), **`destino`** (`interna`, `interestadual`, `exterior`), **`movimenta_estoque`**, **`gera_financeiro`** (booleanos no `store`/`update` a partir de checkbox `on`).
- **Uso:** **`nf.idcfop`**; fillable também inclui **`cfop_codigo`** para desnormalização/cópia rápida em telas.
- **Controller:** `CFOPController` — CRUD, `fetch` (URL de edição no JSON usa **`idagenda`** em vez do id do CFOP — possível **bug** de cópia).

#### 2.4.4 Código de tributação nacional (`codigos_tributacao_nacional` / `CodigoTributacaoNacional`)

- **Escopo:** **global** (sem `TenantScope`), como CFOP — comentário no controller: catálogo para **todos** os tenants.
- **Campos:** `codigo`, `codigo_mascara`, `item_lista_servico`, `descricao`.
- **Uso:** **`produtoservico.id_codigo_tributacao_nacional`** (relação `produtoServicos()` no model); produto pode ter ainda **`codigo_tributacao_municipal`**.
- **Controller:** `CodigoTributacaoNacionalController` — CRUD com validação de unicidade de `codigo`, ação **`import`** (CSV/txt) para carga em lote.

#### 2.4.5 Agência (`agencia` / `Agencia`)

- **Escopo:** `TenantScope` via **`idempresa`** (igual demais cadastros por empresa).
- **Campos principais:** vínculo **`idempresa`**, identificação, **`padrao`**, **`saldoinicial`**, **`saldoatual`**, `chavepix`, `status`.
- **Integração financeira:** parcelas com **`idagencia`** disparam **`NfParcelaService`**; **`NfParcelaDebitoController`** exige agência para quitar em fluxo completo.
- **Operações no model:** `incrementarSaldo`, `decrementarSaldo`, `incrementarSaldoInicial`.
- **Controller:** `AgenciaController` — lista traz `GrupoItem` como “centro de custos” para a view; **`fetch`** usa **`idagenda`** no switch de status (provável typo — deveria ser **`idagencia`**); no **`update`**, trecho que trata `padrao` referencia **`$agenciaCreate`** inexistente (possível bug); **`search`** filtra coluna **`agencia`** — o model usa tabela **`agencia`** / campo **`nome`**, não `agencia` (validar em runtime).

---

### 2.5 Fluxo de status (telas crédito/débito)

| Tabela (inferida pelo uso em `FluxoService`) | Uso |
|-----------------------------------------------|-----|
| **`fluxostatus`**, **`fluxostatustransicao`**, **`fluxostatushist`** | Transições permitidas, persistência de `idfluxostatus` na parcela e histórico. |

### 2.6 Observação de implementação (`PedidoController::geraNfParcelas`)

A contagem de parcelas existentes usa `where('idnf', $pedido->id)`. O model `Nf` define **`$primaryKey = 'idnf'`**, não `id`. Em Eloquent, o identificador correto costuma ser **`$pedido->idnf`** (ou `$pedido->getKey()`). Vale validar em runtime se `$pedido->id` está preenchido; caso contrário, a condição `count <= 0` pode falhar e afetar a geração de parcelas.

---

## 3. Principais regras de negócio

### 3.1 Status da NF (`nf.status`)

- **Compras (`NfController`)**: `ATIVO`, `CONCLUÍDO`, `INATIVO` (e `PENDENTE` apenas para exibição de cor na edição).
- **Vendas**: `PENDENTE`, `CONCLUÍDO`, `INATIVO`.
- **Pedidos**: `ATIVO`, `CONCLUÍDO`, `INATIVO`.

**Compras — `CONCLUÍDO`:**

- Se **não existir** parcela para o `idnf`: cria `qtdparcelas` registros em `nfparcela` com:
  - valor da parcela = `totalnf / qtdparcela` (0 se `qtdparcela` for 0);
  - vencimentos mensais a partir de `datavencimento`, com ajuste de **dia útil** (seg–sex); **atenção**: em `NfController::ajustarDiaUtil` o código retrocede dias (`-1`/`-2`), enquanto em `VendaController` e `PedidoController` o ajuste **avança** para o próximo dia útil (`+1`/`+2`). Comportamentos distintos para o mesmo conceito.
  - `status` inicial **`PENDENTE`**.
- Se **já existirem** parcelas e **nenhuma** estiver **`QUITADO`**: redistribui valores apenas entre parcelas **`PENDENTE`** ou **`PROGRAMADO`**, com total baseado em **`sum(valoritem)` dos itens** ou, se vazio, `totalnf`; última parcela recebe diferença de arredondamento.

**Compras — `ATIVO`:**

- Se não há parcelas **`QUITADO`**, **remove** parcelas com status **diferente** de `QUITADO` (limpeza para renegociação).

**Vendas — `CONCLUÍDO`:**

- Lógica análoga à compra para criar parcelas, com `status` inicial **`PENDENTE`**.
- Se já existem parcelas e nenhuma `QUITADO`: redistribui apenas parcelas **`PENDENTE`** (não inclui `PROGRAMADO` na lista de pendentes, diferente da compra).
- Após processar parcelas, **`update` em massa** nas parcelas da venda: copia `idformapagamento` e `idagencia` da NF para todas as parcelas.

**Pedidos — `CONCLUÍDO`:**

- Chama `geraNfParcelas`: cria parcelas só se contagem for 0, `qtdparcela > 0`, com `status` inicial **`ATIVO`** (não `PENDENTE`).

### 3.2 Status da parcela (`nfparcela.status`)

Valores usados nos controllers/views:

- **`PENDENTE`**, **`PROGRAMADO`**, **`QUITADO`**, **`CANCELADO`**.
- Pedidos / transferência interna também usam **`ATIVO`** em alguns fluxos.

**Quitação (`QUITADO`) e saldo:**

- **`NfParcelaService::concluirParcela($parcela, $debito, $credito, $idagencia)`** (sempre em transação DB):
  - **Débito** (`$debito === true`): `saldoinicial` da parcela = saldo atual da agência; `saldoatual` da parcela = saldo − valor; **agência.`saldoatual`** passa a igualar esse novo saldo (pagamento reduz caixa).
  - **Crédito** (`$credito === true`): idem, porém **soma** o valor ao saldo (recebimento aumenta caixa).
- **`estornarParcela`**: reverte apenas o valor da parcela no **`agencia.saldoatual`** e zera `saldoinicial`/`saldoatual` na parcela.
- **Não há validação explícita de saldo insuficiente** antes de débito: o saldo pode ficar negativo se os dados permitirem.
- Concluir/estornar via **`FluxoService`** para módulos `nfparcela_debito` / `nfparcela_credito` exige **`idagencia`**; se ausente, as regras de saldo não são aplicadas (retorno silencioso no fluxo).

**`NfParcelaDebitoController::update`:**

- Exige **`idagencia`** para aplicar quitação/estorno; caso contrário, **rollback** e mensagem de erro.

**Transição manual de status (ex.: AJAX com `redirect=false`):**

- Em débito, se passar a `QUITADO` sem `datatransacao`, preenche com **data/hora atual**.

### 3.3 Tipo da parcela (`nfparcela.tipo`)

- **`C`**: crédito (receita) — índices e edição em `NfParcelaCreditoController`; `concluirParcela(..., false, true, agencia)`.
- **`D`**: débito (despesa) — `NfParcelaDebitoController`; `concluirParcela(..., true, false, agencia)`.

Listagens de crédito/débito usam **`scopeNaoPedido`**: excluem parcelas cuja NF é pedido (`tipo = C` e `saida = P`).

### 3.3.1 Domínio de `nf.saida` com cartão/fatura

- `P` = pedido
- `V` = venda (receita)
- `N` = compra/despesa normal
- **`T` = transferência financeira** (pagamento de fatura/cartão)
- **`transferkey` preenchido** = par de NFs da **transferência entre contas/agências** (`TransferenciaController`, `saida` `N` + `V`) — movimento interno de caixa, sem efeito de resultado

Regras gerenciais (DRE/DFC): scope **`Nf::paraDemonstrativoGerencial()`** exclui **`P`**, **`T`** e NF com **`transferkey`**. Pagamento de fatura (`T`) evita duplicar custo do cartão; exclusão por `transferkey` evita inflar receita/despesa na mesma empresa.

### 3.4 Duplicação de NF (`duplicate` em compras e vendas)

- Nova NF com itens e parcelas clonados; `nfe` limpa.
- Se `status_nfparcela === 'QUITADO'`, percorre parcelas novas com `idagencia` e chama `concluirParcela` (compra: débito; venda: crédito), refletindo saldo na agência.

### 3.5 Formatação monetária

- Controllers normalizam strings no padrão brasileiro (milhar `.`, decimal `,`) para `float` antes de persistir em `nf`/`nfitem`/`nfparcela`.

### 3.6 Evento: conclusão e impacto em NF

- **Conclusão do evento (`EventoController::update`)**: apenas persiste os dados do request; **não** chama `NfController` nem `VendaController`. A sincronização pedido/evento está **desligada** (comentada).
- **Venda `PENDENTE`**: `store`/`update` em `VendaController` chamam `sincronizaEvento` — é aí que eventos pendentes viram linhas em `nfitem` e recebem `idnfitem`.
- **Compra (`NfController`)**: status **`CONCLUÍDO`** da NF afeta **parcelas** e itens; **não** há regra ligada ao status do evento na agenda.

### 3.7 Exclusões

- **`VendaController::destroy`**: remove parcelas, itens e NF em transação.
- **`NfController::removeitem`**: remove `nfitem` e desvincula `evento.idnfitem`.
- **`NfController::destroy`** / **`PedidoController::destroy`**: `delete` na NF (efeitos em cascata dependem do banco/ORM; não há transação explícita em todos os casos).

### 3.8 Pontuação de campanha (efeito colateral)

- Model `Nf`: ao atualizar certos campos, se for **venda concluída** (`tipo === 'C'`, `saida === 'V'`, status `CONCLUÍDO`/`CONCLUIDO`), dispara **`ProcessarPontuacaoCampanhaJob`** (detalhes, fila e worker em **`Doc_Jobs_e_Agendamento.md`** § 2).

### 3.9 Contrato × recorrência × parcelas (diferença em relação à seção 3.1)

- **Parcelamento manual (seção 3.1):** uma única NF; ao concluir, várias linhas em **`nfparcela`** com vencimentos mensais escalonados.
- **Contrato recorrente:** várias **NFs** ao longo do tempo (uma por período elegível), cada uma tipicamente com **`qtdparcela = 1`** e uma parcela criada pelo **`NfService`** se ainda não houver parcelas para aquela NF.
- **Alinhamento de regras:** geração por contrato usa **dia útil anterior** no **`NfService`**; compras/vendas manuais usam lógicas distintas de dia útil nos controllers — documentar ao comparar vencimentos.

---

## 4. Referência rápida de arquivos

| Arquivo | Responsabilidade financeira resumida |
|---------|--------------------------------------|
| `NfController.php` | CRUD compras; geração/ajuste/exclusão de parcelas conforme status; importação de itens; duplicação. |
| `VendaController.php` | Vendas; parcelas ao concluir; sync forma/agência nas parcelas; transferência de mercadoria; duplicação; eventos. |
| `TransferenciaController.php` | Transferência entre contas/agências (débito+crédito com `transferkey`, `nfitem`, `nfparcela`, ajuste de saldo; rotas detalhes/concluir). |
| `ConciliacaoAgenciaController.php` | Conciliar/reabrir período por agência; histórico e auditoria. |
| `PedidoController.php` | Pedidos; geração de parcelas ao concluir (`geraNfParcelas`). |
| `NfParcelaController.php` | CRUD genérico de parcelas; quitação/estorno por tipo C/D. |
| `NfParcelaCreditoController.php` | Listagem/edição crédito; fluxo; quitação/estorno como receita. |
| `NfParcelaDebitoController.php` | Listagem/edição débito; fluxo; exige agência no update; quitação/estorno como despesa. |
| `CartaoCreditoController.php` | CRUD de cartões corporativos; pagamento de fatura via transferência (`saida='T'`). |
| `App\Models\Nf`, `NfParcela`, `NfItem` | Tabelas, fills, scopes (`compra`, `venda`, `pedido`, `credito`, `debito`, `NaoPedido`). |
| `App\Models\CartaoCredito`, `CartaoFatura` | Cadastro do cartão e competências de fatura mensal. |
| `App\Services\NfParcelaService.php` | Regra de saldo da agência na quitação/estorno. |
| `App\Services\CartaoFaturaService.php` | Geração de competências, recálculo de valor de fatura, fechamento automático e marcação de pagamento. |
| `App\Services\FluxoService.php` | Transições de status com integração ao `NfParcelaService` para parcelas crédito/débito. |
| `App\Services\ConciliacaoAgenciaService.php` | Cadeado de período conciliado; validações em NF e parcelas. |
| `App\Models\Nf::paraDemonstrativoGerencial` | Scope: exclui `P`, `T` e `transferkey` (DRE/DFC hierárquicos). |
| `DfcHierarquiaService` / `DreHierarquiaService` | Demonstrativos — ver **`Doc_Modulo_Dashboards.md`**. |
| `EventoController.php` | CRUD de eventos; **sem** integração ativa com NF na `update` (sync com pedido comentado). |
| `App\Services\PedidoService.php` | `sincronizaPedidoEvento`: rascunho para evento `CONCLUÍDO` → pedido/NF; **não** usado (chamada comentada; código com `die`/`dd`). |
| `ContratoController.php` | CRUD contratos; ao salvar, processa recorrências pendentes; `atualizarNfsEmAndamento` para alinhar NFs com parcelas abertas ao contrato editado. |
| `App\Models\Contrato` | `getProximaDataRecorrencia`, `verificaRecorrencia`, vínculos com `pessoa`, `nfs`. |
| `App\Services\ContratoService.php` | `processarRecorrencias`: orquestra `NfService` (NF + parcelas + itens) e atualiza `dataultimarecorrencia`. |
| `App\Services\NfService.php` | NF/parcelas/itens gerados a partir do contrato (`store`, `handleParcels`, `storeNfItem`). |
| `FinalidadeFiscalController.php` | CRUD finalidades fiscais por tenant. |
| `FormaPagamentoController.php` | CRUD formas de pagamento; flag PDV. |
| `CFOPController.php` | CRUD CFOP (catálogo global). |
| `CodigoTributacaoNacionalController.php` | CRUD + importação CSV códigos LC 116 / NFS-e. |
| `AgenciaController.php` | CRUD agências/caixas por empresa; saldo inicial/atual. |

---

*Documento gerado com base na leitura do código na árvore do projeto. Comportamentos de banco (FKs, `ON DELETE`) devem ser confirmados nas migrations para ambiente de produção.*
