129 lines
6.3 KiB
PL/PgSQL
129 lines
6.3 KiB
PL/PgSQL
-- =====================================================================
|
||
-- 2026-08-28 商机阶段历史数据换算更新(CRM 码值更换)
|
||
-- PostgreSQL 17
|
||
-- =====================================================================
|
||
-- 背景:
|
||
-- CRM 商机阶段码值更换。当前数据库 crm_opportunity.stage 存的是 OMS 侧
|
||
-- 码值,需换算回新 CRM 码值。权威对应关系以 crm_oms_dict_mapping 表
|
||
-- (dict_type='sj_xmjd')为准:oms_value -> crm_value。
|
||
--
|
||
-- 当前库映射表(已与字典 sys_dict_item/sj_xmjd 对齐):
|
||
-- OMS(当前库值) -> CRM(新值)
|
||
-- S0 -> S0 | S1 -> S1 | S2 -> S1 | S3 -> S2
|
||
-- S4A/S4B/S4C -> S3 | S5 -> S4
|
||
-- S6/S7A/S7B/S8 -> S5(已签单统一为 S5)
|
||
-- L -> L
|
||
--
|
||
-- 注意:原方案的「细分已签单」(S5/S6A/S6B/S7)与当前字典/映射表不符
|
||
-- (字典当前为 S0/S1/S2/S3/S4/S5/L,无 S6A/S6B/S7),已废弃。本脚本
|
||
-- 一律以当前映射表为准,保证换算结果全部落在字典定义内。
|
||
--
|
||
-- 安全性说明(务必审阅后执行):
|
||
-- 1) 前提:当前库 stage 全部为 OMS 码值(用户已确认)。
|
||
-- 2) 历史旧阶段(initial_contact/solution_discussion/bidding/
|
||
-- business_negotiation/won/lost)不在此对应范围,保持不动;NULL 不处理。
|
||
-- 3) 脚本默认只读诊断(A/B/C),更新语句(E/D)已注释;确认后按
|
||
-- 「先 E 校正映射表,再 D 换算」顺序取消注释并整段重跑(事务内,可回滚)。
|
||
-- 4) 新环境部署:20260827.sql 第 7 节插入的是旧码映射种子,必须启用
|
||
-- E 节将其校正为当前 S5 版,再执行 D 换算(对当前库 E 为幂等)。
|
||
-- =====================================================================
|
||
|
||
begin;
|
||
|
||
set search_path to public;
|
||
|
||
-- ---------------------------------------------------------------------
|
||
-- A) 诊断:当前 crm_opportunity.stage 分布(全部值)
|
||
-- ---------------------------------------------------------------------
|
||
select stage, count(*) as cnt
|
||
from crm_opportunity
|
||
group by stage
|
||
order by stage;
|
||
|
||
-- ---------------------------------------------------------------------
|
||
-- B) 诊断:按 crm_oms_dict_mapping 统计需换算的记录
|
||
-- oms_value=当前库里值,crm_value=将换算成的新 CRM 码值
|
||
-- ---------------------------------------------------------------------
|
||
select m.oms_value as 当前_oms码值, m.crm_value as 目标_crm码值, count(*) as cnt
|
||
from crm_opportunity op
|
||
join crm_oms_dict_mapping m
|
||
on m.dict_type = 'sj_xmjd' and m.oms_value = op.stage
|
||
where m.crm_value <> op.stage
|
||
group by m.oms_value, m.crm_value
|
||
order by m.oms_value;
|
||
|
||
-- ---------------------------------------------------------------------
|
||
-- C) 诊断:将被换算的具体行样例(id、商机编号、当前值、目标值)
|
||
-- 请核对命中记录确实为 OMS 语义的阶段,确认无误后再启用更新
|
||
-- ---------------------------------------------------------------------
|
||
select op.id, op.opportunity_code, op.stage as 当前_oms码值, m.crm_value as 目标_crm码值
|
||
from crm_opportunity op
|
||
join crm_oms_dict_mapping m
|
||
on m.dict_type = 'sj_xmjd' and m.oms_value = op.stage
|
||
where m.crm_value <> op.stage
|
||
order by op.id;
|
||
|
||
-- ---------------------------------------------------------------------
|
||
-- E) 校正 crm_oms_dict_mapping(sj_xmjd)为当前权威版本(S5 已签单统一)
|
||
-- 数据源:当前库实际映射表,与字典 sys_dict_item/sj_xmjd 对齐。
|
||
-- 默认注释。新环境(20260827.sql 旧码种子)必须启用;当前库为幂等。
|
||
-- =====================================================================
|
||
/*
|
||
delete from crm_oms_dict_mapping where dict_type = 'sj_xmjd';
|
||
|
||
insert into crm_oms_dict_mapping
|
||
(dict_type, crm_value, crm_label, oms_value, oms_label, is_default)
|
||
values
|
||
('sj_xmjd', 'S0', 'S0-配置报价', 'S0', 'S0-配置报价', true),
|
||
('sj_xmjd', 'S1', 'S1-深化设计', 'S1', 'S1-标前引导', true),
|
||
('sj_xmjd', 'S1', 'S1-深化设计', 'S2', 'S2-招投标签', false),
|
||
('sj_xmjd', 'S2', 'S2-招投标签', 'S3', 'S3-招投标签期', true),
|
||
('sj_xmjd', 'S3', 'S3-中标未下单', 'S4A', 'S4A-中标未签(总包)', false),
|
||
('sj_xmjd', 'S3', 'S3-中标未下单', 'S4B', 'S4B-中标未签(省代)', false),
|
||
('sj_xmjd', 'S3', 'S3-中标未下单', 'S4C', 'S4C-中标未签(汇智)', true),
|
||
('sj_xmjd', 'S4', 'S4-下单未签单', 'S5', 'S5-订单合同签订期', true),
|
||
('sj_xmjd', 'S5', 'S5-已签单', 'S6', 'S6-订单合同已生效', true),
|
||
('sj_xmjd', 'S5', 'S5-已签单', 'S7A', 'S7A-订单部分发货', false),
|
||
('sj_xmjd', 'S5', 'S5-已签单', 'S7B', 'S7B-订单全部发货', false),
|
||
('sj_xmjd', 'S5', 'S5-已签单', 'S8', 'S8-已签收', false),
|
||
('sj_xmjd', 'L', 'L-已丢单', 'L', 'L-已丢单', true)
|
||
on conflict (dict_type, crm_value, oms_value) do update
|
||
set crm_label = excluded.crm_label,
|
||
oms_label = excluded.oms_label,
|
||
is_default = excluded.is_default,
|
||
updated_at = now();
|
||
*/
|
||
|
||
-- ---------------------------------------------------------------------
|
||
-- D) 执行更新:按 crm_oms_dict_mapping 把 OMS 码值换算回新 CRM 码值
|
||
-- 默认注释。确认 E(映射表校正)与上方诊断无误后,取消注释并整段重跑。
|
||
-- =====================================================================
|
||
/*
|
||
-- 注意:这是单条 UPDATE,每行仅按执行前的原始 stage 匹配一次、SET 一次完成,
|
||
-- 不会出现 S3->S2 之后再按 S2->S1 二次匹配的连环更新。
|
||
-- 请勿将映射拆成多条顺序 UPDATE 执行,否则先 S3->S2 生成的 S2 会被
|
||
-- 后续 S2->S1 语句误判为 OMS 原值再次转换。
|
||
update crm_opportunity op
|
||
set stage = m.crm_value,
|
||
updated_at = now()
|
||
from crm_oms_dict_mapping m
|
||
where m.dict_type = 'sj_xmjd'
|
||
and op.stage = m.oms_value
|
||
and op.stage <> m.crm_value;
|
||
|
||
-- 核对本次受影响记录数
|
||
select count(*) as updated_rows
|
||
from crm_opportunity op
|
||
join crm_oms_dict_mapping m
|
||
on m.dict_type = 'sj_xmjd' and m.oms_value = op.stage
|
||
where m.crm_value <> op.stage;
|
||
|
||
-- 核对更新后分布,确认已全部转为新 CRM 码值(应落在 S0/S1/S2/S3/S4/S5/L)
|
||
select stage, count(*) as cnt
|
||
from crm_opportunity
|
||
group by stage
|
||
order by stage;
|
||
*/
|
||
|
||
commit;
|