This commit is contained in:
2026-08-13 11:57:41 +08:00
parent 842178d385
commit fd51b26fc6
4 changed files with 96 additions and 57 deletions
@@ -38,11 +38,16 @@ test('uses client finance read APIs without browser-selected customer scope', ()
assert.doesNotMatch(apiSource, /params:\s*\{\s*billId/)
})
test('adapts the finance snake-case wire contract and filters receipts locally by bill id', () => {
for (const field of ['bill_no', 'customer_name_snapshot', 'bill_date', 'total_amount', 'outstanding_amount', 'fee_item_name', 'order_id', 'receipt_no', 'bill_id', 'applied_amount']) {
test('adapts the Finance Java DTO contract and filters nested receipt allocations by bill id', () => {
for (const field of ['billNo', 'customerName', 'billDate', 'totalAmount', 'outstandingAmount', 'feeItemName', 'orderId', 'receiptNo', 'allocations', 'billId', 'appliedAmount']) {
assert.match(adapterSource, new RegExp(field))
}
assert.match(adapterSource, /filter\(\(receipt\).*receipt\.bill_id/s)
assert.match(adapterSource, /flatMap\(\(receipt\).*receipt\.allocations/s)
assert.match(adapterSource, /detail\.statement/)
assert.match(adapterSource, /detail\.lines/)
assert.doesNotMatch(adapterSource, /bill_no|customer_name|bill_date|total_amount|outstanding_amount|receipt_no|bill_id|applied_amount/)
assert.doesNotMatch(adapterSource, /receipt\.billId|receipt\.appliedAmount/)
assert.doesNotMatch(adapterSource, /voucherNo|voucher_no/)
assert.match(viewSource, /loadDetail\(row\.id\)/)
assert.doesNotMatch(viewSource, /loadDetail\(row\.billNo\)/)
})
@@ -50,15 +55,16 @@ test('adapts the finance snake-case wire contract and filters receipts locally b
test('does not expose draft or voided bills returned by the server', () => {
const bill = (id, status) => ({
id,
bill_no: `B-${id}`,
customer_name_snapshot: '测试客户',
currency_code: 'CNY',
bill_date: '2026-08-11',
due_date: '2026-09-10',
customerId: 10001,
billNo: `B-${id}`,
customerName: '测试客户',
currency: 'CNY',
billDate: '2026-08-11',
dueDate: '2026-09-10',
status,
total_amount: '100.00',
received_amount: '0.00',
outstanding_amount: '100.00',
totalAmount: '100.00',
receivedAmount: '0.00',
outstandingAmount: '100.00',
})
const visible = financeAdapters.mapFinanceBills([
bill(1, 'DRAFT'),
@@ -70,6 +76,26 @@ test('does not expose draft or voided bills returned by the server', () => {
assert.deepEqual(visible.map((item) => item.status), ['ISSUED', 'PARTIALLY_PAID', 'PAID'])
})
test('maps nested bill detail and customer-safe receipt allocations', () => {
const detail = financeAdapters.mapFinanceBillDetail({
statement: {
id: 2, customerId: 10001, billNo: 'B-2', customerName: '测试客户', currency: 'CNY',
billDate: '2026-08-11', dueDate: '2026-09-10', status: 'ISSUED', totalAmount: '100.00',
receivedAmount: '40.00', outstandingAmount: '60.00',
},
lines: [{ id: 21, sourceType: 'INBOUND_FEE', sourceId: 81, sourceVersion: 3, orderId: 31, inboundId: 41, feeItemCode: 'FREIGHT', feeItemName: '运费', amount: '100.00', currency: 'CNY' }],
})
const receipts = financeAdapters.mapFinanceReceipts([{
id: 51, receiptNo: 'RCPT-51', receivedAmount: '40.00', receivedAt: '2026-08-12T10:00:00',
paymentMethod: 'BANK_TRANSFER', currency: 'CNY', status: 'CONFIRMED',
allocations: [{ billId: 2, billNo: 'B-2', appliedAmount: '40.00' }],
}], '2')
assert.equal(detail.billNo, 'B-2')
assert.deepEqual(detail.lines[0], { id: '21', orderId: '31', feeNo: 'INBOUND_FEE:81/v3', feeName: '运费', amount: '100.00', currencyCode: 'CNY' })
assert.deepEqual(receipts[0], { id: '51', receiptNo: 'RCPT-51', receivedAt: '2026-08-12T10:00:00', amount: '40.00', currencyCode: 'CNY', method: 'BANK_TRANSFER', allocatedAmount: '40.00' })
})
test('requires both finance statement authorities for the page permission', () => {
const allowed = (codes) => permissionContracts.hasMappedMerchantPermission('finance:bill:view', new Set(codes))
assert.equal(allowed([]), false)