103 lines
3.7 KiB
Python
103 lines
3.7 KiB
Python
"""
|
|
Primary acceptance test: process the three Jan-2026 Amazon files and assert the
|
|
engine reproduces the sample workbook's USA receivable to the penny.
|
|
|
|
Benchmarks (from `Accounts Receivable Aging (Jan-26) 1.xlsx`, verified during reverse-engineering):
|
|
Detail!D11 USA receivable (local, rounded) .......... 11,110,433
|
|
Detail!C10 Standard additional sales ............. 11,042,453.21
|
|
Detail!B10 Invoiced additional sales .................. 67,854.71
|
|
Detail!C9 Standard Net Closing Balance (reserve) ....... 125.44
|
|
|
|
This is an integration test over ~2.4M rows; it is slow (~2 min) and skips if the
|
|
sample files are absent. Run with: pytest -m integration
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import date
|
|
|
|
import pytest
|
|
|
|
from app.core.pipeline import process
|
|
|
|
pytestmark = pytest.mark.integration
|
|
|
|
MONTH_END = date(2026, 1, 31)
|
|
RESERVES = {("USA", "Standard Orders"): 125.44, ("USA", "Invoiced Orders"): 0.0}
|
|
|
|
EXP_STANDARD_ADDITIONAL = 11_042_453.21
|
|
EXP_INVOICED_ADDITIONAL = 67_854.71
|
|
EXP_TOTAL_ADDITIONAL = 11_110_307.92
|
|
EXP_RECEIVABLE = 11_110_433
|
|
|
|
PAID = {"25218044401", "25327934061", "25434014921", "25231317951"}
|
|
RECEIVABLE_SETTS = {"25468048861", "25546871121", "25342616501", "25564376091"}
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def result(jan_files):
|
|
return process(
|
|
jan_files, month_end=MONTH_END, clearing_lag_days=2,
|
|
reserves=RESERVES, expected_receivable=EXP_RECEIVABLE,
|
|
)
|
|
|
|
|
|
def test_all_files_parsed(result):
|
|
assert len(result.file_metas) == 3
|
|
total_rows = sum(m.imported_rows for m in result.file_metas)
|
|
assert total_rows > 2_000_000
|
|
for m in result.file_metas:
|
|
assert not m.missing_required
|
|
assert m.currency == "USD"
|
|
|
|
|
|
def test_date_coverage_full_month(result):
|
|
dates = [(m.min_date, m.max_date) for m in result.file_metas]
|
|
all_min = min(d[0] for d in dates)
|
|
all_max = max(d[1] for d in dates)
|
|
assert all_min == date(2026, 1, 1)
|
|
assert all_max == date(2026, 1, 31)
|
|
|
|
|
|
def test_settlement_classification(result):
|
|
usa = {sid: st for (mkt, acct, sid), st in result.aggregation.settlements.items()
|
|
if mkt == "USA"}
|
|
for sid in PAID:
|
|
assert usa[sid].status == "paid", f"{sid} should be paid"
|
|
for sid in RECEIVABLE_SETTS:
|
|
assert usa[sid].status == "receivable", f"{sid} should be receivable"
|
|
|
|
|
|
def test_jan30_transfer_in_transit(result):
|
|
jan30 = [t for t in result.aggregation.transfers
|
|
if t.settlement_id == "25546871121" and t.account_type == "Standard Orders"]
|
|
assert jan30 and jan30[0].received is False
|
|
|
|
|
|
def test_additional_sales_exact(result):
|
|
usa = result.receivable.marketplaces["USA"]
|
|
std = usa.accounts["Standard Orders"].additional_sales
|
|
inv = usa.accounts["Invoiced Orders"].additional_sales
|
|
assert std == pytest.approx(EXP_STANDARD_ADDITIONAL, abs=0.01)
|
|
assert inv == pytest.approx(EXP_INVOICED_ADDITIONAL, abs=0.01)
|
|
assert usa.additional_sales == pytest.approx(EXP_TOTAL_ADDITIONAL, abs=0.01)
|
|
|
|
|
|
def test_receivable_matches_workbook(result):
|
|
usa = result.receivable.marketplaces["USA"]
|
|
assert usa.receivable_local == EXP_RECEIVABLE # 11,110,433 == Detail!D11
|
|
assert usa.receivable_usd == pytest.approx(EXP_RECEIVABLE, abs=0.01)
|
|
|
|
|
|
def test_receivable_base_without_reserve(jan_files):
|
|
"""Without the reserve, the base = additional sales rounded = 11,110,308 (from files alone)."""
|
|
res = process(jan_files, month_end=MONTH_END, clearing_lag_days=2)
|
|
usa = res.receivable.marketplaces["USA"]
|
|
assert usa.receivable_local == 11_110_308
|
|
|
|
|
|
def test_reconciled(result):
|
|
r = result.reconciliation
|
|
assert r.status == "Reconciled"
|
|
assert abs(r.identity_difference) <= 0.01
|
|
assert r.expected_difference is not None and abs(r.expected_difference) <= 0.01
|