feat: 同步报销流程与工作台改动

This commit is contained in:
caoxiaozhu
2026-06-09 08:32:00 +00:00
parent e124e4bbcb
commit 25724c354f
64 changed files with 6518 additions and 687 deletions

View File

@@ -250,6 +250,45 @@ class ExpenseClaimAccessPolicy:
return role_code
return BUDGET_MONITOR_ROLE_CODE
@staticmethod
def resolve_claim_finance_owner_name(claim: ExpenseClaim) -> str:
employee = claim.employee
if employee is not None and employee.finance_owner_name:
return str(employee.finance_owner_name).strip()
return ""
def resolve_finance_approver(self, claim: ExpenseClaim) -> Employee | None:
claim_employee_id = str(claim.employee_id or "").strip()
base_stmt = (
select(Employee)
.options(selectinload(Employee.roles))
.where(Employee.roles.any(Role.role_code == "finance"))
)
if claim_employee_id:
base_stmt = base_stmt.where(Employee.id != claim_employee_id)
finance_owner_name = self.resolve_claim_finance_owner_name(claim)
if finance_owner_name:
named_finance = self.db.scalar(
base_stmt
.where(Employee.name == finance_owner_name)
.order_by(Employee.name.asc(), Employee.employee_no.asc())
.limit(1)
)
if named_finance is not None:
return named_finance
owner_matched_finance = self.db.scalar(
base_stmt
.where(func.lower(func.coalesce(Employee.finance_owner_name, "")) == finance_owner_name.lower())
.order_by(Employee.name.asc(), Employee.employee_no.asc())
.limit(1)
)
if owner_matched_finance is not None:
return owner_matched_finance
return self.db.scalar(base_stmt.order_by(Employee.name.asc(), Employee.employee_no.asc()).limit(1))
def attach_budget_approval_snapshot(self, claim: ExpenseClaim | None) -> ExpenseClaim | None:
if claim is None:
return None
@@ -269,9 +308,25 @@ class ExpenseClaimAccessPolicy:
)
return claim
def attach_finance_approval_snapshot(self, claim: ExpenseClaim | None) -> ExpenseClaim | None:
if claim is None:
return None
if str(claim.approval_stage or "").strip() != FINANCE_APPROVAL_STAGE:
return claim
finance_approver = self.resolve_finance_approver(claim)
if finance_approver is not None and finance_approver.name:
setattr(claim, "finance_approver_name", str(finance_approver.name).strip())
return claim
def attach_approval_snapshot(self, claim: ExpenseClaim | None) -> ExpenseClaim | None:
self.attach_budget_approval_snapshot(claim)
self.attach_finance_approval_snapshot(claim)
return claim
def attach_budget_approval_snapshots(self, claims: list[ExpenseClaim]) -> list[ExpenseClaim]:
for claim in claims:
self.attach_budget_approval_snapshot(claim)
self.attach_approval_snapshot(claim)
return claims
@staticmethod
@@ -647,6 +702,11 @@ class ExpenseClaimAccessPolicy:
*,
include_approval_scope: bool = False,
) -> Any:
if current_user.is_admin:
if include_approval_scope:
return stmt
return stmt.where(~self.build_archived_claim_condition())
conditions = self.build_personal_claim_conditions(current_user)
role_codes = self.normalize_role_codes(current_user)