<?xml version="1.0" encoding="ISO-8859-15"?>
<ROOT>
	<NODE name="INIT" label="INITIALISATIONS">
        <NODE label="Pré-traitements">
			<sqlcmd><![CDATA[

            DROP TABLE IF EXISTS w_ets
            ;

            CREATE TEMP TABLE w_ets AS
                SELECT 
                    code_societe_juridique AS entreprise_code,
                    libelle_societe_juridique AS entreprise_texte,
                    code_etablissement AS etablissement_code,
                    libelle_etablissement AS etablissement_texte,
                    siret
                FROM prod_cegidhru_melioris.etablissement
                WHERE
                    code_etablissement  IN (SELECT rhp_in('siren')) -- et/ou soit un ou plusieurs codes établissment.
                    OR siret			IN (SELECT rhp_in('siren')) -- et/ou soit un ou plusieurs codes établissment.
                    OR left(siret, 9)	IN (SELECT rhp_in('siren')) -- et/ou soit un ou plusieurs codes établissment.
            ;

            -- Màj des Entreprises.
			INSERT INTO rh.t_entreprises(code_original, code, texte, texte_court, siren)
                SELECT
                    entreprise_code,
                    entreprise_code,
                    entreprise_texte, 
					substr(entreprise_texte, 1, 50),
					substr(siret, 1, 9)
                FROM w_ets
                WHERE entreprise_code NOT IN (SELECT code_original FROM rh.t_entreprises WHERE code_original IS NOT NULL)
                GROUP BY 1,2,3,4,5
			;

			-- Màj des Etablissements.
			INSERT INTO rh.t_etablissements(code_original, code, texte, texte_court, entreprise_id, siret)
                SELECT
                    etablissement_code,
                    etablissement_code,
                    etablissement_texte, 
                    substr(etablissement_texte, 1, 50),
                    t_entreprises.oid,
                    siret
                FROM w_ets
                JOIN rh.t_entreprises ON t_entreprises.code_original = w_ets.entreprise_code
                WHERE etablissement_code NOT IN (SELECT code_original FROM rh.t_etablissements WHERE code_original IS NOT NULL)
                GROUP BY 1,2,3,4,5,6
			;

            -- On ne traite que les salariés ayant des bulletins de salaire
            DROP TABLE IF EXISTS w_sal_ets
            ;

            CREATE TEMP TABLE w_sal_ets AS
                SELECT
                    matricule
                FROM prod_cegidhru_melioris.bulletin
                WHERE COALESCE(date_fin_mois_paie, '2099-12-31')::date >= rhp('rhprovider_start')::date
                GROUP BY 1
            ;

			]]></sqlcmd>
		</NODE>
		<NODE name="INIT" type="common" />
	</NODE>
	<NODE name="PROD" label="RECUPERATION DES DONNEES DE PRODUCTION">
		<NODE label="Récupération des bulletins">
			<sqlcmd><![CDATA[

            DROP SEQUENCE IF EXISTS s_bulletins
            ;

            CREATE SEQUENCE s_bulletins
            ;

            ALTER SEQUENCE s_bulletins RESTART WITH 1
            ;            

            -- Récupération des bulletins. Ne semble servir uniquement pour trouver l'affectation de l'établissement
            DROP TABLE IF EXISTS w_bulletins
            ;

            CREATE TEMP TABLE w_bulletins AS (
                with gestion_multi_bulletins AS (
                -- Gestion des cas de plusieurs bulletins sur le même mois
                SELECT 
                    bulletin.matricule,
                    to_char(bulletin.date_debut_mois_paie::date,'YYYYMM')::int AS mois,
		            (MAX(ARRAY[total_brut, right(code_etablissement, 4)::numeric]))[2] AS code_etablissement,
                    MIN(bulletin.date_debut_mois_paie::date) AS date_debut,
                    MAX(COALESCE(bulletin.date_fin_mois_paie::date, base.cti_last_day(bulletin.date_debut_mois_paie::date))) AS date_fin,
                    SUM(bulletin.total_brut::numeric) AS total_brut,
                    SUM(bulletin.total_heures_payees::numeric) AS total_heures_payees,
                    SUM(bulletin.total_heures_travaillees::numeric) AS total_heures_travaillees
                FROM prod_cegidhru_melioris.bulletin
                WHERE COALESCE(date_fin_mois_paie, '2099-12-31')::date >= rhp('rhprovider_start')::date
                GROUP BY 1,2
                )
                SELECT
                    nextval('s_bulletins'::regclass) AS bulletin_id,
                    t_etablissements.entreprise_id,
                    t_etablissements.oid AS etablissement_id,
                    'BULLETIN' || '-' || matricule || '-' || mois  AS numero_bulletin,
                    date_debut,
                    date_fin,
                    mois,
                    matricule,
                    total_brut,
                    total_heures_payees,
                    total_heures_travaillees,
                    0::int AS affectation_contrat_mois_id,
                    0::int AS est_hors_periode_contrat
                FROM gestion_multi_bulletins
	            JOIN rh.t_etablissements ON t_etablissements.code_original::numeric = right(gestion_multi_bulletins.code_etablissement, 4)
                WHERE t_etablissements.oid != 0
            )
            ;

			]]></sqlcmd>
		</NODE>
        <NODE label="Récupération des contrats">
			<sqlcmd><![CDATA[

                DROP SEQUENCE IF EXISTS s_contrats
                ;

                CREATE SEQUENCE s_contrats;

                ALTER SEQUENCE s_contrats RESTART WITH 1
                ;

                -- Récupération des contrats
                DROP TABLE IF EXISTS w_contrats
                ;

                CREATE TEMP TABLE w_contrats AS (
                    with dernier_bulletin_salaries AS (
                        SELECT 
                            matricule,
                            MAX(date_fin) AS date_fin_dernier_bulletin
                        FROM w_bulletins
                        GROUP BY 1
                    ),
                    contrats AS (	
                        SELECT
                            DISTINCT ON (matricule, date_debut_contrat)
                            COALESCE(date_fin_situation, '2099-12-31')::date AS date_fin_situation,
                            matricule,
                            date_debut_contrat,
                            COALESCE(date_fin_contrat, '2099-12-31')::date AS date_fin_contrat,
                            code_type_contrat,
                            libelle_type_contrat,
                            nombres_heures_contractuelles,
                            code_motif_debut_contrat,
                            libelle_motif_debut_contrat,
                            code_motif_fin_contrat,
                            libelle_motif_fin_contrat
                        FROM prod_cegidhru_melioris.contrat
                        ORDER BY matricule, date_debut_contrat, date_fin_situation DESC
                    )
                    SELECT 
                        nextval('s_contrats'::regclass) AS contrat_id,
                        contrats.matricule,
                        0::int AS salarie_id,
                        contrats.date_debut_contrat::date AS date_debut_contrat,
                        COALESCE(contrats.date_fin_contrat, '2099-12-31')::date AS date_fin_contrat,
                        'CONTRAT' || '-' || contrats.matricule || '-' || to_char(row_number() OVER (PARTITION BY contrats.matricule ORDER BY contrats.date_debut_contrat), 'FM99900') AS numero_contrat,
                        'CONTRAT' || '-' || contrats.matricule || '-' || to_char(row_number() OVER (PARTITION BY contrats.matricule ORDER BY contrats.date_debut_contrat), 'FM99900') AS code_original,
                        contrats.code_type_contrat,
                        contrats.libelle_type_contrat,
                        contrats.code_motif_debut_contrat,
                        contrats.libelle_motif_debut_contrat,
                        contrats.code_motif_fin_contrat,
                        contrats.libelle_motif_fin_contrat,
                        0::int AS etablissement_id,
                        0::int AS entreprise_id,
                        0::int AS profil_id,
                        contrats.nombres_heures_contractuelles::numeric AS heures_theoriques,
                        coalesce(case when contrats.nombres_heures_contractuelles::numeric >= 151.67 then 'TC' else 'TP' end||round(contrats.nombres_heures_contractuelles::numeric, 2)::text, chr(1)||'*') AS type_temps_travail,
                        coalesce(nullif(contrats.nombres_heures_contractuelles::numeric / 151.67, 0), 1.0) AS etp_theorique,
                        0::int AS est_hors_periode,
                        dernier_bulletin_salaries.date_fin_dernier_bulletin
                    FROM contrats
                    JOIN w_sal_ets ON w_sal_ets.matricule = contrats.matricule -- Limiter la remontée des contrats aux seuls salariés ayant un bulletin
                    JOIN dernier_bulletin_salaries ON dernier_bulletin_salaries.matricule = contrats.matricule
                    ORDER BY contrats.date_debut_contrat::date
                )
                ;

        ]]></sqlcmd>
		</NODE>
        <NODE label="Attribution de l'établissement aux contrats">
			<sqlcmd><![CDATA[

            -- Mise à jour de l'établissement dans les contrats
            -- Si plusieurs contrats sur le même mois.
            UPDATE w_contrats
            SET 
                etablissement_id = w_bulletins.etablissement_id,
                entreprise_id = w_bulletins.entreprise_id
            FROM w_bulletins
            WHERE 
                w_bulletins.matricule = w_contrats.matricule
                AND w_bulletins.date_debut >= w_contrats.date_debut_contrat
                AND w_bulletins.date_fin <= w_contrats.date_fin_contrat
            ;

            -- Si etablissement_id restant à 0, on renseigne le dernier id connu dans les contrats
            UPDATE w_contrats
            SET 
                etablissement_id = subview.etablissement_id,
                entreprise_id = subview.entreprise_id
            FROM 
				(
					SELECT 
						matricule,
						(MAX(array[w_contrats.date_fin_contrat::text, w_contrats.etablissement_id::text]))[2]::int AS etablissement_id,
						(MAX(array[w_contrats.date_fin_contrat::text, w_contrats.entreprise_id::text]))[2]::int AS entreprise_id
					FROM w_contrats
					WHERE etablissement_id <> 0
					GROUP BY 1
				) AS subview
            WHERE
                w_contrats.etablissement_id = 0
                AND w_contrats.matricule = subview.matricule
            ;

			-- Si etablissement_id restant à 0, on renseigne l'établissement le plus récent
            UPDATE w_contrats
            SET 
                etablissement_id = subview.etablissement_id,
                entreprise_id = subview.entreprise_id
            FROM 
				(
					SELECT 
						matricule,
						(MAX(array[w_bulletins.date_fin::text, w_bulletins.etablissement_id::text]))[2]::int AS etablissement_id,
						(MAX(array[w_bulletins.date_fin::text, w_bulletins.entreprise_id::text]))[2]::int AS entreprise_id
					FROM w_bulletins
					GROUP BY 1
				) AS subview
            WHERE
                w_contrats.etablissement_id = 0
                AND w_contrats.matricule = subview.matricule
            ;

            ANALYZE w_contrats
            ;

            -- Mise à jours des bulletins hors période de contrat
            UPDATE w_bulletins
            SET est_hors_periode_contrat = 1
            FROM 
                (
                    SELECT 
                        w_bulletins.matricule,
                        w_bulletins.bulletin_id
                    FROM w_bulletins
                    LEFT JOIN w_contrats ON 
                        w_contrats.matricule = w_bulletins.matricule 
                        AND base.cti_overlaps(w_contrats.date_debut_contrat, w_contrats.date_fin_contrat, w_bulletins.date_debut, w_bulletins.date_fin)
                    WHERE w_contrats.contrat_id IS NULL
                ) AS subview
            WHERE 
                w_bulletins.matricule = subview.matricule
                AND w_bulletins.bulletin_id = subview.bulletin_id
            ;

            ANALYZE w_bulletins
            ;

            ]]></sqlcmd>
		</NODE>
        <NODE label="Création des contrats mois">
			<sqlcmd><![CDATA[

            DROP SEQUENCE IF EXISTS s_contrats_mois
            ;

            CREATE SEQUENCE s_contrats_mois;

            ALTER SEQUENCE s_contrats_mois RESTART WITH 1
            ;

            -- Ventilation (découpage) des contrats par mois
            DROP TABLE IF EXISTS w_contrats_mois
            ;

            CREATE TEMP TABLE w_contrats_mois AS (
                with date_debut_mois AS (
                    SELECT
                        *,
                        generate_series(
                            date_trunc('month', date_debut_contrat),
                            CASE 
                                WHEN date_fin_contrat = '2099-12-31' AND w_contrats.date_fin_dernier_bulletin IS NOT NULL THEN w_contrats.date_fin_dernier_bulletin
                                WHEN date_fin_contrat = '2099-12-31' AND w_contrats.date_fin_dernier_bulletin IS NULL THEN NOW() 
                                ELSE date_fin_contrat END, 
                            '1 month'
                        )::date AS date_debut_mois
                    FROM w_contrats
                    WINDOW w AS (PARTITION BY matricule ORDER BY date_debut_contrat DESC)
                )
                SELECT
                    nextval('s_contrats_mois'::regclass) AS contrat_mois_id,
                    row_number() over (PARTITION BY matricule, date_debut_mois) AS nombre_contrats_mois,
                    *,
                    CASE 
                        WHEN to_char(date_debut_mois,'YYYYMM')::numeric = to_char(date_debut_contrat,'YYYYMM')::numeric
                        THEN date_debut_contrat
                        ELSE date_debut_mois
                    END AS date_debut_contrat_mois,
                    CASE
                        WHEN to_char(base.cti_last_day(date_debut_mois),'YYYYMM')::numeric = to_char(date_fin_contrat,'YYYYMM')::numeric
                        THEN date_fin_contrat
                        ELSE base.cti_last_day(date_debut_mois)
                    END AS date_fin_contrat_mois,
                    CASE 
                        WHEN to_char(date_debut_mois,'YYYYMM')::numeric = to_char(date_debut_contrat,'YYYYMM')::numeric
                        THEN to_char(date_debut_contrat,'YYYYMM')::numeric 
                        ELSE to_char(date_debut_mois,'YYYYMM')::numeric  
                    END AS mois_activite,
                    COALESCE(code_motif_debut_contrat, chr(1)||'*') AS motif_debut_code,
                    COALESCE(libelle_motif_debut_contrat, chr(1)||'*') AS motif_debut_texte,
                    COALESCE(code_motif_fin_contrat, chr(1)||'*') AS motif_fin_code,
                    COALESCE(libelle_motif_fin_contrat, chr(1)||'*') AS motif_fin_texte,
                    chr(1)||'*' AS categorie_socio_professionnelle_code,
                    chr(1)||'*' AS categorie_socio_professionnelle_texte,
                    chr(1)||'*' AS qualification_code,
                    chr(1)||'*' AS qualification_texte,
                    chr(1)||'*' AS service_code,
                    chr(1)||'*' AS service_texte,
                    chr(1)||'*' AS code_emploi_code,
                    chr(1)||'*' AS code_emploi_texte,
                    chr(1)||'*' AS grille_code,
                    chr(1)||'*' AS grille_texte,
                    chr(1)||'*' AS grille_groupe_code,
                    chr(1)||'*' AS grille_groupe_texte,
                    chr(1)||'*' AS statut_code,
                    chr(1)||'*' AS statut_texte,
                    COALESCE(code_type_contrat, chr(1)||'*') AS type_contrat_code,
                    COALESCE(libelle_type_contrat, chr(1)||'*') AS type_contrat_texte,
                    COALESCE(type_temps_travail, chr(1)||'*') AS type_temps_travail_code,
                    COALESCE(type_temps_travail, chr(1)||'*') AS type_temps_travail_texte,
                    chr(1)||'*' AS specialite_code,
                    chr(1)||'*' AS groupe_cotisant_code,
                    chr(1)||'*' AS section_analytique_code,
                    chr(1)||'*' AS section_analytique_paie_code,
                    chr(1)||'*' AS societe_interim_code,
                    chr(1)||'*' AS type_horaire_code,
                    chr(1)||'*' AS cadre_emploi_code,         -- public
                    chr(1)||'*' AS categorie_conge_code,      -- public
                    chr(1)||'*' AS categorie_statutaire_code, -- public
                    chr(1)||'*' AS commission_paritaire_code, -- public
                    chr(1)||'*' AS compte_salarie_code,       -- public
                    chr(1)||'*' AS filiere_code,              -- public
                    chr(1)||'*' AS lettre_budgetaire_code,    -- public
                    chr(1)||'*' AS unite_fonctionnelle_code   -- public
                FROM date_debut_mois
                WHERE date_debut_mois >= (rhp('rhprovider_start')::date - interval '2 YEAR')
            )
            ;

            ]]></sqlcmd>
		</NODE>
        <NODE label="Récupération des informations administratives des salariés">
			<sqlcmd><![CDATA[

            -- Récupération des informations positp des salariés
            DROP TABLE IF EXISTS w_infos_positp
            ;

            CREATE TEMP TABLE w_infos_positp AS (
                SELECT 
                    row_number() OVER() AS id,
                    w_contrats_mois.contrat_mois_id,
                    positp.date_debut::date AS date_debut,
                    positp.date_fin::date AS date_fin,
                    positp.code_emploi AS qualification_code,
                    positp.libelle_emploi AS qualification_texte,
                    positp.code_statut AS statut_code,
                    positp.libelle_statut AS statut_texte
                FROM w_contrats_mois
                JOIN prod_cegidhru_melioris.positp ON positp.matricule = w_contrats_mois.matricule 
                    AND w_contrats_mois.date_debut_contrat_mois <= COALESCE(positp.date_fin, '2099-12-31')::date
                    AND w_contrats_mois.date_fin_contrat_mois >= positp.date_debut::date
            )
            ;

            -- Récupération pour chaque contrat_mois des informations les plus récentes du salarié
            DROP TABLE IF EXISTS dernieres_infos_contrat_mois
            ;

            CREATE TEMP TABLE dernieres_infos_contrat_mois AS 
                with dernieres_infos_par_contrat_mois AS (
                    SELECT
                        w_contrats_mois.contrat_mois_id,
                        (MAX(ARRAY[EXTRACT(EPOCH FROM w_infos_positp.date_debut), w_infos_positp.id]))[2] AS dernier_infos_positp_id
                    FROM w_contrats_mois
                    LEFT JOIN w_infos_positp ON w_infos_positp.contrat_mois_id = w_contrats_mois.contrat_mois_id
                    GROUP BY 1
                )
                SELECT 
                    w_contrats_mois.contrat_mois_id,
                    w_infos_positp.qualification_code,
                    w_infos_positp.qualification_texte,
                    w_infos_positp.statut_code,
                    w_infos_positp.statut_texte
                FROM w_contrats_mois
                LEFT JOIN dernieres_infos_par_contrat_mois ON dernieres_infos_par_contrat_mois.contrat_mois_id = w_contrats_mois.contrat_mois_id
                LEFT JOIN w_infos_positp ON w_infos_positp.contrat_mois_id = w_contrats_mois.contrat_mois_id 
                    AND w_infos_positp.id = dernieres_infos_par_contrat_mois.dernier_infos_positp_id
            ;

            -- Mise à jour des éléments de positp et sadmin sur les contrats_mois
            UPDATE w_contrats_mois
            SET 
                qualification_code = COALESCE(dernieres_infos_contrat_mois.qualification_code, chr(1)||'*'),
                qualification_texte = COALESCE(dernieres_infos_contrat_mois.qualification_texte, chr(1)||'*'),
                statut_code = COALESCE(dernieres_infos_contrat_mois.statut_code, chr(1)||'*'),
                statut_texte = COALESCE(dernieres_infos_contrat_mois.statut_texte, chr(1)||'*')
            FROM dernieres_infos_contrat_mois
            WHERE dernieres_infos_contrat_mois.contrat_mois_id = w_contrats_mois.contrat_mois_id
            ;

            ANALYZE w_contrats_mois
            ;

            ]]></sqlcmd>
		</NODE>
        <NODE label="Profils">
			<sqlcmd><![CDATA[

            -- Création des profils
            DROP TABLE IF EXISTS w_profils
            ;

            CREATE TEMP TABLE w_profils AS (
                SELECT 
                    0::int AS profil_id, -- Mis à jour dans le SHARE
                    motif_debut_code AS motif_debut_code_original,
                    motif_fin_code AS motif_fin_code_original,
                    categorie_socio_professionnelle_code AS categorie_socio_professionnelle_code_original,
                    qualification_code AS qualification_code_original,
                    service_code AS service_code_original,
                    code_emploi_code AS code_emploi_code_original,
                    grille_code AS grille_code_original,
                    grille_groupe_code AS grille_groupe_code_original,
                    specialite_code AS specialite_code_original,
                    groupe_cotisant_code AS groupe_cotisant_code_original,
                    section_analytique_code AS section_analytique_code_original,
                    section_analytique_paie_code AS section_analytique_paie_code_original,
                    societe_interim_code AS societe_interim_code_original,
                    type_horaire_code AS type_horaire_code_original,
                    statut_code AS statut_code_original,
                    type_contrat_code AS type_contrat_code_original,
                    type_temps_travail_code AS type_temps_travail_code_original,
                    cadre_emploi_code AS cadre_emploi_code_original,
                    categorie_conge_code AS categorie_conge_code_original,
                    categorie_conge_code AS categorie_statutaire_code_original,
                    commission_paritaire_code AS commission_paritaire_code_original,
                    compte_salarie_code AS compte_salarie_code_original,
                    filiere_code AS filiere_code_original,
                    lettre_budgetaire_code AS lettre_budgetaire_code_original,
                    unite_fonctionnelle_code AS unite_fonctionnelle_code_original
                FROM w_contrats_mois
                GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
            )	
            ;

            ]]></sqlcmd>
		</NODE>
        <NODE name="PROFIL" type="common" />
        <NODE label="Attribution profil_id aux contrats_mois">
			<sqlcmd><![CDATA[

            -- Mise à jour du profil_id dans w_contrats_mois
            UPDATE w_contrats_mois
            SET profil_id = p_profils.oid
            FROM rh.p_profils
            WHERE 1=1
                AND p_profils.cadre_emploi_code_original                    = w_contrats_mois.cadre_emploi_code
                AND p_profils.categorie_conge_code_original                 = w_contrats_mois.categorie_conge_code
                AND p_profils.categorie_socio_professionnelle_code_original = w_contrats_mois.categorie_socio_professionnelle_code
                AND p_profils.categorie_statutaire_code_original            = w_contrats_mois.categorie_statutaire_code
                AND p_profils.code_emploi_code_original                     = w_contrats_mois.code_emploi_code
                AND p_profils.commission_paritaire_code_original            = w_contrats_mois.commission_paritaire_code
                AND p_profils.compte_salarie_code_original                  = w_contrats_mois.compte_salarie_code
                AND p_profils.filiere_code_original                         = w_contrats_mois.filiere_code
                AND p_profils.grille_code_original                          = w_contrats_mois.grille_code
                AND p_profils.grille_groupe_code_original                   = w_contrats_mois.grille_groupe_code
                AND p_profils.groupe_cotisant_code_original                 = w_contrats_mois.groupe_cotisant_code
                AND p_profils.lettre_budgetaire_code_original               = w_contrats_mois.lettre_budgetaire_code
                AND p_profils.motif_debut_code_original                     = w_contrats_mois.motif_debut_code
                AND p_profils.motif_fin_code_original                       = w_contrats_mois.motif_fin_code
                AND p_profils.qualification_code_original                   = w_contrats_mois.qualification_code
                AND p_profils.section_analytique_code_original              = w_contrats_mois.section_analytique_code
                AND p_profils.section_analytique_paie_code_original         = w_contrats_mois.section_analytique_paie_code
                AND p_profils.service_code_original                         = w_contrats_mois.service_code
                AND p_profils.societe_interim_code_original                 = w_contrats_mois.societe_interim_code
                AND p_profils.specialite_code_original                      = w_contrats_mois.specialite_code
                AND p_profils.statut_code_original                          = w_contrats_mois.statut_code
                AND p_profils.type_contrat_code_original                    = w_contrats_mois.type_contrat_code
                AND p_profils.type_horaire_code_original                    = w_contrats_mois.type_horaire_code
                AND p_profils.type_temps_travail_code_original              = w_contrats_mois.type_temps_travail_code
                AND p_profils.unite_fonctionnelle_code_original             = w_contrats_mois.unite_fonctionnelle_code
            ;

            ]]></sqlcmd>
		</NODE>
        <NODE label="Gestion des bulletins hors période de contrat">
			<sqlcmd><![CDATA[

            -- Création de contrats_mois fictifs avec les données de profil du plus proche contrat_mois existant
            INSERT INTO w_contrats_mois  (matricule, date_debut_contrat_mois, date_fin_contrat_mois, mois_activite, contrat_mois_id, nombre_contrats_mois, contrat_id, etablissement_id, entreprise_id, profil_id, est_hors_periode)
                SELECT
                    w_bulletins.matricule,
                    w_bulletins.date_debut,
                    w_bulletins.date_fin,
                    to_char(w_bulletins.date_debut,'YYYYMM')::numeric AS mois_activite,
                    nextval('s_contrats_mois'::regclass) AS contrat_mois_id,
                    row_number() over (PARTITION BY w_bulletins.matricule, to_char(w_bulletins.date_debut,'YYYYMM')) AS nombre_contrats_mois,
                    (MAX(array[to_char(w_contrats_mois.date_fin_contrat_mois, 'YYYYMMDD')::int, w_contrats_mois.contrat_id::int]))[2] AS contrat_id,
                    (MAX(array[to_char(w_contrats_mois.date_fin_contrat_mois, 'YYYYMMDD')::int, w_contrats_mois.etablissement_id::int]))[2] AS etablissement_id,
                    (MAX(array[to_char(w_contrats_mois.date_fin_contrat_mois, 'YYYYMMDD')::int, w_contrats_mois.entreprise_id::int]))[2] AS entreprise_id,
                    (MAX(array[to_char(w_contrats_mois.date_fin_contrat_mois, 'YYYYMMDD')::int, w_contrats_mois.profil_id::int]))[2] AS profil_id,
                    1 AS est_hors_periode
                FROM w_bulletins
                JOIN w_contrats_mois AS w_contrats_mois ON w_contrats_mois.matricule = w_bulletins.matricule AND w_contrats_mois.date_fin_contrat_mois < w_bulletins.date_debut
                WHERE w_bulletins.est_hors_periode_contrat = 1
                GROUP BY 1,2,3,4
            ;

            -- Affectation au premier contrat_mois_id sur le mois au bulletin concerné
			UPDATE w_bulletins
			SET affectation_contrat_mois_id = w_contrats_mois.contrat_mois_id
			FROM w_contrats_mois
			WHERE 
				w_contrats_mois.matricule = w_bulletins.matricule 
				AND w_contrats_mois.mois_activite = w_bulletins.mois 
				AND w_contrats_mois.nombre_contrats_mois = 1
			;

			]]></sqlcmd>
		</NODE>
		<NODE label="Salariés">
			<sqlcmd><![CDATA[

            DROP TABLE IF EXISTS w_salaries
            ;

            CREATE TEMP TABLE w_salaries AS
				with derniere_situation AS (
					SELECT 
						matricule,
						MAX(date_debut_situation) AS date_derniere_situation
					FROM prod_cegidhru_melioris.etat_civil
					GROUP BY 1
				)
                SELECT
                    rhp('finess') AS finess,
                    etat_civil.matricule AS matricule,
                    etat_civil.matricule AS matricule_planning,
                    etat_civil.matricule AS code,
                    etat_civil.matricule AS code_original,
                    etat_civil.numero_securite_sociale AS nir,
                    COALESCE(w_contrats_mois.entreprise_id, 0) AS entreprise_id,
                    etat_civil.nom AS nom,
                    etat_civil.nom_jeune_fille AS nom_naissance,
                    etat_civil.prenom AS prenom,
                    etat_civil.date_naissance::date AS date_naissance,
                    etat_civil.sexe AS sexe,
                    coalesce(t_nationalites.oid, 0) AS nationalite_id, -- etcnat, etlnat
                    coalesce(t_codes_postaux.oid,0) AS code_postal_id,
                    coalesce(t_situations_famille.oid, 0) AS situation_famille_id, -- etlsfa, etcsfa
                    etat_civil.numero_voie AS adresse1,
                    etat_civil.libelle_voie AS adresse2,
                    COALESCE((MAX(ARRAY[EXTRACT(EPOCH FROM w_contrats_mois.date_debut_contrat_mois), w_contrats_mois.profil_id]))[2], 0) AS profil_id,
                    MAX(w_contrats_mois.date_debut_contrat) AS date_debut,
                    MAX(w_contrats_mois.date_fin_contrat) AS date_fin,
                    MIN(w_contrats_mois.date_debut_contrat) AS date_entree_ets,
                    MAX(w_contrats_mois.date_fin_contrat) AS date_sortie_ets,
                    -- Champs dédiés au public.
                    null::date AS date_entree_fp,
                    null::date AS date_entree_fph,
                    0 AS no_adeli,
                    0 AS code_cotisation_id,
                    0 AS matricule_retraite
                FROM prod_cegidhru_melioris.etat_civil
					JOIN derniere_situation ON derniere_situation.matricule = etat_civil.matricule AND derniere_situation.date_derniere_situation = etat_civil.date_debut_situation
                    LEFT JOIN w_contrats_mois ON w_contrats_mois.matricule = etat_civil.matricule
                    LEFT join rh.t_nationalites ON t_nationalites.code_original = etat_civil.code_nationalite
                    LEFT join rh.t_situations_famille ON t_situations_famille.code_original = etat_civil.code_situation_familiale
                    LEFT JOIN rh.t_codes_postaux ON t_codes_postaux.code = etat_civil.code_postal
                GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17
            ;

			]]></sqlcmd>
		</NODE>
		<NODE name="SALARIE" type="common" />
        <NODE label="Salariés (Màj oid)">
            <sqlcmd><![CDATA[

            UPDATE w_contrats_mois SET
                salarie_id = p_salaries.oid
            FROM rh.p_salaries
            WHERE w_contrats_mois.matricule = p_salaries.matricule
            ;

            ]]></sqlcmd>
        </NODE>
		<NODE label="Contrats">
			<sqlcmd><![CDATA[

            TRUNCATE rh.p_contrats
            ;

            WITH dernier_profil_id AS (
                SELECT
                    contrat_id,
                    (MAX(ARRAY[EXTRACT(EPOCH FROM date_fin_contrat_mois), profil_id]))[2] AS profil_id
                FROM w_contrats_mois
                GROUP BY 1
            )
			INSERT INTO rh.p_contrats(
                oid,
                salarie_id,
                date_debut,
                date_fin,
                numero_contrat,
                code_original,
                etablissement_id,
                profil_id)
				SELECT
                    w_contrats.contrat_id,
					p_salaries.oid AS salarie_id,
					w_contrats.date_debut_contrat,
					w_contrats.date_fin_contrat,
					w_contrats.numero_contrat,
					w_contrats.code_original,
					w_contrats.etablissement_id,
                    dernier_profil_id.profil_id
				FROM w_contrats
                    JOIN rh.p_salaries ON p_salaries.code_original = w_contrats.matricule
                    JOIN dernier_profil_id on dernier_profil_id.contrat_id = w_contrats.contrat_id
			;

            TRUNCATE rh.p_contrats_mois
            ;

            INSERT INTO rh.p_contrats_mois(
                oid,
                salarie_id,
                contrat_id,
                profil_id,
                code_original,
                mois_activite,
                date_debut,
                date_fin,
                nombre_entrees,
                nombre_departs,
                nombre_debut_contrat,
                nombre_fin_contrat,
                present_debut_mois,
                present_fin_mois,
                equivalent_temps_plein,
                age_jours,
                etablissement_id)
                SELECT
                    w_contrats_mois.contrat_mois_id,
                    w_contrats_mois.salarie_id,
                    w_contrats_mois.contrat_id,
                    w_contrats_mois.profil_id,
                    w_contrats_mois.salarie_id || ' - ' || w_contrats_mois.contrat_mois_id,
                    w_contrats_mois.mois_activite,
                    w_contrats_mois.date_debut_contrat_mois,
                    w_contrats_mois.date_fin_contrat_mois,
                    CASE WHEN p_salaries.date_entree_ets BETWEEN w_contrats_mois.date_debut_contrat_mois AND w_contrats_mois.date_fin_contrat_mois THEN 1 ELSE 0 END AS nombre_entrees,
					CASE WHEN p_salaries.date_sortie_ets BETWEEN w_contrats_mois.date_debut_contrat_mois AND w_contrats_mois.date_fin_contrat_mois THEN 1 ELSE 0 END AS nombre_departs,
                    CASE WHEN p_contrats.date_debut BETWEEN date_debut_contrat_mois AND w_contrats_mois.date_fin_contrat_mois THEN 1 ELSE 0 END AS nombre_debut_contrat,
					CASE WHEN p_contrats.date_fin BETWEEN date_debut_contrat_mois AND w_contrats_mois.date_fin_contrat_mois THEN 1 ELSE 0 END AS nombre_fin_contrat,
                    case when w_contrats_mois.date_debut_contrat > base.cti_first_day(w_contrats_mois.date_debut_contrat_mois) then 0 else 1 end AS present_debut_mois,
                    case when w_contrats_mois.date_fin_contrat < base.cti_last_day(w_contrats_mois.date_debut_contrat_mois) then 0 else 1 end AS present_fin_mois,
                    w_contrats_mois.etp_theorique AS equivalent_temps_plein,
                    w_contrats_mois.date_fin_contrat_mois - coalesce(p_salaries.date_naissance, '1962-04-18'::date) AS age_jours,
                    w_contrats_mois.etablissement_id
                FROM rh.p_contrats
                    JOIN w_contrats_mois on w_contrats_mois.contrat_id = p_contrats.oid
                    JOIN rh.p_salaries on p_salaries.oid = w_contrats_mois.salarie_id
            ;

			]]></sqlcmd>
		</NODE>
        <NODE label="Mise à jour des informations permanentes">
			<sqlcmd><![CDATA[

			-- Màj des catégories socio-professionnelles
			INSERT INTO rh.t_categories_socio_professionnelle (code_original, code, texte, texte_court)
				SELECT categorie_socio_professionnelle_code, categorie_socio_professionnelle_code, categorie_socio_professionnelle_code, substr(categorie_socio_professionnelle_code, 1, 50)
				FROM w_contrats_mois
				WHERE 
                    categorie_socio_professionnelle_code <> chr(1)||'*'
					AND categorie_socio_professionnelle_code NOT IN (SELECT code_original FROM rh.t_categories_socio_professionnelle WHERE code_original IS NOT NULL)
				GROUP BY 1,2,3,4
			;

			-- Màj des motifs de début de contrat.
			INSERT INTO rh.t_motifs_debut_contrat(code_original, code, texte, texte_court)
                SELECT 
                    code_motif_debut_contrat, 
                    code_motif_debut_contrat, 
                    libelle_motif_debut_contrat, 
                    substr(libelle_motif_debut_contrat,1,50)
                FROM prod_cegidhru_melioris.contrat
                WHERE code_motif_debut_contrat NOT IN (SELECT code_original FROM rh.t_motifs_debut_contrat WHERE code_original IS NOT NULL)
                GROUP BY 1,2,3,4
                ORDER BY 2
			;

			-- Màj des motifs de fin de contrat.
			INSERT INTO rh.t_motifs_fin_contrat(code_original, code, texte, texte_court)
                SELECT 
                    code_motif_fin_contrat, 
                    code_motif_fin_contrat, 
                    libelle_motif_fin_contrat, 
                    substr(libelle_motif_fin_contrat,1,50)
                FROM prod_cegidhru_melioris.contrat
                WHERE code_motif_fin_contrat NOT IN (SELECT code_original FROM rh.t_motifs_fin_contrat WHERE code_original IS NOT NULL)
                GROUP BY 1,2,3,4
                ORDER BY 2
			;

			-- Màj des nationalités.
			INSERT INTO rh.t_nationalites(code, code_original, texte, texte_court)
                SELECT 
                    code_nationalite, 
                    code_nationalite, 
                    libelle_nationalite,
                    substr(libelle_nationalite,1,50)
                FROM prod_cegidhru_melioris.etat_civil
                WHERE code_nationalite NOT IN (SELECT code_original FROM rh.t_nationalites WHERE code_original IS NOT NULL)
                GROUP BY 1,2,3,4
			;

			-- Màj des qualifications
			INSERT INTO rh.t_qualifications(code_original, code, texte, texte_court)
				SELECT qualification_code, qualification_code, max(qualification_texte), substr(max(qualification_texte), 1, 50)
                FROM w_contrats_mois
                WHERE 
                    qualification_code <> chr(1)||'*'
                    AND qualification_code NOT IN (SELECT code_original FROM rh.t_qualifications WHERE code_original IS NOT NULL)
                GROUP BY 1,2
			;

            -- Màj des rubriques
            INSERT INTO rh.t_rubriques(code_original, code, texte, texte_court)
                SELECT 
                    code_rubrique, 
                    code_rubrique, 
                    libelle_rubrique, 
                    substr(libelle_rubrique, 1, 50)
                FROM prod_cegidhru_melioris.rubrique
                WHERE code_rubrique NOT IN (SELECT code_original FROM rh.t_rubriques WHERE code_original IS NOT NULL)
                GROUP BY 1,2,3,4
            ;

			-- Màj des situations de famille
			INSERT INTO rh.t_situations_famille(code_original, code, texte, texte_court)
				SELECT 
					code_situation_familiale, 
					code_situation_familiale, 
					libelle_situation_familiale, 
					substr(libelle_situation_familiale, 1, 50)
				FROM prod_cegidhru_melioris.etat_civil
				WHERE code_situation_familiale NOT IN (SELECT code_original FROM rh.t_situations_famille WHERE code_original IS NOT NULL)
				GROUP BY 1,2,3,4
			;

			-- Màj des types de contrat
			INSERT INTO rh.t_types_contrat(code_original, code, texte, texte_court)
				SELECT type_contrat_code, type_contrat_code, type_contrat_texte, substr(type_contrat_texte, 1, 50)
				FROM w_contrats_mois
				WHERE 
                    type_contrat_code <> chr(1)||'*'
                    AND type_contrat_code NOT IN (SELECT code_original FROM rh.t_types_contrat WHERE code_original IS NOT NULL)
				GROUP BY 1,2,3,4
			;

			-- Màj des statuts
			INSERT INTO rh.t_statuts(code_original, code, texte, texte_court)
				SELECT statut_code, statut_code, statut_texte, substr(statut_texte, 1, 50)
				FROM w_contrats_mois
				WHERE 
                    statut_code <> chr(1)||'*'
                    AND statut_code NOT IN (SELECT code_original FROM rh.t_statuts WHERE code_original IS NOT NULL)
				GROUP BY 1,2,3,4
			;

			-- Màj des types de temps de travail
			INSERT INTO rh.t_types_temps_travail(code_original, code, texte, texte_court)
                SELECT
                    CASE WHEN heures_theoriques >= 151.67 THEN 'TC' ELSE 'TP' END||ROUND(heures_theoriques::numeric, 2)::text,
                    CASE WHEN heures_theoriques >= 151.67 THEN 'TC' ELSE 'TP' END||ROUND(heures_theoriques::numeric, 2)::text,
                    CASE WHEN heures_theoriques >= 151.67 THEN 'Temps Complet ' ELSE 'Temps Partiel ' end||round(heures_theoriques::numeric, 2)::text,
                    CASE WHEN heures_theoriques >= 151.67 THEN 'TC ' ELSE 'TP ' END||ROUND(heures_theoriques::numeric, 2)::text
                FROM w_contrats_mois
                WHERE CASE WHEN heures_theoriques >= 151.67 THEN 'TC' ELSE 'TP' END||ROUND(heures_theoriques::numeric, 2)::text NOT IN (SELECT code_original FROM rh.t_types_temps_travail WHERE code_original IS NOT NULL)
                GROUP BY 1,2,3,4
			;

			-- Màj des services
			INSERT INTO rh.t_services(code_original, code, texte, texte_court)
				SELECT service_code, service_code, max(service_texte), max(substr(service_texte, 1, 50))
                FROM w_contrats_mois
                WHERE 
                    service_code <> chr(1)||'*'
                    AND service_code NOT IN (SELECT code_original FROM rh.t_services WHERE code_original IS NOT NULL)
                GROUP BY 1,2
			;

			]]></sqlcmd>
		</NODE>
        <NODE label="Pre-traitement de la paie">
            <sqlcmd><![CDATA[

            DROP TABLE IF EXISTS w_hp
            ;

            CREATE TEMP TABLE w_hp AS
                with bulletin_detail AS (
                -- Pré-traitement détail bulletin avec plusieurs lignes par matricule/mois/rubrique
                    SELECT 
                        matricule,
                        date_paie,
                        code_rubrique,
                        libelle_rubrique,
                        SUM(nombre::numeric) AS nombre,
                        SUM(taux::numeric) AS taux,
                        SUM(montant::numeric) AS montant,
                        SUM(taux_pat::numeric) AS taux_pat,
                        SUM(mtt_pat::numeric) AS mtt_pat
                    FROM prod_cegidhru_melioris.bulletin_detail
                    GROUP BY 1,2,3,4
                )
                SELECT
                    w_contrats_mois.contrat_mois_id AS bul_code,
                    w_contrats_mois.contrat_mois_id,
                    w_contrats_mois.contrat_id,
                    w_contrats_mois.salarie_id,
                    w_bulletins.date_debut,
                    w_bulletins.date_fin,
                    0 AS profil_id,
                    bulletin_detail.matricule,
                    bulletin_detail.date_paie::date AS date_paie,
                    to_char(bulletin_detail.date_paie::date, 'YYYYMM')::int AS mois_paie,
                    t_rubriques.oid AS rubrique_id,
                    w_bulletins.etablissement_id,
                    t_rubriques.p_detail,
                    t_rubriques.p_cumul,
                    t_rubriques.c_base
                        * case when @t_rubriques.c_base != 1 then coalesce(case when proratiser_conversion then etp_theorique else 1.0 end, 1.0) else 1.0 end
                        * CASE WHEN p_base THEN (CASE s_base
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                            END)::numeric else 0 end AS base,
                    t_rubriques.c_nombre
                        * case when @t_rubriques.c_nombre != 1 then coalesce(case when proratiser_conversion then etp_theorique else 1.0 end, 1.0) else 1.0 end
                        * CASE WHEN p_nombre THEN (CASE s_nombre
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                            END)::numeric else 0 end AS nombre,
                    t_rubriques.c_heures_contrat
                        * case when @t_rubriques.c_heures_contrat != 1 then coalesce(case when proratiser_conversion then etp_theorique else 1.0 end, 1.0) else 1.0 end
                        * CASE WHEN p_heures_contrat
                            then (CASE s_heures_contrat
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                            END)::numeric
                            else 0 end
                        AS heure_contrat,
                    t_rubriques.c_heures_payees
                        * case when @t_rubriques.c_heures_payees != 1 then coalesce(case when proratiser_conversion then etp_theorique else 1.0 end, 1.0) else 1.0 end
                        * CASE WHEN p_heures_payees
                            then (CASE s_heures_payees
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                            END)::numeric else 0 end AS heure_payee,
                    t_rubriques.c_heures_travaillees
                        * case when @t_rubriques.c_heures_travaillees != 1 then coalesce(case when proratiser_conversion then etp_theorique else 1.0 end, 1.0) else 1.0 end
                        * CASE WHEN p_heures_travaillees
                            then (CASE s_heures_travaillees
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric else 0 end AS heure_travaillee,
                    t_rubriques.c_masse_salariale
                        * (CASE WHEN p_masse_salariale      THEN
                            (CASE s_masse_salariale
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric
                            else 0 end) AS masse_salariale,
                    t_rubriques.c_brut
                        * (CASE WHEN p_brut                 THEN
                            (CASE s_brut
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric
                            else 0 end) AS montant_brut,
                    t_rubriques.c_frais_imposables
                        * (case when p_frais_imposables     then
                            (CASE s_frais_imposables
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric
                            else 0 end) AS montant_frais_imposables,
                    t_rubriques.coefficient_txs * (case when p_cotisation_salarie then bulletin_detail.taux::numeric else 0 end) AS taux_sal,
                    t_rubriques.c_cotisation_salarie
                        * (case when p_cotisation_salarie   then
                            (CASE s_cotisation_salarie
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montantWHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric
                            else 0 end) AS montant_cot_sal,
                    t_rubriques.coefficient_txp * (case when p_cotisation_patronale then bulletin_detail.taux::numeric else 0 end) AS taux_pat,
                    t_rubriques.c_cotisation_patronale
                        * (case when p_cotisation_patronale then
                            (CASE s_cotisation_patronale
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montantWHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric
                            else 0 end) AS montant_cot_pat,
                    t_rubriques.c_od_net_salarie
                        * (CASE WHEN p_od_net_salarie       THEN
                            (CASE s_od_net_salarie
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montantWHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric
                            ELSE 0 END) AS od_net,
                    t_rubriques.c_od_net_patronale
                        * (CASE WHEN p_od_net_patronale     THEN
                            (CASE s_od_net_patronale
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montantWHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric
                            ELSE 0 END) AS od_net_p,
                    t_rubriques.c_avantage_nature
                        * (CASE WHEN p_avantage_nature      THEN
                            (CASE s_avantage_nature
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montantWHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric
                            ELSE 0 END) AS avt_nat,
                    t_rubriques.c_net_imposable
                        * (CASE WHEN p_net_imposable        THEN
                            (CASE s_net_imposable
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric
                            ELSE 0 END) AS net_imposable,
                    t_rubriques.c_net_a_payer
                        * (CASE WHEN p_net_a_payer          THEN
                            (CASE s_net_a_payer
                                WHEN 0 THEN bulletin_detail.montant
                                WHEN 1 THEN bulletin_detail.nombre
                                WHEN 2 THEN bulletin_detail.taux
                                WHEN 3 THEN bulletin_detail.montant
                                --WHEN 4 THEN bulletin_detail.taux_pat
                                WHEN 5 THEN bulletin_detail.mtt_pat
                                --WHEN 6 THEN bulletin_detail.montant + bulletin_detail.mtt_pat
                                --WHEN 7 THEN bulletin_detail.montant - bulletin_detail.mtt_pat
                                --WHEN 8 THEN bulletin_detail.mtt_pat - bulletin_detail.montant
                                END)::numeric
                            ELSE 0 END) AS net_a_payer
                FROM bulletin_detail
                    JOIN rh.t_rubriques ON t_rubriques.code_original = lpad(bulletin_detail.code_rubrique, 5, '0')
                    JOIN w_bulletins ON w_bulletins.matricule = bulletin_detail.matricule AND w_bulletins.mois = to_char(bulletin_detail.date_paie::date, 'YYYYMM')::int
                    JOIN w_contrats_mois ON w_contrats_mois.contrat_mois_id = w_bulletins.affectation_contrat_mois_id
                WHERE
                    bulletin_detail.date_paie::date >= rhp('rhprovider_start')::date
            ;

			]]></sqlcmd>
		</NODE>
        <NODE label="Chiffrier">
            <sqlcmd><![CDATA[

            TRUNCATE rh.p_chiffrier_production
            ;

			INSERT INTO rh.p_chiffrier_production (entreprise_id, etablissement_id, mois, nombre_salaries, montant_brut, nombre_heures)
                SELECT
                    entreprise_id,
                    etablissement_id,
                    mois,
                    count(DISTINCT matricule),
                    sum(total_brut),
                    sum(total_heures_payees)
                FROM w_bulletins
                GROUP BY 1,2,3
            ;

            ]]></sqlcmd>
		</NODE>
        <NODE label="Historique de la paie">
            <sqlcmd><![CDATA[

            -- -- Génération paie
            SELECT base.cti_stash_table_indexes('rh', 'p_historique_paie')
            ;

            TRUNCATE rh.p_historique_paie
            ;

            INSERT INTO rh.p_historique_paie(
                code_original,
                age_id,
                base,
                nombre,
                contrat_id,
                contrat_mois_id,
                date_debut,
                date_fin,
                date_paie,
                mois_activite,
                mois_paie,
                heure_contrat,
                heure_payee,
                heure_travaillee,
                montant_avantage_nature,
                montant_brut,
                montant_masse_salariale,
                montant_cotisation_patronale,
                montant_cotisation_salarie,
                montant_frais_imposables,
                montant_net_a_payer_salarie,
                montant_net_imposable_salarie,
                montant_od_net_salarie,
                organisme_cotisation_id,
                profil_id,
                rubrique_id,
                compte_id,
                salarie_id,
                taux_cotisation_patronale,
                taux_cotisation_salarie,
                etablissement_id)
                SELECT
                    w_hp.bul_code as code_original,
                    date_part('year', age(w_hp.date_paie, date_naissance)) AS age_id,
                    w_hp.base,
                    w_hp.nombre,
                    w_hp.contrat_id,
                    w_hp.contrat_mois_id,
                    w_hp.date_debut,
                    w_hp.date_fin,
                    w_hp.date_paie AS date_paie,
                    w_hp.mois_paie AS mois_activite,
                    w_hp.mois_paie AS mois_paie,
                    w_hp.heure_contrat,
                    w_hp.heure_payee,
                    w_hp.heure_travaillee,
                    w_hp.avt_nat AS montant_avantage_nature,
                    w_hp.montant_brut AS montant_brut,
                    w_hp.masse_salariale as montant_masse_salariale,
                    w_hp.montant_cot_pat AS montant_cotisation_patronale,
                    w_hp.montant_cot_sal AS montant_cotisation_salarie,
                    w_hp.montant_frais_imposables,
                    w_hp.net_a_payer AS montant_net_a_payer_salarie,
                    w_hp.net_imposable AS montant_net_imposable_salarie,
                    w_hp.od_net AS montant_od_net_salarie,
                    0 AS organisme_cotisation_id,
                    w_hp.profil_id,
                    w_hp.rubrique_id,
                    0 AS compte_id,
                    w_hp.salarie_id,
                    w_hp.taux_pat AS taux_cotisation_patronale,
                    w_hp.taux_sal AS taux_cotisation_salarie,
                    w_hp.etablissement_id
                FROM w_hp
                    JOIN rh.p_salaries ON p_salaries.oid = w_hp.salarie_id
                WHERE p_detail
            ;

            SELECT base.cti_stash_pop_table_indexes('rh', 'p_historique_paie')
            ;

            -- Création d'une table récapitulative des écarts à calculer par indicateur de paie (1 seule ligne).
            DROP TABLE IF EXISTS w_cumul
			;

            CREATE TEMP TABLE w_cumul AS
                SELECT
                    bool_or(p_cumul and p_heures_contrat) as total_h_contrat,
                    bool_or(p_cumul and p_heures_travaillees) as total_h_travaillees,
                    bool_or(p_cumul and p_heures_payees) as total_h_payees,
                    bool_or(p_cumul and p_masse_salariale) as total_masse_salariale,
                    bool_or(p_cumul and p_brut) as total_brut,
                    bool_or(p_cumul and p_avantage_nature) as total_avantage_nature,
                    bool_or(p_cumul and p_cotisation_salarie) as total_cot_sal,
                    bool_or(p_cumul and p_cotisation_patronale) as total_cot_pat,
                    bool_or(p_cumul and p_od_net_salarie) as total_od_net,
                    bool_or(p_cumul and p_net_imposable) as total_imposable,
                    bool_or(p_cumul and p_net_a_payer) as total_payer
                FROM rh.t_rubriques
            ;

			-- Création d'une table temp qui regroupe tous les totaux à atteindre pour calculer l'écart.
			DROP TABLE IF EXISTS w_totaux
			;

            CREATE TEMP TABLE w_totaux AS
                SELECT
                    w_hp.bul_code as code_original,
                    w_hp.matricule,
                    w_hp.date_paie as date,
                    w_hp.mois_paie,
                    coalesce(sum(case when p_cumul then heure_contrat else 0 end), 0) AS hcum_heures_contrat,
                    coalesce(sum(case when p_cumul then heure_payee else 0 end), 0) AS hcum_heures_payees,
                    coalesce(sum(case when p_cumul then heure_travaillee else 0 end), 0) AS hcum_heures_travaillees,
                    coalesce(round(sum(case when p_cumul then masse_salariale else 0 end), 2), 0) AS hcum_masse_salariale,
                    coalesce(round(sum(case when p_cumul then montant_brut else 0 end), 2), 0) AS hcum_brut,
                    coalesce(round(sum(case when p_cumul then avt_nat else 0 end), 2), 0) AS hcum_avantage_nature,
                    0::numeric AS hcum_frais_imposables,
                    coalesce(round(sum(case when p_cumul then montant_cot_sal else 0 end), 2), 0) AS hcum_cotisation_salarie,
                    coalesce(round(sum(case when p_cumul then montant_cot_pat else 0 end), 2), 0) AS hcum_cotisation_patronale,
                    coalesce(round(sum(case when p_cumul then od_net else 0 end), 2), 0) AS hcum_od_net_salarie,
                    coalesce(round(sum(case when p_cumul then net_imposable else 0 end), 2), 0) AS hcum_net_imposable_salarie,
                    coalesce(round(sum(case when p_cumul then net_a_payer else 0 end), 2), 0) AS hcum_net_a_payer_salarie
                FROM w_hp 
                WHERE p_cumul
                GROUP BY 1,2,3,4
            ;

            -- Insérer pour chaque bulletin une ligne qui va faire le compte avec le total (rubrique 'C000' nommée 'Ecart cumulé')
            INSERT INTO rh.p_historique_paie (
                code_original,
                age_id,
                contrat_id,
                contrat_mois_id,
                date_debut,
                date_fin,
                date_paie,
                mois_activite,
                mois_paie,
                base,
                nombre,
                heure_contrat,
                heure_payee,
                heure_travaillee,
                montant_avantage_nature,
                montant_brut,
                montant_masse_salariale,
                montant_cotisation_patronale,
                montant_cotisation_salarie,
                montant_frais_imposables,
                montant_net_a_payer_salarie,
                montant_net_imposable_salarie,
                montant_od_net_salarie,
                organisme_cotisation_id,
                profil_id,
                rubrique_id,
                compte_id,
                salarie_id,
                taux_cotisation_patronale,
                taux_cotisation_salarie,
                etablissement_id)
                SELECT
                    subq.code_original,
                    subq.age_id,
                    subq.contrat_id,
                    subq.contrat_mois_id,
                    subq.date_debut,
                    subq.date_fin,
                    subq.date_paie,
                    subq.mois_activite,
                    subq.mois_paie,
                    0 AS base,
                    0 AS nombre,
                    case when total_h_contrat then COALESCE(hcum_heures_contrat, 0) - subq.heure_contrat else 0.0 end AS heure_contrat,
                    case when total_h_payees then COALESCE(hcum_heures_payees,0) - subq.heure_payee else 0.0 end AS heure_payee,
                    case when total_h_travaillees then COALESCE(hcum_heures_travaillees,0) - subq.heure_travaillee else 0.0 end AS heure_travaillee,
                    case when total_avantage_nature then COALESCE(hcum_avantage_nature,0) - subq.montant_avantage_nature else 0.0 end AS montant_avantage_nature,
                    case when total_brut then COALESCE(hcum_brut,0) - subq.montant_brut else 0.0 end AS montant_brut,
                    case when total_masse_salariale then COALESCE(hcum_masse_salariale, 0) - subq.montant_masse_salariale else 0.0 end AS montant_masse_salariale,
                    case when total_cot_pat then COALESCE(hcum_cotisation_patronale,0) - subq.montant_cotisation_patronale else 0.0 end AS montant_cotisation_patronale,
                    case when total_cot_sal then COALESCE(hcum_cotisation_salarie,0) - subq.montant_cotisation_salarie else 0.0 end AS montant_cotisation_salarie,
                    0 AS montant_frais_imposables,
                    case when total_payer then COALESCE(hcum_net_a_payer_salarie,0) - subq.montant_net_a_payer_salarie else 0.0 end AS montant_net_a_payer_salarie,
                    case when total_imposable then COALESCE(hcum_net_imposable_salarie,0) - subq.montant_net_imposable_salarie else 0.0 end AS montant_net_imposable_salarie,
                    case when total_imposable then COALESCE(hcum_od_net_salarie,0) - subq.montant_od_net_salarie else 0.0 end AS montant_od_net_salarie,
                    subq.organisme_cotisation_id AS organisme_cotisation_id,
                    subq.profil_id AS profil_id,
                    (SELECT oid FROM rh.t_rubriques WHERE code = 'C000') AS rubrique_id,
                    0 AS compte_id,
                    subq.salarie_id AS salarie_id,
                    0 AS taux_cotisation_patronale,
                    0 AS taux_cotisation_salarie,
                    subq.etablissement_id
                FROM (
                    SELECT
                        p_historique_paie.code_original,
                        p_historique_paie.age_id,
                        p_historique_paie.contrat_id,
                        p_historique_paie.contrat_mois_id,
                        p_historique_paie.date_debut,
                        p_historique_paie.date_fin,
                        p_historique_paie.date_paie,
                        p_historique_paie.mois_activite,
                        p_historique_paie.mois_paie,
                        0 AS base,
                        0 AS nombre,
                        sum(heure_contrat) AS heure_contrat,
                        sum(heure_payee) AS heure_payee,
                        sum(heure_travaillee) AS heure_travaillee,
                        sum(montant_avantage_nature) AS montant_avantage_nature,
                        sum(montant_brut) AS montant_brut,
                        sum(montant_masse_salariale) AS montant_masse_salariale,
                        sum(montant_cotisation_patronale) AS montant_cotisation_patronale,
                        sum(montant_cotisation_salarie) AS montant_cotisation_salarie,
                        0 AS montant_frais_imposables,
                        sum(montant_net_a_payer_salarie) AS montant_net_a_payer_salarie,
                        sum(montant_net_imposable_salarie) AS montant_net_imposable_salarie,
                        sum(montant_od_net_salarie) AS montant_od_net_salarie,
                        p_historique_paie.organisme_cotisation_id,
                        p_historique_paie.profil_id,
                        (SELECT oid FROM rh.t_rubriques WHERE code = 'C000'),
                        p_historique_paie.salarie_id,
                        0 AS taux_cotisation_patronale,
                        0 AS taux_cotisation_salarie,
                        etablissement_id
                    FROM rh.p_historique_paie
                        JOIN rh.p_salaries ON p_salaries.oid = p_historique_paie.salarie_id
                    GROUP BY 1,2,3,4,5,6,7,8,9,10,11, 24,25,26,27,28,29,30) AS subq
                JOIN w_totaux ON w_totaux.code_original = subq.code_original
                JOIN w_cumul ON true
            WHERE 1!=1
                OR case when total_avantage_nature then COALESCE(hcum_avantage_nature,0) - subq.montant_avantage_nature != 0 else false end
                OR case when total_brut            then COALESCE(hcum_brut,0) - subq.montant_brut != 0 else false end
                OR case when total_masse_salariale then COALESCE(hcum_masse_salariale,0) - subq.montant_masse_salariale != 0 else false end
                OR case when total_payer           then COALESCE(hcum_net_a_payer_salarie,0) - subq.montant_net_a_payer_salarie != 0 else false end
                OR case when total_imposable       then COALESCE(hcum_net_imposable_salarie,0) - subq.montant_net_imposable_salarie != 0 else false end
                OR case when total_od_net          then COALESCE(hcum_od_net_salarie,0) - subq.montant_od_net_salarie != 0 else false end
                OR case when total_cot_pat         then COALESCE(hcum_cotisation_patronale,0) - subq.montant_cotisation_patronale != 0 else false end
                OR case when total_cot_sal         then COALESCE(hcum_cotisation_salarie,0) - subq.montant_cotisation_salarie != 0 else false end
                OR case when total_h_contrat       then COALESCE(hcum_heures_contrat, 0) - subq.heure_contrat != 0 else false end
                OR case when total_h_payees        then COALESCE(hcum_heures_payees,0) - subq.heure_payee != 0 else false end
                OR case when total_h_travaillees   then COALESCE(hcum_heures_travaillees,0) - subq.heure_travaillee != 0 else false end
            ;

            ]]></sqlcmd>
        </NODE>
        <NODE label="Ventilation des profils">
			<sqlcmd><![CDATA[

			-- Alimentation des profils simultanés.
			TRUNCATE rh.p_profil_contrat_mois
			;

			INSERT INTO rh.p_profil_contrat_mois (
				profil_id,
				contrat_mois_id,
				salarie_id,
				ratio,
				mois)
				SELECT
					p_contrats_mois.profil_id,
					p_contrats_mois.oid AS contrat_mois_id,
					p_contrats_mois.salarie_id,
					1 AS ratio,
					p_contrats_mois.mois_activite
				FROM rh.p_contrats_mois
				GROUP BY 1,2,3,4,5
			;

			]]></sqlcmd>
		</NODE>
	</NODE>
	<NODE name="POST" label="POST-TRAITEMENTS">
		<NODE name="DIVERS" type="common"/>
		<NODE name="POST" type="common"/>
	</NODE>
	<NODE name="VACUUM" label="REORGANISATION BASE DE DONNEES">
		<NODE name="VACUUM" type="common" />
	</NODE>
	<NODE name="RAZ" label="RAZ BASE">
		<NODE name="RAZ" type="common" />
	</NODE>
	<NODE name="RAZ_ALL" label="RAZ ALL">
		<NODE name="RAZ_ALL" type="common" />
	</NODE>
</ROOT>
