fix: 统一报销付款状态与进度(09-04-reimbursement-state-gap-finance-view)
这个提交包含在:
@@ -0,0 +1,66 @@
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const ts = require("../../../../client/node_modules/typescript");
|
||||
const { buildPaymentProcessingSemantics } = require("../../../src/services/paymentProcessingProgress");
|
||||
|
||||
const filename = path.resolve(__dirname, "../../../../client/src/lib/reimbursementPaymentHandoff.ts");
|
||||
const compiled = ts.transpileModule(fs.readFileSync(filename, "utf8"), {
|
||||
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 },
|
||||
}).outputText;
|
||||
const clientModule = { exports: {} };
|
||||
new Function("exports", compiled)(clientModule.exports);
|
||||
const { resolveReimbursementPaymentHandoff } = clientModule.exports;
|
||||
|
||||
function project(status, options = {}) {
|
||||
const stages = Object.values(buildPaymentProcessingSemantics({ status, ...options }));
|
||||
return { stages: stages.map((stage) => ({ ...stage, actorName: null, targetHref: null })) };
|
||||
}
|
||||
|
||||
describe("报销付款下一步消费服务端阶段,不猜测批次存在性", () => {
|
||||
it.each([
|
||||
["draft", {}, "待非制单人复核付款"],
|
||||
["reviewed", { requiresBankReceipt: true }, "等待财务线下付款并上传回单,非审批环节"],
|
||||
["reviewed", { requiresBankReceipt: true, paymentOrderExportCount: 1 }, "已生成银行制单,等待付款完成并上传回单,非审批环节"],
|
||||
["reviewed", { requiresBankReceipt: true, receiptCount: 1 }, "银行回单已上传,等待财务登记付款完成,非审批环节"],
|
||||
["reviewed", {}, "付款复核已通过,等待财务登记付款完成,非审批环节"],
|
||||
["failed", {}, "付款登记失败,待财务核对后重试,非审批环节"],
|
||||
["cancelled", {}, "付款安排已取消,流程已终止"],
|
||||
["cancelled", { reviewedAt: "2026-09-11T00:00:00Z" }, "付款安排已取消,流程已终止"],
|
||||
])("%s 无读取链接也不允许重新组批 (%j)", (status, options, expected) => {
|
||||
const result = resolveReimbursementPaymentHandoff({ status: "approved", progress: project(status, options) });
|
||||
expect(result).toEqual({ nextStep: expected, canCreateBatch: false, targetHref: null });
|
||||
});
|
||||
|
||||
it("只有明确待组批投影才提供资格,入口权限仍由调用者检查", () => {
|
||||
const progress = project("unknown");
|
||||
progress.stages[0] = { ...progress.stages[0], state: "current", detail: "待财务组建付款批次" };
|
||||
expect(resolveReimbursementPaymentHandoff({ status: "approved", progress }).canCreateBatch).toBe(true);
|
||||
progress.stages[1].targetHref = "/payment-batches?id=synthetic";
|
||||
expect(resolveReimbursementPaymentHandoff({ status: "approved", progress }).canCreateBatch).toBe(false);
|
||||
});
|
||||
|
||||
it("保留服务端有权的同一个批次入口", () => {
|
||||
const progress = project("reviewed");
|
||||
progress.stages[2].targetHref = "/payment-batches?id=synthetic";
|
||||
expect(resolveReimbursementPaymentHandoff({ status: "approved", progress }).targetHref).toBe(progress.stages[2].targetHref);
|
||||
});
|
||||
|
||||
it.each([undefined, { stages: [] }, { stages: project("reviewed").stages.slice(1) }, project("unknown")])("缺失或未知阶段拒绝猜测", (progress) => {
|
||||
expect(resolveReimbursementPaymentHandoff({ status: "approved", progress })).toEqual({
|
||||
nextStep: "付款进度暂不可用,请刷新后重试", canCreateBatch: false, targetHref: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("已付款只展示完成事实,不把制单当付款", () => {
|
||||
expect(resolveReimbursementPaymentHandoff({ status: "paid", progress: project("executed") }).nextStep).toBe("付款已登记完成");
|
||||
expect(resolveReimbursementPaymentHandoff({ status: "paid", progress: project("reviewed") }).targetHref).toBeNull();
|
||||
});
|
||||
|
||||
it.each(["draft", "reviewing", "rejected", "cancelled"])("%s 不生成付款动作", (status) => {
|
||||
expect(resolveReimbursementPaymentHandoff({ status, progress: project("reviewed") })).toBeNull();
|
||||
});
|
||||
|
||||
it("删除记录不生成付款动作", () => {
|
||||
expect(resolveReimbursementPaymentHandoff({ status: "approved", deletedAt: "2026-09-11T00:00:00Z", progress: project("reviewed") })).toBeNull();
|
||||
});
|
||||
});
|
||||
在新工单中引用
屏蔽一个用户