{
  "id": "transacoes",
  "title": "Transações",
  "description": "Receitas, despesas, transferências, parcelas e comprovantes do núcleo financeiro.",
  "type": "feature",
  "status": "observed",
  "visibility": "public",
  "tags": [
    "finanças",
    "transações",
    "parcelamento"
  ],
  "related": [
    "financas",
    "contas-financeiras",
    "cartoes",
    "recorrencias",
    "tags-financeiras",
    "nfce",
    "auditoria"
  ],
  "sourceRefs": [
    "https://github.com/james-suite/james/blob/master/app/Models/FinancialTransaction.php",
    "https://github.com/james-suite/james/blob/master/app/Models/FinancialTransactionItem.php",
    "https://github.com/james-suite/james/blob/master/routes/financial.php"
  ],
  "authors": [],
  "updated": null,
  "diagram": null,
  "body": "## Visão Geral\n\nAs **Transações** são o coração do módulo financeiro. Elas representam qualquer movimentação de dinheiro no sistema, seja uma receita, uma despesa ou uma transferência entre contas. Uma transação pode estar vinculada diretamente a uma Conta Financeira ou indiretamente via uma Fatura de Cartão de Crédito.\n\n## Tabelas\n\n### `financial_transactions`\n\n| Coluna | Tipo | Descrição |\n| --- | --- | --- |\n| `id` | bigint | Chave primária. |\n| `financial_account_id` | foreignId | (Opcional) A conta bancária onde a transação ocorreu. |\n| `financial_credit_card_invoice_id` | foreignId | (Opcional) A fatura de cartão de crédito à qual esta compra pertence. |\n| `financial_recurrence_id` | foreignId | (Opcional) A recorrência que gerou esta transação. |\n| `transfer_pair_id` | bigint | (Opcional) ID da transação correspondente (par) em caso de transferência. |\n| `type` | enum | `income` (receita) ou `expense` (despesa). |\n| `amount` | decimal | Valor total da transação. |\n| `description` | string | Descrição/Título da movimentação. |\n| `date` | date | Data em que a transação ocorreu. |\n| `status` | string | Enum `TransactionStatus` (`draft`, `pending`, `posted`). |\n| `installment_current` | integer | (Opcional) Qual parcela é esta (ex: 1). |\n| `installment_total` | integer | (Opcional) Total de parcelas (ex: 12). |\n\n### `financial_transaction_items`\n\nPermite a divisão de uma única transação em múltiplos itens para categorização mais granular.\n\n| Coluna | Tipo | Descrição |\n| --- | --- | --- |\n| `id` | bigint | Chave primária. |\n| `financial_transaction_id` | foreignId | Transação pai. |\n| `description` | string | Descrição do item específico. |\n| `quantity` | decimal | Quantidade. |\n| `unit_price` | decimal | Preço unitário. |\n| `total` | decimal | Total calculado a partir da quantidade e do preço unitário. |\n\n## Diagrama Relacional (ER)\n\n{{diagram:transactions-model}}\n\n## Regras de Negócio e Comportamento\n\n### Ciclo de Vida e Status (`TransactionStatus`)\n\nO status da transação é gerenciado pelo Enum `App\\Enums\\TransactionStatus`:\n\n- **Rascunho (`TransactionStatus::Draft` / `'draft'`)**: Utilizado para lançamentos parciais, rascunhos de conciliação ou importações pendentes de revisão.\n- **Pendente (`TransactionStatus::Pending` / `'pending'`)**: Indica que a transação está prevista para acontecer (compras futuras, despesas não pagas, compras em faturas de cartão ainda abertas).\n- **Efetivada (`TransactionStatus::Posted` / `'posted'`)**: O fluxo de caixa real aconteceu. Transações efetivadas impactam diretamente o saldo real consolidado da conta.\n- Ao criar compras parceladas ou transferências, o sistema avalia automaticamente se a data da transação é hoje ou no passado para defini-la como efetivada (`posted`). Caso a data seja futura, ela nasce como pendente (`pending`).\n\n### Anexos e Comprovantes (Spatie MediaLibrary)\n\nO modelo `FinancialTransaction` implementa a interface `HasMedia` com a coleção privada `attachments`. É possível anexar comprovantes de pagamento, recibos fiscais em PDF ou imagens diretamente na tela de criação/edição. Os arquivos são armazenados no disco privado (`attachments`), garantindo privacidade total.\n\n### Itens da Transação\n\nOs itens são opcionais e detalham a transação para permitir classificação por tags e relatórios mais precisos. A quantidade deve ser maior que zero; o preço unitário não pode ser zero e pode ser negativo, por exemplo para registrar um desconto, estorno ou ajuste dentro da composição da transação. O total da transação é recalculado a partir dos itens enquanto eles estão sendo editados.\n\nAo salvar uma edição, os itens existentes são atualizados preservando sua identidade e seu histórico. Um item removido do formulário é excluído definitivamente junto com os seus vínculos de tags, e a auditoria mantém o registro dos dados que foram removidos.\n\n### Parcelamentos\n\nA criação de compras parceladas (via método `createInstallmentsOnAccount`) gera automaticamente as `N` transações futuras no banco de dados. \nCada transação recebe a data deslocada mensalmente, e possui metadados de controle (`installment_current` e `installment_total`) para facilitar a identificação visual (\"1/12\", \"2/12\", etc.). O valor total é dividido, e eventuais centavos de arredondamento são somados à última parcela.\n\n### Transferências\n\nAs transferências não possuem uma entidade própria; elas são representadas por **duas** transações vinculadas entre si:\n1. Uma transação do tipo `expense` na conta de Origem.\n2. Uma transação do tipo `income` na conta de Destino.\n3. Ambas compartilham o mesmo `transfer_pair_id` apontando para o ID da despesa geradora.\n4. Automaticamente recebem a tag protegida de \"Transferência\" (`FinancialTag::TRANSFERENCIA_ID`) para que relatórios financeiros possam ignorá-las sem distorcer o fluxo de caixa líquido.\n5. Em caso de taxa bancária associada à transferência, uma 3ª transação (despesa) é gerada na conta de origem separadamente.\n\n### Soft Deletes e Proteção em Cascata\n\nSe uma das pernas de uma transferência for excluída, o sistema intercepta o evento de *deleting* e apaga automaticamente a transação correspondente (par) para manter a coerência financeira. Deleções definitivas (`forceDelete`) também forçam a purga da contraparte.",
  "sections": [
    {
      "id": "visao-geral",
      "level": 2,
      "title": "Visão Geral",
      "text": "As **Transações** são o coração do módulo financeiro. Elas representam qualquer movimentação de dinheiro no sistema, seja uma receita, uma despesa ou uma transferência entre contas. Uma transação pode estar vinculada diretamente a uma Conta Financeira ou indiretamente via uma Fatura de Cartão de Crédito.",
      "line": 1
    },
    {
      "id": "tabelas",
      "level": 2,
      "title": "Tabelas",
      "text": "",
      "line": 5
    },
    {
      "id": "financial-transactions",
      "level": 3,
      "title": "financial_transactions",
      "text": "| Coluna | Tipo | Descrição | | --- | --- | --- | | `id` | bigint | Chave primária. | | `financial_account_id` | foreignId | (Opcional) A conta bancária onde a transação ocorreu. | | `financial_credit_card_invoice_id` | foreignId | (Opcional) A fatura de cartão de crédito à qual esta compra pertence. | | `financial_recurrence_id` | foreignId | (Opcional) A recorrência que gerou esta transação. | | `transfer_pair_id` | bigint | (Opcional) ID da transação correspondente (par) em caso de transferência. | | `type` | enum | `income` (receita) ou `expense` (despesa). | | `amount` | decimal | Valor total da transação. | | `description` | string | Descrição/Título da movimentação. | | `date` | date | Data em que a transação ocorreu. | | `status` | string | Enum `TransactionStatus` (`draft`, `pending`, `posted`). | | `installment_current` | integer | (Opcional) Qual parcela é esta (ex: 1). | | `installment_total` | integer | (Opcional) Total de parcelas (ex: 12). |",
      "line": 7
    },
    {
      "id": "financial-transaction-items",
      "level": 3,
      "title": "financial_transaction_items",
      "text": "Permite a divisão de uma única transação em múltiplos itens para categorização mais granular.  | Coluna | Tipo | Descrição | | --- | --- | --- | | `id` | bigint | Chave primária. | | `financial_transaction_id` | foreignId | Transação pai. | | `description` | string | Descrição do item específico. | | `quantity` | decimal | Quantidade. | | `unit_price` | decimal | Preço unitário. | | `total` | decimal | Total calculado a partir da quantidade e do preço unitário. |",
      "line": 24
    },
    {
      "id": "diagrama-relacional-er",
      "level": 2,
      "title": "Diagrama Relacional (ER)",
      "text": "",
      "line": 37
    },
    {
      "id": "regras-de-negocio-e-comportamento",
      "level": 2,
      "title": "Regras de Negócio e Comportamento",
      "text": "",
      "line": 41
    },
    {
      "id": "ciclo-de-vida-e-status-transactionstatus",
      "level": 3,
      "title": "Ciclo de Vida e Status (TransactionStatus)",
      "text": "O status da transação é gerenciado pelo Enum `App\\Enums\\TransactionStatus`:  - **Rascunho (`TransactionStatus::Draft` / `'draft'`)**: Utilizado para lançamentos parciais, rascunhos de conciliação ou importações pendentes de revisão. - **Pendente (`TransactionStatus::Pending` / `'pending'`)**: Indica que a transação está prevista para acontecer (compras futuras, despesas não pagas, compras em faturas de cartão ainda abertas). - **Efetivada (`TransactionStatus::Posted` / `'posted'`)**: O fluxo de caixa real aconteceu. Transações efetivadas impactam diretamente o saldo real consolidado da conta. - Ao criar compras parceladas ou transferências, o sistema avalia automaticamente se a data da transação é hoje ou no passado para defini-la como efetivada (`posted`). Caso a data seja futura, ela nasce como pendente (`pending`).",
      "line": 43
    },
    {
      "id": "anexos-e-comprovantes-spatie-medialibrary",
      "level": 3,
      "title": "Anexos e Comprovantes (Spatie MediaLibrary)",
      "text": "O modelo `FinancialTransaction` implementa a interface `HasMedia` com a coleção privada `attachments`. É possível anexar comprovantes de pagamento, recibos fiscais em PDF ou imagens diretamente na tela de criação/edição. Os arquivos são armazenados no disco privado (`attachments`), garantindo privacidade total.",
      "line": 52
    },
    {
      "id": "itens-da-transacao",
      "level": 3,
      "title": "Itens da Transação",
      "text": "Os itens são opcionais e detalham a transação para permitir classificação por tags e relatórios mais precisos. A quantidade deve ser maior que zero; o preço unitário não pode ser zero e pode ser negativo, por exemplo para registrar um desconto, estorno ou ajuste dentro da composição da transação. O total da transação é recalculado a partir dos itens enquanto eles estão sendo editados.  Ao salvar uma edição, os itens existentes são atualizados preservando sua identidade e seu histórico. Um item removido do formulário é excluído definitivamente junto com os seus vínculos de tags, e a auditoria mantém o registro dos dados que foram removidos.",
      "line": 56
    },
    {
      "id": "parcelamentos",
      "level": 3,
      "title": "Parcelamentos",
      "text": "A criação de compras parceladas (via método `createInstallmentsOnAccount`) gera automaticamente as `N` transações futuras no banco de dados. Cada transação recebe a data deslocada mensalmente, e possui metadados de controle (`installment_current` e `installment_total`) para facilitar a identificação visual (\"1/12\", \"2/12\", etc.). O valor total é dividido, e eventuais centavos de arredondamento são somados à última parcela.",
      "line": 62
    },
    {
      "id": "transferencias",
      "level": 3,
      "title": "Transferências",
      "text": "As transferências não possuem uma entidade própria; elas são representadas por **duas** transações vinculadas entre si: 1. Uma transação do tipo `expense` na conta de Origem. 2. Uma transação do tipo `income` na conta de Destino. 3. Ambas compartilham o mesmo `transfer_pair_id` apontando para o ID da despesa geradora. 4. Automaticamente recebem a tag protegida de \"Transferência\" (`FinancialTag::TRANSFERENCIA_ID`) para que relatórios financeiros possam ignorá-las sem distorcer o fluxo de caixa líquido. 5. Em caso de taxa bancária associada à transferência, uma 3ª transação (despesa) é gerada na conta de origem separadamente.",
      "line": 67
    },
    {
      "id": "soft-deletes-e-protecao-em-cascata",
      "level": 3,
      "title": "Soft Deletes e Proteção em Cascata",
      "text": "Se uma das pernas de uma transferência for excluída, o sistema intercepta o evento de *deleting* e apaga automaticamente a transação correspondente (par) para manter a coerência financeira. Deleções definitivas (`forceDelete`) também forçam a purga da contraparte.",
      "line": 76
    }
  ],
  "sourcePath": "content/transacoes.md",
  "visuals": [
    {
      "id": "transactions-model",
      "kind": "er",
      "title": "Modelo relacional de transações",
      "description": "Transações conectam contas, faturas, recorrências, itens e tags financeiras.",
      "summary": "Transações podem vir de contas, faturas ou recorrências; possuem itens e tags, e duas transações podem formar o par de uma transferência.",
      "renderMode": "mermaid",
      "api": "api/diagrams/transactions-model.json",
      "human": "diagrams/transactions-model.html"
    }
  ],
  "apiVersion": 1
}
