feat(finance): 商品渠道能力、自动发货转人工与成本异常收口
- 商品可同时支持自动发货/人工,新增渠道能力与成本冲销字段 - 卡券缺商品时按内部中文 SKU 自动建 tpv: 商品并补渠道规则 - 自动发货失败转人工并冲销原渠道成本 - 配置成本后按最早缺失订单生效并立即补算、关闭异常 - tpv: 商品来源计入第三方卡券
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
-- 115_product_channel_capabilities.sql
|
||||
--
|
||||
-- 渠道能力与履约兜底:
|
||||
-- 1. 商品可同时具备多个渠道能力(自动发货 + 人工兜底);
|
||||
-- 2. 订单项记录原始渠道与切换原因;
|
||||
-- 3. 成本快照支持冲销(reversed_at),切换渠道时不双算;
|
||||
-- 4. fulfillment_source 增加 affiliate_fallback。
|
||||
|
||||
CREATE TABLE IF NOT EXISTS product_channel_capabilities (
|
||||
product_id BIGINT NOT NULL REFERENCES product_catalog(id) ON DELETE CASCADE,
|
||||
channel TEXT NOT NULL,
|
||||
priority INTEGER NOT NULL DEFAULT 100,
|
||||
is_fallback BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
source TEXT NOT NULL DEFAULT 'auto',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (product_id, channel)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE product_channel_capabilities IS
|
||||
'商品渠道能力:一个商品可同时支持自动发货、人工等;priority 越小越优先';
|
||||
|
||||
-- 自动发货商品:默认自动优先,人工兜底
|
||||
INSERT INTO product_channel_capabilities (product_id, channel, priority, is_fallback)
|
||||
SELECT p.id, 'affiliate_dash', 10, FALSE
|
||||
FROM product_catalog p
|
||||
WHERE p.canonical_sku LIKE 'aff:%' AND p.status = 'active'
|
||||
ON CONFLICT (product_id, channel) DO NOTHING;
|
||||
|
||||
INSERT INTO product_channel_capabilities (product_id, channel, priority, is_fallback)
|
||||
SELECT p.id, 'manual', 90, TRUE
|
||||
FROM product_catalog p
|
||||
WHERE p.canonical_sku LIKE 'aff:%' AND p.status = 'active'
|
||||
ON CONFLICT (product_id, channel) DO NOTHING;
|
||||
|
||||
-- 人工商品:人工优先
|
||||
INSERT INTO product_channel_capabilities (product_id, channel, priority, is_fallback)
|
||||
SELECT p.id, 'manual', 10, FALSE
|
||||
FROM product_catalog p
|
||||
WHERE p.canonical_sku LIKE 'man:%' AND p.status = 'active'
|
||||
ON CONFLICT (product_id, channel) DO NOTHING;
|
||||
|
||||
-- 卡券:只统计
|
||||
INSERT INTO product_channel_capabilities (product_id, channel, priority, is_fallback)
|
||||
SELECT p.id, 'third_party_voucher', 10, FALSE
|
||||
FROM product_catalog p
|
||||
WHERE p.canonical_sku LIKE 'tpv:%' AND p.status = 'active'
|
||||
ON CONFLICT (product_id, channel) DO NOTHING;
|
||||
|
||||
-- 接单模板/工单商品
|
||||
INSERT INTO product_channel_capabilities (product_id, channel, priority, is_fallback)
|
||||
SELECT p.id, 'work_order', 10, FALSE
|
||||
FROM product_catalog p
|
||||
WHERE (p.canonical_sku LIKE 'tpl:%' OR p.canonical_sku LIKE 'wo:%') AND p.status = 'active'
|
||||
ON CONFLICT (product_id, channel) DO NOTHING;
|
||||
|
||||
ALTER TABLE order_items
|
||||
ADD COLUMN IF NOT EXISTS original_channel TEXT,
|
||||
ADD COLUMN IF NOT EXISTS channel_switch_reason TEXT NOT NULL DEFAULT '',
|
||||
ADD COLUMN IF NOT EXISTS channel_switched_at TIMESTAMPTZ;
|
||||
|
||||
COMMENT ON COLUMN order_items.original_channel IS
|
||||
'首次分流渠道;fallback/运营改渠道后仍保留,用于审计';
|
||||
COMMENT ON COLUMN order_items.channel_switch_reason IS
|
||||
'渠道切换原因:affiliate_failed / manual_supplement / operator';
|
||||
|
||||
ALTER TABLE cost_snapshots
|
||||
ADD COLUMN IF NOT EXISTS reversed_at TIMESTAMPTZ,
|
||||
ADD COLUMN IF NOT EXISTS reversal_reason TEXT NOT NULL DEFAULT '';
|
||||
|
||||
DROP INDEX IF EXISTS uq_cost_snapshots_active_subject_item;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_cost_snapshots_active_subject_item
|
||||
ON cost_snapshots (subject_type, subject_id, cost_item_id)
|
||||
WHERE superseded_at IS NULL AND reversed_at IS NULL;
|
||||
|
||||
-- 人工成本快照同样排除已冲销行,允许冲销后重新确认。
|
||||
DROP INDEX IF EXISTS uq_cost_snapshots_manual_order_item;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_cost_snapshots_manual_order_item
|
||||
ON cost_snapshots (order_item_id)
|
||||
WHERE subject_type = 'manual_case' AND superseded_at IS NULL
|
||||
AND reversed_at IS NULL AND subject_id > 0;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_order_items_fulfillment_source'
|
||||
) THEN
|
||||
ALTER TABLE order_items DROP CONSTRAINT chk_order_items_fulfillment_source;
|
||||
END IF;
|
||||
ALTER TABLE order_items
|
||||
ADD CONSTRAINT chk_order_items_fulfillment_source
|
||||
CHECK (
|
||||
fulfillment_source IN (
|
||||
'', 'auto_rule', 'auto_mapping', 'carrier_evidence',
|
||||
'manual_confirm', 'operator_assigned', 'cutover_archive',
|
||||
'affiliate_fallback'
|
||||
)
|
||||
);
|
||||
END $$;
|
||||
Reference in New Issue
Block a user