This commit is contained in:
2026-10-21 07:53:31 +08:00
parent af5cf1e3bd
commit f00d0e16cf
147 changed files with 1696 additions and 872 deletions
@@ -352,7 +352,7 @@ export async function verifyFormalDeclarationAndExceptions(context, routes, fixt
const before = await platformDetail(context, routes, fixture)
const baseline = customsDocumentFacts(before.body?.data)
const created = await routes.platformCreateDeclaration(context, fixture, {
expectedVersion: Number(before.body?.data?.version), batchNo: `${context.marker}-DECL`.slice(-64), remark: context.marker,
expectedVersion: Number(before.body?.data?.version), remark: context.marker,
}, key(context, 'formal-create'))
context.assert(MODULE, '平台人工创建正式申报批次', created,
success(created) && created.body?.data?.status === 'READY', evidence(created), OPTIONS)
@@ -61,7 +61,7 @@ export async function prepareTaxCustoms(context,loading){
{expectedVersion:Number(current.version),confirm:true,remark:context.marker},context.token,key('execute'))
current=await detail()
const batch=await api(context,'POST','F40 人工创建真实正式申报批次',`${base}/declaration-batches`,
{expectedVersion:Number(current.version),batchNo:`${context.marker}-DECL`.slice(-64),remark:context.marker},context.token,key('declaration'))
{expectedVersion:Number(current.version),remark:context.marker},context.token,key('declaration'))
proof.declarationBatchId=id(batch.id)
const submitted=await api(context,'POST','F40 人工提交正式申报',`${PLATFORM}/declaration-batches/${batch.id}/submit`,
{expectedVersion:Number(batch.version),customsEntryNo:`F40TAX-${proof.loadingPlanId}`,remark:context.marker},context.token,key('submit-declaration'))
@@ -91,8 +91,8 @@ export async function runReturnBoundaries(context, { merchantToken, warehouse, p
items,
})
resources.returnNos.push(data.order.returnNo)
check('新退货单及退货主单采用独立完整编号', null,
/^RT-[0-9A-Z]{25}$/.test(data.order.returnNo) && /^RETU-[0-9A-Z]{25}$/.test(data.order.lastlegOrderNo))
check('新退货单使用日流水且尾程主单沿用来源业务号', null,
/^TH[0-9]{12}$/.test(data.order.returnNo) && data.order.lastlegOrderNo === data.order.returnNo)
const customerId = customerByToken.get(token)
if (!customerId || data.order.status !== 'PENDING_REVIEW') throw new Error('边界退货客户或审核初态不符')
const reviewed = await context.request('POST', `/api/platform/v1/last-leg/return-orders/${data.order.returnNo}/review`, { decision: 'APPROVE', remark: context.marker }, undefined, { 'X-Customer-Id': customerId })
@@ -113,7 +113,7 @@ export async function runReturnBoundaries(context, { merchantToken, warehouse, p
async function receive(order, operator = picker) {
const data = await good(operator.token, 'POST', '准备边界场景实收库存', `${RECEIPTS}/confirm`, receiptBody(order))
check('签收单批次采用独立完整编号且绑定本轮包裹', null,
/^RR-[0-9A-Z]{25}$/.test(data.receiptNo) && /^RB-[0-9A-Z]{25}$/.test(data.receiptBatchNo)
/^RR[0-9]{12}$/.test(data.receiptNo) && /^RB[0-9]{12}$/.test(data.receiptBatchNo)
&& data.unitType === 'PARCEL' && data.unitCode === order.unitCode && !data.palletCode)
order.cartonMark = data.cartonMark
order.batch = data.receiptBatchNo
@@ -6,8 +6,8 @@ export const IMMUTABLE_TAILLEG_EVENT_FIXTURE = Object.freeze({
})
export const TAILLEG_ORDER_NUMBER = Object.freeze({
pattern: /^LMO-\d{6}-\d{4}$/,
timeZone: 'Asia/Shanghai',
pattern: /^FL-WH-\d{8}-\d{6}$/,
timeZone: 'server-local',
sharedBy: 'containerNo',
})
@@ -62,34 +62,30 @@ test('Lastleg query DTO uses the persisted frozen owner name', () => {
assert.match(orderService, /o\.getCustomerName\(\)/)
})
test('new tailleg number is Shanghai daily LMO-yyMMdd-#### with concurrency and cross-day tests', () => {
assert.equal(TAILLEG_ORDER_NUMBER.pattern.test('LMO-260827-0001'), true)
test('head-leg sourced tail orders preserve the existing container grouping number', () => {
assert.equal(TAILLEG_ORDER_NUMBER.pattern.test('FL-WH-20261020-000042'), true)
assert.equal(TAILLEG_ORDER_NUMBER.pattern.test('LMO2087379674555461633'), false)
assert.equal(TAILLEG_ORDER_NUMBER.timeZone, 'Asia/Shanghai')
assert.match(generator, /Asia\/Shanghai/)
assert.match(generator, /yyMMdd/)
assert.match(generator, /LMO-/)
assert.match(generator, /%04d|padStart\(4|String\.format/)
assert.match(generatorTests, /(?:concurrent|并发)/i)
assert.match(generatorTests, /(?:cross.?day|next.?day|跨天)/i)
assert.match(generatorTests, /LMO-260827-0001/)
assert.match(generatorTests, /LMO-260828-0001/)
assert.equal(TAILLEG_ORDER_NUMBER.sharedBy, 'containerNo')
assert.match(generator, /FL-WH-/)
assert.match(generator, /BASIC_ISO_DATE/)
assert.match(generator, /SHA-256/)
assert.match(generatorTests, /actualContainerNumberRemainsStableAndShared/)
})
test('one container with 15 inbound rows shares one stable container order number', () => {
const rows = Array.from({ length: 15 }, (_, index) => ({
containerNo: 'CONT-15', orderNo: 'LMO-260827-0042', sourceInboundId: `inbound-${index + 1}`,
containerNo: 'CONT-15', orderNo: 'FL-WH-20261020-000042', sourceInboundId: `inbound-${index + 1}`,
}))
assert.equal(validContainerOrderGroup(rows), true)
assert.equal(validContainerOrderGroup(rows.map((row, index) => index === 14
? { ...row, orderNo: 'LMO-260827-0043' } : row)), false)
? { ...row, orderNo: 'FL-WH-20261020-000043' } : row)), false)
assert.match(consumer, /String orderNo\s*=\s*orderNoGenerator\.forContainerNo\(payload\.containerNo\(\)\);[\s\S]*for \(int index/)
assert.match(consumer, /createOrder\(envelope, payload, source, orderNo, rawSource, containerNo/)
assert.match(consumerTests, /oneContainerWith15InboundRowsSharesOneStableContainerOrderNumber/)
})
test('same event replay adds nothing and preserves the allocated number', () => {
const before = { orderCount: 15, orderNo: 'LMO-260827-0042', detailCount: 30, historyCount: 15 }
const before = { orderCount: 15, orderNo: 'FL-WH-20261020-000042', detailCount: 30, historyCount: 15 }
assert.equal(validEventReplay(before, { ...before }), true)
assert.equal(validEventReplay(before, { ...before, orderCount: 30 }), false)
const duplicateBranch = consumer.slice(consumer.indexOf('if(existing!=null)'), consumer.indexOf('LastlegEventInbox inbox='))
@@ -103,5 +99,5 @@ test('same event replay adds nothing and preserves the allocated number', () =>
assert.match(racedBranch, /DeliveryAck\.Outcome\.DUPLICATE/)
assert.match(consumerTests, /replayPreservesExistingLmoNumberAndAddsNothing/)
assert.match(consumerTests, /verify\(sequences,never\(\)\)\.nextValue/)
assert.match(consumerTests, /verifyNoInteractions\(sequences\)/)
})