payment_chase.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. """催缴纳入规则(纯函数)"""
  2. from __future__ import annotations
  3. from datetime import date, timedelta
  4. from decimal import Decimal
  5. from typing import Any, Dict, Iterable, Mapping, Optional, Tuple
  6. from app.services.sample_payment_period_summary import summarize_period
  7. def _dec(v: Any) -> Decimal:
  8. if v is None or v == "":
  9. return Decimal("0")
  10. return Decimal(str(v))
  11. def chase_period_money(
  12. *,
  13. due_amount: Any,
  14. transfers: Iterable[Mapping[str, Any]],
  15. ) -> Tuple[Decimal, Decimal]:
  16. """已缴 = 仅 yjf;欠缴 = max(应缴 − 已缴, 0)。"""
  17. summary: Dict[str, Any] = summarize_period(
  18. due_amount=due_amount, transfers=transfers
  19. )
  20. return summary["displayPaidAmount"], summary["arrearsAmount"]
  21. def is_chase_candidate(*, due_date: date, today: date, arrears: Any) -> bool:
  22. """欠缴>0,且应缴日已逾期或落在 [today, today+30]。"""
  23. if _dec(arrears) <= 0:
  24. return False
  25. if due_date < today:
  26. return True
  27. return today <= due_date <= today + timedelta(days=30)
  28. def parse_due_date_ymd(raw: Any) -> Optional[date]:
  29. value = str(raw or "")
  30. if len(value) == 8 and value.isdigit():
  31. normalized = value
  32. elif (
  33. len(value) == 10
  34. and value[4] == "-"
  35. and value[7] == "-"
  36. and value[:4].isdigit()
  37. and value[5:7].isdigit()
  38. and value[8:].isdigit()
  39. ):
  40. normalized = value.replace("-", "")
  41. else:
  42. return None
  43. try:
  44. return date(
  45. int(normalized[:4]),
  46. int(normalized[4:6]),
  47. int(normalized[6:8]),
  48. )
  49. except ValueError:
  50. return None