FL6 完善财务台账与导出审计

这个提交包含在:
2026-05-12 09:33:45 +08:00
父节点 a0dc6fc408
当前提交 f99fbce3d8
共修改 14 个文件,包含 1005 行新增和 18 行删除
+49 -3
查看文件
@@ -308,7 +308,7 @@ async function listOpenRiskFlagsForBatch(tx, batch) {
return items.map(buildPersistedRiskFlag);
}
async function executeReimbursementPayment(tx, { batch, item, actorId, index }) {
async function executeReimbursementPayment(tx, { batch, item, actorId, index, request }) {
const current = await tx.reimbursementForm.findUnique({
where: { id: item.entity_id },
select: {
@@ -348,11 +348,31 @@ async function executeReimbursementPayment(tx, { batch, item, actorId, index })
if (conflict) {
throw buildValidationError({ payment: "already_paid_conflict" }, 409);
}
await tx.auditLog.create({
data: buildAuditLogData(request, {
actorId,
action: "REIMBURSEMENT_PAYMENT_MARKED",
targetType: "reimbursement_form",
targetId: current.id,
extra: {
formNumber: current.form_number ?? null,
paymentVoucherNo: current.payment_voucher_no ?? null,
paymentDate: existingPaymentDate,
paymentChannel: current.payment_channel ?? null,
paymentNote: null,
idempotent: true,
archivedInvoiceCount: 0,
source: "payment_batch",
paymentBatchId: batch.id,
paymentBatchItemId: item.id,
},
}),
});
return { idempotent: true };
}
const now = new Date();
await tx.invoicePool.updateMany({
const archivedResult = await tx.invoicePool.updateMany({
where: { linked_reimbursement_id: item.entity_id, status: "bound" },
data: {
status: "archived",
@@ -373,6 +393,26 @@ async function executeReimbursementPayment(tx, { batch, item, actorId, index })
updated_by: actorId,
},
});
await tx.auditLog.create({
data: buildAuditLogData(request, {
actorId,
action: "REIMBURSEMENT_PAYMENT_MARKED",
targetType: "reimbursement_form",
targetId: current.id,
extra: {
formNumber: current.form_number ?? null,
paymentVoucherNo: voucher,
paymentDate,
paymentChannel,
paymentNote: null,
idempotent: false,
archivedInvoiceCount: archivedResult.count,
source: "payment_batch",
paymentBatchId: batch.id,
paymentBatchItemId: item.id,
},
}),
});
return { idempotent: false };
}
@@ -842,7 +882,13 @@ async function paymentBatchesRoutes(fastify) {
try {
if (batch.entity_type === "reimbursement") {
const paymentResult = await executeReimbursementPayment(tx, { batch, item, actorId: request.employee.id, index });
const paymentResult = await executeReimbursementPayment(tx, {
batch,
item,
actorId: request.employee.id,
index,
request,
});
if (!paymentResult.idempotent) {
successfulReimbursementIds.push(item.entity_id);
}