test_protocol_sample_payment.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. """按样本缴费:转账状态机与批次已缴/欠缴计算"""
  2. from decimal import Decimal
  3. import unittest
  4. from app.services.protocol_transfer_status import (
  5. can_confirm_receipt,
  6. can_edit_transfer,
  7. can_submit_receipt,
  8. schedule_paid_and_arrears,
  9. )
  10. class TestTransferStatusRules(unittest.TestCase):
  11. def test_submit_only_dfj(self):
  12. self.assertTrue(can_submit_receipt("dfj"))
  13. self.assertFalse(can_submit_receipt("jfqrz"))
  14. self.assertFalse(can_submit_receipt("yjf"))
  15. self.assertFalse(can_submit_receipt(""))
  16. self.assertFalse(can_submit_receipt(None))
  17. def test_confirm_only_jfqrz(self):
  18. self.assertTrue(can_confirm_receipt("jfqrz"))
  19. self.assertFalse(can_confirm_receipt("dfj"))
  20. self.assertFalse(can_confirm_receipt("yjf"))
  21. def test_edit_before_finance_confirm(self):
  22. """已付款、付款确认中可编辑;付款完成不可编辑。"""
  23. self.assertTrue(can_edit_transfer("dfj"))
  24. self.assertTrue(can_edit_transfer("jfqrz"))
  25. self.assertFalse(can_edit_transfer("yjf"))
  26. self.assertFalse(can_edit_transfer(""))
  27. self.assertFalse(can_edit_transfer(None))
  28. def test_schedule_arrears(self):
  29. paid, arrears = schedule_paid_and_arrears(
  30. due=Decimal("1000"),
  31. confirmed_transfers=[Decimal("300"), Decimal("200")],
  32. )
  33. self.assertEqual(paid, Decimal("500"))
  34. self.assertEqual(arrears, Decimal("500"))
  35. def test_schedule_arrears_overpay(self):
  36. paid, arrears = schedule_paid_and_arrears(
  37. due=Decimal("100"),
  38. confirmed_transfers=[Decimal("60"), Decimal("50")],
  39. )
  40. self.assertEqual(paid, Decimal("110"))
  41. self.assertEqual(arrears, Decimal("-10"))
  42. class TestProtocolWithdrawReceipt(unittest.TestCase):
  43. def test_withdraw_sets_dfj_keeps_finance_remark(self):
  44. from types import SimpleNamespace
  45. from unittest.mock import MagicMock
  46. from app.crud import protocol_sample_payment as psp
  47. t = SimpleNamespace(
  48. id="t1",
  49. pay_status="jfqrz",
  50. finance_remark="keep-me",
  51. finance_confirm_attachments="http://x",
  52. update_by=None,
  53. update_time=None,
  54. tenant_no="zkxw",
  55. del_flag=0,
  56. )
  57. db = MagicMock()
  58. orig = psp._get_transfer_with_schedule_lock
  59. psp._get_transfer_with_schedule_lock = lambda *a, **k: t
  60. try:
  61. out = psp.withdraw_receipt(
  62. db, transfer_id="t1", tenant_no="zkxw", user_id="u1"
  63. )
  64. self.assertEqual(out.pay_status, "dfj")
  65. self.assertEqual(out.finance_remark, "keep-me")
  66. self.assertEqual(out.finance_confirm_attachments, "http://x")
  67. db.commit.assert_called()
  68. finally:
  69. psp._get_transfer_with_schedule_lock = orig
  70. def test_withdraw_rejects_non_jfqrz(self):
  71. from types import SimpleNamespace
  72. from unittest.mock import MagicMock
  73. from app.crud import protocol_sample_payment as psp
  74. t = SimpleNamespace(
  75. id="t1",
  76. pay_status="dfj",
  77. finance_remark="x",
  78. tenant_no="zkxw",
  79. del_flag=0,
  80. )
  81. db = MagicMock()
  82. orig = psp._get_transfer_with_schedule_lock
  83. psp._get_transfer_with_schedule_lock = lambda *a, **k: t
  84. try:
  85. with self.assertRaises(ValueError) as ctx:
  86. psp.withdraw_receipt(
  87. db, transfer_id="t1", tenant_no="zkxw", user_id="u1"
  88. )
  89. self.assertIn("撤回", str(ctx.exception))
  90. finally:
  91. psp._get_transfer_with_schedule_lock = orig
  92. if __name__ == "__main__":
  93. unittest.main()