feat(pl): set recharge apply to pending when entering disburse node
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
01d607d766
commit
c8174ab3f2
3 files changed
+118
-7
No files matched your search
@@ -6,7 +6,7 @@ from typing import List, Optional
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
RECHARGE_TYPES = {"etc", "fuel", "shanxia", "bailian"}
|
||||
APPLY_STATUSES = {"draft", "in_approval", "rejected", "disbursed", "cancelled"}
|
||||
APPLY_STATUSES = {"draft", "in_approval", "pending", "rejected", "disbursed", "cancelled"}
|
||||
NODE_ACTION_TYPES = {"approve", "disburse"}
|
||||
APPROVAL_STATUSES = {"approved", "rejected", "disbursed"}
|
||||
|
||||
|
||||
@@ -58,8 +58,8 @@ def _current_node(
|
||||
user: DbUserContext,
|
||||
tenant_no: str,
|
||||
) -> BxWorkflowNode:
|
||||
if apply.status != "in_approval" or not apply.current_node:
|
||||
raise HTTPException(status_code=400, detail="申请单不在审批中")
|
||||
if apply.status not in ("in_approval", "pending") or not apply.current_node:
|
||||
raise HTTPException(status_code=400, detail="申请单不在可审批/发放状态")
|
||||
node = (
|
||||
db.query(BxWorkflowNode)
|
||||
.filter(
|
||||
@@ -145,7 +145,7 @@ def list_pending(
|
||||
.filter(
|
||||
PlVehicleRechargeApply.tenant_no == tenant_no,
|
||||
PlVehicleRechargeApply.del_flag == 0,
|
||||
PlVehicleRechargeApply.status == "in_approval",
|
||||
PlVehicleRechargeApply.status.in_(("in_approval", "pending")),
|
||||
BxWorkflowNode.tenant_no == tenant_no,
|
||||
BxWorkflowNode.del_flag == 0,
|
||||
BxWorkflowNode.approver_id == user.id,
|
||||
@@ -294,7 +294,11 @@ def approve_apply(
|
||||
opinion=opinion,
|
||||
now=now,
|
||||
)
|
||||
apply.current_node = nodes[idx + 1].id
|
||||
next_node = nodes[idx + 1]
|
||||
apply.current_node = next_node.id
|
||||
next_action = (next_node.action_type or "approve").strip() or "approve"
|
||||
if next_action == "disburse":
|
||||
apply.status = "pending"
|
||||
apply.update_by = user.id
|
||||
apply.update_time = now
|
||||
sync_approval_notifications(
|
||||
|
||||
@@ -20,7 +20,7 @@ from app.schemas.pl.vehicle_recharge import APPLY_STATUSES, NODE_ACTION_TYPES, R
|
||||
|
||||
|
||||
def test_apply_statuses_include_workflow_states():
|
||||
assert {"draft", "in_approval", "rejected", "disbursed", "cancelled"} <= APPLY_STATUSES
|
||||
assert {"draft", "in_approval", "pending", "rejected", "disbursed", "cancelled"} <= APPLY_STATUSES
|
||||
assert {"approve", "disburse"} <= NODE_ACTION_TYPES
|
||||
assert {"etc", "fuel"} <= RECHARGE_TYPES
|
||||
|
||||
@@ -98,6 +98,40 @@ def _seed_workflow(db) -> tuple[str, str, str]:
|
||||
return wf_id, node_gm, node_fin
|
||||
|
||||
|
||||
def _seed_three_node_workflow(db) -> tuple[str, str, str, str]:
|
||||
wf_id = "wf-3"
|
||||
n1, n2, n3 = "node-a1", "node-a2", "node-dis"
|
||||
db.add(
|
||||
BxWorkflowDef(
|
||||
id=wf_id,
|
||||
biz_type="vehicle_recharge",
|
||||
wf_name="三级充值流程",
|
||||
status=1,
|
||||
tenant_no="t1",
|
||||
create_dept_id="d1",
|
||||
)
|
||||
)
|
||||
for nid, name, order, uid, uname, action in (
|
||||
(n1, "一审", 1, "u-a1", "一审", "approve"),
|
||||
(n2, "二审", 2, "u-a2", "二审", "approve"),
|
||||
(n3, "发放", 3, "u-fin", "财务", "disburse"),
|
||||
):
|
||||
db.add(
|
||||
BxWorkflowNode(
|
||||
id=nid,
|
||||
wf_id=wf_id,
|
||||
node_name=name,
|
||||
node_order=order,
|
||||
approver_id=uid,
|
||||
approver_name=uname,
|
||||
action_type=action,
|
||||
tenant_no="t1",
|
||||
create_dept_id="d1",
|
||||
)
|
||||
)
|
||||
return wf_id, n1, n2, n3
|
||||
|
||||
|
||||
def _patch_scope(monkeypatch, *modules) -> None:
|
||||
for mod in modules:
|
||||
monkeypatch.setattr(mod, "apply_pl_scope", lambda query, *_a, **_k: query)
|
||||
@@ -272,7 +306,7 @@ def test_approve_advances_to_next_node(monkeypatch):
|
||||
result = approval_svc.approve_apply(
|
||||
db, "t1", _user("u-gm", "总经理"), "apply-1", opinion="同意"
|
||||
)
|
||||
assert result.status == "in_approval"
|
||||
assert result.status == "pending"
|
||||
assert result.current_node == node_fin
|
||||
assert any(a.approval_status == "approved" for a in result.approvals)
|
||||
assert len(result.approval_flow) == 2
|
||||
@@ -285,6 +319,79 @@ def test_approve_advances_to_next_node(monkeypatch):
|
||||
assert result.approval_history[0].approval_status == "approved"
|
||||
|
||||
|
||||
def test_mid_approve_stays_in_approval_final_approve_sets_pending(monkeypatch):
|
||||
from app.services import pl_vehicle_recharge_approval_service as approval_svc
|
||||
from app.services import pl_vehicle_recharge_service as svc
|
||||
|
||||
db = _make_session()
|
||||
_seed_vehicle(db)
|
||||
wf_id, n1, n2, n3 = _seed_three_node_workflow(db)
|
||||
db.add(
|
||||
PlVehicleRechargeApply(
|
||||
id="apply-1",
|
||||
apply_no="YK2026092601",
|
||||
license_plate="鄂A00001",
|
||||
recharge_type="fuel",
|
||||
apply_date=date(2026, 9, 26),
|
||||
applicant_id="u-applicant",
|
||||
status="in_approval",
|
||||
wf_id=wf_id,
|
||||
current_node=n1,
|
||||
approval_round=1,
|
||||
tenant_no="t1",
|
||||
create_dept_id="d1",
|
||||
)
|
||||
)
|
||||
db.commit()
|
||||
_patch_scope(monkeypatch, svc)
|
||||
|
||||
mid = approval_svc.approve_apply(db, "t1", _user("u-a1", "一审"), "apply-1", opinion="ok")
|
||||
assert mid.status == "in_approval"
|
||||
assert mid.current_node == n2
|
||||
|
||||
final = approval_svc.approve_apply(db, "t1", _user("u-a2", "二审"), "apply-1", opinion="ok")
|
||||
assert final.status == "pending"
|
||||
assert final.current_node == n3
|
||||
|
||||
|
||||
def test_disburse_accepts_pending_status(monkeypatch):
|
||||
from app.services import pl_vehicle_recharge_approval_service as approval_svc
|
||||
from app.services import pl_vehicle_recharge_service as svc
|
||||
from app.schemas.pl.vehicle_recharge import VehicleRechargeRecordCreate
|
||||
|
||||
db = _make_session()
|
||||
_seed_vehicle(db)
|
||||
wf_id, _gm, node_fin = _seed_workflow(db)
|
||||
db.add(
|
||||
PlVehicleRechargeApply(
|
||||
id="apply-1",
|
||||
apply_no="ETC2026092601",
|
||||
license_plate="鄂A00001",
|
||||
recharge_type="etc",
|
||||
apply_date=date(2026, 9, 26),
|
||||
applicant_id="u-applicant",
|
||||
status="pending",
|
||||
wf_id=wf_id,
|
||||
current_node=node_fin,
|
||||
approval_round=1,
|
||||
tenant_no="t1",
|
||||
create_dept_id="d1",
|
||||
)
|
||||
)
|
||||
db.commit()
|
||||
_patch_scope(monkeypatch, svc)
|
||||
payload = VehicleRechargeRecordCreate(
|
||||
rechargeDate=date(2026, 9, 26),
|
||||
rechargeType="etc",
|
||||
amount=Decimal("50.00"),
|
||||
applyId="apply-1",
|
||||
)
|
||||
result = approval_svc.disburse_apply(
|
||||
db, "t1", _user("u-fin", "财务"), "apply-1", payload
|
||||
)
|
||||
assert result.status == "disbursed"
|
||||
|
||||
|
||||
def test_reject_sets_rejected_and_appends_history(monkeypatch):
|
||||
from app.services import pl_vehicle_recharge_approval_service as approval_svc
|
||||
from app.services import pl_vehicle_recharge_service as svc
|
||||
|
||||
Reference in new issue
Block a user