feat(fulfillment): 渠道联动与管道兜底
- 人工配置保存/删除同步渠道规则,人工确认写 channel/status - 按 SKU 指定渠道默认同时落规则 - 管道补充:载体缺失、人工成本未记录、事实与总账按水位追赶
This commit is contained in:
@@ -96,7 +96,11 @@ export async function listManualFulfillmentPending(
|
||||
const keyword = String(input.keyword || '').trim()
|
||||
const status = String(input.status || '').trim()
|
||||
|
||||
const conditions = ["oi.fulfillment_mode = 'manual'", 'cfg.id IS NOT NULL']
|
||||
const conditions = [
|
||||
"oi.fulfillment_status = 'assigned'",
|
||||
"oi.fulfillment_channel = 'manual'",
|
||||
'cfg.id IS NOT NULL',
|
||||
]
|
||||
const params: unknown[] = []
|
||||
|
||||
if (status === 'pending') {
|
||||
@@ -219,7 +223,7 @@ export async function confirmManualFulfillment(payload: JsonObject, session: Adm
|
||||
COALESCE(oi.revenue_amount_fen, 0)::bigint AS revenue_fen,
|
||||
COALESCE(o.paid_at, o.created_at) AS basis_at,
|
||||
oi.canonical_product_id,
|
||||
oi.fulfillment_mode,
|
||||
COALESCE(oi.fulfillment_channel, CASE WHEN oi.fulfillment_status = 'archived' THEN 'archived' ELSE 'pending' END) AS fulfillment_mode,
|
||||
oi.fulfillment_config_id AS config_id,
|
||||
COALESCE(cfg.platform_key, '') AS platform_key,
|
||||
COALESCE(cfg.credit_quantity, 0)::bigint AS credit_quantity,
|
||||
@@ -450,6 +454,21 @@ export async function confirmManualFulfillment(payload: JsonObject, session: Adm
|
||||
})
|
||||
}
|
||||
|
||||
// 人工确认即渠道成立:写新三列,避免订单一直停在 pending。
|
||||
await client.query(
|
||||
`
|
||||
UPDATE order_items
|
||||
SET fulfillment_channel = 'manual',
|
||||
fulfillment_status = 'assigned',
|
||||
fulfillment_source = 'manual_confirm',
|
||||
fulfillment_decided_at = $2,
|
||||
updated_at = $2
|
||||
WHERE id = $1
|
||||
AND fulfillment_status <> 'archived'
|
||||
`,
|
||||
[orderItemId, now],
|
||||
)
|
||||
|
||||
// 人工缺成本异常立即收口,不等下一轮定时任务。
|
||||
await client.query(
|
||||
`UPDATE cost_exceptions
|
||||
@@ -461,6 +480,20 @@ export async function confirmManualFulfillment(payload: JsonObject, session: Adm
|
||||
[orderItemId, now],
|
||||
)
|
||||
|
||||
// v2 聚合异常:删除本条明细,没人再引用的异常头自动关闭。
|
||||
await client.query(`DELETE FROM cost_exception_items WHERE order_item_id = $1`, [orderItemId])
|
||||
await client.query(
|
||||
`
|
||||
UPDATE cost_exceptions ce
|
||||
SET status = 'resolved', resolved_at = $1, item_count = 0, last_seen_at = $1
|
||||
WHERE ce.status <> 'resolved'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM cost_exception_items i WHERE i.exception_id = ce.id
|
||||
)
|
||||
`,
|
||||
[now],
|
||||
)
|
||||
|
||||
return {
|
||||
orderItemId,
|
||||
orderId: Number(row.order_id_resolved),
|
||||
@@ -582,7 +615,7 @@ async function matchManualFulfillmentConfigWithClient(
|
||||
)
|
||||
)
|
||||
WHERE oi.id = $1
|
||||
AND oi.fulfillment_mode = 'manual'
|
||||
AND oi.fulfillment_status = 'assigned' AND oi.fulfillment_channel = 'manual'
|
||||
AND oi.fulfillment_config_id IS NULL
|
||||
ORDER BY
|
||||
(cfg.canonical_product_id IS NOT NULL
|
||||
@@ -820,7 +853,7 @@ export async function getManualFulfillmentCountsByOrderIds(
|
||||
LEFT JOIN manual_fulfillment_configs cfg ON cfg.id = oi.fulfillment_config_id
|
||||
LEFT JOIN fulfilled ON fulfilled.order_item_id = oi.id
|
||||
WHERE oi.order_id = ANY($1::bigint[])
|
||||
AND oi.fulfillment_mode = 'manual'
|
||||
AND oi.fulfillment_status = 'assigned' AND oi.fulfillment_channel = 'manual'
|
||||
GROUP BY oi.order_id
|
||||
`,
|
||||
[ids],
|
||||
|
||||
Reference in New Issue
Block a user