Skip to content

Módulo Contábil

O módulo Contábil implementa um sistema de contabilidade por partidas dobradas (double-entry bookkeeping) integrado ao fluxo operacional do restaurante. Lançamentos são gerados automaticamente a partir de vendas, despesas e compras via fila assíncrona BullMQ.

Visão Geral

CaracterísticaDetalhe
ArquiteturaNestJS module: backend/src/accounting/
Banco de dadosMongoDB/Mongoose — 6 schemas
AutomaçãoBullMQ fila accounting-queue (fire-and-forget)
Permissãomanage_accounting (Role Admin ou Superadmin)
Rota principal/t/:slug/admin/accounting

Schemas

SchemaDescriçãoArquivo
ChartAccountPlano de Contas — hierarquia de contas contábeisschemas/chart-account.schema.ts
JournalEntryLançamentos em partidas dobradas (débito=crédito)schemas/journal-entry.schema.ts
AccountsReceivableContas a receber — fiado, cartão D+N, PIX pendenteschemas/accounts-receivable.schema.ts
BankAccountCadastro de contas bancáriasschemas/bank-account.schema.ts
BankStatementLineLinhas do extrato OFX/CSV importadoschemas/bank-statement-line.schema.ts
PeriodClosingFechamento de competência com snapshot do balanceteschemas/period-closing.schema.ts

Serviços

ServiçoResponsabilidadeArquivo
ChartOfAccountsServiceCRUD do plano de contas; seed dos defaults brasileirosservices/chart-of-accounts.service.ts
JournalEntryServiceCriar/listar/postar/estornar lançamentosservices/journal-entry.service.ts
GeneralLedgerServiceBalancete, razão geral, períodos e fechamentoservices/general-ledger.service.ts
AccountsReceivableServiceRecebíveis — liquidar, baixar, aging reportservices/accounts-receivable.service.ts
BankReconciliationServiceImportar OFX/CSV, conciliação automáticaservices/bank-reconciliation.service.ts
AccountingAutomationServiceProcessa eventos da fila e gera lançamentosaccounting-queue/accounting-automation.service.ts

Fila de Automação (BullMQ)

O módulo AccountingQueueModule (backend/src/accounting-queue/) gerencia a geração assíncrona de lançamentos:

OrdersService.closeTab()         → evento sale_completed
DreService.createExpense()       → evento expense_created
InboundNfeService.confirm()      → evento inventory_purchase

        accounting-queue (Redis)

AccountingAutomationService      → gera JournalEntry automaticamente

Os hooks são fire-and-forget com @Optional() injection — o módulo funciona mesmo sem Redis configurado.

Plano de Contas

Estrutura hierárquica

Códigos no formato X.X.X.XX (ex: 1.1.2.03 — Contas a Receber – Fiado):

NaturezaGrupoSaldo normal
ativo1 — AtivoDevedor (debit)
passivo2 — PassivoCredor (credit)
patrimonio_liquido2.3 — Patrimônio LíquidoCredor (credit)
receita3 — ReceitasCredor (credit)
custo4 — CMVDevedor (debit)
despesa5 — DespesasDevedor (debit)

Tipos de conta:

  • sintetica — Conta grupo (apenas agrupamento, não recebe lançamentos)
  • analitica — Conta analítica (recebe lançamentos diretamente)

Seed de defaults

POST /t/:slug/accounting/chart/seed/defaults (Superadmin) — popula ~40 contas com hierarquia completa para restaurante brasileiro: Caixa, Bancos, Fiado, Cartões, Estoques, Fornecedores, Obrigações, Receitas, CMV, Folha, Aluguel, etc.

Lançamentos (Journal Entries)

Cada lançamento:

  • Tem N linhas de débito + N linhas de crédito
  • totalDebit === totalCredit (invariante de partidas dobradas)
  • Passa pelos estados: draft → posted → reversed
  • Estorno cria contra-lançamento automático

Contas a Receber

TipoGatilho de criação
fiadoPedido fechado com pagamento fiado no PDV
card_creditPedido com cartão de crédito (recebimento D+N)
card_debitPedido com cartão de débito
pix_pendingPIX não confirmado
otherManual ou outros meios

Status: open → partially_settled → settled ou open → written_off

Aging report: agrupa recebíveis por vencimento (Vencidos >90d, 60-90d, 30-60d, Até 30d, A Vencer) com totais e contagens.

