优化
This commit is contained in:
@@ -74,7 +74,9 @@ function mapBillLine(line: FinanceBillLineWire): FinanceBillLine {
|
||||
}
|
||||
|
||||
export function mapFinanceBills(bills: FinanceBillWire[]) {
|
||||
return bills.map(mapBillSummary)
|
||||
return bills
|
||||
.filter((bill) => bill.status === 'ISSUED' || bill.status === 'PARTIALLY_PAID' || bill.status === 'PAID')
|
||||
.map(mapBillSummary)
|
||||
}
|
||||
|
||||
export function mapFinanceBillDetail(bill: FinanceBillWire): FinanceBillDetail {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import test from 'node:test'
|
||||
import ts from 'typescript'
|
||||
|
||||
const routesSource = readFileSync(new URL('../routes.ts', import.meta.url), 'utf8')
|
||||
const viewSource = readFileSync(new URL('./FinanceBillsView.vue', import.meta.url), 'utf8')
|
||||
@@ -8,6 +9,17 @@ const apiSource = readFileSync(new URL('../api/finance.ts', import.meta.url), 'u
|
||||
const adapterSource = readFileSync(new URL('../api/adapters.ts', import.meta.url), 'utf8')
|
||||
const permissionSource = readFileSync(new URL('../../tenant-management/contracts.ts', import.meta.url), 'utf8')
|
||||
|
||||
async function importTypeScriptModule(url) {
|
||||
const source = readFileSync(url, 'utf8')
|
||||
const compiled = ts.transpileModule(source, {
|
||||
compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2022 },
|
||||
}).outputText
|
||||
return import(`data:text/javascript;base64,${Buffer.from(compiled).toString('base64')}`)
|
||||
}
|
||||
|
||||
const financeAdapters = await importTypeScriptModule(new URL('../api/adapters.ts', import.meta.url))
|
||||
const permissionContracts = await importTypeScriptModule(new URL('../../tenant-management/contracts.ts', import.meta.url))
|
||||
|
||||
test('activates the customer finance route with a read-only permission', () => {
|
||||
assert.match(routesSource, /path: 'finance\/bills'/)
|
||||
assert.match(routesSource, /FinanceBillsView\.vue/)
|
||||
@@ -35,6 +47,37 @@ test('adapts the finance snake-case wire contract and filters receipts locally b
|
||||
assert.doesNotMatch(viewSource, /loadDetail\(row\.billNo\)/)
|
||||
})
|
||||
|
||||
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',
|
||||
status,
|
||||
total_amount: '100.00',
|
||||
received_amount: '0.00',
|
||||
outstanding_amount: '100.00',
|
||||
})
|
||||
const visible = financeAdapters.mapFinanceBills([
|
||||
bill(1, 'DRAFT'),
|
||||
bill(2, 'ISSUED'),
|
||||
bill(3, 'PARTIALLY_PAID'),
|
||||
bill(4, 'PAID'),
|
||||
bill(5, 'VOIDED'),
|
||||
])
|
||||
assert.deepEqual(visible.map((item) => item.status), ['ISSUED', 'PARTIALLY_PAID', 'PAID'])
|
||||
})
|
||||
|
||||
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)
|
||||
assert.equal(allowed(['merchant:finance:statement:list']), false)
|
||||
assert.equal(allowed(['merchant:finance:statement:view']), false)
|
||||
assert.equal(allowed(['merchant:finance:statement:list', 'merchant:finance:statement:view']), true)
|
||||
})
|
||||
|
||||
test('keeps actions first and exposes list, balance, detail, receipt, empty and error states', () => {
|
||||
const actionIndex = viewSource.indexOf('label="操作"')
|
||||
const billNumberIndex = viewSource.indexOf('label="账单编号"')
|
||||
@@ -52,4 +95,5 @@ test('catalogs customer finance as an assignable view-only role permission', ()
|
||||
assert.match(permissionSource, /不包含任何财务写操作/)
|
||||
assert.match(permissionSource, /merchant:finance:statement:list/)
|
||||
assert.match(permissionSource, /merchant:finance:statement:view/)
|
||||
assert.match(permissionSource, /FRONTEND_PERMISSIONS_REQUIRING_ALL_BACKEND_CODES/)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user