delimiter //

create procedure get_treedata(
  in p_type varchar(20) default 'sprintid', -- sprint etc..
  in p_para01 nvarchar(100) default '1' -- 特別傳入的參數, 目前是 bookid 會傳入 1, 擴充用途(說明如下)
)
/*
  Function   : 配合 amis 的 treeview, 取得 year-sprint 類的2階資料
               目前的寫法只適用於固定2階, 如果階數不固定, 要找時間修改(bom 展開), 暫時不適用
			   擴充 @para, 目前是電子書專用, 如果有 @, @後的就是內文的全文檢索內容
  Description: 可以用在 pbi, 會計科目等左方有 tree-view 的 UX, api 回傳用 6
			   新增 @type 參數
			   sprint   取得 year-sprint 資料(給 menu 使用)
			   basdepartment
			   acctitle 取得 類別-科目 資料(大部分都是用這個)
			   eipmxx.idno 避免 key 重複導致的錯誤
  Build Date : 2021/10/19
  
  Modify History
    Item Who        Date       Modify Docs
    ==== ========== ========== ================================================
    1    Michael    2021/11/26
	2    Michael    2021/12/31 新增 on lone books
	3    Michael    2022/04/14 新增 sys_aside_setup, aside 改為依設定即可產生 aside 相關 json 設定
    4    Michael    2022/06/19 @type 加上 tag.type 以防止重複, tag 僅供識別用
	5    Michael    2022/07/18 key-value 擴充能支援2層式的 tree(開發中)
	6    Michael    2022/07/27 擴充 @para01 內容, 支援內文查詢過濾
	7    Michael    2023/01/13 將 @para01 第一碼的 bookid 改為傳入 functag
*/
as

declare max_val int;
declare curr_id int;
declare group_id int;
declare next_group_id int;
declare datas nvarchar(max);
declare footer varchar(600);
declare dept_name varchar(100);
declare emp_name varchar(100);
declare person_id varchar(100);
declare crlf varchar(2);
declare comm varchar(1);
declare aside_id varchar(100);
declare group_partitionby varchar(100);
declare group_orderby varchar(100);
declare row_orderby varchar(100);
declare filter_field varchar(100);
declare tablename varchar(100);
declare rel_tablename varchar(100);
declare g_partition1 varchar(100);
declare g_partition2 varchar(100);
declare filter_value varchar(100);
declare para02 varchar(100);
declare pos int;
declare cnt int;
declare sql_cmd nvarchar(max);

set crlf = char(10) + char(13);

declare data table (
  xr_id varchar(100), x_id varchar(100),
  xr_name varchar(100), x_name varchar(100),
  groupid int, rowid int
);

-- 取得相關設定參數
select 
  aside_id, group_partitionby, group_orderby, row_orderby,
  filter_field, tablename, rel_tablename, filter_value
into aside_id, group_partitionby, group_orderby, row_orderby,
     filter_field, tablename, rel_tablename, filter_value
from sys_aside_setup where aside_id = p_type;

-- 去除 p_type 中的 tag
set pos = charindex('.', p_type);
if pos > 0 then
  set p_type = substring(p_type, pos + 1, len(p_type));
end if;

set sql_cmd = '';
set pos = charindex('@', p_para01);
set para02 = '';
if pos > 0 then
  set para02 = substring(p_para01, pos + 1, 100);
  set p_para01 = substring(p_para01, 1, pos - 1);

  -- 將 p_para01 由 functag 改為 bookid, add by Michael 2023/01/13 
  select keyid into p_para01 from zen_keyvalue where fieldname = 'book_mapping_id' and keyvalue = p_para01;
  if isnull(p_para01, '') = '' then
    set p_para01 = '1';
  end if;
end if;

set cnt = 0;
select count(*) into cnt from zen_keyvalue where fieldname = 'classid' and isnull(keydesc, '') <> '';

if isnull(filter_field, '') <> '' and isnull(filter_value, '') <> '' then
  set filter_value = char(39) + filter_value + char(39);
end if;

