94 lines
3.7 KiB
Python
94 lines
3.7 KiB
Python
"""备用金、报销与车辆充值的审批通知快照;不执行发放或支付通知。"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Optional
|
|
from urllib.parse import quote
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.bx_models import (
|
|
BxAdvanceApply, BxAdvanceApproval, BxReimburseApply, BxReimburseApproval,
|
|
BxWorkflowNode,
|
|
)
|
|
from app.models.pl_models import PlVehicleRechargeApply, PlVehicleRechargeApproval
|
|
from app.services.wechat_notice_types import NoticeSnapshot, PendingApprover
|
|
|
|
|
|
_SOURCES = {
|
|
"bx_advance": (BxAdvanceApply, BxAdvanceApproval, "备用金审批", "pages/bx/advance/detail"),
|
|
"bx_reimburse": (BxReimburseApply, BxReimburseApproval, "报销审批", "pages/bx/reimburse/detail"),
|
|
"pl_recharge": (PlVehicleRechargeApply, PlVehicleRechargeApproval, "车辆充值审批", "pages/pl/vehicle-recharge-apply/form"),
|
|
}
|
|
|
|
|
|
def get_snapshot(
|
|
db: Session, biz_type: str, biz_id: str, tenant_no: str
|
|
) -> Optional[NoticeSnapshot]:
|
|
source = _SOURCES.get(biz_type)
|
|
if source is None:
|
|
return None
|
|
model, approval_model, name, page = source
|
|
row = db.query(model).filter(
|
|
model.id == biz_id, model.tenant_no == tenant_no, model.del_flag == 0
|
|
).first()
|
|
if row is None:
|
|
return None
|
|
recharge = biz_type == "pl_recharge"
|
|
snapshot = NoticeSnapshot(
|
|
business_name=name,
|
|
business_no=(row.apply_no if recharge else row.apply_code) or "",
|
|
applicant_id=row.applicant_id,
|
|
page=f"{page}?id={quote(str(row.id), safe='')}",
|
|
)
|
|
active = row.status == ("in_approval" if recharge else "pending")
|
|
current = None
|
|
action = ""
|
|
if active and row.wf_id and row.current_node:
|
|
current = db.query(BxWorkflowNode).filter(
|
|
BxWorkflowNode.tenant_no == tenant_no,
|
|
BxWorkflowNode.del_flag == 0,
|
|
BxWorkflowNode.wf_id == row.wf_id,
|
|
(BxWorkflowNode.id == row.current_node if recharge else
|
|
BxWorkflowNode.node_name == row.current_node),
|
|
).order_by(BxWorkflowNode.node_order).first()
|
|
if current:
|
|
action = (current.action_type or "approve").strip() or "approve"
|
|
if current and (not recharge or action == "approve"):
|
|
if current.approver_id:
|
|
snapshot.pending = [PendingApprover(current.id, current.approver_id)]
|
|
# 现有小程序仅详情/申请表单,无审批按钮;待办仅提醒,不提供跳转。
|
|
snapshot.page = ""
|
|
return snapshot
|
|
|
|
# 业务状态优先,撤回/重提后不得复用历史通过或驳回记录。
|
|
outcome = None
|
|
if row.status == "rejected":
|
|
outcome = "rejected"
|
|
elif recharge:
|
|
if row.status == "disbursed" or (
|
|
active and current and action == "disburse"
|
|
):
|
|
outcome = "approved"
|
|
elif row.status in ("approved", "issued", "processed", "paid", "offset"):
|
|
outcome = "approved"
|
|
if outcome is None:
|
|
return snapshot
|
|
|
|
query = db.query(approval_model).filter(
|
|
approval_model.apply_id == row.id,
|
|
approval_model.tenant_no == tenant_no,
|
|
approval_model.del_flag == 0,
|
|
approval_model.approval_status.in_(("approved", "rejected")),
|
|
)
|
|
if recharge:
|
|
query = query.filter(approval_model.approval_round == row.approval_round)
|
|
latest = query.order_by(
|
|
approval_model.approval_time.desc(), approval_model.create_time.desc(),
|
|
approval_model.id.desc(),
|
|
).first()
|
|
if latest and latest.approval_status == outcome and latest.approver_id and latest.approval_time:
|
|
snapshot.result = outcome
|
|
snapshot.approver_id = latest.approver_id
|
|
snapshot.occurred_at = latest.approval_time
|
|
return snapshot
|