feat(finance): 商品渠道能力、自动发货转人工与成本异常收口
- 商品可同时支持自动发货/人工,新增渠道能力与成本冲销字段 - 卡券缺商品时按内部中文 SKU 自动建 tpv: 商品并补渠道规则 - 自动发货失败转人工并冲销原渠道成本 - 配置成本后按最早缺失订单生效并立即补算、关闭异常 - tpv: 商品来源计入第三方卡券
This commit is contained in:
@@ -622,7 +622,7 @@ async function assertPeriodCloseable(
|
||||
SELECT 1 FROM cost_snapshots cs
|
||||
WHERE cs.subject_type = 'manual_case'
|
||||
AND cs.order_item_id = oi.id
|
||||
AND cs.superseded_at IS NULL
|
||||
AND cs.superseded_at IS NULL AND reversed_at IS NULL
|
||||
)
|
||||
`,
|
||||
[dateFrom, dateTo],
|
||||
@@ -639,7 +639,7 @@ async function assertPeriodCloseable(
|
||||
JOIN order_items oi ON oi.id = cs.order_item_id
|
||||
JOIN orders o ON o.id = oi.order_id
|
||||
WHERE cs.subject_type = 'manual_case'
|
||||
AND cs.superseded_at IS NULL
|
||||
AND cs.superseded_at IS NULL AND reversed_at IS NULL
|
||||
AND (COALESCE(o.paid_at, o.created_at) AT TIME ZONE 'Asia/Shanghai')::date
|
||||
BETWEEN $1::date AND $2::date
|
||||
AND cs.created_at >= (SELECT MIN(created_at) FROM manual_fulfillment_configs)
|
||||
@@ -661,7 +661,7 @@ async function assertPeriodCloseable(
|
||||
JOIN order_items oi ON oi.id = cs.order_item_id
|
||||
JOIN orders o ON o.id = oi.order_id
|
||||
WHERE cs.subject_type = 'manual_case'
|
||||
AND cs.superseded_at IS NULL
|
||||
AND cs.superseded_at IS NULL AND reversed_at IS NULL
|
||||
AND (COALESCE(o.paid_at, o.created_at) AT TIME ZONE 'Asia/Shanghai')::date
|
||||
BETWEEN $1::date AND $2::date
|
||||
AND cs.created_at >= (SELECT MIN(created_at) FROM manual_fulfillment_configs)
|
||||
|
||||
@@ -134,7 +134,7 @@ export async function listManualFulfillmentPending(
|
||||
cs.order_item_id,
|
||||
MAX(cs.created_at) AS fulfilled_at
|
||||
FROM cost_snapshots cs
|
||||
WHERE cs.subject_type = 'manual_case' AND cs.superseded_at IS NULL
|
||||
WHERE cs.subject_type = 'manual_case' AND cs.superseded_at IS NULL AND reversed_at IS NULL
|
||||
GROUP BY cs.order_item_id
|
||||
)
|
||||
`
|
||||
@@ -294,7 +294,7 @@ export async function confirmManualFulfillment(payload: JsonObject, session: Adm
|
||||
// 锁内复查:并发/双击的第二个请求会等锁,醒来后看到快照直接拒绝,不会重复扣款。
|
||||
const existing = await client.query<{ id: number }>(
|
||||
`SELECT id FROM cost_snapshots
|
||||
WHERE subject_type = 'manual_case' AND order_item_id = $1 AND superseded_at IS NULL
|
||||
WHERE subject_type = 'manual_case' AND order_item_id = $1 AND superseded_at IS NULL AND reversed_at IS NULL
|
||||
LIMIT 1`,
|
||||
[orderItemId],
|
||||
)
|
||||
@@ -874,7 +874,7 @@ export async function getManualFulfillmentCountsByOrderIds(
|
||||
WITH fulfilled AS (
|
||||
SELECT order_item_id, MAX(created_at) AS fulfilled_at
|
||||
FROM cost_snapshots
|
||||
WHERE subject_type = 'manual_case' AND superseded_at IS NULL
|
||||
WHERE subject_type = 'manual_case' AND superseded_at IS NULL AND reversed_at IS NULL
|
||||
GROUP BY order_item_id
|
||||
)
|
||||
SELECT
|
||||
|
||||
@@ -105,18 +105,18 @@ export async function rebuildChannelSalesDailyFacts(input: {
|
||||
FROM cost_snapshots cs
|
||||
JOIN cost_items ci ON ci.id = cs.cost_item_id
|
||||
WHERE cs.order_item_id = s.order_item_id
|
||||
AND cs.superseded_at IS NULL
|
||||
AND cs.superseded_at IS NULL AND reversed_at IS NULL AND cs.reversed_at IS NULL
|
||||
AND ci.code = s.channel_cost_code
|
||||
)
|
||||
WHEN s.channel = 'manual' THEN NOT EXISTS (
|
||||
SELECT 1 FROM cost_snapshots cs
|
||||
WHERE cs.order_item_id = s.order_item_id
|
||||
AND cs.superseded_at IS NULL
|
||||
AND cs.superseded_at IS NULL AND reversed_at IS NULL AND cs.reversed_at IS NULL
|
||||
AND cs.subject_type = 'manual_case'
|
||||
)
|
||||
ELSE NOT EXISTS (
|
||||
SELECT 1 FROM cost_snapshots cs
|
||||
WHERE cs.order_item_id = s.order_item_id AND cs.superseded_at IS NULL
|
||||
WHERE cs.order_item_id = s.order_item_id AND cs.superseded_at IS NULL AND reversed_at IS NULL AND cs.reversed_at IS NULL
|
||||
)
|
||||
END AS cost_missing,
|
||||
COALESCE(c.has_actual, FALSE) AS has_actual
|
||||
@@ -128,7 +128,7 @@ export async function rebuildChannelSalesDailyFacts(input: {
|
||||
SUM(cs.total_amount_fen)::bigint AS cost_fen,
|
||||
BOOL_AND(cs.snapshot_stage = 'actual') AS has_actual
|
||||
FROM cost_snapshots cs
|
||||
WHERE cs.superseded_at IS NULL
|
||||
WHERE cs.superseded_at IS NULL AND reversed_at IS NULL AND cs.reversed_at IS NULL
|
||||
GROUP BY cs.order_item_id
|
||||
) c ON c.order_item_id = s.order_item_id
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user