解耦接单与履约订单处理
This commit is contained in:
@@ -118,29 +118,8 @@ export async function upsertOrderFromSource(
|
||||
}),
|
||||
),
|
||||
)
|
||||
const configuredItems = (resolvedItems as FulfillmentOrderItem[]).filter(
|
||||
(item) => item.isConfigured,
|
||||
)
|
||||
|
||||
if (configuredItems.length === 0) {
|
||||
logIntegration('[order-service]', `${sourceLabel} 订单已忽略:未命中任何已配置履约商品`, {
|
||||
provider: event.provider,
|
||||
platform: event.platform,
|
||||
shopId: event.shopId,
|
||||
shopName: event.shopName,
|
||||
platformOrderId: event.platformOrderId,
|
||||
existingOrderId: existing?.id || null,
|
||||
rawItemCount: event.items.length,
|
||||
})
|
||||
|
||||
return {
|
||||
ignored: true,
|
||||
ignoreReason: 'unconfigured_items',
|
||||
order: null,
|
||||
orderItems: [],
|
||||
tasks: [],
|
||||
}
|
||||
}
|
||||
const resolvedFulfillmentItems = resolvedItems as FulfillmentOrderItem[]
|
||||
const configuredItems = resolvedFulfillmentItems.filter((item) => item.isConfigured)
|
||||
|
||||
const basePayload = {
|
||||
provider: event.provider,
|
||||
@@ -182,7 +161,7 @@ export async function upsertOrderFromSource(
|
||||
|
||||
const orderItems = await replaceOrderItems(
|
||||
order.id,
|
||||
configuredItems.map((item) => ({
|
||||
resolvedFulfillmentItems.map((item) => ({
|
||||
skuCode: item.skuCode,
|
||||
skuName: item.skuName,
|
||||
quantity: item.quantity,
|
||||
@@ -193,7 +172,11 @@ export async function upsertOrderFromSource(
|
||||
})),
|
||||
)
|
||||
|
||||
const readiness = await resolveOrderFulfillmentReadiness(order)
|
||||
const configuredOrderItems = orderItems.filter(isOrderItemConfiguredForFulfillment)
|
||||
const readiness =
|
||||
configuredOrderItems.length > 0
|
||||
? await resolveOrderFulfillmentReadiness(order)
|
||||
: { allowed: true as const, voucherCount: 0, reason: '', blockReason: '' }
|
||||
if (!readiness.allowed) {
|
||||
logIntegration(
|
||||
'[order-service]',
|
||||
@@ -209,6 +192,10 @@ export async function upsertOrderFromSource(
|
||||
{ level: 'warn' },
|
||||
)
|
||||
|
||||
await syncWorkerOrdersForSourceOrder(order, orderItems, {
|
||||
source: `${sourceLabel}_order_upsert`,
|
||||
autoOnly: true,
|
||||
})
|
||||
return {
|
||||
ignoreReason: readiness.blockReason || 'fulfillment_not_ready',
|
||||
order,
|
||||
@@ -217,7 +204,10 @@ export async function upsertOrderFromSource(
|
||||
}
|
||||
}
|
||||
|
||||
const tasks = await syncDeliveryTasksForOrder(order, orderItems)
|
||||
const tasks =
|
||||
configuredOrderItems.length > 0
|
||||
? await syncDeliveryTasksForOrder(order, configuredOrderItems)
|
||||
: []
|
||||
await syncOrderFulfillmentAttachments(order, tasks, {
|
||||
source: `${sourceLabel}_order_upsert`,
|
||||
now,
|
||||
@@ -293,6 +283,20 @@ export function mergeSourceOrderState(
|
||||
}
|
||||
}
|
||||
|
||||
function isOrderItemConfiguredForFulfillment(item: OrderItemRow): boolean {
|
||||
try {
|
||||
const snapshot = JSON.parse(String(item.item_snapshot_json || '{}'))
|
||||
return Boolean(
|
||||
snapshot &&
|
||||
typeof snapshot === 'object' &&
|
||||
!Array.isArray(snapshot) &&
|
||||
snapshot.isConfigured === true,
|
||||
)
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function chooseHigherPriorityStatus(
|
||||
existingValue: string,
|
||||
incomingValue: string,
|
||||
|
||||
@@ -594,12 +594,21 @@ export function resolveMatchingProductRule(
|
||||
if (!matchesOptionalText(rule.platform, order.platform)) return false
|
||||
if (!matchesOptionalText(rule.shop_id, order.shop_id)) return false
|
||||
|
||||
const skuCode = String(item.sku_code || '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
const skuName = String(item.sku_name || '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
const snapshot = safeParseJson(item.item_snapshot_json)
|
||||
const skuCodes = [item.sku_code, snapshot.externalSkuCode, snapshot.externalItemId]
|
||||
.map((value) =>
|
||||
String(value || '')
|
||||
.trim()
|
||||
.toLowerCase(),
|
||||
)
|
||||
.filter(Boolean)
|
||||
const skuNames = [item.sku_name, snapshot.externalSkuName, snapshot.externalSkuNameNormalized]
|
||||
.map((value) =>
|
||||
String(value || '')
|
||||
.trim()
|
||||
.toLowerCase(),
|
||||
)
|
||||
.filter(Boolean)
|
||||
const ruleSkuCode = String(rule.sku_code || '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
@@ -607,16 +616,19 @@ export function resolveMatchingProductRule(
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
|
||||
if (ruleSkuCode && ruleSkuCode !== skuCode) {
|
||||
if (ruleSkuCode && !skuCodes.includes(ruleSkuCode)) {
|
||||
return false
|
||||
}
|
||||
if (!ruleProductName) {
|
||||
return Boolean(ruleSkuCode)
|
||||
}
|
||||
if (rule.match_type === 'exact') {
|
||||
return ruleProductName === skuName || ruleProductName === skuCode
|
||||
return skuNames.includes(ruleProductName) || skuCodes.includes(ruleProductName)
|
||||
}
|
||||
return skuName.includes(ruleProductName) || skuCode.includes(ruleProductName)
|
||||
return (
|
||||
skuNames.some((value) => value.includes(ruleProductName)) ||
|
||||
skuCodes.some((value) => value.includes(ruleProductName))
|
||||
)
|
||||
}) || null
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user