Repository navigation
v0.5.0
F&B Margin Kit 0.5.0 calculates menu ingredient costs from purchase pack prices, recipe quantities and usable yields.
Run fnb-recipe ingredients.csv recipes.csv --menu menu.csv --output-dir recipe-report. Recipe quantities are edible use per sold menu unit. For each ingredient, cost equals purchase price multiplied by recipe quantity, divided by purchase pack quantity and usable yield, with both quantities expressed in the same base unit. The command supports g/kg, ml/l and each, with unit conversions within the same dimension.
The audit reports preserve exact rational line and menu costs alongside decimal values. Menu CSV costs round once from the exact value using half-up rounding within the existing numeric input limits. With --menu, the generated costed-menu.csv can be passed directly to fnb-margin; other menu values and row order are preserved.
Both input CSVs and the optional menu are protected from planned output aliases before any report is written. Existing margin, comparison and dashboard commands retain their behavior. The package has no runtime dependencies.
The worked synthetic example includes purchase prices, usable yields, recipe quantities and an existing menu plan, with generated audit and downstream contribution results. Its latte uses 18 g of beans and 180 ml of milk. Beans cost 24,000 per kg; milk costs 3,000 per litre with 0.95 usable yield. The exact recipe cost is 19008/19, exported as 1000.421052631579 per menu unit.
Validation passed 107 unit tests, including 22 recipe tests, and hosted Python 3.10, 3.12 and 3.14 checks. Independent review passed 13 oracle scenarios with 1,189 assertions, 52 invalid-input probes, 42 input/output alias probes, and byte comparisons of 18 report files from six legacy command scenarios.
The actual tagged wheel and linux/amd64 container each passed 16 recipe-command execution checks, including consuming the exported menu with the existing margin command. Their existing margin-package checks also passed: 32 for the installed wheel and 31 for the exact container. The tested container image was then published.