Align displayPaidAmount/arrears with business rule: 已缴费 excludes 已付款 and 付款确认中 transfers. Co-authored-by: Cursor <cursoragent@cursor.com>
47 lines
1.3 KiB
Python
47 lines
1.3 KiB
Python
"""催缴纳入规则(纯函数)"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from datetime import date, timedelta
|
||
from decimal import Decimal
|
||
from typing import Any, Dict, Iterable, Mapping, Optional, Tuple
|
||
|
||
from app.services.sample_payment_period_summary import summarize_period
|
||
|
||
|
||
def _dec(v: Any) -> Decimal:
|
||
if v is None or v == "":
|
||
return Decimal("0")
|
||
return Decimal(str(v))
|
||
|
||
|
||
def chase_period_money(
|
||
*,
|
||
due_amount: Any,
|
||
transfers: Iterable[Mapping[str, Any]],
|
||
) -> Tuple[Decimal, Decimal]:
|
||
"""已缴 = 仅 yjf;欠缴 = max(应缴 − 已缴, 0)。"""
|
||
summary: Dict[str, Any] = summarize_period(
|
||
due_amount=due_amount, transfers=transfers
|
||
)
|
||
return summary["displayPaidAmount"], summary["arrearsAmount"]
|
||
|
||
|
||
def is_chase_candidate(*, due_date: date, today: date, arrears: Any) -> bool:
|
||
"""欠缴>0,且应缴日已逾期或落在 [today, today+30]。"""
|
||
if _dec(arrears) <= 0:
|
||
return False
|
||
if due_date < today:
|
||
return True
|
||
return today <= due_date <= today + timedelta(days=30)
|
||
|
||
|
||
def parse_due_date_ymd(raw: Any) -> Optional[date]:
|
||
s = str(raw or "").strip().replace("-", "")[:8]
|
||
if len(s) != 8 or not s.isdigit():
|
||
return None
|
||
try:
|
||
return date(int(s[:4]), int(s[4:6]), int(s[6:8]))
|
||
except ValueError:
|
||
return None
|