test_bx_invoice_ledger.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. """发票额度流水汇总与退回幂等。"""
  2. from decimal import Decimal
  3. from app.services.bx.invoice_ledger import (
  4. ENTRY_CREDIT_RELEASE,
  5. ENTRY_CREDIT_UPLOAD,
  6. ENTRY_DEBIT_DELETE,
  7. ENTRY_DEBIT_REIMBURSE,
  8. should_skip_release,
  9. summarize_entries,
  10. )
  11. def test_summarize_upload_and_reimburse():
  12. rows = [
  13. {"entry_type": ENTRY_CREDIT_UPLOAD, "amount": Decimal("1000")},
  14. {"entry_type": ENTRY_DEBIT_REIMBURSE, "amount": Decimal("300")},
  15. ]
  16. s = summarize_entries(rows)
  17. assert s["total_amount"] == Decimal("1000")
  18. assert s["used_amount"] == Decimal("300")
  19. assert s["balance"] == Decimal("700")
  20. def test_summarize_delete_and_release():
  21. rows = [
  22. {"entry_type": ENTRY_CREDIT_UPLOAD, "amount": Decimal("500")},
  23. {"entry_type": ENTRY_DEBIT_DELETE, "amount": Decimal("100")},
  24. {"entry_type": ENTRY_DEBIT_REIMBURSE, "amount": Decimal("200")},
  25. {"entry_type": ENTRY_CREDIT_RELEASE, "amount": Decimal("200")},
  26. ]
  27. s = summarize_entries(rows)
  28. assert s["total_amount"] == Decimal("400")
  29. assert s["used_amount"] == Decimal("0")
  30. assert s["balance"] == Decimal("400")
  31. def test_release_idempotent_guard():
  32. assert should_skip_release(has_debit=True, has_release=True) is True
  33. assert should_skip_release(has_debit=True, has_release=False) is False
  34. assert should_skip_release(has_debit=False, has_release=False) is True
  35. def test_summarize_allows_negative_balance():
  36. """提交占用可超过已上传总额,余额可为负(补票后再回升)。"""
  37. rows = [
  38. {"entry_type": ENTRY_CREDIT_UPLOAD, "amount": Decimal("100")},
  39. {"entry_type": ENTRY_DEBIT_REIMBURSE, "amount": Decimal("300")},
  40. ]
  41. s = summarize_entries(rows)
  42. assert s["total_amount"] == Decimal("100")
  43. assert s["used_amount"] == Decimal("300")
  44. assert s["balance"] == Decimal("-200")