01
O problema
Peças que saem sem papel são peças que não se cobram. E o stock só se descobre que acabou quando o carro já está levantado na rampa.
02
O modelo
Peças com stock, mínimo, custo e preço. Cada mexida no stock é um movimento: saída para uma reparação ou entrada de uma encomenda.
| Tabela | Para que serve |
|---|---|
| parts | Referência, fornecedor, stock, mínimo, custo, preço e localização. |
| movements | Cada mexida no stock: saída para uma reparação ou entrada de uma encomenda. |
| purchase_orders | Encomenda por fornecedor, com as linhas e se já foi recebida. |
03
As encomendas
O que está abaixo do mínimo é agrupado por fornecedor, com quantidade para voltar ao dobro do mínimo. Ao receber, o stock sobe e fica o movimento de entrada.
ts
// O que está abaixo do mínimo agrupa-se por fornecedor,
// com quantidade para voltar ao dobro do mínimo.
for (const p of parts.filter(p => p.stock < p.min)) {
const lines = bySupplier.get(p.supplier) ?? [];
lines.push({ ref: p.ref, qty: p.min * 2 - p.stock });
bySupplier.set(p.supplier, lines);
}04
O que faria diferente em produção
O stock seria a soma dos movimentos e não um número que se edita, para nunca haver diferença entre o que diz o sistema e o histórico.
sql
-- Em produção o stock é a soma dos movimentos,
-- nunca um número que se edita à mão.
create view part_stock as
select ref, sum(case kind when 'in' then qty else -qty end) as stock
from movements
group by ref;