feat(dispatch): unify whole vehicle scheduling, source ownership and staged execution

This commit is contained in:
2026-10-19 23:40:42 +08:00
parent e0677e7ae7
commit 9dd34791f7
346 changed files with 29245 additions and 12602 deletions
@@ -9,7 +9,7 @@ test('default fulfillment runs finance verification using its own departed trip
const source = readFileSync(new URL('./phase5-overseas-fulfillment.mjs', import.meta.url), 'utf8')
assert.match(source, /import \{ verifyFleetTripFinance \} from '\.\/fleet-trip-finance-acceptance\.mjs'/)
assert.match(source, /verifyFleetTripFinance\(context, MODULE, \{ tripNo: tripProof\.tripNo, dispatchNos: \[dispatchNo\]/)
assert.match(source, /businesses: deliveryNos\.map\(deliveryNo => \(\{ customerId, deliveryNo \}\)\)/)
assert.match(source, /businesses: deliveries\.map\(row => \(\{ customerId: id\(row\.customerId\), deliveryNo: row\.deliveryNo \}\)\)/)
})
function fixture(status = 'AVAILABLE', received = null) {
return { tripNo: scope.tripNo, dispatchNos: [...scope.dispatchNos], receiptsVisible: true,
@@ -42,6 +42,19 @@ test('currencies are reconciled separately without floating point addition', ()
value.finance.totals[0].receivableAmount = '100.23'
assert.throws(() => validateTripFinance(value, scope), /原币/)
})
test('one dispatch retains each delivery customer in whole-trip finance attribution', () => {
const value = fixture()
const second = { customerId: '9007199254740994', deliveryNo: 'DL-SECOND' }
const mixed = { ...scope, businesses: [...scope.businesses, second] }
value.finance.sources.push({ ...value.finance.sources[0], customerId: second.customerId,
businessNo: second.deliveryNo, sourceNo: 'FS-SECOND', amount: '20.07' })
value.finance.totals[0].receivableAmount = '120.10'
assert.equal(validateTripFinance(value, mixed), true)
assert.throws(() => validateTripFinance(value, scope), /其他客户或派送/)
value.finance.sources[1].customerId = scope.businesses[0].customerId
assert.throws(() => validateTripFinance(value, mixed), /其他客户或派送/)
})
test('pending allocation is explicitly unknown and never promoted to complete or zero', () => {
const value = fixture('BILLED')
value.finance.documents = [{ billNo: 'MIXED-BILL', currency: 'USD', receivedAmount: null,