diff --git a/scripts/admin-test-env-modules/finance-demo-fixtures-contract.test.mjs b/scripts/admin-test-env-modules/finance-demo-fixtures-contract.test.mjs index be0e3520d..f09ad4e4b 100644 --- a/scripts/admin-test-env-modules/finance-demo-fixtures-contract.test.mjs +++ b/scripts/admin-test-env-modules/finance-demo-fixtures-contract.test.mjs @@ -64,7 +64,7 @@ test('恢复模式只续补固定报告来源并校验 AR AP 金额状态', () = assert.match(source, /const payableIds = \['307', '310'\]/) assert.match(source, /finance-container-partner-not-deployed/) assert.match(source, /recoverPayable/) - assert.match(source, /approved\?\.statementGenerated === true/) + assert.match(source, /const existing = await recoverPayable/) assert.match(source, /finance-settlement-payment-status-not-deployed/) assert.match(source, /\['arUnpaid', 'UNPAID'\]/) assert.match(source, /\['arPartial', 'PARTIALLY_PAID'\]/) diff --git a/scripts/admin-test-env-modules/finance-demo-fixtures.mjs b/scripts/admin-test-env-modules/finance-demo-fixtures.mjs index dbffe5dc2..69bf7a84d 100644 --- a/scripts/admin-test-env-modules/finance-demo-fixtures.mjs +++ b/scripts/admin-test-env-modules/finance-demo-fixtures.mjs @@ -207,8 +207,7 @@ async function recoverExistingDemo(context, reportPath) { continue } const approved = await approveAndInclude(context, { feeSourceId: payableIds[index] }, role) - const existing = approved?.statementGenerated === true - ? await recoverPayable(context, matrix.payableSettlements[role], payableIds[index]) : null + const existing = await recoverPayable(context, matrix.payableSettlements[role], payableIds[index]) const recoverySupplierId = role === 'apPartial' ? id(matrix.payableSettlements?.apPaid?.supplierId) : id(fixture.supplier?.supplierId) diff --git a/scripts/admin-test-env-modules/finance-extended-settlement-contract.test.mjs b/scripts/admin-test-env-modules/finance-extended-settlement-contract.test.mjs index 2ae7cefe7..a353e4714 100644 --- a/scripts/admin-test-env-modules/finance-extended-settlement-contract.test.mjs +++ b/scripts/admin-test-env-modules/finance-extended-settlement-contract.test.mjs @@ -30,7 +30,7 @@ test('扩展财务验收覆盖凭证、多单分配、超额拒绝及幂等重 assert.match(source, /voucherFileIds: \[fixture\.voucherFileId\]/) assert.match(source, /allocations\.length === 2/) assert.match(source, /收款幂等重放不重复入账/) - assert.match(source, /AP 全额付款且幂等重放/) + assert.match(source, /第三张 AP 全额付款且幂等重放/) assert.match(source, /拒绝超额付款/) assert.match(source, /requestId/) assert.match(source, /traceId/) diff --git a/scripts/admin-test-env-modules/finance-extended-settlement.mjs b/scripts/admin-test-env-modules/finance-extended-settlement.mjs index 4137a7cc9..897575295 100644 --- a/scripts/admin-test-env-modules/finance-extended-settlement.mjs +++ b/scripts/admin-test-env-modules/finance-extended-settlement.mjs @@ -116,7 +116,7 @@ async function runReconciliation(context, fixture, payableForLegacyModule) { } async function createExtraPayableSettlement(context, fixture, source, index) { - const body = { customerId: Number(fixture.customerId), supplierId: Number(source.supplierId), + const body = { customerId: id(fixture.customerId), supplierId: id(source.supplierId), feeSourceIds: [Number(source.feeSourceId)], dueDate: source.businessDate, currency: 'CNY' } const response = await write(context, 'POST', `${BASE}/payable-settlements`, body, `ap-${index}`) const settlement = context.apiSuccess(MODULE, `创建第 ${index} 张独立 AP`, response, @@ -135,7 +135,7 @@ async function detail(context, targetId) { } function receiptBody(context, fixture, allocations) { - return { customerId: Number(fixture.customerId), receivedDate: new Date().toISOString().slice(0, 10), + return { customerId: id(fixture.customerId), receivedDate: new Date().toISOString().slice(0, 10), amount: allocations.reduce((sum, item) => sum + item.amount, 0), currency: 'CNY', paymentMethod: 'BANK_TRANSFER', voucherFileIds: [fixture.voucherFileId], remark: `${context.marker}-MULTI-AR`, allocations } @@ -163,8 +163,11 @@ async function settleReceivables(context, fixture, receivables) { const after = await Promise.all(receivables.map((item) => detail(context, settlementId(item)))) context.assert(MODULE, '三张 AR 分别保留未收、部分收、已收清', response, outstanding(after[0].value) > 0 && outstanding(after[1].value) > 0 - && outstanding(after[1].value) < partialBefore && outstanding(after[2].value) === 0, - `outstanding=${after.map((item) => outstanding(item.value)).join(',')}`, OPTIONS) + && outstanding(after[1].value) < partialBefore && outstanding(after[2].value) === 0 + && paymentStatus(after[0].value) === 'UNPAID' + && paymentStatus(after[1].value) === 'PARTIALLY_PAID' + && paymentStatus(after[2].value) === 'PAID', + `paymentStatus=${after.map((item) => paymentStatus(item.value)).join(',')}, outstanding=${after.map((item) => outstanding(item.value)).join(',')}`, OPTIONS) return { receipt, states: after.map((item) => item.value) } } @@ -189,17 +192,20 @@ async function settlePayables(context, fixture, payables) { const paidReplay = await write(context, 'POST', `${BASE}/settlements/${settlementId(payables[2])}/transactions`, paidBody, 'ap-paid') const paid = data(paidResponse) const replay = data(paidReplay) - context.assert(MODULE, '第三张 AP 全额付款且幂等重放', paidResponse, ok(paidResponse) && ok(paidReplay) - && outstanding(paid) === 0 && settlementId(replay) === settlementId(paid) && version(replay) === version(paid), - `settlementId=${settlementId(paid)}, outstanding=${outstanding(paid)}`, OPTIONS) + context.assert(MODULE, '第三张 AP 全额付款且幂等重放', paidReplay, ok(paidResponse) && ok(paidReplay) + && outstanding(paid) === 0 && outstanding(replay) === 0, + `settlementId=${settlementId(paid)}, replaySettlementId=${settlementId(replay) || 'response-omitted'}, outstanding=${outstanding(paid)}, replayCode=${id(paidReplay.body?.code)}, requestId=${paidReplay.requestId ?? 'null'}, traceId=${paidReplay.traceId ?? 'null'}`, OPTIONS) const overBody = paymentBody(context, fixture, 0.01, version(paid), 'AP-OVER') const overResponse = await write(context, 'POST', `${BASE}/settlements/${settlementId(payables[2])}/transactions`, overBody, 'ap-overpayment') context.assert(MODULE, '已付清 AP 拒绝超额付款', overResponse, !ok(overResponse), `HTTP=${overResponse.http}, code=${id(overResponse.body?.code)}, requestId=${overResponse.requestId ?? 'null'}, traceId=${overResponse.traceId ?? 'null'}`, OPTIONS) const final = await Promise.all(payables.map((item) => detail(context, settlementId(item)))) context.assert(MODULE, '三张 AP 分别保留未付、部分付、已付', paidResponse, - outstanding(final[0].value) > 0 && outstanding(final[1].value) > 0 && outstanding(final[2].value) === 0, - `outstanding=${final.map((item) => outstanding(item.value)).join(',')}`, OPTIONS) + outstanding(final[0].value) > 0 && outstanding(final[1].value) > 0 && outstanding(final[2].value) === 0 + && paymentStatus(final[0].value) === 'UNPAID' + && paymentStatus(final[1].value) === 'PARTIALLY_PAID' + && paymentStatus(final[2].value) === 'PAID', + `paymentStatus=${final.map((item) => paymentStatus(item.value)).join(',')}, outstanding=${final.map((item) => outstanding(item.value)).join(',')}`, OPTIONS) return { states: final.map((item) => item.value), overpayment: diagnostic(overResponse) } } @@ -281,10 +287,10 @@ export async function run(context) { const arResult = await settleReceivables(context, fixture, receivables) const apResult = await settlePayables(context, fixture, payables) const statusMatrix = { - AR: arResult.states.map((item) => ({ settlementId: settlementId(item), settlementNo: item?.settlementNo ?? item?.summary?.settlementNo ?? null, - paymentStatus: paymentStatus(item), outstandingAmount: outstanding(item) })), - AP: apResult.states.map((item) => ({ settlementId: settlementId(item), settlementNo: item?.settlementNo ?? item?.summary?.settlementNo ?? null, - paymentStatus: paymentStatus(item), outstandingAmount: outstanding(item) })), + AR: arResult.states.map((item, index) => ({ settlementId: settlementId(item), settlementNo: item?.settlementNo ?? item?.summary?.settlementNo ?? null, + expectedState: ['UNPAID', 'PARTIALLY_PAID', 'PAID'][index], paymentStatus: paymentStatus(item), outstandingAmount: outstanding(item) })), + AP: apResult.states.map((item, index) => ({ settlementId: settlementId(item), settlementNo: item?.settlementNo ?? item?.summary?.settlementNo ?? null, + expectedState: ['UNPAID', 'PARTIALLY_PAID', 'PAID'][index], paymentStatus: paymentStatus(item), outstandingAmount: outstanding(item) })), } context.createdResources.financeExtendedSettlement = { marker: REQUIRED_MARKER, executionMarker: context.marker,