|
|
|
@@ -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,
|
|
|
|
|