Coverage for apps/core_los/reports_api.py: 98%

78 statements  

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

1"""Reports & MCR: org-wide pipeline/revenue/call-report endpoints (mounted at ""). 

2 

3The MCR line item (`GET /{guid}/mcr`) and its exclude toggle (`PATCH /{guid}/mcr-exclude`) 

4are loan sub-resources and live on the loans router in `apps/core_los/api.py`, which 

5imports `_pass_through_fees` from here. 

6""" 

7 

8from __future__ import annotations 

9 

10from decimal import Decimal 

11 

12from django.db.models import Sum 

13from django.utils import timezone 

14from ninja import Router 

15 

16from apps.accounts.auth import requires, staff_loan_queryset 

17from apps.core_los.reports_schemas import CallReportOut, PipelineReportOut, RevenueReportOut 

18from apps.core_los.schemas import _safe_transaction 

19from apps.pricing_ppe.models import RateLock 

20from domain.enums import LoanStage, PaidToType 

21from domain.reports import broker_compensation, is_active_loan, quarter_of 

22 

23router = Router(tags=["reports"]) 

24 

25_PASS_THROUGH_PAID_TO = [PaidToType.THIRD_PARTY.value, PaidToType.GOVERNMENT.value] 

26 

27 

28def _pass_through_fees(loan) -> Decimal: 

29 """Third-party and government fees not Paid Outside of Closing (reports.types.ts).""" 

30 total = loan.fees.filter( 

31 paid_to__in=_PASS_THROUGH_PAID_TO, poc_ind=False 

32 ).aggregate(Sum("total_amt"))["total_amt__sum"] 

33 return total or Decimal("0.00") 

34 

35 

36def _is_locked(loan) -> bool: 

37 try: 

38 lock = loan.rate_lock 

39 except RateLock.DoesNotExist: 

40 return False 

41 return lock.status in ("LOCKED", "RELOCKED") and lock.expires_at > timezone.now() 

42 

43 

44def _active_loans(request): 

45 qs = staff_loan_queryset(request.principal, "all").select_related( 

46 "transaction", "rate_lock" 

47 ) 

48 return [loan for loan in qs if is_active_loan(loan.stage)] 

49 

50 

51@router.get("/reports/pipeline", response=PipelineReportOut, auth=requires("LOAN_VIEW")) 

52def pipeline_report(request): 

53 loans = _active_loans(request) 

54 by_stage: dict[str, dict] = {} 

55 total_volume = Decimal("0.00") 

56 for loan in loans: 

57 txn = _safe_transaction(loan) 

58 amt = txn.base_loan_amt if txn else Decimal("0.00") 

59 bucket = by_stage.setdefault(loan.stage, {"count": 0, "volume": Decimal("0.00")}) 

60 bucket["count"] += 1 

61 bucket["volume"] += amt 

62 total_volume += amt 

63 return {"total": len(loans), "total_volume": total_volume, "by_stage": by_stage} 

64 

65 

66@router.get("/reports/revenue", response=RevenueReportOut, auth=requires("LOAN_VIEW")) 

67def revenue_report(request): 

68 loans = _active_loans(request) 

69 

70 def volume(subset) -> Decimal: 

71 total = Decimal("0.00") 

72 for loan in subset: 

73 txn = _safe_transaction(loan) 

74 total += txn.base_loan_amt if txn else Decimal("0.00") 

75 return total 

76 

77 funded = [loan for loan in loans if loan.stage == LoanStage.LOAN_FUNDED.value] 

78 locked_pipeline = [ 

79 loan for loan in loans if loan.stage == LoanStage.LOAN_FUNDED.value or _is_locked(loan) 

80 ] 

81 locked_volume = volume(locked_pipeline) 

82 return { 

83 "funded_count": len(funded), 

84 "funded_volume": volume(funded), 

85 "locked_pipeline_count": len(locked_pipeline), 

86 "est_comp_bps": 200, 

87 "est_comp_amt": broker_compensation(locked_volume), 

88 "note": "Revenue reflects only rate-locked and funded loans; floating loans are " 

89 "excluded until locked.", 

90 } 

91 

92 

93@router.get("/reports/call-report", response=CallReportOut, auth=requires("LOAN_VIEW")) 

94def call_report(request, year: int | None = None, quarter: int | None = None): 

95 year = year or timezone.now().year 

96 loans = _active_loans(request) 

97 

98 by_state: dict[str, dict] = {} 

99 applications = 0 

100 excluded = 0 

101 for loan in loans: 

102 created = loan.created_at 

103 if created.year != year: 103 ↛ 104line 103 didn't jump to line 104 because the condition on line 103 was never true

104 continue 

105 if quarter and quarter_of(created) != quarter: 

106 continue 

107 if loan.exclude_from_mcr: 

108 excluded += 1 

109 continue 

110 

111 bucket = by_state.setdefault( 

112 loan.state_code, 

113 { 

114 "applications": 0, 

115 "closed": 0, 

116 "volume": Decimal("0.00"), 

117 "broker_comp": Decimal("0.00"), 

118 "pass_through": Decimal("0.00"), 

119 }, 

120 ) 

121 bucket["applications"] += 1 

122 applications += 1 

123 txn = _safe_transaction(loan) 

124 amt = txn.base_loan_amt if txn else Decimal("0.00") 

125 if loan.stage == LoanStage.LOAN_FUNDED.value: 

126 bucket["closed"] += 1 

127 bucket["volume"] += amt 

128 bucket["broker_comp"] += broker_compensation(amt) 

129 bucket["pass_through"] += _pass_through_fees(loan) 

130 

131 return { 

132 "period": {"year": year, "quarter": f"Q{quarter}" if quarter else "FY"}, 

133 "by_state": by_state, 

134 "totals": {"applications": applications, "excluded": excluded}, 

135 }