feat: Enhance currency handling and validation across scenarios
- Updated form template to prefill currency input with default value and added help text for clarity. - Modified integration tests to assert more descriptive error messages for invalid currency codes. - Introduced new tests for currency normalization and validation in various scenarios, including imports and exports. - Added comprehensive tests for pricing calculations, ensuring defaults are respected and overrides function correctly. - Implemented unit tests for pricing settings repository, ensuring CRUD operations and default settings are handled properly. - Enhanced scenario pricing evaluation tests to validate currency handling and metadata defaults. - Added simulation tests to ensure Monte Carlo runs are accurate and handle various distribution scenarios.
This commit is contained in:
@@ -13,6 +13,7 @@ from models import (
|
||||
FinancialCategory,
|
||||
FinancialInput,
|
||||
MiningOperationType,
|
||||
PricingSettings,
|
||||
Project,
|
||||
Scenario,
|
||||
ScenarioStatus,
|
||||
@@ -147,6 +148,30 @@ def test_unit_of_work_commit_and_rollback(engine) -> None:
|
||||
projects = ProjectRepository(session).list()
|
||||
assert len(projects) == 1
|
||||
|
||||
|
||||
def test_unit_of_work_set_project_pricing_settings(engine) -> None:
|
||||
TestingSession = sessionmaker(bind=engine, expire_on_commit=False, future=True)
|
||||
with UnitOfWork(session_factory=TestingSession) as uow:
|
||||
assert uow.projects is not None and uow.pricing_settings is not None
|
||||
project = Project(name="Project Pricing", operation_type=MiningOperationType.OTHER)
|
||||
uow.projects.create(project)
|
||||
pricing_settings = PricingSettings(
|
||||
name="Default Pricing",
|
||||
slug="default",
|
||||
default_currency="usd",
|
||||
default_payable_pct=100.0,
|
||||
moisture_threshold_pct=8.0,
|
||||
moisture_penalty_per_pct=0.0,
|
||||
)
|
||||
uow.pricing_settings.create(pricing_settings)
|
||||
uow.set_project_pricing_settings(project, pricing_settings)
|
||||
|
||||
with TestingSession() as session:
|
||||
repo = ProjectRepository(session)
|
||||
stored = repo.get(1, with_pricing=True)
|
||||
assert stored.pricing_settings is not None
|
||||
assert stored.pricing_settings.slug == "default"
|
||||
|
||||
# Rollback path
|
||||
with pytest.raises(RuntimeError):
|
||||
with UnitOfWork(session_factory=TestingSession) as uow:
|
||||
@@ -302,6 +327,44 @@ def test_project_repository_filtered_for_export(session: Session) -> None:
|
||||
assert results[0].scenarios[0].name == "Alpha Scenario"
|
||||
|
||||
|
||||
def test_project_repository_with_pricing_settings(session: Session) -> None:
|
||||
repo = ProjectRepository(session)
|
||||
settings = PricingSettings(
|
||||
name="Contract Core",
|
||||
slug="contract-core",
|
||||
default_currency="usd",
|
||||
default_payable_pct=95.0,
|
||||
moisture_threshold_pct=7.5,
|
||||
moisture_penalty_per_pct=100.0,
|
||||
)
|
||||
project = Project(
|
||||
name="Project Pricing",
|
||||
operation_type=MiningOperationType.OPEN_PIT,
|
||||
pricing_settings=settings,
|
||||
)
|
||||
session.add(project)
|
||||
session.flush()
|
||||
|
||||
fetched = repo.get(project.id, with_pricing=True)
|
||||
assert fetched.pricing_settings is not None
|
||||
assert fetched.pricing_settings.slug == "contract-core"
|
||||
assert fetched.pricing_settings.default_currency == "USD"
|
||||
|
||||
listed = repo.list(with_pricing=True)
|
||||
assert listed[0].pricing_settings is not None
|
||||
|
||||
repo.set_pricing_settings(project, None)
|
||||
session.refresh(project)
|
||||
assert project.pricing_settings is None
|
||||
|
||||
repo.set_pricing_settings(project, settings)
|
||||
session.refresh(project)
|
||||
assert project.pricing_settings is settings
|
||||
|
||||
export_results = repo.filtered_for_export(None, include_pricing=True)
|
||||
assert export_results[0].pricing_settings is not None
|
||||
|
||||
|
||||
def test_scenario_repository_filtered_for_export(session: Session) -> None:
|
||||
repo = ScenarioRepository(session)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user