Coverage for domain/reports.py: 100%

12 statements  

« prev     ^ index     » next       coverage.py v7.17.0, created at 2026-11-04 17:24 +0000

1"""Pure domain logic for the Reports & MCR dashboard (add-reports-mcr-api). 

2 

3Pure, side-effect-free. Zero dependencies on Django or external databases. 

4""" 

5 

6from __future__ import annotations 

7 

8import datetime 

9from decimal import ROUND_HALF_UP, Decimal 

10 

11_CENTS = Decimal("0.01") 

12_BROKER_COMP_BPS = Decimal("200") 

13 

14# A loan not in ADVERSE counts as "active" everywhere in Reports & MCR (design.md): 

15# the one concrete signal is the frontend mock's single ADVERSE-stage seed loan, 

16# excluded uniformly from pipeline, revenue, and call-report figures. SUSPENDED 

17# stays active — it is resumable (LOAN_TRANSITIONS), unlike ADVERSE, a dead end. 

18_INACTIVE_STAGES = frozenset({"ADVERSE"}) 

19 

20 

21def is_active_loan(stage: str) -> bool: 

22 return stage not in _INACTIVE_STAGES 

23 

24 

25def broker_compensation(base_loan_amt: Decimal) -> Decimal: 

26 """Flat 200bps of the base loan amount (reports.types.ts `est_comp_amt`/`broker_comp`).""" 

27 return (base_loan_amt * _BROKER_COMP_BPS / Decimal("10000")).quantize( 

28 _CENTS, rounding=ROUND_HALF_UP 

29 ) 

30 

31 

32def quarter_of(dt: datetime.date | datetime.datetime) -> int: 

33 """The calendar quarter (1-4) a date falls in.""" 

34 return (dt.month - 1) // 3 + 1