Seed additional products, improve left rail, improve search box, add visuals to buttons, rename working documents to working docs and improve left rail nav

This commit is contained in:
2026-04-30 22:27:36 +12:00
parent 4f876372c2
commit 151676265c
10 changed files with 816 additions and 128 deletions
+19 -5
View File
@@ -16,7 +16,7 @@ from app.models.mix import Mix, MixIngredient
from app.models.product import Product
from app.models.raw_material import RawMaterial, RawMaterialPriceVersion
from app.services.client_access_service import build_client_access_export, ensure_user_module_permissions, serialize_client_account
from app.services.costing_engine import calculate_mix_cost, calculate_product_cost, calculate_raw_material_cost
from app.services.costing_engine import calculate_mix_cost, calculate_product_cost, calculate_raw_material_cost, serialize_raw_material
from app.services.mix_calculator_service import calculate_mix_calculator_preview
@@ -38,6 +38,15 @@ def test_calculate_raw_material_cost():
assert result.cost_per_kg == 0.51
def test_serialize_raw_material_ignores_non_positive_active_price():
raw_material = RawMaterial(name="Apple Flavouring", unit_of_measure="kg", kg_per_unit=1, status="active")
raw_material.price_versions.append(RawMaterialPriceVersion(market_value=0, waste_percentage=0, effective_date=date(2026, 4, 1), status="active"))
serialized = serialize_raw_material(raw_material)
assert serialized["current_price"] is None
def test_mix_and_product_cost_breakdown():
db = build_session()
@@ -286,14 +295,17 @@ def test_mix_calculator_endpoints_respect_owner_visibility():
options_response = client.get("/api/mix-calculator/options", headers=superadmin_headers)
assert options_response.status_code == 200
assert options_response.json()["products"][0]["product_name"] == "Hunter Orchard Blend 20kg"
options_payload = options_response.json()
assert len(options_payload["products"]) >= 100
seeded_product = next(product for product in options_payload["products"] if product["product_name"] == "Specialty Pigeon Breeder 20kg")
assert seeded_product["unit_size_kg"] == 20
create_response = client.post(
"/api/mix-calculator",
json={
"mix_date": "2026-04-29",
"client_name": "Hunter Premium Produce",
"product_id": 1,
"client_name": seeded_product["client_name"],
"product_id": seeded_product["product_id"],
"batch_size_kg": 560,
"prepared_by_name": "Amelia Hart",
"notes": "Morning production run",
@@ -302,9 +314,11 @@ def test_mix_calculator_endpoints_respect_owner_visibility():
)
assert create_response.status_code == 201
created = create_response.json()
assert created["product_name"] == seeded_product["product_name"]
assert created["session_number"].startswith("HPP-20260429-")
assert created["total_bags"] == 28
assert created["lines"][0]["required_kg"] == 360
assert len(created["lines"]) > 0
assert created["lines"][0]["required_kg"] > 0
patch_response = client.patch(
f"/api/mix-calculator/{created['id']}",