137 lines
5.3 KiB
Python
137 lines
5.3 KiB
Python
"""样本缴费进度:状态码与已缴/待缴汇总"""
|
|
|
|
from decimal import Decimal
|
|
import unittest
|
|
|
|
from app.services.sample_payment_progress import (
|
|
compute_sample_payment_progress,
|
|
)
|
|
|
|
|
|
class TestSamplePaymentProgress(unittest.TestCase):
|
|
def test_pending_when_no_transfers(self):
|
|
r = compute_sample_payment_progress(
|
|
schedules=[
|
|
{"scheduleStatus": "open", "dueAmount": Decimal("1000")},
|
|
],
|
|
transfers=[],
|
|
)
|
|
self.assertEqual(r["progressStatus"], "dfj")
|
|
self.assertEqual(r["paidAmount"], Decimal("0"))
|
|
self.assertEqual(r["dueRemainAmount"], Decimal("1000"))
|
|
self.assertEqual(r["clearedScheduleCount"], 0)
|
|
self.assertEqual(r["activeScheduleCount"], 1)
|
|
self.assertTrue(r["canConfirm"])
|
|
|
|
def test_confirming_does_not_set_progress_status(self):
|
|
"""付款确认中不再作为样本缴费进度;有 yjf 则部分已缴,仍不可再提交确认。"""
|
|
r = compute_sample_payment_progress(
|
|
schedules=[
|
|
{"id": "s1", "scheduleStatus": "open", "dueAmount": Decimal("1000")},
|
|
],
|
|
transfers=[
|
|
{"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("200")},
|
|
{"scheduleId": "s1", "payStatus": "jfqrz", "transferAmount": Decimal("100")},
|
|
],
|
|
)
|
|
self.assertEqual(r["progressStatus"], "bfyj")
|
|
self.assertEqual(r["paidAmount"], Decimal("200"))
|
|
self.assertFalse(r["canConfirm"])
|
|
|
|
def test_confirming_only_stays_pending(self):
|
|
"""仅有付款确认中、尚无 yjf 时,缴费进度仍为待缴费。"""
|
|
r = compute_sample_payment_progress(
|
|
schedules=[
|
|
{"id": "s1", "scheduleStatus": "open", "dueAmount": Decimal("1000")},
|
|
],
|
|
transfers=[
|
|
{"scheduleId": "s1", "payStatus": "jfqrz", "transferAmount": Decimal("100")},
|
|
],
|
|
)
|
|
self.assertEqual(r["progressStatus"], "dfj")
|
|
self.assertEqual(r["paidAmount"], Decimal("0"))
|
|
self.assertFalse(r["canConfirm"])
|
|
|
|
def test_partial_paid(self):
|
|
r = compute_sample_payment_progress(
|
|
schedules=[
|
|
{"id": "s1", "scheduleStatus": "cleared", "dueAmount": Decimal("500")},
|
|
{"id": "s2", "scheduleStatus": "open", "dueAmount": Decimal("500")},
|
|
],
|
|
transfers=[
|
|
{"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("500")},
|
|
],
|
|
)
|
|
self.assertEqual(r["progressStatus"], "bfyj")
|
|
self.assertEqual(r["clearedScheduleCount"], 1)
|
|
self.assertEqual(r["activeScheduleCount"], 2)
|
|
self.assertTrue(r["canConfirm"])
|
|
|
|
def test_open_schedule_is_cleared_when_confirmed_paid_covers_due(self):
|
|
"""财务已确认实缴覆盖应缴时,即使批次仍是 open,也按已缴清计。"""
|
|
r = compute_sample_payment_progress(
|
|
schedules=[
|
|
{
|
|
"id": "s1",
|
|
"scheduleStatus": "open",
|
|
"dueAmount": Decimal("22880.00"),
|
|
},
|
|
],
|
|
transfers=[
|
|
{
|
|
"scheduleId": "s1",
|
|
"payStatus": "yjf",
|
|
"transferAmount": Decimal("22880.00"),
|
|
},
|
|
],
|
|
)
|
|
self.assertEqual(r["progressStatus"], "yjq")
|
|
self.assertEqual(r["clearedScheduleCount"], 1)
|
|
self.assertEqual(r["activeScheduleCount"], 1)
|
|
self.assertEqual(r["dueRemainAmount"], Decimal("0"))
|
|
self.assertFalse(r["canConfirm"])
|
|
|
|
def test_partial_confirmed_on_open_schedule_stays_partial(self):
|
|
r = compute_sample_payment_progress(
|
|
schedules=[
|
|
{"id": "s1", "scheduleStatus": "open", "dueAmount": Decimal("100")},
|
|
],
|
|
transfers=[
|
|
{"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("20")},
|
|
],
|
|
)
|
|
self.assertEqual(r["progressStatus"], "bfyj")
|
|
self.assertEqual(r["clearedScheduleCount"], 0)
|
|
self.assertEqual(r["activeScheduleCount"], 1)
|
|
|
|
def test_all_cleared(self):
|
|
r = compute_sample_payment_progress(
|
|
schedules=[
|
|
{"id": "s1", "scheduleStatus": "cleared", "dueAmount": Decimal("500")},
|
|
{"id": "s2", "scheduleStatus": "void", "dueAmount": Decimal("500")},
|
|
],
|
|
transfers=[
|
|
{"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("500")},
|
|
],
|
|
)
|
|
self.assertEqual(r["progressStatus"], "yjq")
|
|
self.assertEqual(r["activeScheduleCount"], 1)
|
|
self.assertEqual(r["clearedScheduleCount"], 1)
|
|
self.assertFalse(r["canConfirm"])
|
|
self.assertEqual(r["dueRemainAmount"], Decimal("0"))
|
|
|
|
def test_void_schedules_ignored(self):
|
|
r = compute_sample_payment_progress(
|
|
schedules=[
|
|
{"scheduleStatus": "void", "dueAmount": Decimal("9999")},
|
|
{"scheduleStatus": "open", "dueAmount": Decimal("100")},
|
|
],
|
|
transfers=[],
|
|
)
|
|
self.assertEqual(r["activeScheduleCount"], 1)
|
|
self.assertEqual(r["dueRemainAmount"], Decimal("100"))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|