DROP FUNCTION if exists sp_DivisionLoad;
drop procedure if exists sp_DivisionLoad;

CREATE procedure sp_DivisionLoad
(
    x xml default null::xml
,	inout "Res" boolean default null::boolean
,	inout "Err" xml default null::xml
)
LANGUAGE plpgsql
AS $procedure$
declare 
    _MO varchar(6);
    _TYPE varchar(6);
    _rc int;
begin
    Drop Table If Exists TmpZGLV;
    Create Temp Table TmpZGLV
    As
    select
        (xpath('//MO[1]/text()', z))[1]::varchar(6)     as MO
    ,    (xpath('//TYPE[1]/text()', z))[1]::varchar(6)    as TYPE
    from
    (
        select unnest(xpath('/DIVISION//header', x)) as z
    ) t1;
    
    select 
        into _MO, _TYPE
        t.MO, t.TYPE
    from TmpZGLV t
    limit 1;
    
    Drop Table If Exists TmpZAP;
    Create Temp Table TmpZAP
    As
    select
        (xpath('//BR_CODE[1]/text()', z))[1]::varchar(16)       as BR_CODE
    ,    (xpath('//CODE[1]/text()', z))[1]::varchar(16)           as CODE
    ,    (xpath('//NAME[1]/text()', z))[1]::varchar(128)            as NAME
    ,    (xpath('//FULLNAME[1]/text()', z))[1]::varchar(255)        as FULLNAME
    ,    (xpath('//ADDRESS[1]/text()', z))[1]::varchar(255)        as ADDRESS
    ,    (xpath('//DIVISION_TYPE[1]/text()', z))[1]::text::int    as DIVISION_TYPE
    ,    (xpath('//ACTIVE[1]/text()', z))[1]::text::int            as ACTIVE
    ,    null::uuid                                                as DivisionID
    ,    null::uuid                                                as BranchID
    from
    (
        select unnest(xpath('/DIVISION//body', x)) as z
    ) t1;
    
    Drop Table If Exists TmpErrors;
    Create Temp Table TmpErrors
    as
    select 1::int as CODE, 'МО не найдена'::varchar(250) as COMMENT
    from TmpZGLV zglv
    where not exists(select* from iszl.t_f003 lm where lm.mcod = zglv.MO);
    
    -- поиск отделения и филиала
    update TmpZAP zap
    set DivisionID = 
    (
        select div.DivisionID 
        from iszl.T_DIVISION div 
        left join
            iszl.T_BRANCH br
            on div.Branch = br.BranchID 
        where div.CODE = zap.CODE
        and (div.LpuMain = _MO OR br.F003Mo = _MO)
        limit 1
    )
    ,    BranchID = 
    (
        select br.BranchID 
        from iszl.T_BRANCH br 
        where br.BR_CODE = zap.BR_CODE
        and br.F003Mo = _MO
        limit 1
    );
    
    if _type not in ('Insert', 'Delete', 'Update')
    then
        insert into TmpErrors(CODE, COMMENT)
        select 4, 'Неверный тип операции.';
    end if;
    
    if    _type = 'Insert'
    then
        -- нельзя удалять, тк могут быть профили коек в отделении
        -- удаляем, если есть
        --delete t from [ISZL].[T_DIVISION] t
        --join #ZAP zap on t.DivisionID = zap.DivisionID
        insert into TmpErrors(CODE, COMMENT)
        select 2, 'Отделение было добавлено ранее' 
        from TmpZAP z
        where z.DivisionID is not null;

        -- вставка, если нет ошибок
        INSERT INTO ISZL.T_DIVISION(DivisionID, NAME, CODE, FULLNAME, ADDRESS, ACTIVE, Branch
        , V006MedicalTerms, BR_CODE, LpuMain)
        select gen_random_uuid(), zap.NAME, zap.CODE, zap.FULLNAME, zap.ADDRESS, zap.ACTIVE::boolean, zap.BranchID
        , zap.DIVISION_TYPE
        , zap.BR_CODE, _MO
        from TmpZAP zap
        where not exists(select* from TmpErrors);
    end if;

    if _type = 'Update'
    then
        UPDATE ISZL.T_DIVISION t
           SET NAME = zap.NAME
        ,    CODE = zap.CODE
        ,    FULLNAME = zap.FULLNAME
        ,    ADDRESS = zap.ADDRESS
        ,    ACTIVE = zap.ACTIVE::boolean
        ,    Branch = zap.BranchID
        ,    V006MedicalTerms = zap.DIVISION_TYPE
        ,    BR_CODE = zap.BR_CODE
        ,    LpuMain = _MO
        from TmpZAP zap
        where t.DivisionID = zap.DivisionID
        and not exists(select* from TmpErrors);
        
        GET DIAGNOSTICS _rc = ROW_COUNT;
        
        -- вставка, если не найдена
        if _rc = 0
        then
            INSERT INTO ISZL.T_DIVISION(DivisionID, NAME, CODE, FULLNAME, ADDRESS, ACTIVE, Branch
            , V006MedicalTerms, BR_CODE, LpuMain)
            select gen_random_uuid(), zap.NAME, zap.CODE, zap.FULLNAME, zap.ADDRESS, zap.ACTIVE::boolean, zap.BranchID
            , zap.DIVISION_TYPE
            , zap.BR_CODE, _MO
            from Tmp zap
            where not exists(select* from TmpErrors);
        end if;
    end if;

    if _type = 'Delete'
    then
        insert into TmpErrors(CODE, COMMENT)
        select 3, 'Запись не найдена в ранее загруженных списках'
        from TmpZAP zap
        where zap.DivisionID is null;

        delete from ISZL.T_DIVISION t
        where exists(select* from TmpZAP zap where t.DivisionID = zap.DivisionID)
        and not exists(select* from TmpErrors);
    end if;

   	create temp table temp_table(Res boolean,Err text);
   	insert into temp_table(Res,Err)
	    select case when exists(select* from TmpErrors) then '0'::boolean else '1'::boolean end
	    , case when exists(select* from TmpErrors) then '<?xml version="1.0" encoding="Windows-1251"?>
	    ' || 
	    (
	        xmlelement
	        (
	            name "ROOT"
	        ,    (
	                select
	                xmlagg
	                (
	                    xmlelement
	                    (
	                        name "ERR"
	                    ,    xmlforest
	                        (
	                            te.CODE AS "CODE"
	                        ,    te.COMMENT AS "COMMENT"
	                        )
	                    )
	                )
	                FROM TmpErrors te
	            )
	        )
	    )::text end;

   	select Res from temp_table into "Res";
	select Err from temp_table into "Err";

	drop table if exists temp_table;
    DROP TABLE if exists TmpZGLV;
    DROP TABLE if exists TmpZAP;
    DROP TABLE if exists TmpErrors;
end;
$procedure$;
