Custo Médio Ponderado Móvel
Visão Geral
O PopinaFlow usa o método de Custo Médio Ponderado Móvel (weighted-average moving cost) para calcular o custo unitário de cada item do estoque. O custo é recalculado a cada entrada de mercadoria — NF-e importada, Pedido de Compra recebido ou ajuste manual.
Este método é o mais utilizado por restaurantes brasileiros e está alinhado com os critérios do Pronunciamento Técnico CPC 16 (Estoques) e com o leiaute do SPED.
Fórmula
novo_custo_unitario = ((qtd_atual × custo_atual) + (qtd_recebida × custo_recebido))
÷ (qtd_atual + qtd_recebida)Casos de borda
| Situação | Comportamento |
|---|---|
qtd_recebida ≤ 0 | Custo inalterado — nenhuma entrada para calcular |
qtd_atual ≤ 0 | Custo passa a ser o custo_recebido — evita divisão por zero |
O resultado é arredondado a 4 casas decimais (Math.round(x * 10000) / 10000).
Arquivo: backend/src/inventory/utils/cost-calculator.ts — função computeMovingAverage()
Quando o custo é atualizado
| Evento | Gatilho | Como |
|---|---|---|
| Importação de NF-e | NfeImportPipelineService.applyImport() (Passo 10) | Chama computeMovingAverage() e persiste via InventoryItem.$set costPrice = newAvgCost |
| Recebimento de Pedido de Compra | PurchaseOrderService.receiveItems() | Mesmo cálculo por item recebido |
| Ajuste de entrada manual | InventoryService.createMovement() com type: 'entry' | Custo médio atualizado se unitCost for fornecido |
Exemplo prático (importação NF-e)
Estoque atual: 100 UN × R$ 2,00/UN = R$ 200,00
Entrada NF-e: 50 UN × R$ 2,40/UN = R$ 120,00
Rateio frete (10%): custo efetivo NF-e = R$ 2,40 × 1,10 = R$ 2,64/UN
novo_custo = (100 × 2,00 + 50 × 2,64) / 150
= (200,00 + 132,00) / 150
= R$ 2,2133/UNO campo InventoryItem.costPrice passa a ser 2.2133.
Relação com a DRE (CMV)
O custo médio ponderado é usado pelo módulo DRE para calcular o Custo das Mercadorias Vendidas (CMV):
CMV = Σ (qty_vendida × costPrice) por item no períodoAs movimentações de saída por venda (type: 'exit', reason: 'sale') geradas em OrdersService.processOrderInventory() registram o unitCost vigente no momento da venda, preservando a rastreabilidade histórica independentemente de atualizações de custo futuras.
Método COGS por Lote (FIFO/FEFO/Média)
Para empresas com controle de lotes (InventoryLot), o serviço CogsCalculationService (backend/src/inventory/cogs-calculation.service.ts) suporta três métodos:
| Método | Algoritmo | Ideal para |
|---|---|---|
FIFO | Lotes ordenados por receivedDate ASC — consome o mais antigo primeiro | Produtos não perecíveis, industrial |
FEFO | Lotes ordenados por expiryDate ASC (nulos por último) — consome o que vence antes | Padrão para alimentos |
weighted_avg | Custo médio ponderado de todos os lotes ativos | Commodities sem diferença de lote |
O método é configurado por item no campo InventoryItem.costMethod. Se não configurado, o default é FEFO.
API de simulação COGS
POST /t/:slug/inventory/:itemId/cogs-simulation
Body: { "qtyConsumed": 30 }Retorna CogsResult com:
totalCost— custo total da baixamethod— método aplicadolotsConsumed— detalhamento por lote (lotId, qty, unitCost, lineCost)qtyCostable— quantidade efetivamente custeable (pode ser <qtyConsumedse estoque insuficiente)shortfall— quantidade sem cobertura de lote
Esta chamada é somente-leitura — não altera lotes.
Alertas de Variação de Preço
Ao importar uma NF-e, o pipeline verifica se o costPerSupplierUnit da nota difere mais de 5% do lastSeenPrice registrado no SupplierProductMap. Se sim, um alerta de variação aparece no Ledger de importação com badge âmbar.
Relacionados
- Estoque — Cadastro de itens, movimentações, schemas
- NF-e Entrada — Pipeline de Importação — Atualização de custo ao confirmar NF-e
- BOM — Fichas Técnicas — Recálculo de custo de prato após atualização de insumo
- DRE — CMV usa
costPricedos movimentos de saída