set sql_cmd = '';
if p_type <> 'classid' then
  if isnull(group_partitionby, '') <> '' then
    set g_partition1 = 'Partition by ' + group_partitionby;
    set g_partition2 = 'R.' + group_partitionby + ',';
  end if;

  if rel_tablename = '' then
    if cnt > 0 then
      set g_partition1 = 'Partition by keydesc';
      set g_partition2 = 'keydesc,';
      set sql_cmd = 
        'insert into sys_aside_temp (aside_guid, xr_id, x_id, xr_name, x_name, groupid, rowid)' +
        ' select ' + char(39) + p_type + char(39) + ',' + 
        case when group_id = '*' then char(39) + group_id + char(39) else group_id end + ',' + row_id + ',' + 
        case when group_id = '*' then char(39) + group_name + char(39) else group_name end + ',' + row_name + ',' +
        '   ROW_NUMBER() OVER(' + g_partition1 + ' ORDER BY ' + group_orderby + ') AS groupid,' +
        '   ROW_NUMBER() OVER(ORDER BY ' + g_partition2 + row_orderby + ') AS rowid' +
        ' from ' + tablename +
        ' where coalesce(' + row_id + ', char(39) + char(39)) <> ' + char(39) + char(39) + filter_value;
    else
      set sql_cmd = 
        'insert into sys_aside_temp (aside_guid, xr_id, x_id, xr_name, x_name, groupid, rowid)' +
        ' select ' + char(39) + p_type + char(39) + ',' + 
        case when group_id = '*' then char(39) + group_id + char(39) else group_id end + ',' + row_id + ',' + 
        case when group_id = '*' then char(39) + group_name + char(39) else group_name end + ',' + row_name + ',' +
        '   ROW_NUMBER() OVER(' + g_partition1 + ' ORDER BY ' + group_orderby + ') AS groupid,' +
        '   ROW_NUMBER() OVER(ORDER BY ' + g_partition2 + row_orderby + ') AS rowid' +
        ' from ' + tablename +
        ' where coalesce(' + row_id + ', char(39) + char(39)) <> ' + char(39) + char(39) + filter_value;
    end if;
  else
    set sql_cmd = 
      'insert into sys_aside_temp (aside_guid, xr_id, x_id, xr_name, x_name, groupid, rowid)' +
      ' select ' + char(39) + p_type + char(39) + ',' + 
      case when group_id = '*' then char(39) + 'R.' + group_id + char(39) else 'R.' + group_id end + ',' + 'M.' + row_id + ',' + 
      case when group_id = '*' then char(39) + 'R.' + group_name + char(39) else 'R.' + group_name end + ',' + 'M.' + row_name + ',' +
      '   ROW_NUMBER() OVER(' + g_partition1 + ' ORDER BY ' + 'M.' + group_orderby + ') AS groupid,' +
      '   ROW_NUMBER() OVER(ORDER BY ' + g_partition2 + 'M.' + row_orderby + ') AS rowid' +
      ' from ' + tablename + ' M' +
      ' left join ' + rel_tablename + ' R on M.' + group_partitionby + ' = R.' + group_partitionby +
      ' where coalesce(' + 'M.' + row_id + ', char(39) + char(39)) <> ' + char(39) + char(39) + filter_value;
  end if;
