fix(fulfillment): 封堵重复载体并完善统一SKU映射
This commit is contained in:
@@ -71,3 +71,28 @@ test('工单门禁:无配置、冲突、缺模板、模板不一致都不放
|
||||
'work_rule_mismatch',
|
||||
)
|
||||
})
|
||||
|
||||
test('工单门禁:已分配其它渠道或已有其它真实载体时不放行', () => {
|
||||
assert.equal(
|
||||
resolveWorkOrderChannelGate(plan(channel()), undefined, {
|
||||
fulfillmentStatus: 'assigned',
|
||||
assignedChannel: 'affiliate_dash',
|
||||
}).reason,
|
||||
'already_assigned_other_channel',
|
||||
)
|
||||
assert.equal(
|
||||
resolveWorkOrderChannelGate(plan(channel()), undefined, {
|
||||
fulfillmentStatus: 'pending',
|
||||
existingCarrierChannels: ['affiliate_dash'],
|
||||
}).reason,
|
||||
'existing_carrier_taken',
|
||||
)
|
||||
assert.equal(
|
||||
resolveWorkOrderChannelGate(plan(channel()), undefined, {
|
||||
fulfillmentStatus: 'assigned',
|
||||
assignedChannel: 'work_order',
|
||||
existingCarrierChannels: ['work_order'],
|
||||
}).allowed,
|
||||
true,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -51,11 +51,27 @@ import {
|
||||
canonicalizeInternalSku,
|
||||
resolveInternalSkuKey,
|
||||
} from '../fulfillment/internal-sku-resolver.js'
|
||||
import { loadActiveCarrierEvidence } from '../fulfillment/carrier-evidence-service.js'
|
||||
|
||||
export function resolveWorkOrderChannelGate(
|
||||
plan: InternalSkuChannelPlan | undefined,
|
||||
preferredWorkRuleKey?: string,
|
||||
context: {
|
||||
fulfillmentStatus?: string
|
||||
assignedChannel?: string
|
||||
existingCarrierChannels?: string[]
|
||||
} = {},
|
||||
): { allowed: boolean; reason: string; workRuleKey: string } {
|
||||
if (
|
||||
context.fulfillmentStatus === 'assigned' &&
|
||||
context.assignedChannel &&
|
||||
context.assignedChannel !== 'work_order'
|
||||
) {
|
||||
return { allowed: false, reason: 'already_assigned_other_channel', workRuleKey: '' }
|
||||
}
|
||||
if (context.existingCarrierChannels?.some((channel) => channel !== 'work_order')) {
|
||||
return { allowed: false, reason: 'existing_carrier_taken', workRuleKey: '' }
|
||||
}
|
||||
if (!plan?.primary) {
|
||||
return {
|
||||
allowed: false,
|
||||
@@ -109,6 +125,7 @@ export async function syncWorkerOrdersForSourceOrder(
|
||||
)
|
||||
}
|
||||
const channelPlans = await loadInternalSkuChannelPlans([...internalSkuByItemId.values()])
|
||||
const carrierEvidence = await loadActiveCarrierEvidence(orderItems.map((item) => Number(item.id)))
|
||||
|
||||
for (const item of orderItems) {
|
||||
const internalSku = canonicalizeInternalSku(internalSkuByItemId.get(Number(item.id)))
|
||||
@@ -123,7 +140,12 @@ export async function syncWorkerOrdersForSourceOrder(
|
||||
)
|
||||
continue
|
||||
}
|
||||
const channelGate = resolveWorkOrderChannelGate(channelPlan, options.preferredWorkRuleKey)
|
||||
const assignedChannel = String(item.fulfillment_channel || '').trim()
|
||||
const channelGate = resolveWorkOrderChannelGate(channelPlan, options.preferredWorkRuleKey, {
|
||||
fulfillmentStatus: item.fulfillment_status || '',
|
||||
assignedChannel,
|
||||
existingCarrierChannels: carrierEvidence.get(Number(item.id))?.channels || [],
|
||||
})
|
||||
if (!channelGate.allowed) {
|
||||
skipped.push({ orderItemId: Number(item.id), reason: channelGate.reason })
|
||||
decisions.push(
|
||||
|
||||
Reference in New Issue
Block a user