fix: 退回报销支持留痕删除(09-04-reimbursement-state-gap-finance-view)
这个提交包含在:
@@ -234,6 +234,7 @@ async function buildApp({
|
||||
const prisma = {
|
||||
$transaction: vi.fn(async (callback) => callback(tx)),
|
||||
reimbursementForm: {
|
||||
updateMany: vi.fn(async () => ({ count: 1 })),
|
||||
findUnique: vi.fn(async ({ where }) => {
|
||||
if (where.id !== REIMBURSEMENT_ID) {
|
||||
return null;
|
||||
@@ -1083,7 +1084,7 @@ describe("POST /api/reimbursements/:id/link-project authorization", () => {
|
||||
});
|
||||
|
||||
expect(response.statusCode, response.body).toBe(403);
|
||||
expect(prisma.reimbursementForm.update).not.toHaveBeenCalled();
|
||||
expect(prisma.reimbursementForm.updateMany).not.toHaveBeenCalled();
|
||||
await app.close();
|
||||
});
|
||||
|
||||
@@ -1101,7 +1102,7 @@ describe("POST /api/reimbursements/:id/link-project authorization", () => {
|
||||
});
|
||||
|
||||
expect(response.statusCode, response.body).toBe(409);
|
||||
expect(prisma.reimbursementForm.update).not.toHaveBeenCalled();
|
||||
expect(prisma.reimbursementForm.updateMany).not.toHaveBeenCalled();
|
||||
await app.close();
|
||||
});
|
||||
|
||||
@@ -1119,12 +1120,33 @@ describe("POST /api/reimbursements/:id/link-project authorization", () => {
|
||||
});
|
||||
|
||||
expect(response.statusCode, response.body).toBe(200);
|
||||
expect(prisma.reimbursementForm.update).toHaveBeenCalledTimes(1);
|
||||
expect(prisma.reimbursementForm.updateMany).toHaveBeenCalledWith({
|
||||
where: { id: REIMBURSEMENT_ID, deleted_at: null, status: { in: ["draft", "rejected"] } },
|
||||
data: { project_id: projectId, updated_by: SUBMITTER_ID },
|
||||
});
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
|
||||
describe("reimbursement maintenance authorization", () => {
|
||||
it("marks deleted historical detail and terminates next-action projections", async () => {
|
||||
const { app } = await buildApp({
|
||||
employeeId: SUBMITTER_ID,
|
||||
permissionCodes: ["expense.view_own"],
|
||||
reimbursement: buildReimbursementRecord({ status: "cancelled", deleted_at: new Date("2026-09-10T01:00:00Z") }),
|
||||
});
|
||||
try {
|
||||
const response = await app.inject({ method: "GET", url: `/api/reimbursements/${REIMBURSEMENT_ID}`, headers: { authorization: "Bearer test" } });
|
||||
expect(response.statusCode).toBe(200);
|
||||
const detail = response.json().data;
|
||||
expect(detail.deletedAt).toBe("2026-09-10T01:00:00.000Z");
|
||||
expect(detail.processingProgress.stages.some((stage) => ["pending", "current"].includes(stage.state))).toBe(false);
|
||||
expect(detail.processingProgress.stages.at(-1)).toMatchObject({ key: "deleted", result: "已删除", state: "terminated" });
|
||||
} finally {
|
||||
await app.close();
|
||||
}
|
||||
});
|
||||
|
||||
const itemId = "77777777-7777-4777-8777-777777777777";
|
||||
const expenseTypeId = "88888888-8888-4888-8888-888888888888";
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户