else
  if isnull(group_partitionby, '') = '' then
    set sql_cmd = 
      'insert into sys_aside_temp (aside_guid, xr_id, x_id, xr_name, x_name, groupid, rowid) ' +
      'select ' + char(39) + p_type + char(39) + ',' + 
      '  x.' + group_id + ', x.' + row_id + ', b.' + group_name + ', x.' + group_name + ', groupid, rowid' + crlf +
      'from' + crlf +
      '(' + crlf +
      '  select ' + group_id + ',' + row_id + ',' + group_name + ',' + 
      case when group_name <> row_name then row_name + ',' else '' end + 
      group_id + ' as p_classid,' + crlf +
      '    ROW_NUMBER() OVER(ORDER BY ' + group_orderby + ') AS groupid,' + crlf +
      '    ROW_NUMBER() OVER(ORDER BY ' + row_orderby + ') AS rowid' + crlf +
      '  from ' + tablename + crlf +
      '  where coalesce(' + group_id + ', char(39) + char(39)) <> ' + char(39) + char(39) + ' and ' + filter_field + ' = ' + p_para01 + crlf +
      case when para02 <> '' then ' and book_desc like ' + char(39) + '%' + para02 + '%' + char(39) else '' end + crlf +
      ') x' + crlf +
      'left join ' + tablename + ' b on x.p_classid = b.' + row_id + ' and ' + filter_field + ' = ' + p_para01;
  else
    set sql_cmd = 
      'insert into sys_aside_temp (aside_guid, xr_id, x_id, xr_name, x_name, groupid, rowid) ' +
      'select ' + char(39) + p_type + char(39) + ',' + 
      '  x.' + group_id + ', x.' + row_id + ', b.' + group_name + ', x.' + group_name + ', groupid, rowid' + crlf +
      'from' + crlf +
      '(' + crlf +
      '  select ' + group_id + ',' + row_id + ',' + group_name + ',' +
      case when group_name <> row_name then row_name + ',' else '' end + 
      group_id + ' as p_classid,' + crlf +
      '    ROW_NUMBER() OVER(Partition by ' + group_partitionby + ' ORDER BY ' + group_orderby + ') AS groupid,' + crlf +
      '    ROW_NUMBER() OVER(ORDER BY ' + row_orderby + ') AS rowid' + crlf +
      '  from ' + tablename + crlf +
      '  where coalesce(' + group_id + ', char(39) + char(39)) <> ' + char(39) + char(39) + ' and ' + filter_field + ' = ' + p_para01 + crlf +
      case when para02 <> '' then ' and book_desc like ' + char(39) + '%' + para02 + '%' + char(39) else '' end + crlf +
      ') x' + crlf +
      'left join ' + tablename + ' b on x.p_classid = b.' + row_id + ' and ' + filter_field + ' = ' + p_para01;
  end if;
end if;

print sql_cmd;
execute immediate sql_cmd;

-- 配合原程式, 將資料寫入 data
insert into data select xr_id, x_id, xr_name, x_name, groupid, rowid from sys_aside_temp where aside_guid = p_type;
delete from sys_aside_temp where aside_guid = p_type;

/* 開始 main loop */
select count(*) into max_val from data;
select min(rowid) into curr_id from data;

set datas = '';
set comm = '';
while (curr_id <= max_val) do
  -- get data
  select groupid, xr_name, x_id, x_name into group_id, deptname, personid, empname from data where rowid = curr_id;
  if curr_id = max_val then
    set comm = '';
  else
    select groupid into next_group_id from data where rowid = curr_id + 1;
    if next_group_id = 1 then
      set comm = '';
    else
      set comm = ',';
    end if;
  end if;
  
  if group_id = 1 then
    if curr_id > 1 then
     

	 
/* 開始 main loop */
select @max=count(*) from @data;
select @currid=min(rowid) from @data;

set @datas = '';
set @comm = '';
while (@currid <= @max)
begin
  -- get data
  select @groupid=groupid,@deptname=xr_name,@personid=x_id,@empname=x_name from @data where rowid = @currid;
  if @currid = @max 
    set @comm = ''
  else begin
    select @next_groupid=groupid from @data where rowid = @currid + 1;
	if @next_groupid = 1 set @comm = '' else set @comm = ',';
  end;
  
  if @groupid = 1 begin
    if @currid > 1 
	    set @footer = '			]' + @crlf +
		'          },' + @crlf
    else 
		set @footer = '';
	  
	set @datas = @datas + @footer + 
		'        {' + @crlf +
		'            "label": "'+@deptname+'",' + @crlf +
		'            "children": [' + @crlf + 
		'			   {' + @crlf +
		'                "label": "'+@empname+'",' + @crlf +
		'                "value": "'+@personid+'"' + @crlf +
		'              }' + @comm + @crlf;  
  end
  else 
    set @datas = @datas +
		'			   {' + @crlf +
		'                "label": "'+@empname+'",' + @crlf +
		'                "value": "'+@personid+'"' + @crlf +
		'              }' + @comm + @crlf;  
  
  set @currid = @currid + 1;
end;

set @datas = '	[' + @crlf + @datas +
		'			]' + @crlf +
		'		}' + @crlf +
		'	]';

select 0 as code,'ok' as msg;
select @datas as jsoncode;

