feat: Add currency and unit support across models, routes, and templates; enhance UI for consumption, costs, and production
This commit is contained in:
@@ -111,21 +111,27 @@ def seeded_ui_data(db_session: Session) -> Generator[Dict[str, Any], None, None]
|
||||
scenario_id=scenario.id,
|
||||
amount=1_000_000.0,
|
||||
description="Drill purchase",
|
||||
currency_code="USD",
|
||||
)
|
||||
opex = Opex(
|
||||
scenario_id=scenario.id,
|
||||
amount=250_000.0,
|
||||
description="Fuel spend",
|
||||
currency_code="USD",
|
||||
)
|
||||
consumption = Consumption(
|
||||
scenario_id=scenario.id,
|
||||
amount=1_200.0,
|
||||
description="Diesel (L)",
|
||||
unit_name="Liters",
|
||||
unit_symbol="L",
|
||||
)
|
||||
production = ProductionOutput(
|
||||
scenario_id=scenario.id,
|
||||
amount=800.0,
|
||||
description="Ore (tonnes)",
|
||||
unit_name="Tonnes",
|
||||
unit_symbol="t",
|
||||
)
|
||||
equipment = Equipment(
|
||||
scenario_id=scenario.id,
|
||||
|
||||
@@ -25,6 +25,8 @@ def test_create_consumption(client: TestClient) -> None:
|
||||
"scenario_id": scenario_id,
|
||||
"amount": 125.5,
|
||||
"description": "Fuel usage baseline",
|
||||
"unit_name": "Liters",
|
||||
"unit_symbol": "L",
|
||||
}
|
||||
|
||||
response = client.post("/api/consumption/", json=payload)
|
||||
@@ -34,6 +36,7 @@ def test_create_consumption(client: TestClient) -> None:
|
||||
assert body["scenario_id"] == scenario_id
|
||||
assert body["amount"] == pytest.approx(125.5)
|
||||
assert body["description"] == "Fuel usage baseline"
|
||||
assert body["unit_symbol"] == "L"
|
||||
|
||||
|
||||
def test_list_consumption_returns_created_items(client: TestClient) -> None:
|
||||
@@ -46,6 +49,8 @@ def test_list_consumption_returns_created_items(client: TestClient) -> None:
|
||||
"scenario_id": scenario_id,
|
||||
"amount": amount,
|
||||
"description": f"Consumption {amount}",
|
||||
"unit_name": "Tonnes",
|
||||
"unit_symbol": "t",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
@@ -7,6 +7,7 @@ from main import app
|
||||
|
||||
|
||||
def setup_module(module):
|
||||
Base.metadata.drop_all(bind=engine)
|
||||
Base.metadata.create_all(bind=engine)
|
||||
|
||||
|
||||
@@ -34,12 +35,14 @@ def test_create_and_list_capex_and_opex():
|
||||
"scenario_id": sid,
|
||||
"amount": 1000.0,
|
||||
"description": "Initial capex",
|
||||
"currency_code": "USD",
|
||||
}
|
||||
resp2 = client.post("/api/costs/capex", json=capex_payload)
|
||||
assert resp2.status_code == 200
|
||||
capex = resp2.json()
|
||||
assert capex["scenario_id"] == sid
|
||||
assert capex["amount"] == 1000.0
|
||||
assert capex["currency_code"] == "USD"
|
||||
|
||||
resp3 = client.get("/api/costs/capex")
|
||||
assert resp3.status_code == 200
|
||||
@@ -51,12 +54,14 @@ def test_create_and_list_capex_and_opex():
|
||||
"scenario_id": sid,
|
||||
"amount": 500.0,
|
||||
"description": "Recurring opex",
|
||||
"currency_code": "USD",
|
||||
}
|
||||
resp4 = client.post("/api/costs/opex", json=opex_payload)
|
||||
assert resp4.status_code == 200
|
||||
opex = resp4.json()
|
||||
assert opex["scenario_id"] == sid
|
||||
assert opex["amount"] == 500.0
|
||||
assert opex["currency_code"] == "USD"
|
||||
|
||||
resp5 = client.get("/api/costs/opex")
|
||||
assert resp5.status_code == 200
|
||||
@@ -71,8 +76,12 @@ def test_multiple_capex_entries():
|
||||
for amount in amounts:
|
||||
resp = client.post(
|
||||
"/api/costs/capex",
|
||||
json={"scenario_id": sid, "amount": amount,
|
||||
"description": f"Capex {amount}"},
|
||||
json={
|
||||
"scenario_id": sid,
|
||||
"amount": amount,
|
||||
"description": f"Capex {amount}",
|
||||
"currency_code": "EUR",
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
|
||||
@@ -91,8 +100,12 @@ def test_multiple_opex_entries():
|
||||
for amount in amounts:
|
||||
resp = client.post(
|
||||
"/api/costs/opex",
|
||||
json={"scenario_id": sid, "amount": amount,
|
||||
"description": f"Opex {amount}"},
|
||||
json={
|
||||
"scenario_id": sid,
|
||||
"amount": amount,
|
||||
"description": f"Opex {amount}",
|
||||
"currency_code": "CAD",
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ def test_create_production_record(client: TestClient) -> None:
|
||||
"scenario_id": scenario_id,
|
||||
"amount": 475.25,
|
||||
"description": "Daily output",
|
||||
"unit_name": "Tonnes",
|
||||
"unit_symbol": "t",
|
||||
}
|
||||
|
||||
response = client.post("/api/production/", json=payload)
|
||||
@@ -33,6 +35,7 @@ def test_create_production_record(client: TestClient) -> None:
|
||||
assert created["scenario_id"] == scenario_id
|
||||
assert created["amount"] == pytest.approx(475.25)
|
||||
assert created["description"] == "Daily output"
|
||||
assert created["unit_symbol"] == "t"
|
||||
|
||||
|
||||
def test_list_production_filters_by_scenario(client: TestClient) -> None:
|
||||
@@ -46,6 +49,8 @@ def test_list_production_filters_by_scenario(client: TestClient) -> None:
|
||||
"scenario_id": scenario_id,
|
||||
"amount": amount,
|
||||
"description": f"Output {amount}",
|
||||
"unit_name": "Kilograms",
|
||||
"unit_symbol": "kg",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
Reference in New Issue
Block a user