A solução que você procura contará com um modelo de estilo contábil e algumas listas de materiais (BOM). Seus principais tipos de entidade incluirão:
-
SKU Esta é a lista de coisas que você vende. Suas propriedades incluirão coisas como descrição do produto e preço de varejo atual. Você pode ser sofisticado e dividir o preço em uma tabela filho que fornece os preços ao longo do tempo. Vamos supor que você vai deixar essa ruga de fora por enquanto. Alguns SKUs podem ser "combos" do tipo que você está falando.
-
COMPONENTE Esta é a lista de coisas que compõem um SKU, como guardanapos, copos, pães, rissóis, xarope de coca etc. - para usar seu exemplo. Assim como o SKU possui descrições e preços, os COMPONENTES possuem descrições e custos unitários. (O que também pode ser historiado em uma tabela filha.) Esta tabela é onde você normalmente armazenaria seu ROP também.
-
COMPOSIÇÃO Este é um BOM que cruza SKU e COMPONENTE e diz quantas unidades de cada COMPONENTE cabem em uma unidade de um SKU. Você precisa de um desses para cruzar dois SKUs também (para combos). Você pode usar uma tabela ou duas tabelas para isso. Duas mesas manterão os puristas felizes, uma mesa será conveniente do ponto de vista do codificador.
-
VENDA Esta é uma tabela de transações que fornece um cabeçalho para registrar uma venda de um ou mais SKUs. Essa tabela teria itens como data da transação, ID do caixa e outros itens de cabeçalho.
-
SALE_ITEM Esta é a tabela de detalhes da transação que inclui qual SKU foi vendido (e quantos) e por quanto. O quanto é uma desnormalização do preço do SKU no momento da venda, mas também pode incluir quaisquer substituições especiais no preço. O preço realmente cobrado pelo SKU é uma boa coisa para desnormalizar porque alguém poderia editar o preço de tabela no SKU e então você perderia o controle de quanto foi realmente cobrado pelo item no momento.
-
INVENTORY_HDR Esta é uma tabela transacional que é semelhante à SALE conceitualmente, mas é o cabeçalho para uma transação de estoque, como recebimento de novo estoque, uso de estoque (como ao vendê-lo) e para ajustes de estoque. Novamente, isso seria um material de data/descrição, mas pode incluir um link direto para um SALE_ITEM para movimentos de estoque que são vendas, se desejar. Você não precisa fazer dessa forma, mas algumas pessoas gostam de estabelecer a conexão entre receitas e custos transação por transação.
-
INVENTORY_DTL Este é o detalhe de uma transação de estoque. Isso indica qual COMPONENT está entrando ou saindo, a quantidade que entrou ou saiu e a transação INVENTORY_HDR à qual esse movimento foi aplicado. Isso também seria onde você mantém o custo real pago pelo item de componente.
-
LOCAL Você pode (se desejar) também rastrear a localização física do inventário que recebe e usa/vende. Em um restaurante, isso pode não ser importante, mas se você tiver uma rede ou se o seu restaurante tiver um depósito externo para ingredientes componentes, talvez você se importe.
Considere o seguinte ERD:
Para fazer sua contabilidade de receita, você somaria o dinheiro registrado na tabela SALE_ITEM.
Os níveis de estoque são calculados com base na soma das entradas e saídas INVENTORY_DTL para cada COMPONENTE. (Não armazene os níveis de estoque atuais em uma tabela - isso está fadado a causar problemas de reconciliação.)
Para fazer sua contabilidade de custos, você somaria o dinheiro registrado na tabela INVENTORY_DTL. Observe que você normalmente não saberá exatamente qual guardanapo ou pão que você vendeu, portanto, não será possível vincular recibos de componentes específicos a vendas de SKU específicas. Em vez disso, você precisa ter uma convenção para determinar quais componentes foram usados para qualquer SKU. Você pode ter regras contábeis que especificam qual convenção você deve usar. A maioria das pessoas usa FIFO. Algumas indústrias usam LIFO e eu até vi contabilidade de custo médio ponderado.