Conciliação Bancária

  1. Importar extrato OFX (padrão Open Financial Exchange), CSV ou CNAB240 via upload
  2. Sistema pareia automaticamente linhas do extrato com lançamentos contábeis por valor + data (auto-match)
  3. Linhas podem ser: unmatched → matched ou ignored

Importação CNAB240

O formato CNAB 240 é o padrão brasileiro de remessa bancária usado pela maioria dos bancos (Bradesco, Itaú, Santander, BB, Caixa).

Como importar:

  1. Baixe o arquivo de extrato no internet banking do seu banco (extensão .rem, .ret ou .txt, 240 caracteres por linha)
  2. Acesse Contabilidade → Contas Bancárias
  3. Selecione a conta bancária correspondente
  4. Clique em Importar Extrato e selecione o arquivo CNAB240
  5. O sistema processa e exibe um resumo: N lançamentos importados, N ignorados (duplicatas)

O que é extraído (Segmento T):

Campo CNAB240Posição (0-indexed)Mapeado para
Data20–27 (DDMMYYYY)BankStatementLine.date
Indicador D/C118 (D=débito, C=crédito)BankStatementLine.amount (negativo=D, positivo=C)
Valor119–131 (13 dígitos, 2 decimais)BankStatementLine.amount
Histórico73–102 (30 chars)BankStatementLine.description

Deduplicação: Cada linha gera um hash SHA-1 de date|value|description. Linhas já importadas são ignoradas silenciosamente — reimportar o mesmo arquivo é seguro.

Encoding: Arquivos CNAB240 brasileiros usam latin1 (ISO-8859-1). O sistema converte automaticamente para UTF-8.

Auto-matching: Após a importação, BankReconciliationService.autoMatch() tenta parear cada linha com lançamentos contábeis existentes por valor exato e data próxima (±1 dia). Linhas pareadas recebem status: matched; as demais ficam unmatched para conciliação manual.

Serviço: backend/src/accounting/services/bank-reconciliation.service.tsimportCnab240()

Endpoint: POST /t/:slug/accounting/bank-accounts/:id/import-cnab240 (multipart/form-data, campo file)

Fechamento de Período

  • Fecha uma competência mensal — impede novos lançamentos
  • Captura snapshot do balancete no momento do fechamento (trialBalanceSnapshot)
  • Pode ser reaberto para correções (status: reopened)

Componentes Frontend

ViewRotaDescrição
AccountingOverviewView/accountingDashboard KPIs + balancete resumido + quick links
ChartOfAccountsView/accounting/chartPlano de Contas com filtros, form de criação, deactivate
JournalEntriesView/accounting/journalDiário expandível, post/estorno paginado
GeneralLedgerView/accounting/ledgerTabs Balancete / Razão Geral com running balance
ReceivablesOverviewView/accounting/receivablesAging buckets, liquidar/baixar
BankAccountsView/accounting/bank-accountsContas bancárias, import OFX, conciliação
PeriodClosingView/accounting/closingFechamento de competência, expand snapshot

Store Zustand

frontend-react/src/stores/accountingStore.ts — ver accountingStore

Componente AmountDisplay

AmountDisplay é o átomo padronizado de exibição de valores monetários em reais:

tsx
<AmountDisplay value={1234.56} size="md" color="auto" />
// color="auto": negativo=vermelho, zero=cinza, positivo=padrão

Ver AmountDisplay

Balanço Patrimonial (Balance Sheet)

Endpoint: GET /t/:slug/admin/accounting/balance-sheet?asOf=YYYY-MM-DD

Permissão: Admin, Superadmin ou Accountant.

Retorna a estrutura do balanço patrimonial na data especificada (default: hoje, final do dia):

json
{
  "asOf": "2026-05-28T23:59:59.999Z",
  "ativo": {
    "circulante": [ { "code": "1.1", "name": "Caixa e Bancos", "balance": 4500000 } ],
    "naoCirculante": [ ... ],
    "total": 12000000
  },
  "passivoEPatrimonio": {
    "circulante": [ ... ],
    "naoCirculante": [ ... ],
    "patrimonioLiquido": [ ... ],
    "total": 12000000
  }
}

Valores em centavos. Saldos calculados agregando JournalEntry postados até asOf.

