fix: 财务本人报销由总经理独立审批(09-04-reimbursement-state-gap-finance-view)
这个提交包含在:
@@ -131,6 +131,50 @@ describe("workflow assignee resolution", () => {
|
||||
});
|
||||
|
||||
describe("buildApprovalWorkflowSnapshot", () => {
|
||||
it.each([
|
||||
["small", "finance", null],
|
||||
["large", "ceo", "finance"],
|
||||
])("uses exactly one CEO step for finance-owned reimbursement %s", async (_name, level2, level3) => {
|
||||
const tx = buildTx({ ownerRoles: ["finance", "employee"], managerId: MANAGER_ID });
|
||||
const steps = await workflowUtils.buildApprovalWorkflowSnapshot({
|
||||
tx, entityType: "reimbursement", ownerId: OWNER_ID, submitterId: MANAGER_ID,
|
||||
approvalRule: { level1_role: "manager", level2_role: level2, level3_role: level3 },
|
||||
});
|
||||
expect(steps).toEqual([{
|
||||
id: "approval_1_ceo_finance_owner", name: "总经理审批", type: "approval",
|
||||
assignee_rule: { type: "role", value: "ceo" },
|
||||
}]);
|
||||
expect(tx.employeeRole.findFirst).toHaveBeenCalledWith({
|
||||
where: {
|
||||
role_code: "ceo",
|
||||
employee_id: { notIn: [OWNER_ID, MANAGER_ID] },
|
||||
employee: { status: "active", archived_at: null },
|
||||
},
|
||||
select: { employee_id: true },
|
||||
});
|
||||
});
|
||||
|
||||
it.each([["finance"], ["finance", "ceo"]])("blocks finance owner roles %j without non-applicant CEO", async (...ownerRoles) => {
|
||||
const tx = buildTx({ ownerRoles, fallbackHasHolder: false });
|
||||
await expect(workflowUtils.buildApprovalWorkflowSnapshot({
|
||||
tx, entityType: "reimbursement", ownerId: OWNER_ID, submitterId: OWNER_ID,
|
||||
approvalRule: { level1_role: "finance" },
|
||||
})).rejects.toMatchObject({
|
||||
statusCode: 409,
|
||||
details: { workflow: "no_actionable_approver", reason: "finance_owner_ceo_unavailable" },
|
||||
});
|
||||
});
|
||||
|
||||
it("does not simplify other entities or a finance submitter's employee-owned form", async () => {
|
||||
for (const [entityType, ownerRoles] of [["purchase_request", ["finance"]], ["reimbursement", ["employee"]]]) {
|
||||
const steps = await workflowUtils.buildApprovalWorkflowSnapshot({
|
||||
tx: buildTx({ ownerRoles }), entityType, ownerId: OWNER_ID, submitterId: FINANCE_MGR_ID,
|
||||
approvalRule: { level1_role: "manager", level2_role: "ceo", level3_role: "finance" },
|
||||
});
|
||||
expect(steps).toHaveLength(3);
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps ordinary employee approval snapshots unchanged", async () => {
|
||||
const tx = buildTx({ ownerRoles: ["employee"], managerId: MANAGER_ID });
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户