"""Consolidated-from-GL flux computation + tie-out against the .xls report. Pins the LOGIC that decides whether finance-flux can drop its manual upload: the consolidated SuiteQL shape (consolidatedexchangerate join + per-account-type rate), account→line aggregation with sign, and the tie-out comparison vs the .xls figures in finance_flux_lines. The live numeric tie-out runs post-deploy (no NetSuite creds in CI). """ from __future__ import annotations from decimal import Decimal import pytest from app.core.coordinators import finance_flux_gl_coordinator as glc from app.domains.finance_flux.models import ( FinanceFluxAccountMap, FinanceFluxLine, FinanceFluxPeriod, ) PERIOD = "2026-05" # ─── Pure: consolidated SuiteQL shape ─────────────────────────────── def test_consolidated_suiteql_applies_rate_by_type(): q = glc._build_consolidated_suiteql(parent_subsidiary_id=11, period_ids="101,102") assert "consolidatedexchangerate" in q assert "er.tosubsidiary = 11" in q assert "t.postingperiod IN (101,102)" in q # Asset/liab default = currentrate; P&L = averagerate; equity = historical. assert "er.averagerate" in q and "er.currentrate" in q and "er.historicalrate" in q assert "COALESCE(" in q # parent / same-currency rows fall back to 1.0 assert "tal.posting = 'T'" in q # ─── Pure: account → line aggregation ─────────────────────────────── def test_compute_consolidated_lines_aggregates_with_sign(): gl_rows = [ {"account_id": "1", "consolidated_amount": "1000.00"}, {"account_id": "2", "consolidated_amount": "250.00"}, {"account_id": "3", "consolidated_amount": "9999.00"}, # unmapped → ignored {"account_id": "4", "consolidated_amount": "500.00"}, # contra (sign -1) ] amap = { "1": ("BS", "cash_and_equivalents", 1), "2": ("BS", "cash_and_equivalents", 1), "4": ("BS", "cash_and_equivalents", -1), } out = glc.compute_consolidated_lines(gl_rows, amap) # 1000 + 250 - 500 = 750 to one line; unmapped account 3 dropped. assert out[("BS", "cash_and_equivalents")] == Decimal("750.00") assert ("BS", "__unmapped__") not in out assert len(out) == 1 # ─── tie_out comparison (DB-backed, NS pull monkeypatched) ────────── @pytest.mark.asyncio async def test_tie_out_diffs_reported_vs_computed(db_session, monkeypatch): db = db_session # .xls ground truth: a period with two BS lines. period = FinanceFluxPeriod(period_key=PERIOD, label="May 2026") db.add(period) await db.flush() db.add(FinanceFluxLine(period_id=period.id, statement="BS", line_key="cash_and_equivalents", value=Decimal("32228212.53"))) db.add(FinanceFluxLine(period_id=period.id, statement="BS", line_key="accounts_receivable", value=Decimal("1000000.00"))) # account_map: two GL accounts → the two lines. db.add(FinanceFluxAccountMap(ns_account_id="10", account_number="1010", statement="BS", line_key="cash_and_equivalents", sign=1)) db.add(FinanceFluxAccountMap(ns_account_id="20", account_number="1200", statement="BS", line_key="accounts_receivable", sign=1)) await db.flush() async def _fake_pull(_db, _period): return { "parent_subsidiary_id": 11, "rows": [ # Cash ties out exactly; AR is off by 200k (clear variance). {"account_id": "10", "consolidated_amount": "32228212.53"}, {"account_id": "20", "consolidated_amount": "1200000.00"}, ], } monkeypatch.setattr(glc, "_pull_consolidated_accounts", _fake_pull) res = await glc.tie_out(db, PERIOD, "BS") assert res["has_reported"] is True by_line = {r["line_key"]: r for r in res["lines"]} assert by_line["cash_and_equivalents"]["tie"] is True assert by_line["cash_and_equivalents"]["diff_usd"] == "0.00" assert by_line["accounts_receivable"]["tie"] is False assert by_line["accounts_receivable"]["diff_usd"] == "200000.00" assert res["tie_count"] == 1 and res["line_count"] == 2 @pytest.mark.asyncio async def test_tie_out_skips_when_pull_unavailable(db_session, monkeypatch): async def _skip(_db, _period): return {"skipped": "no_connector", "rows": []} monkeypatch.setattr(glc, "_pull_consolidated_accounts", _skip) res = await glc.tie_out(db_session, PERIOD, "BS") assert res["skipped"] == "no_connector"