<?xml version="1.0" encoding="ISO-8859-1"?>
<ROOT>
    <NODE name="RAZ">
        <NODE label="Nettoyage des tables">
            <sqlcmd><![CDATA[

            TRUNCATE rh.p_planning_mouvement
            ;

            ]]></sqlcmd>
        </NODE>
    </NODE>
    <NODE name="DISABLE_INDEX" label="DESACTIVATION INDEX">
        <NODE label="Mouvements du planning">
            <sqlcmd><![CDATA[

            SELECT base.cti_stash_table_constraints('rh.p_planning_mouvement')
            ;

            SELECT base.cti_stash_table_indexes('rh.p_planning_mouvement')
            ;

            ]]></sqlcmd>
        </NODE>
    </NODE>
    <NODE name="ENABLE_INDEX" label="REACTIVATION INDEX">
        <NODE label="Mouvements du planning">
            <sqlcmd><![CDATA[

            SELECT base.cti_stash_pop_table_constraints('rh.p_planning_mouvement')
            ;

            SELECT base.cti_stash_pop_table_indexes('rh.p_planning_mouvement')
            ;

            ]]></sqlcmd>
        </NODE>
    </NODE>
    <NODE name="INIT">
        <NODE label="Paramètres">
            <sqlcmd><![CDATA[

            INSERT INTO rh.t_planning_type_absence(oid, code_original, code, texte, texte_court)
                SELECT 0, '', chr(1)||'*', 'Non renseigné', 'Non renseigné'
                WHERE 0 NOT IN (SELECT oid FROM rh.t_planning_type_absence)
            ;

            INSERT INTO rh.t_planning_qualification(oid, code_original, code, texte, texte_court)
                SELECT 0, '', chr(1)||'*', 'Non renseignée', 'Non renseignée'
                WHERE 0 NOT IN (SELECT oid FROM rh.t_planning_qualification)
            ;

            INSERT INTO rh.t_planning_service(oid, code_original, code, texte, texte_court)
                SELECT 0, '', chr(1)||'*', 'Non renseigné', 'Non renseigné'
                WHERE 0 NOT IN (SELECT oid FROM rh.t_planning_service)
            ;

            INSERT INTO rh.t_planning_niveau(oid, code_original, code, texte, texte_court)
                SELECT 0, '', chr(1)||'*', 'Non renseigné', 'Non renseigné'
                WHERE 0 NOT IN (SELECT oid FROM rh.t_planning_niveau)
            ;

            INSERT INTO rh.t_planning_code_horaire(oid, code_original, code, texte, texte_court)
                SELECT 0, '', chr(1)||'*', 'Non renseigné', 'Non renseigné'
                WHERE 0 NOT IN (SELECT oid FROM rh.t_planning_code_horaire)
            ;

            ]]></sqlcmd>
        </NODE>
    </NODE>
    <NODE name="POST">
        <NODE label="Compléments Planning">
            <sqlcmd><![CDATA[
            
            -- Identification des évènements d'absences (plusieurs jours consécutifs de même motif d'absence) et comptage du nombre de jours total.
            with toto as (
                select
                    salarie_id,
                    date,
                    replace(replace(array_to_string(array_agg(type_absence_id) over w, '|'), '|0', ''), '0|', '') as type_absence_id
                from rh.p_planning_mouvement
                   window w as (partition by salarie_id, date)
                   order by 2 desc
            )
            , toto2 as (
                select
                    salarie_id,
                    date,
                    array_agg(distinct type_absence_id) as type_absence_id
                from toto
                group by 1,2
                order by 2 desc
            )
            , toto3 as (
                select
                    salarie_id,
                    date,
                    type_absence_id,
                    row_number() over (order by salarie_id, date, type_absence_id) as rang
                from toto2
            )
            , toto4 as (
                select
                    salarie_id,
                    date,
                    unnest(type_absence_id) as type_absence_id,
                    rang
                from toto3
                order by 2 desc
            )
            , clustering as (
            select
                t1.salarie_id,
                t1.date,
                t1.type_absence_id,
                t1.rang,
                case
                    when t1.type_absence_id = 0 then null
                    when t2.type_absence_id is null then true
                    else null
                end as new_cluster
            from toto4 as t1
                left join toto4 as t2 on true
                    and t1.salarie_id = t2.salarie_id
                    and t1.type_absence_id = t2.type_absence_id
                    -- and t1.rang = t2.rang + 1 -- permettait d'identifier des jours non consécutifs mais de même motifs (ex: week-end maladie).
                    and t1.date = t2.date + 1
                    order by  2 desc
            )
            , assigned_clustering as (
                select
                    salarie_id,
                    rang,
                    date,
                    type_absence_id,
                    new_cluster,
                    nullif(count(new_cluster) over (order by salarie_id, type_absence_id, date  rows unbounded preceding), 0) as cluster_id
                from clustering
                order by  3 desc
            )
            , abs as (
                select
                    salarie_id,
                    rang,
                    date,
                    type_absence_id,
                    cluster_id as abs_id,
                    count(cluster_id) over (partition by cluster_id) as nb_jours
                from assigned_clustering
                where type_absence_id != 0
            )
            update rh.p_planning_mouvement set
                absence_id = abs.abs_id,
                absence_nb_jours = abs.nb_jours
            from abs
            where 1=1
                and p_planning_mouvement.salarie_id = abs.salarie_id
                and p_planning_mouvement.date = abs.date
                and p_planning_mouvement.type_absence_id = abs.type_absence_id
            ;
            
            ]]></sqlcmd>
        </NODE>
        <NODE label="Post traitements planning">
            <sqlcmd><![CDATA[
            
            -- essayer de faire un rapprochement des qualifications et services selon le paramétrage
           UPDATE rh.t_planning_qualification SET
                qualification_id = t_qualifications.oid
            FROM rh.t_qualifications 
            	JOIN rh.t_divers ON t_divers.code = 'QUALIF_ASSOC'
            WHERE 1=1
            	AND valeur != 0
                AND t_planning_qualification.qualification_id = 0
                AND ((t_qualifications.code = t_planning_qualification.code AND valeur IN (1,3)) OR valeur = 2 )
				AND ((t_qualifications.texte = t_planning_qualification.texte AND valeur IN (2,3)) OR valeur = 1 )
			;
			
            UPDATE rh.t_planning_service SET
                service_id = t_services.oid
            FROM rh.t_services 
				JOIN rh.t_divers ON t_divers.code = 'SERVICE_ASSOC'
            WHERE 1=1
            	AND valeur != 0
                AND t_planning_service.service_id = 0
                AND ((t_services.code = t_planning_service.code AND valeur IN (1,3)) OR valeur = 2 )
				AND ((t_services.texte = right(t_planning_service.texte, length(t_services.texte)) AND valeur IN (2,3)) OR valeur = 1 )
            ;

            -- Report des Qualification Paie sur Qualification Planning.
            UPDATE rh.t_planning_qualification SET
                qualification_code = t_qualifications.code,
                qualification_texte = t_qualifications.texte_court,
                qualification_section_id = t_qualifications.section_id,
                qualification_section_code = t_qualifications.section_code,
                qualification_section_texte = t_qualifications.section_texte
            FROM rh.t_qualifications
            WHERE 1=1
                AND t_planning_qualification.qualification_id = t_qualifications.oid
                AND (1!=1
                    OR qualification_code IS DISTINCT FROM t_qualifications.code
                    OR qualification_texte IS DISTINCT FROM t_qualifications.texte_court
                    OR qualification_section_id IS DISTINCT FROM t_qualifications.section_id
                    OR qualification_section_code IS DISTINCT FROM t_qualifications.section_code
                    OR qualification_section_texte IS DISTINCT FROM t_qualifications.section_texte)
            ;

            -- Report des Services Paie sur Services Planning.
            UPDATE rh.t_planning_service SET
                service_code = t_services.code,
                service_texte = t_services.texte_court,
                service_section_id = t_services.section_id,
                service_section_code = t_services.section_code,
                service_section_texte = t_services.section_texte
            FROM rh.t_services
            WHERE 1=1
                AND t_planning_service.service_id = t_services.oid
                AND (1!=1
                    OR service_code IS DISTINCT FROM t_services.code
                    OR service_texte IS DISTINCT FROM t_services.texte_court
                    OR service_section_id IS DISTINCT FROM t_services.section_id
                    OR service_section_code IS DISTINCT FROM t_services.section_code
                    OR service_section_texte IS DISTINCT FROM t_services.section_texte)
            ;

            -- Création des 3 classes de niveaux.
            DROP TABLE IF EXISTS w_classes
            ;

            CREATE TEMP TABLE w_classes AS
                with classe_table as (
                    select 'PLANIV1' as code, '[DICT.RH.NIVEAU1#1]' as texte, 1 as sequence
                UNION ALL
                    select 'PLANIV2' as code, '[DICT.RH.NIVEAU2#1]' as texte, 2 as sequence
                UNION ALL
                    select 'PLANIV3' as code, '[DICT.RH.NIVEAU3#1]' as texte, 3 as sequence)
                SELECT code, texte, table_id, 0 as is_cti, sequence
                FROM classe_table, (select oid as table_id from rh.t_listes_tables where code = 'PNI' LIMIT 1) as subq
            ;

            insert into rh.t_classes (code, texte, table_id, is_cti, sequence)
                select code, texte, table_id, is_cti, sequence
                FROM w_classes
                where code NOT in (select code from rh.t_classes where code is not null)
            ;

            update rh.t_classes set
                texte = w_classes.texte
            FROM w_classes
            WHERE true
                and w_classes.code = t_classes.code
                and w_classes.texte is distinct from t_classes.texte
            ;

            -- Nettoyage du contenu
            delete from rh.t_classes_sections_elements
            where section_id in (
                select s.oid from rh.t_classes as c
                join rh.t_classes_sections as s on s.classe_id = c.oid
                where c.code IN ('PLANIV1', 'PLANIV2', 'PLANIV3'))
            ;

            -- Mise à jour des sections Niveau 1.
            DROP TABLE IF EXISTS w_clasec_1
            ;

            CREATE TEMP TABLE w_clasec_1 AS
                SELECT
                    -- On ne travaille pas sur le code_original pour 2 raisons :
                    --  * pose pb lors de la conso (stratégie où l'oid écrase le code_original)
                    --  * permet de prendre en compte les éventuelles modifications de l'utilisateur.
                    split_part(code, '|', 1) as code,
                    trim(split_part(texte, '-|-', 1)) as texte,
                    (select oid from rh.t_classes where code = 'PLANIV1') as classe_id
                FROM rh.t_planning_niveau
                WHERE oid > 0
                GROUP BY 1,2,3
            ;

            INSERT INTO rh.t_classes_sections(code, texte, classe_id)
                SELECT code, texte, classe_id
                from w_clasec_1
                where 1=1
                    and classe_id = (select oid from rh.t_classes where code = 'PLANIV1')
                    and code not in (select code from rh.t_classes_sections where t_classes_sections.classe_id = w_clasec_1.classe_id and code is not null)
                group by 1,2,3
            ;

            update rh.t_classes_sections set
                texte = w_clasec_1.texte
            FROM w_clasec_1
            WHERE true
                and w_clasec_1.classe_id = t_classes_sections.classe_id
                and w_clasec_1.code = t_classes_sections.code
                and w_clasec_1.texte is distinct from t_classes_sections.texte
            ;

            -- Mise à jour du contenu des sections Niveau 1.
            INSERT INTO rh.t_classes_sections_elements (section_id, to_id)
                SELECT
                    t_classes_sections.oid AS section_id,
                    t_planning_niveau.oid AS to_id
                FROM rh.t_classes
                    join rh.t_classes_sections on t_classes_sections.classe_id = t_classes.oid
                    join rh.t_planning_niveau on split_part(t_planning_niveau.code, '|', 1) = t_classes_sections.code
                WHERE t_classes.code = 'PLANIV1'
                group by 1,2
            ;

            -- Mise à jour des sections Niveau 2.
            DROP TABLE IF EXISTS w_clasec_2
            ;

            CREATE TEMP TABLE w_clasec_2 AS
                with nb_niv as (
                    select
                        split_part(code, '|', 2) as niv_cod2,
                        count(DISTINCT trim(split_part(texte, '-|-', 2))) as niv_count
                    from rh.t_planning_niveau
                    group by 1
                    )
                SELECT
                    case when niv_count = 1 then split_part(code, '|', 2) else split_part(code, '|', 1) || '|' || split_part(code, '|', 2) end as code,
                    split_part(code, '|', 1) || '|' || split_part(code, '|', 2) as code_original,
                    trim(split_part(texte, '-|-', 2)) as texte,
                    (select oid from rh.t_classes where code = 'PLANIV2') as classe_id
                from rh.t_planning_niveau as niveau2
                    JOIN nb_niv ON nb_niv.niv_cod2 = split_part(code, '|', 2)
                WHERE oid > 0
                group by 1,2,3
            ;

            INSERT INTO rh.t_classes_sections(code, texte, classe_id)
                SELECT code, texte, classe_id
                from w_clasec_2
                where 1=1
                    and classe_id = (select oid from rh.t_classes where code = 'PLANIV2')
                    and code not in (select code from rh.t_classes_sections where t_classes_sections.classe_id = w_clasec_2.classe_id and code is not null)
                group by 1,2,3
            ;

            update rh.t_classes_sections set
                texte = w_clasec_2.texte
            FROM w_clasec_2
            WHERE true
                and w_clasec_2.classe_id = t_classes_sections.classe_id
                and w_clasec_2.code = t_classes_sections.code
                and w_clasec_2.texte is distinct from t_classes_sections.texte
            ;

            -- Mise à jour du contenu des sections Niveau 2.
            INSERT INTO rh.t_classes_sections_elements (section_id, to_id)
                SELECT
                    t_classes_sections.oid AS section_id,
                    t_planning_niveau.oid AS to_id
                FROM rh.t_classes
                    join rh.t_classes_sections on t_classes_sections.classe_id = t_classes.oid
                    join w_clasec_2 on true
                        and w_clasec_2.classe_id = t_classes.oid
                        and w_clasec_2.code = t_classes_sections.code
                    join rh.t_planning_niveau on split_part(t_planning_niveau.code, '|', 1)||'|'||split_part(t_planning_niveau.code, '|', 2) = w_clasec_2.code_original
                WHERE t_classes.code = 'PLANIV2'
                group by 1,2
            ;

            -- Mise à jour des sections Niveau 3.
            DROP TABLE IF EXISTS w_clasec_3
            ;

            CREATE TEMP TABLE w_clasec_3 AS
                with nb_niv as (
                    select
                        split_part(code, '|', 3) as niv_cod3,
                        count(DISTINCT trim(split_part(texte, '-|-', 3))) as niv_count
                    from rh.t_planning_niveau
                    group by 1
                    )
                SELECT
                    case when niv_count = 1 then split_part(code, '|', 3) else split_part(code, '|', 1) || '|' || split_part(code, '|', 2) || '|' || split_part(code, '|', 3) end as code,
                    split_part(code, '|', 1) || '|' || split_part(code, '|', 2) || '|' || split_part(code, '|', 3) as code_original,
                    trim(split_part(texte, '-|-', 3)) as texte,
                    (select oid from rh.t_classes where code = 'PLANIV3') as classe_id
                from rh.t_planning_niveau as niveau3
                    JOIN nb_niv ON nb_niv.niv_cod3 = split_part(code, '|', 3)
                WHERE oid > 0
                group by 1,2,3
            ;

            INSERT INTO rh.t_classes_sections(code, texte, classe_id)
                SELECT code, texte, classe_id
                from w_clasec_3
                where 1=1
                    and classe_id = (select oid from rh.t_classes where code = 'PLANIV3')
                    and code not in (select code from rh.t_classes_sections where t_classes_sections.classe_id = w_clasec_3.classe_id and code is not null)
                group by 1,2,3
            ;

            update rh.t_classes_sections set
                texte = w_clasec_3.texte
            FROM w_clasec_3
            WHERE true
                and w_clasec_3.classe_id = t_classes_sections.classe_id
                and w_clasec_3.code = t_classes_sections.code
                and w_clasec_3.texte is distinct from t_classes_sections.texte
            ;

            -- Mise à jour du contenu des sections Niveau 3.
            INSERT INTO rh.t_classes_sections_elements (section_id, to_id)
                SELECT
                    t_classes_sections.oid AS section_id,
                    t_planning_niveau.oid AS to_id
                FROM rh.t_classes
                    join rh.t_classes_sections on t_classes_sections.classe_id = t_classes.oid
                    join w_clasec_3 on true
                        and w_clasec_3.classe_id = t_classes.oid
                        and w_clasec_3.code = t_classes_sections.code
                    join rh.t_planning_niveau on t_planning_niveau.code = w_clasec_3.code_original
                WHERE t_classes.code = 'PLANIV3'
                group by 1,2
            ;

            SELECT rh.cti_update_schema_classes('*ALL')
            ;

            -- Recensement des oid utilisés.
            INSERT INTO rh.p_oids (code_table, oid)
                SELECT 'planning_service', service_id
                FROM rh.p_planning_mouvement
                WHERE service_id NOT IN (SELECT oid FROM rh.p_oids WHERE code_table = 'planning_service')
                GROUP BY 1,2
            ;

            INSERT INTO rh.p_oids (code_table, oid)
                SELECT 'planning_qualification', qualification_id
                FROM rh.p_planning_mouvement
                WHERE qualification_id NOT IN (SELECT oid FROM rh.p_oids WHERE code_table = 'planning_qualification')
                GROUP BY 1,2
            ;

            INSERT INTO rh.p_oids (code_table, oid)
                SELECT 'planning_niveau', niveau_id
                FROM rh.p_planning_mouvement
                WHERE niveau_id NOT IN (SELECT oid FROM rh.p_oids WHERE code_table = 'planning_niveau')
                GROUP BY 1,2
            ;

            INSERT INTO rh.p_oids (code_table, oid)
                SELECT 'planning_type_absence', type_absence_id
                FROM rh.p_planning_mouvement
                WHERE type_absence_id NOT IN (SELECT oid FROM rh.p_oids WHERE code_table = 'planning_type_absence')
                GROUP BY 1,2
            ;

            INSERT INTO rh.p_oids (code_table, oid)
                SELECT 'planning_code_horaire', code_horaire_id
                FROM rh.p_planning_mouvement
                WHERE code_horaire_id NOT IN (SELECT oid FROM rh.p_oids WHERE code_table = 'planning_code_horaire')
                GROUP BY 1,2
            ;

            -- Pour remonter le type de contrat intérim.
            INSERT INTO rh.p_oids (code_table, oid)
				SELECT 'types_contrat', type_contrat_id
				FROM rh.p_profils
                WHERE type_contrat_id NOT IN (SELECT oid FROM rh.p_oids WHERE code_table = 'types_contrat')
				GROUP BY 1,2
			;

            -- Populations : pas encore de règle de population basée sur le Planning.
            -- SELECT rh.cti_reorganize_population()
            -- ;

            -- Poles
            SELECT rh.cti_reorganize_pole()
            ;
			
			-- Options Divers
			INSERT INTO rh.t_divers(
				code,
  				texte,
  				valeur,
  				valeur_date,
  				description)
			SELECT
				'PLANNING_BASE_ETP'::text,
				'Base pour calcul ETP Planning'::text,
				'0'::text,
				NULL,
				'0 : La base des ETP est 151,67h / mois, 1 : La base des ETP est nb jours ouvrés période * 7h13, 2 : La base des ETP est nb jours semaine période * 7'::text
			WHERE 'PLANNING_BASE_ETP' NOT IN (SELECT code FROM rh.t_divers)
			;

            ]]></sqlcmd>
        </NODE>
    </NODE>
    <NODE name="VACUUM">
        <NODE label="Réorganisation tables">
            <sqlcmd><![CDATA[
            
            SELECT base.cti_vacuum('rh.p_oids');
            SELECT base.cti_vacuum('rh.p_planning_mouvement');
            SELECT base.cti_vacuum('rh.t_planning_niveau');
            SELECT base.cti_vacuum('rh.t_planning_qualification');
            SELECT base.cti_vacuum('rh.t_planning_service');
            SELECT base.cti_vacuum('rh.t_planning_type_absence');
            SELECT base.cti_vacuum('rh.p_ventilation');
            SELECT base.cti_vacuum('rh.p_ventilation_section');
                
            ]]></sqlcmd>
        </NODE>
    </NODE>
</ROOT>
