Skip to content

Fichas Técnicas (BOM — Bill of Materials)

Visão Geral

O módulo de Fichas Técnicas calcula o custo de produção de cada item do cardápio, combinando:

  • Custo direto: insumos da composição (ProductIngredient) × custo unitário atual do estoque
  • Custo indireto: mão de obra, energia, embalagens, etc. (fixo por unidade ou % do custo direto)

O custo é recalculado automaticamente sempre que:

  • Uma NF-e de entrada é confirmada (novo costPrice no estoque)
  • O custo de um insumo é atualizado manualmente no estoque

Localização

frontend-react/src/features/bom/index.tsx

Rota: /t/:slug/admin/bom

Estrutura de Dados

MenuItem
  └──< ProductIngredient (existente)   ← composição: item → insumo + qty
  └──< BomIndirectCost (novo)          ← custos indiretos por prato
  └──< BomCostSnapshot (novo, append-only) ← histórico de custo

ProductIngredient é o schema existente do módulo de inventário — não foi alterado. O BOM constrói sobre ele sem duplicar.

Tipos de Custo Indireto

TipoLabel sugeridounitType
laborMão de Obrafixed ou percentage_of_direct
energyEnergia / Gásfixed
packagingEmbalagemfixed
otherOutroqualquer
  • fixed: valor em R$ por unidade produzida
  • percentage_of_direct: fração do custo direto (ex: 0.15 = 15%)

Fórmula de Cálculo

directCost      = Σ(ProductIngredient.quantityPerUnit × InventoryItem.costPrice)
fixedIndirect   = Σ(BomIndirectCost.valuePerUnit WHERE unitType='fixed')
percentIndirect = directCost × Σ(valuePerUnit WHERE unitType='percentage_of_direct')
totalCost       = directCost + fixedIndirect + percentIndirect
suggestedPrice  = totalCost / (1 − targetMargin)   ← se targetMargin informado

BomCostSnapshot — Histórico Append-Only

Cada recálculo cria um novo snapshot, nunca atualiza o anterior. Isso garante auditoria completa.

O custo "atual" é sempre o snapshot mais recente: findOne().sort({ createdAt: -1 }).

CampoDescrição
totalDirectCostCusto direto de insumos
totalIndirectCostTotal de custos indiretos
totalCostPerUnitCusto total por unidade
suggestedSellingPricePreço sugerido de venda (se targetMargin fornecido)
triggeredBymanual | nfe_import | cost_update
ingredientSnapshotDetalhamento por ingrediente no momento do cálculo

Indicadores na Lista

BadgeMargemSignificado
Verde≥ 60%Boa rentabilidade
Amarelo40–59%Atenção
Vermelho< 40%Preço de venda inadequado

Fórmula da margem: (preçoVenda − custo) / preçoVenda × 100

Componentes Frontend

ComponenteDescrição
BomEditorLayout 2 colunas: ingredientes (esq) + custos indiretos (dir); rodapé com resumo, input de margem e botão Calcular
BomCostBreakdownCardBarra visual diretos vs. indiretos
BomHistoryChartSparkline de totalCostPerUnit por snapshot
BomIndirectCostFormModal para criar/editar custo indireto

Backend

  • backend/src/bom/bom.module.ts
  • backend/src/bom/bom.service.ts
  • backend/src/bom/bom.controller.ts
  • backend/src/bom/schemas/bom-indirect-cost.schema.ts
  • backend/src/bom/schemas/bom-cost-snapshot.schema.ts

Dependência Circular

InventoryModule ↔ BomModule e InboundNfeModule → BomModule são resolvidos com forwardRef().

Relacionados

Lançado sob a licença MIT.