feat(backend): allow soft-delete of dfj payment transfers
Supports 缴费明细 list-mode row delete for draft transfers. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
5025aa09c2
commit
628a20dbbd
3 files changed
+96
No files matched your search
@@ -467,6 +467,30 @@ async def withdraw_payment_transfer(
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
@router.delete("/payment-transfers/{transfer_id}")
|
||||
async def delete_payment_transfer(
|
||||
transfer_id: str,
|
||||
user: dict = Depends(require_admin_or_super_admin),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
try:
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
user_id = _get_current_user_id(user)
|
||||
obj = psp_svc._get_transfer_or_raise(
|
||||
db, transfer_id=transfer_id, tenant_no=tenant_no
|
||||
)
|
||||
if not _protocol_accessible(db, obj.collection_protocol_id, tenant_no, user):
|
||||
return error_response(403, "无权操作该协议")
|
||||
psp_svc.soft_delete_payment_transfer(
|
||||
db, transfer_id=transfer_id, tenant_no=tenant_no, user_id=user_id
|
||||
)
|
||||
return success_response(None, message="删除成功")
|
||||
except PermissionError as e:
|
||||
return error_response(403, str(e))
|
||||
except ValueError as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
@router.get("/payment-transfers")
|
||||
async def list_payment_transfers(
|
||||
page: int = Query(1, ge=1),
|
||||
|
||||
@@ -901,6 +901,23 @@ def withdraw_receipt(
|
||||
return t
|
||||
|
||||
|
||||
def soft_delete_payment_transfer(
|
||||
db: Session,
|
||||
*,
|
||||
transfer_id: str,
|
||||
tenant_no: str,
|
||||
user_id: Optional[str],
|
||||
) -> None:
|
||||
t = _get_transfer_or_raise(db, transfer_id=transfer_id, tenant_no=tenant_no)
|
||||
if t.pay_status != "dfj":
|
||||
raise ValueError("仅待缴费(已缴费草稿)转账笔可删除")
|
||||
t.del_flag = 1
|
||||
t.update_by = user_id
|
||||
t.update_time = _now()
|
||||
db.add(t)
|
||||
db.commit()
|
||||
|
||||
|
||||
def _transfer_to_dict(
|
||||
db: Session, t: BizProtocolPaymentTransfer, tenant_no: str
|
||||
) -> Dict[str, Any]:
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
"""软删除待缴费(dfj)转账笔"""
|
||||
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from app.crud import protocol_sample_payment as psp
|
||||
|
||||
|
||||
class TestSoftDeletePaymentTransfer(unittest.TestCase):
|
||||
def test_function_exists(self):
|
||||
self.assertTrue(callable(getattr(psp, "soft_delete_payment_transfer", None)))
|
||||
|
||||
def test_soft_delete_dfj_sets_del_flag_and_commits(self):
|
||||
t = SimpleNamespace(
|
||||
id="t1",
|
||||
pay_status="dfj",
|
||||
del_flag=0,
|
||||
update_by=None,
|
||||
update_time=None,
|
||||
)
|
||||
db = MagicMock()
|
||||
orig = psp._get_transfer_or_raise
|
||||
psp._get_transfer_or_raise = lambda *a, **k: t
|
||||
try:
|
||||
with patch.object(psp, "_now", return_value="2026-10-10T12:00:00"):
|
||||
psp.soft_delete_payment_transfer(
|
||||
db, transfer_id="t1", tenant_no="zkxw", user_id="u1"
|
||||
)
|
||||
self.assertEqual(t.del_flag, 1)
|
||||
self.assertEqual(t.update_by, "u1")
|
||||
self.assertEqual(t.update_time, "2026-10-10T12:00:00")
|
||||
db.add.assert_called_once_with(t)
|
||||
db.commit.assert_called_once()
|
||||
finally:
|
||||
psp._get_transfer_or_raise = orig
|
||||
|
||||
def test_soft_delete_rejects_non_dfj(self):
|
||||
t = SimpleNamespace(id="t1", pay_status="jfqrz", del_flag=0)
|
||||
db = MagicMock()
|
||||
orig = psp._get_transfer_or_raise
|
||||
psp._get_transfer_or_raise = lambda *a, **k: t
|
||||
try:
|
||||
with self.assertRaises(ValueError) as ctx:
|
||||
psp.soft_delete_payment_transfer(
|
||||
db, transfer_id="t1", tenant_no="zkxw", user_id="u1"
|
||||
)
|
||||
self.assertIn("删除", str(ctx.exception))
|
||||
db.commit.assert_not_called()
|
||||
finally:
|
||||
psp._get_transfer_or_raise = orig
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user