Serviço: backend/src/accounting/services/balance-sheet.service.tsController: backend/src/accounting/controllers/balance-sheet.controller.tsView: frontend-react/src/views/admin/accounting/BalanceSheetView.tsx

Demonstração do Fluxo de Caixa (DFC)

Endpoint: GET /t/:slug/admin/accounting/cash-flow?start=YYYY-MM-DD&end=YYYY-MM-DD&method=direct|indirect

Permissão: Admin, Superadmin ou Accountant.

Parâmetros:

ParâmetroDefaultDescrição
start1º dia do mês atualData inicial
endhojeData final
methoddirectdirect (recebimentos/pagamentos) ou indirect (lucro líquido + ajustes)

Retorna estrutura de DFC com seções: atividades operacionais, de investimento e de financiamento.

Serviço: backend/src/accounting/services/cash-flow.service.tsController: backend/src/accounting/controllers/cash-flow.controller.tsView: frontend-react/src/views/admin/accounting/CashFlowStatementView.tsx

Exportação Contábil

Endpoint: GET /t/:slug/admin/accounting/export?format=omie|contaazul|sap|sped&start=YYYY-MM-DD&end=YYYY-MM-DD

Permissão: Admin, Superadmin ou Accountant.

Retorna download de arquivo com lançamentos no formato solicitado:

FormatoTipo de arquivoDescrição
omieJSONPayload compatível com API Omie (/financas/contapagar/)
contaazulJSONPayload compatível com API Conta Azul
sapCSVSAP Business One Journal Entries (GL_Account, Debit, Credit)
spedTXTSPED Contábil — Registro I010/I020/I050/I075/I150/I155/I200/I350

Serviço: backend/src/accounting/services/accounting-export.service.tsController: backend/src/accounting/controllers/accounting-export.controller.ts

Integrações ERP

O módulo de integrações permite configurar credenciais por provedor e enviar lançamentos contábeis diretamente às APIs externas.

Schema AccountingIntegration

CampoTipoDescrição
tenantObjectId
provideromie | contaazul | sap | sped
enabledboolean
testModebooleanUsa sandbox/homologação do provedor
apiKeyEncryptedEncryptedFieldChave API criptografada com DEK do tenant
apiSecretEncryptedEncryptedFieldSegredo criptografado
baseUrlOverridestring?URL customizada (obrigatória para SAP, opcional para outros)
lastSyncAtDate?Último envio bem-sucedido
lastErrorstring?Último erro de sincronização

Arquivo: backend/src/accounting/schemas/accounting-integration.schema.ts

Endpoints de Integrações

MétodoRotaDescrição
GET/t/:slug/admin/accounting/integrationsListar todas as integrações configuradas (apiKey/apiSecret mascarados como ****)
PUT/t/:slug/admin/accounting/integrations/:providerCriar ou atualizar configuração (provider: omie, contaazul, sap, sped)
POST/t/:slug/admin/accounting/integrations/:provider/testTestar credenciais contra endpoint low-cost do provedor

Controller: backend/src/accounting/controllers/accounting-integration.controller.ts

Clientes ERP

ProvedorClienteBase URL padrão
OMIEbackend/src/accounting/providers/omie.client.tshttps://app.omie.com.br/api/v1/
Conta Azulbackend/src/accounting/providers/contaazul.client.tshttps://api.contaazul.com/
SAP B1backend/src/accounting/providers/sap.client.tsConfigurável — ex: https://host:50000/b1s/v1
SPEDbackend/src/accounting/providers/sped.client.tsfile:/// local ou s3://bucket/prefix

Todos os clientes usam retry com backoff exponencial (backend/src/accounting/providers/retry.util.ts).

Configuração por provedor

OMIE:

  • apiKey: app_key da integração Omie
  • apiSecret: app_secret da integração Omie
  • baseUrlOverride: opcional

Conta Azul:

  • apiKey: Client ID OAuth2
  • apiSecret: Client Secret OAuth2
  • baseUrlOverride: opcional

SAP Business One:

  • apiKey: usuário SAP
  • apiSecret: senha SAP
  • baseUrlOverride: obrigatório — URL do Service Layer (https://hostname:50000/b1s/v1)

SPED:

  • Sem credenciais — gera arquivo local ou S3
  • baseUrlOverride: caminho destino (file:///var/sped/ ou s3://meu-bucket/sped/)

Relacionados

Lançado sob a licença MIT.