Add engagement margin reporting
This commit is contained in:
parent
33883e0977
commit
8338c501ed
10 changed files with 397 additions and 8 deletions
|
|
@ -5,7 +5,14 @@ import pytest
|
|||
|
||||
from fin_hub.services.evaluate import evaluate_runway
|
||||
from fin_hub.services.evidence import build_runway_report, seed_fixture_ledger, write_runway_evidence
|
||||
from fin_hub.services.ledger import import_csv, monthly_burn_series, monthly_summary, set_opening_balance
|
||||
from fin_hub.services.ledger import (
|
||||
client_margin_report,
|
||||
import_csv,
|
||||
monthly_burn_series,
|
||||
monthly_summary,
|
||||
record_engagement_price,
|
||||
set_opening_balance,
|
||||
)
|
||||
|
||||
FIXTURES = Path(__file__).parent / "fixtures"
|
||||
|
||||
|
|
@ -84,6 +91,107 @@ def test_existing_ledger_schema_is_migrated_additively(tmp_path: Path):
|
|||
}.issubset(columns)
|
||||
|
||||
|
||||
def test_engagement_price_and_margin_report(tmp_path: Path):
|
||||
source = tmp_path / "attributed.csv"
|
||||
source.write_text(
|
||||
"product,amount,currency,invoice_date,client_id,application_id,app_instance_id\n"
|
||||
"Managed cluster,42.00,EUR,2026-07-01,acme,portal,prod-01\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
ledger = tmp_path / "ledger.db"
|
||||
import_csv(source, "hosteurope", ledger_path=ledger)
|
||||
price = record_engagement_price(
|
||||
client_id="acme",
|
||||
application_id="portal",
|
||||
app_instance_id="prod-01",
|
||||
period_month="2026-07",
|
||||
amount=100.0,
|
||||
currency="eur",
|
||||
source="agreement-2026-01",
|
||||
ledger_path=ledger,
|
||||
)
|
||||
|
||||
margins = client_margin_report(ledger_path=ledger)
|
||||
|
||||
assert margins[0].price_id == price.id
|
||||
assert margins[0].revenue == 100.0
|
||||
assert margins[0].attributed_cost == 42.0
|
||||
assert margins[0].margin == 58.0
|
||||
assert margins[0].currency == "EUR"
|
||||
|
||||
|
||||
def test_engagement_price_revision_supersedes_prior_price(tmp_path: Path):
|
||||
ledger = tmp_path / "ledger.db"
|
||||
original = record_engagement_price(
|
||||
client_id="acme",
|
||||
application_id="portal",
|
||||
app_instance_id="prod-01",
|
||||
period_month="2026-07",
|
||||
amount=100.0,
|
||||
currency="EUR",
|
||||
source="agreement-v1",
|
||||
ledger_path=ledger,
|
||||
)
|
||||
revision = record_engagement_price(
|
||||
client_id="acme",
|
||||
application_id="portal",
|
||||
app_instance_id="prod-01",
|
||||
period_month="2026-07",
|
||||
amount=120.0,
|
||||
currency="EUR",
|
||||
source="agreement-v2",
|
||||
revision_of=original.id,
|
||||
ledger_path=ledger,
|
||||
)
|
||||
|
||||
margins = client_margin_report(ledger_path=ledger)
|
||||
|
||||
assert [(row.price_id, row.revenue) for row in margins] == [(revision.id, 120.0)]
|
||||
|
||||
|
||||
def test_engagement_price_requires_explicit_revision(tmp_path: Path):
|
||||
ledger = tmp_path / "ledger.db"
|
||||
kwargs = {
|
||||
"client_id": "acme",
|
||||
"application_id": "portal",
|
||||
"app_instance_id": "prod-01",
|
||||
"period_month": "2026-07",
|
||||
"amount": 100.0,
|
||||
"currency": "EUR",
|
||||
"source": "agreement",
|
||||
"ledger_path": ledger,
|
||||
}
|
||||
original = record_engagement_price(**kwargs)
|
||||
|
||||
with pytest.raises(ValueError, match=original.id):
|
||||
record_engagement_price(**kwargs)
|
||||
|
||||
|
||||
def test_margin_does_not_join_cost_in_another_currency(tmp_path: Path):
|
||||
source = tmp_path / "attributed.csv"
|
||||
source.write_text(
|
||||
"product,amount,currency,invoice_date,client_id,application_id,app_instance_id\n"
|
||||
"Managed cluster,42.00,USD,2026-07-01,acme,portal,prod-01\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
ledger = tmp_path / "ledger.db"
|
||||
import_csv(source, "hosteurope", ledger_path=ledger)
|
||||
record_engagement_price(
|
||||
client_id="acme",
|
||||
application_id="portal",
|
||||
app_instance_id="prod-01",
|
||||
period_month="2026-07",
|
||||
amount=100.0,
|
||||
currency="EUR",
|
||||
source="agreement",
|
||||
ledger_path=ledger,
|
||||
)
|
||||
|
||||
margin = client_margin_report(ledger_path=ledger)[0]
|
||||
assert margin.attributed_cost == 0.0
|
||||
assert margin.margin == 100.0
|
||||
|
||||
|
||||
def test_evaluate_runway_from_ledger(tmp_path: Path):
|
||||
ledger = tmp_path / "ledger.db"
|
||||
seed_fixture_ledger(ledger_path=ledger, opening_balance=12000.0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue