fix finance acceptance source ownership checks

This commit is contained in:
2026-08-12 15:53:47 +08:00
parent 645d20665c
commit 6a26b17e0a
4 changed files with 40 additions and 17 deletions
@@ -104,11 +104,16 @@ async function normalizeFixture(context) {
supplierName: raw.supplierName ?? raw.partnerName ?? root.supplierName ?? root.partnerName ?? null,
}
})
const uncreatedSources = attemptedSources.filter((source) => !source.feeSourceId || isUnboundContainerCost(source.raw))
const hasContainerAllocations = list(root.allocations).length > 0
const uncreatedSources = attemptedSources.filter((source) => !source.feeSourceId
|| (isUnboundContainerCost(source.raw) && !hasContainerAllocations))
return {
root, customerId,
sources: attemptedSources.filter((source) => source.feeSourceId && !isUnboundContainerCost(source.raw)),
uncreatedSources,
sourceMappings: attemptedSources.filter((source) => source.feeSourceId && !isUnboundContainerCost(source.raw))
.map((source) => ({ sourceFeeId: source.sourceFeeId, feeSourceId: source.feeSourceId,
sourceType: source.raw?.sourceType ?? null, direction: source.direction })),
}
}
@@ -263,19 +268,6 @@ export async function run(context) {
return
}
const foreign = fixture.sources.find((source) => source.customerId !== fixture.customerId)
if (foreign) {
const response = await write(context, 'POST', `${BASE}/statements`, {
customerId: fixture.customerId, currency: 'CNY', generationMode: 'SELECTED',
feeSourceIds: [foreign.feeSourceId], periodStart: foreign.businessDate,
periodEnd: foreign.businessDate, remark: `${context.marker}-foreign`,
}, 'cross-customer-rejected')
context.assert(MODULE, 'SELECTED 拒绝混入其他客户来源', response, rejectedWith(response, 'FIN_409'),
`code=${response.body?.code ?? 'missing'}`, OPTIONS)
} else {
context.addCoverageGap(MODULE, SCENARIO, 'cross-customer-isolation',
'Fixture 未提供其他客户 marker 来源,无法执行跨客户负向请求', 'missing-cross-customer-fixture')
}
const allPeriod = dates(receivables)
const currencyResponse = await write(context, 'POST', `${BASE}/statements`, {
customerId: fixture.customerId, currency: 'USD', generationMode: 'SELECTED',
@@ -331,6 +323,25 @@ export async function run(context) {
finish(context, start)
return
}
if (index === 0) {
const customerResponse = await context.request('GET', '/api/platform/v1/iam/tenants?page=1&size=100&status=ACTIVE')
const otherCustomer = rows(customerResponse?.body?.data)
.find((item) => id(item?.id ?? item?.tenantId) !== fixture.customerId)
if (otherCustomer) {
const otherCustomerId = id(otherCustomer.id ?? otherCustomer.tenantId)
const isolationResponse = await write(context, 'POST', `${BASE}/statements`, {
customerId: otherCustomerId, currency: 'CNY', generationMode: 'SELECTED',
feeSourceIds: [groups[index][0].feeSourceId], periodStart: groups[index][0].businessDate,
periodEnd: groups[index][0].businessDate, remark: `${context.marker}-foreign`,
}, 'cross-customer-rejected')
context.assert(MODULE, 'SELECTED 拒绝归入其他客户的本轮来源', isolationResponse,
rejectedWith(isolationResponse, 'FIN_404'),
`sourceCustomerId=${fixture.customerId}, requestedCustomerId=${otherCustomerId}, code=${isolationResponse.body?.code ?? 'missing'}`, OPTIONS)
} else {
context.addCoverageGap(MODULE, SCENARIO, 'cross-customer-isolation',
'未找到另一个 ACTIVE 客户,无法用本轮来源执行跨客户归属负向请求', 'missing-cross-customer-fixture')
}
}
context.assert(MODULE, `第 ${index + 1} 张仅使用分组来源`, created.response,
created.statement && sameIds(lineSourceIds(created.statement), groups[index].map((source) => source.feeSourceId)),
`expected=${groups[index].length}, actual=${lineSourceIds(created.statement).length}`, OPTIONS)
@@ -414,5 +425,6 @@ export async function run(context) {
paymentStatus: payableSettlement.paymentStatus, version: payableSettlement.version,
feeSourceIds: payables.map((source) => source.feeSourceId),
}] : []
fixture.root.sourceMappings = fixture.sourceMappings
finish(context, start)
}