-- 2026-07-02 商机业绩归属地数据回填脚本
--
-- 回填规则：
-- 1. 党旭、杨斯雷：业绩归属地取商机项目地。
--    - 项目地为省级名称/简称/编码时，写入该省级 cnarea.area_code。
--    - 项目地为城市名称/简称/编码时，写入该城市上级省份 cnarea.area_code。
-- 2. 其余表格内销售：业绩归属地取表格“主区域”，写入对应省级 cnarea.area_code。

begin;

set search_path to public;

alter table if exists crm_opportunity
  add column if not exists project_ownership_location varchar(100);

comment on column crm_opportunity.project_ownership_location is '业绩归属地编码，对应 cnarea.area_code';

do $$
declare
  v_user_pk text;
  v_name_queries text[] := array[]::text[];
  v_main_region_updated integer := 0;
  v_project_location_updated integer := 0;
begin
  if to_regclass('public.crm_opportunity') is null then
    raise exception 'crm_opportunity 表不存在，无法回填业绩归属地';
  end if;

  if to_regclass('public.sys_user') is null then
    raise exception 'sys_user 表不存在，无法按销售负责人回填业绩归属地';
  end if;

  if to_regclass('public.cnarea') is null then
    raise exception 'cnarea 表不存在，无法将业绩归属地解析为 area_code';
  end if;

  select case
      when exists (
        select 1
        from information_schema.columns
        where table_schema = 'public'
          and table_name = 'sys_user'
          and column_name = 'user_id'
      ) then 'user_id'
      when exists (
        select 1
        from information_schema.columns
        where table_schema = 'public'
          and table_name = 'sys_user'
          and column_name = 'id'
      ) then 'id'
      else null
    end
    into v_user_pk;

  if v_user_pk is null then
    raise exception 'sys_user 缺少 user_id/id 字段，无法关联 crm_opportunity.owner_user_id';
  end if;

  if exists (
    select 1
    from information_schema.columns
    where table_schema = 'public'
      and table_name = 'sys_user'
      and column_name = 'display_name'
  ) then
    v_name_queries := array_append(
      v_name_queries,
      format(
        'select u.%I::bigint as owner_user_id, nullif(btrim(u.display_name), '''') as owner_name from sys_user u where nullif(btrim(u.display_name), '''') is not null',
        v_user_pk
      )
    );
  end if;

  if exists (
    select 1
    from information_schema.columns
    where table_schema = 'public'
      and table_name = 'sys_user'
      and column_name = 'real_name'
  ) then
    v_name_queries := array_append(
      v_name_queries,
      format(
        'select u.%I::bigint as owner_user_id, nullif(btrim(u.real_name), '''') as owner_name from sys_user u where nullif(btrim(u.real_name), '''') is not null',
        v_user_pk
      )
    );
  end if;

  if exists (
    select 1
    from information_schema.columns
    where table_schema = 'public'
      and table_name = 'sys_user'
      and column_name = 'username'
  ) then
    v_name_queries := array_append(
      v_name_queries,
      format(
        'select u.%I::bigint as owner_user_id, nullif(btrim(u.username), '''') as owner_name from sys_user u where nullif(btrim(u.username), '''') is not null',
        v_user_pk
      )
    );
  end if;

  if array_length(v_name_queries, 1) is null then
    raise exception 'sys_user 缺少 display_name/real_name/username 字段，无法匹配区域销售';
  end if;

  drop table if exists tmp_opportunity_owner_name;
  create temp table tmp_opportunity_owner_name (
    owner_user_id bigint not null,
    owner_name text not null
  ) on commit drop;

  execute
    'insert into tmp_opportunity_owner_name (owner_user_id, owner_name) ' ||
    'select distinct owner_user_id, owner_name from (' ||
    array_to_string(v_name_queries, ' union all ') ||
    ') t';

  with owner_main_region(owner_name, main_region) as (
    values
      ('苑磊', '山东'),
      ('张贝贝', '河南'),
      ('吕志威', '浙江'),
      ('谈欣', '辽宁'),
      ('丰世雄', '内蒙古'),
      ('李继设', '广西'),
      ('王昊玮', '山西'),
      ('韩东升', '云南'),
      ('冯文超', '湖北'),
      ('徐凯', '四川'),
      ('陈志华', '河北'),
      ('向往', '江苏'),
      ('王孟杰', '新疆'),
      ('杨坤融', '新疆')
  )
  update crm_opportunity o
  set project_ownership_location = area.area_code
  from tmp_opportunity_owner_name owner_name
  join owner_main_region region
    on region.owner_name = owner_name.owner_name
  join cnarea area
    on area.level = 1
   and (
      area.short_name = region.main_region
      or area.name = region.main_region
      or area.area_code = region.main_region
   )
  where o.owner_user_id = owner_name.owner_user_id
    and o.project_ownership_location is distinct from area.area_code;

  get diagnostics v_main_region_updated = row_count;

  update crm_opportunity o
  set project_ownership_location = (
    select coalesce(
        case when matched_area.level = 1 then matched_area.area_code end,
        parent_area.area_code
      )
    from cnarea matched_area
    left join cnarea parent_area
      on parent_area.level = 1
     and parent_area.area_code = matched_area.parent_code
    where matched_area.level in (1, 2)
      and (
        matched_area.area_code = btrim(o.project_location)
        or matched_area.short_name = btrim(o.project_location)
        or matched_area.name = btrim(o.project_location)
      )
    order by
      case when matched_area.level = 1 then 0 else 1 end,
      matched_area.area_code asc,
      matched_area.id asc
    limit 1
  )
  from tmp_opportunity_owner_name owner_name
  where o.owner_user_id = owner_name.owner_user_id
    and owner_name.owner_name in ('党旭', '杨斯雷')
    and coalesce(nullif(btrim(o.project_location), ''), '') <> ''
    and (
      select coalesce(
          case when matched_area.level = 1 then matched_area.area_code end,
          parent_area.area_code
        )
      from cnarea matched_area
      left join cnarea parent_area
        on parent_area.level = 1
       and parent_area.area_code = matched_area.parent_code
      where matched_area.level in (1, 2)
        and (
          matched_area.area_code = btrim(o.project_location)
          or matched_area.short_name = btrim(o.project_location)
          or matched_area.name = btrim(o.project_location)
        )
      order by
        case when matched_area.level = 1 then 0 else 1 end,
        matched_area.area_code asc,
        matched_area.id asc
      limit 1
    ) is not null
    and o.project_ownership_location is distinct from (
      select coalesce(
          case when matched_area.level = 1 then matched_area.area_code end,
          parent_area.area_code
        )
      from cnarea matched_area
      left join cnarea parent_area
        on parent_area.level = 1
       and parent_area.area_code = matched_area.parent_code
      where matched_area.level in (1, 2)
        and (
          matched_area.area_code = btrim(o.project_location)
          or matched_area.short_name = btrim(o.project_location)
          or matched_area.name = btrim(o.project_location)
        )
      order by
        case when matched_area.level = 1 then 0 else 1 end,
        matched_area.area_code asc,
        matched_area.id asc
      limit 1
    );

  get diagnostics v_project_location_updated = row_count;

  raise notice '业绩归属地回填完成：按主区域更新 % 条，按项目地更新 % 条',
    v_main_region_updated,
    v_project_location_updated;
end $$;

commit;
