<?xml version="1.0" encoding="ISO-8859-15"?>
<ROOT>
	<NODE name="INIT" label="INITIALISATIONS">
		<NODE name="INIT" type="common" />
        <NODE label="Mise à jour des informations permanentes - 1/2 (mode classique)">
            <condition><![CDATA[
                
            -- Historique de paie classique.
            select valeur = 0
            from rh.t_divers
            where code = 'OPT_STD_HP'
            ;

            ]]></condition>
            <sqlcmd><![CDATA[

            -- (création des rubriques CTI de cumul)
            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C000', 'Ecart cumulé', 'Ecart cumulé', 'C000', -1
                WHERE 'C000' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            -- (création des rubriques CTI de cumul)
            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C006', 'Ecart cumulé Cotisations patronales', 'Ecart cumulé Cotisations patronales', 'C006', -1
                WHERE 'C006' NOT IN (SELECT code_original FROM rh.t_rubriques WHERE code_original IS NOT NULL)
            ;

            -- (création des rubriques CTI de cumul)
            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C007', 'Ecart cumulé Cotisations salariales', 'Ecart cumulé Cotisations salariales', 'C007', -1
                WHERE 'C007' NOT IN (SELECT code_original FROM rh.t_rubriques WHERE code_original IS NOT NULL)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C086', 'Heures travaillées', 'Heures travaillées', 'C086', -1
                WHERE 'C086' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C084', 'Heures payées', 'Heures payées', 'C084', -1
                WHERE 'C084' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C003', 'Net à payer', 'Net à payer', 'C003', -1
                WHERE 'C003' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C004', 'Net imposable', 'Net imposable', 'C004', -1
                WHERE 'C004' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            ]]></sqlcmd>
        </NODE>
        <NODE label="Mise à jour des informations permanentes - 1/2 (mode paramétré)">
            <condition><![CDATA[
                
            -- Historique de paie paramétré.
            select valeur = 1
            from rh.t_divers
            where code = 'OPT_STD_HP'
            ;

            ]]></condition>
            <sqlcmd><![CDATA[

            -- Rubrique C000 d'écart cumulé.
            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C000', 'Ecart cumulé', 'Ecart cumulé', 'C000', -1
                WHERE 'C000' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            -- Rubriques en C de cumul Sage.
            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C003', 'Net à payer', 'Net à payer', 'C003', -1
                WHERE 'C003' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C004', 'Net imposable', 'Net imposable', 'C004', -1
                WHERE 'C004' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C005', 'Avantage en nature', 'Avantage en nature', 'C005', -1
                WHERE 'C005' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C006', 'Cotisations patronales', 'Cotisations patronales', 'C006', -1
                WHERE 'C006' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C007', 'Cotisations salariales', 'Cotisations salariales', 'C007', -1
                WHERE 'C007' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C008', 'Brut', 'Brut', 'C008', -1
                WHERE 'C008' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C084', 'Heures', 'Heures', 'C084', -1
                WHERE 'C084' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT 'C086', 'Heures', 'Heures', 'C086', -1
                WHERE 'C086' NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

            ]]></sqlcmd>
        </NODE>
		<NODE label="Mise à jour des informations permanentes - 2/2 (commun)">
			<sqlcmd><![CDATA[

            -- Table du ou des entreprises/établissements à importer.
            DROP TABLE IF EXISTS w_ets
            ;

            CREATE TEMP TABLE w_ets AS
                SELECT
                    siren,
                    nic,
                    codeetab
                FROM prod_sage.t_eta
				WHERE 1!=1
                    OR siren      IN (SELECT rhp_in('siren')) -- Soit un ou plusieurs SIREN ont été défini,
                    OR siren||nic IN (SELECT rhp_in('siren')) -- et/ou soit un ou plusieurs SIRET,
                    OR codeetab   IN (SELECT rhp_in('siren')) -- et/ou soit un ou plusieurs codes établissement.
				GROUP BY 1,2,3
            ;

			-- Màj des Entreprises
			INSERT INTO rh.t_entreprises(code_original, code, texte, texte_court, siren)
				SELECT
					t_eta.siren,
					t_eta.siren,
					(min(ARRAY[t_eta.codeetab, t_eta.intitule]))[2],
					substr((min(ARRAY[t_eta.codeetab, t_eta.intitule]))[2], 1, 50),
					t_eta.siren
				FROM prod_sage.t_eta
                    JOIN w_ets ON w_ets.codeetab = t_eta.codeetab
                WHERE t_eta.siren NOT IN (SELECT code_original FROM rh.t_entreprises)
                GROUP BY 1,2,5
			;

			with ent as (
                SELECT
                    t_entreprises.oid,
                    t_eta.siren
                FROM rh.t_entreprises
                    JOIN prod_sage.t_eta on t_eta.siren = t_entreprises.code_original)
            UPDATE rh.t_entreprises
			SET siren = ent.siren
			FROM ent
            WHERE 1=1
                and t_entreprises.oid = ent.oid
                and t_entreprises.siren IS DISTINCT FROM ent.siren
			;

			-- Màj des Etablissements
			INSERT INTO rh.t_etablissements(code_original, code, texte, texte_court, entreprise_id, siret)
				SELECT
					t_eta.siren||t_eta.nic,
					t_eta.siren||t_eta.nic,
					(min(ARRAY[t_eta.codeetab, t_eta.intitule]))[2],
					substr((min(ARRAY[t_eta.codeetab, t_eta.intitule]))[2], 1, 50),
					t_entreprises.oid,
					t_eta.siren||t_eta.nic
				FROM prod_sage.t_eta
                    JOIN w_ets ON w_ets.codeetab = t_eta.codeetab
					JOIN rh.t_entreprises ON t_entreprises.code_original = t_eta.siren
				WHERE t_eta.siren||t_eta.nic NOT IN (SELECT code_original FROM rh.t_etablissements)
				GROUP BY 1,2,5,6
			;

            with eta as (
                SELECT
                    t_etablissements.oid,
                    t_eta.siren||t_eta.nic as siret
                FROM rh.t_etablissements
                    JOIN prod_sage.t_eta on t_eta.siren||t_eta.nic = t_etablissements.code_original)
            UPDATE rh.t_etablissements
			SET siret = eta.siret
			FROM eta
            WHERE 1=1
                and t_etablissements.oid = eta.oid
                and t_etablissements.siret IS DISTINCT FROM eta.siret
			;

			-- Màj des catégories socio-professionnelles
			INSERT INTO rh.t_categories_socio_professionnelle (code, texte, texte_court, code_original)
				SELECT codeemploiinsee, max(intitule), max(substr(intitule, 1, 50)), codeemploiinsee
				FROM prod_sage.t_emploiinsee
				WHERE 1=1
					AND codeemploiinsee NOT IN (SELECT code_original FROM rh.t_categories_socio_professionnelle)
				GROUP BY 1
			;

			-- @TODO Màj des groupes cotisants.

			-- MOtifs début
			INSERT INTO rh.t_motifs_debut_contrat(code_original, code, texte, texte_court)
				SELECT code, code, substr(max(intitule),1,50), substr(max(intitule),1,50)
				FROM prod_sage.t_motifsdecontrat
				WHERE code NOT IN (SELECT code_original FROM rh.t_motifs_debut_contrat WHERE code_original IS NOT NULL)
				GROUP BY 1,2
				ORDER BY 2
			;

			-- Màj des motifs de fin de contrat
			INSERT INTO rh.t_motifs_fin_contrat(code, texte, texte_court, code_original)
				SELECT code, MAX(intitule), MAX(substr(intitule,1,50)), code
				FROM prod_sage.t_motifdepart
				WHERE code NOT IN (SELECT code_original FROM rh.t_motifs_fin_contrat WHERE code_original IS NOT NULL)
				GROUP BY 1
			;

			-- Màj des nationalités
			INSERT INTO rh.t_nationalites(code, texte, texte_court, code_original)
				SELECT code, intitule, substr(intitule,1,50), code
				FROM prod_sage.t_nationalite
				WHERE code NOT IN (SELECT code_original FROM rh.t_nationalites)
				GROUP BY 1,2,3,4
			;

			-- @TODO Màj des organismes de cotisation

			-- Màj des qualifications
			INSERT INTO rh.t_qualifications(code_original, code, texte, texte_court)
				SELECT code, code, intitule, substr(intitule, 1, 50)
                FROM prod_sage.t_unite
                WHERE 1=1
                    AND code NOT IN (SELECT code_original FROM rh.t_qualifications)
                    AND (SELECT valeur = 'UNITE' FROM rh.t_divers WHERE code = 'SAGE_QUALIFICATION') -- Valeur à prendre dans "Unité" Sage.
                GROUP BY 1,2,3,4
			;

            INSERT INTO rh.t_qualifications(code_original, code, texte, texte_court)
                SELECT code, code, MAX(intitule), MAX(substr(intitule,1,50))
                FROM prod_sage.t_departement
                WHERE 1=1
                    AND code NOT IN (SELECT code_original FROM rh.t_qualifications)
                    AND (SELECT valeur = 'DEPARTEMENT' FROM rh.t_divers WHERE code = 'SAGE_QUALIFICATION') -- Valeur à prendre dans "Département" Sage.
                GROUP BY 1,2
            ;

            INSERT INTO rh.t_qualifications(code_original, code, texte, texte_court)
                SELECT code, code, max(intitule), max(substr(intitule, 1, 50))
                FROM prod_sage.t_postes
                WHERE 1=1
                    AND code NOT IN (SELECT code_original FROM rh.t_qualifications)
                    AND (SELECT valeur = 'POSTE' FROM rh.t_divers WHERE code = 'SAGE_QUALIFICATION') -- Valeur à prendre dans "Poste" Sage.
                GROUP BY 1,2
            ;

            INSERT INTO rh.t_qualifications(code_original, code, texte, texte_court)
                SELECT qualification, qualification, qualification, substr(qualification, 1, 50)
                FROM prod_sage.t_hst_affectation
                WHERE 1=1
                    AND qualification NOT IN (SELECT code_original FROM rh.t_qualifications)
                    AND (SELECT valeur = 'QUALIFICATION' FROM rh.t_divers WHERE code = 'SAGE_QUALIFICATION') -- Valeur à prendre dans "Qualification" de l'hist. des affectations Sage.
                    AND trim(qualification) != ''
                GROUP BY 1,2,3,4
            ;

            INSERT INTO rh.t_qualifications(code_original, code, texte, texte_court)
                select substr(md5(emploioccupe), 1, 5), substr(md5(emploioccupe), 1, 5), emploioccupe, emploioccupe 
                    from prod_sage.t_hst_affectation 
                    WHERE true
                        and substr(md5(emploioccupe), 1, 5) NOT IN (SELECT code_original FROM rh.t_qualifications)
                        and (SELECT valeur = 'EMPLOI' FROM rh.t_divers WHERE code = 'SAGE_QUALIFICATION') -- Valeur à prendre dans "Emploi" Sage.
                    GROUP BY 1,2,3,4
            ;

            -- Màj des rubriques
            INSERT INTO rh.t_rubriques(code, texte, texte_court, code_original, rang_edition)
                SELECT lpad(coderubrique, 5, '0'), intitule, substr(intitule,1,50), coderubrique, nodordre
                FROM prod_sage.t_rub
                WHERE coderubrique NOT IN (SELECT code_original FROM rh.t_rubriques)
                GROUP BY 1,2,3,4,5
            ;

            -- Màj des rubriques issues des constantes.
            INSERT INTO rh.t_rubriques(code_original, code, texte, texte_court, rang_edition)
                select codeconstante, codeconstante, intitule, substr(intitule, 1, 50), idcst
                from prod_sage.t_cst
                where true
                    and typeconstante = 6
                    and codeconstante NOT IN (SELECT code_original FROM rh.t_rubriques)
            ;

			-- comptes
			INSERT INTO rh.t_compte(code, texte, texte_court, code_original)
				SELECT COMPTE, MAX(INTITULE), MAX(INTITULEABREGE), COMPTE
				FROM prod_sage.T_CPG
				WHERE 1=1
					AND COMPTE BETWEEN '6' AND '79999999'
					AND COMPTE NOT IN (SELECT code_original FROM rh.t_compte WHERE code_original IS NOT NULL)
				GROUP BY 1
			;

			-- Màj des situations de famille
			INSERT INTO rh.t_situations_famille(code, texte, texte_court, code_original)
				SELECT situationfamille, situationfamille, substr(situationfamille,1,50), situationfamille
				FROM prod_sage.t_hst_famille
				WHERE 1=1
					AND situationfamille NOT IN (SELECT code_original FROM rh.t_situations_famille)
					AND InfoEnCours = 1
					AND situationfamille IS NOT NULL
				GROUP BY 1,2,3,4
			;

            -- Màj des libellés en dur (c'est comme ça avec Sage).
            UPDATE rh.t_situations_famille SET
                texte = CASE code_original
                            WHEN 0 THEN 'Célibataire'
                            WHEN 1 THEN 'Marié(e)'
                            WHEN 2 THEN 'Veuf(ve)'
                            WHEN 3 THEN 'Divorcé(e)'
                            WHEN 4 THEN 'Séparé(e)'
                            WHEN 5 THEN 'Vie maritale'
                            WHEN 6 THEN 'Bénéficiaire du PACS'
                            WHEN 7 THEN 'Non connue'
                            WHEN 8 THEN 'Non applicable'
                            ELSE code_original
                        END
            WHERE 1=1
                AND texte = code_original -- uniquement pour les textes inchangés.
                AND oid != 0
            ;

            UPDATE rh.t_situations_famille SET
                texte_court = texte
            WHERE 1=1
                AND texte_court = code_original -- uniquement pour les textes courts inchangés.
                AND oid != 0
            ;

			-- Màj des types de contrat
			INSERT INTO rh.t_types_contrat(code, texte, texte_court, code_original)
				SELECT code, intitule, substr(intitule,1,50), code
				FROM prod_sage.t_naturedecontrat
				WHERE code NOT IN (SELECT code_original FROM rh.t_types_contrat)
				GROUP BY 1,2,3,4
			;

			-- Màj des statuts
			INSERT INTO rh.t_statuts(code_original, code, texte, texte_court)
				SELECT code, code, intitule, substr(intitule, 1, 50)
				FROM prod_sage.t_categorie
				WHERE 1=1
					AND code NOT IN (SELECT code_original FROM rh.t_statuts)
					AND (SELECT valeur = 'CATEGORIE' FROM rh.t_divers WHERE code = 'SAGE_STATUT') -- Valeur à prendre dans "Catégorie" Sage.
				GROUP BY 1,2,3,4
			;

			INSERT INTO rh.t_statuts(code_original, code, texte, texte_court)
				select
					niveau, niveau, niveau, niveau
				from prod_sage.t_hst_affectation
				where 1=1
					AND niveau != ''
					AND niveau NOT IN (SELECT code_original FROM rh.t_statuts)
					AND (SELECT valeur = 'NIVEAU' FROM rh.t_divers WHERE code = 'SAGE_STATUT') -- Valeur à prendre dans "Niveau" Sage.
				group by 1,2,3,4 
			;

            INSERT INTO rh.t_statuts(code_original, code, texte, texte_court)
				select
					indice, indice, indice, indice
				from prod_sage.t_hst_affectation
				where 1=1
					AND indice != ''
					AND indice NOT IN (SELECT code_original FROM rh.t_statuts)
					AND (SELECT valeur = 'INDICE' FROM rh.t_divers WHERE code = 'SAGE_STATUT') -- Valeur à prendre dans "Indice" Sage.
				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 valeurcumul = 1 then 'TC' else 'TP'||(VALEURCUMUL * 100)::int::text end,
    					case when valeurcumul = 1 then 'TC' else 'TP'||(VALEURCUMUL * 100)::int::text end,
    					case when valeurcumul = 1 then 'Temps Complet' else 'Temps Partiel '||(VALEURCUMUL * 100)::int::text|| ' %' end,
    					case when valeurcumul = 1 then 'TC' else 'TP '||(VALEURCUMUL * 100)::int::text|| ' %' end
    				FROM prod_sage.T_HCUM
    				WHERE ENTITE = 68 AND (case when valeurcumul = 1 then 'TC' else 'TP'||(VALEURCUMUL * 100)::int::text end) NOT IN (SELECT code_original FROM rh.t_types_temps_travail)
    				GROUP BY 1,2,3,4
                UNION
                    SELECT 
                        case when round(valeurcumul::numeric, 2) = 151.67 then 'TC' else 'TP'||(round(valeurcumul::numeric, 2) / 151.67 * 100)::int::text end,
                        case when round(valeurcumul::numeric, 2) = 151.67 then 'TC' else 'TP'||(round(valeurcumul::numeric, 2) / 151.67 * 100)::int::text end,
                        case when round(valeurcumul::numeric, 2) = 151.67 then 'Temps Complet' else 'Temps Partiel '||(round(valeurcumul::numeric, 2) / 151.67 * 100)::int::text|| ' %' end,
                        case when round(valeurcumul::numeric, 2) = 151.67 then 'TC' else 'TP '||(round(valeurcumul::numeric, 2) / 151.67 * 100)::int::text|| ' %' end
                    FROM prod_sage.T_HCUM
                    WHERE ENTITE = 81 AND (case when round(valeurcumul::numeric, 2) = 151.67 then 'TC' else 'TP'||(round(valeurcumul::numeric, 2) / 151.67 * 100)::int::text end) NOT IN (SELECT code_original FROM rh.t_types_temps_travail)
                    GROUP BY 1,2,3,4
				order by 1 desc
			;

			-- Màj des services
			INSERT INTO rh.t_services(code_original, code, texte, texte_court)
				SELECT code, code, intitule, substr(intitule,1,50)
				FROM prod_sage.t_service
				WHERE 1=1
                    AND code NOT IN (SELECT code_original FROM rh.t_services)
                    AND (SELECT valeur = 'SERVICE' FROM rh.t_divers WHERE code = 'SAGE_SERVICE') -- Valeur à prendre dans "Département" Sage.
				GROUP BY 1,2,3,4
			;

            INSERT INTO rh.t_services(code_original, code, texte, texte_court)
                SELECT code, code, MAX(intitule), MAX(substr(intitule,1,50))
                FROM prod_sage.t_departement
                WHERE 1=1
                    AND code NOT IN (SELECT code_original FROM rh.t_services)
                    AND (SELECT valeur = 'DEPARTEMENT' FROM rh.t_divers WHERE code = 'SAGE_SERVICE') -- Valeur à prendre dans "Département" Sage.
                GROUP BY 1,2
            ;

            INSERT INTO rh.t_services(code_original, code, texte, texte_court)
                SELECT code, code, MAX(intitule), MAX(substr(intitule,1,50))
                FROM prod_sage.t_unite
                WHERE 1=1
                    AND code NOT IN (SELECT code_original FROM rh.t_services)
                    AND (SELECT valeur = 'UNITE' FROM rh.t_divers WHERE code = 'SAGE_SERVICE') -- Valeur à prendre dans "Département" Sage.
                GROUP BY 1,2
            ;

			-- Màj des spécialités
			INSERT INTO rh.t_specialites(code_original, code, texte, texte_court)
				SELECT code, code, MAX(intitule), MAX(substr(intitule,1,50))
				FROM prod_sage.t_departement
				WHERE code NOT IN (SELECT code_original FROM rh.t_specialites)
				GROUP BY 1,2
			;

			-- Codes emplois (2/2)
			-- #CODE_EMPLOI Etant donné que seul le libellé des emplois est archivé et non le code, et que l'on peut modifier à la main le texte historisé,
			-- on crée un code fictif pour les libellés qui ne sont pas déjà dans t_fonctionentreprise.
			-- Un peu plus loin, on essaie de faire l'association avec le code, et ensuite le libellé.
			INSERT INTO rh.t_codes_emploi(code_original, code, texte, texte_court)
    				select substr(md5(emploioccupe), 1, 5), substr(md5(emploioccupe), 1, 5), emploioccupe, emploioccupe 
    				from prod_sage.t_hst_affectation 
    				WHERE true
    					and substr(md5(emploioccupe), 1, 5) NOT IN (SELECT code_original FROM rh.t_codes_emploi)
    					and emploioccupe NOT IN (SELECT texte FROM rh.t_codes_emploi)
                        and (SELECT valeur = 'EMPLOI' FROM rh.t_divers WHERE code = 'SAGE_EMPLOI') -- Valeur à prendre dans "Emploi" Sage.
    				GROUP BY 1,2,3,4
                UNION ALL
                    SELECT qualification, qualification, qualification, substr(qualification, 1, 50)
                    FROM prod_sage.t_hst_affectation
                    WHERE 1=1
                        AND qualification NOT IN (SELECT code_original FROM rh.t_codes_emploi)
                        AND (SELECT valeur = 'QUALIFICATION' FROM rh.t_divers WHERE code = 'SAGE_EMPLOI') -- Valeur à prendre dans "Qualification" de l'hist. des affectations Sage.
                        AND trim(qualification) != ''
                    GROUP BY 1,2,3,4
                UNION ALL
                    SELECT code, code, max(intitule), max(substr(intitule, 1, 50))
                    FROM prod_sage.t_postes
                    WHERE 1=1
                        AND code NOT IN (SELECT code_original FROM rh.t_codes_emploi)
                        AND (SELECT valeur = 'POSTE' FROM rh.t_divers WHERE code = 'SAGE_EMPLOI') -- Valeur à prendre dans "Poste" Sage.
                    GROUP BY 1,2
			;

			-- Màj des types d'horaire
			INSERT INTO rh.t_types_horaire(code_original, code, texte, texte_court)
				SELECT
                    to_char(round(valeurcumul::numeric, 3), '000.000'),
                    to_char(round(valeurcumul::numeric,3 ), '000.000'),
            		regexp_replace(round(valeurcumul::numeric, 3), '0+$', ''),
                    regexp_replace(round(valeurcumul::numeric, 3), '0+$', '')
				FROM prod_sage.t_hcum
				WHERE true
					AND entite = 81
                    AND to_char(round(valeurcumul::numeric, 3), '000.000') NOT IN (SELECT code_original FROM rh.t_types_horaire)
					AND (SELECT valeur = 'VALEURCUMUL_81' FROM rh.t_divers WHERE code = 'SAGE_TYPE_HORAIRE') -- Valeur à prendre dans "VALEURCUMUL_81" Sage.
				GROUP BY 1,2,3,4
			;

			INSERT INTO rh.t_types_horaire(code_original, code, texte, texte_court)
				SELECT
					code,
					code,
                    intitule,
					substr(intitule, 1, 50)
				FROM prod_sage.t_unite
				WHERE true
					AND code NOT IN (SELECT code_original FROM rh.t_types_horaire)
					AND (SELECT valeur = 'UNITE' FROM rh.t_divers WHERE code = 'SAGE_TYPE_HORAIRE') -- Valeur à prendre dans "Unité" Sage.
				GROUP BY 1,2,3,4
			;

			UPDATE rh.t_types_horaire
			SET code = LEFT(code, LENGTH(code) - 1)
			where 1=1
				and RIGHT(code,1) = '.'
			;

			UPDATE rh.t_types_horaire
			set
				texte = replace(texte,'.','h'),
				texte_court = replace(texte_court,'.','h')
			;

			-- @TODO Màj des sociétés d'interim

			-- Màj des grilles
			INSERT INTO rh.t_grilles(code, texte, texte_court, code_original)
				SELECT code, intitule, substr(intitule, 1, 50), code
				FROM prod_sage.t_unite
				WHERE 1=1
                    AND code NOT IN (SELECT code_original FROM rh.t_grilles)
                    AND (SELECT valeur = 'UNITE' FROM rh.t_divers WHERE code = 'SAGE_GRILLE')
				GROUP BY 1,2,3,4
			;

            INSERT INTO rh.t_grilles(code_original, code, texte, texte_court)
                SELECT coefficient, coefficient, coefficient, substr(coefficient, 1, 50)
                FROM prod_sage.t_hst_affectation
                WHERE 1=1
                    AND coefficient NOT IN (SELECT code_original FROM rh.t_grilles)
                    AND (SELECT valeur = 'COEFFICIENT' FROM rh.t_divers WHERE code = 'SAGE_GRILLE')
                    AND trim(coefficient) != ''
                GROUP BY 1,2,3,4
            ;

			-- Màj des groupes de grilles
            INSERT INTO rh.t_grilles_groupes(code_original, code, texte, texte_court)
                select substr(md5(emploioccupe), 1, 5), substr(md5(emploioccupe), 1, 5), emploioccupe, emploioccupe 
                from prod_sage.t_hst_affectation 
                WHERE true
                    and substr(md5(emploioccupe), 1, 5) NOT IN (SELECT code_original FROM rh.t_grilles_groupes)
                    and emploioccupe NOT IN (SELECT texte FROM rh.t_grilles_groupes)
                GROUP BY 1,2,3,4
            ;

			-- Màj des motifs d'arret
			INSERT INTO rh.t_motifs_arret(code_original, code, texte, texte_court)
				SELECT code, code, intitule, substr(intitule, 1, 50)
				FROM prod_sage.t_motifdabsence
				WHERE code NOT IN (SELECT code_original FROM rh.t_motifs_arret)
				GROUP BY 1,2,3,4
			;

			-- @TODO Màj des précisions du motif d'arrêt

			-- @TODO Màj des motifs de visite médicale

			-- @TODO Màj des circonstances d'accident du travail

			-- @TODO Màj des lieux d'accident du travail

			-- @TODO Màj de la nature de l'accident du travail

			-- @TODO Màj des sièges d'accident du travail

			-- Màj des listes de formations
			INSERT INTO rh.t_liste_formations(code_original, code, texte, texte_court)
				SELECT codeformation, codeformation, intitule, substr(intitule,1,50)
				FROM prod_sage.t_formation
				WHERE codeformation NOT IN (SELECT code_original FROM rh.t_liste_formations)
				GROUP BY 1,2,3,4
			;

			-- Sections analytiques niveau 1

			]]></sqlcmd>
		</NODE>
        <NODE label="Paramétrage des rubriques">
            <condition><![CDATA[
                
            -- Historique de paie paramétré.
            select valeur = 1
            from rh.t_divers
            where code = 'OPT_STD_HP'
            ;

            ]]></condition>
            <sqlcmd><![CDATA[

            -- Pré-paramétrage automatique des rubriques (au mieux).
            -- Cette requête n'intervient pas sur les rubriques paramétrées à la main.
            -- s_* (source_) :
            --   - 0 = nombre
            --   - 1 = base
            --   - 2 = taux salarial
            --   - 3 = montant salarial
            --   - 4 = taux patronal
            --   - 5 = montant patronal
            --   - 6 = montant salarial + montant patronal
            update rh.t_rubriques
            set
                p_detail = subqq.p_detail,
                p_nombre = subqq.p_nombre,
                s_nombre = 0,
                c_nombre = 1,
                p_base = subqq.p_base,
                s_base = 1,
                c_base = 1,
                p_heures_contrat = subqq.p_heures_contrat,
                s_heures_contrat = 0,
                c_heures_contrat = 1,
                p_heures_payees = subqq.p_heures_payees,
                s_heures_payees = 0,
                c_heures_payees = 1,
                p_heures_travaillees = subqq.p_heures_travaillees,
                s_heures_travaillees = 0,
                c_heures_travaillees = 1,
                p_masse_salariale = subqq.p_masse_salariale,
                s_masse_salariale = case when subqq.p_cotisation_patronale or subqq.p_od_net_patronale then 5 else 3 end,
                c_masse_salariale = 1,
                p_brut = subqq.p_brut,
                s_brut = 3,
                c_brut = 1,
                p_avantage_nature = subqq.p_avantage_nature,
                s_avantage_nature = 3,
                c_avantage_nature = 1,
                p_frais_imposables = subqq.p_frais_imposables,
                s_frais_imposables = 3,
                c_frais_imposables = 1,
                p_cotisation_salarie = subqq.p_cotisation_salarie,
                s_cotisation_salarie = 3,
                c_cotisation_salarie = 1,
                p_cotisation_patronale = subqq.p_cotisation_patronale,
                s_cotisation_patronale = 5,
                c_cotisation_patronale = 1,
                p_od_net_salarie = subqq.p_od_net_salarie,
                s_od_net_salarie = 3,
                c_od_net_salarie = 1,
                p_od_net_patronale = subqq.p_od_net_patronale,
                s_od_net_patronale = 5,
                c_od_net_patronale = 1,
                p_net_imposable = subqq.p_net_imposable,
                s_net_imposable = 3,
                c_net_imposable = 1,
                p_net_a_payer = subqq.p_net_a_payer,
                s_net_a_payer = 3,
                c_net_a_payer = 1
            from (
                select
                    coderubrique,
                    true AS p_detail,
                    bool_or(brut) AS p_nombre,
                    bool_or(brut) or bool_or(odns) or bool_or(odnp) or bool_or(cosd) or bool_or(copa) AS p_base,
                    false AS p_heures_contrat,
                    false AS p_heures_payees,
                    false AS p_heures_travaillees,
                    bool_or(brut) or bool_or(odnp) or bool_or(copa) AS p_masse_salariale,
                    bool_or(brut) AS p_brut,
                    false AS p_avantage_nature,
                    false AS p_frais_imposables,
                    bool_or(cosd) AS p_cotisation_salarie,
                    bool_or(copa) AS p_cotisation_patronale,
                    bool_or(odns) AS p_od_net_salarie,
                    false AS p_od_net_patronale,
                    bool_or(brut) or bool_or(cosd) AS p_net_imposable,
                    bool_or(brut) or bool_or(cosd) or bool_or(odns) AS p_net_a_payer
                from (
                    select
                        t_rub.coderubrique,
                        CASE WHEN 1!=1
                                OR t_rub.dasavnat = 1
                                OR t_rub.coderubrique >= 79900
                            THEN false
                            ELSE t_hbns.coderubrique is not null
                        END as brut,
                        CASE WHEN 1=1
                                AND t_rub.coderubrique > 19990
                                AND t_rub.dasavnat != 1
                                and t_hbns.coderubrique is not null
                            THEN true
                            ELSE false
                        END as odns,
                        false as odnp,
                        false as cosd,
                        false as copa
                    from prod_sage.t_rub
                        left join prod_sage.t_hbns on t_hbns.coderubrique = t_rub.coderubrique
                    where 1=1
                        and t_rub.imprimable NOT IN (1, 3)
                        AND t_hbns.valeurmontant != 0 
                    group by 1,2,3
                UNION
                    select
                        t_rub.coderubrique,
                        CASE WHEN 1!=1
                                OR t_rub.dasavnat = 1
                                OR t_rub.coderubrique >= 79900
                            THEN false
                            ELSE T_BNSSAL.coderubrique is not null
                        END as brut,
                        CASE WHEN 1=1
                                AND t_rub.coderubrique > 19990
                                AND t_rub.dasavnat != 1
                                and T_BNSSAL.coderubrique is not null
                            THEN true
                            ELSE false
                        END as odns,
                        false as odnp,
                        false as cosd,
                        false as copa
                    from prod_sage.t_rub
                        left join prod_sage.t_bnssal on t_bnssal.coderubrique = t_rub.coderubrique
                    where 1=1
                        and t_rub.imprimable NOT IN (1, 3)
                        AND t_bnssal.valeurmontantsalarial != 0 
                    group by 1,2,3
                UNION
                    select
                        t_rub.coderubrique,
                        false as brut,
                        false as odns,
                        false as odnp,
                        true as cosd,
                        true as copa
                    FROM prod_sage.t_hcot
                        JOIN prod_sage.t_rub ON t_rub.coderubrique = t_hcot.coderubrique
                    WHERE 1=1
                        AND t_rub.imprimable != 1
                        and (false
                            or t_hcot.valeursmontantsalarial != 0
                            OR t_hcot.valeursmontantpatronal != 0)
                    group by 1,2,3
                UNION
                    select
                        t_rub.coderubrique,
                        false as brut,
                        false as odns,
                        false as odnp,
                        true as cosd,
                        true as copa
                    FROM prod_sage.T_COTSAL
                        JOIN prod_sage.t_rub ON t_rub.coderubrique = T_COTSAL.coderubrique
                    WHERE 1=1
                        AND t_rub.imprimable != 1
                        and (false
                            or t_cotsal.valeurmontantsal != 0
                            or t_cotsal.valeurmontantpatronal != 0)
                    group by 1,2,3
                ) as subq
                group by 1) as subqq
            where 1=1
                AND t_rubriques.code_original = subqq.coderubrique
                AND NOT t_rubriques.user_modified
            ;

            ]]></sqlcmd>
        </NODE>
	</NODE>
	<NODE name="PROD" label="RECUPERATION DES DONNEES DE PRODUCTION">
        <NODE label="Chiffrier - 1/3 (commun)">
            <sqlcmd><![CDATA[

            -- Periode de paie en cours
            DROP TABLE IF EXISTS w_periode
            ;

            CREATE TEMP TABLE w_periode AS
                SELECT
                    base.cti_last_monthday((anneeencours::text||lpad(moisencours, 2, '0')||'01')::date) as date_paie_encours,
                    (anneeencours * 100 + moisencours)::numeric as mois_paie_encours
                FROM prod_sage.t_pai
            ;

            TRUNCATE rh.p_chiffrier_production
            ;

           ]]></sqlcmd>
        </NODE>
        <NODE label="Chiffrier - 2/3 (mode classique)">
            <condition><![CDATA[
                
            -- Historique de paie classique.
            select valeur = 0
            from rh.t_divers
            where code = 'OPT_STD_HP'
            ;

            ]]></condition>
            <sqlcmd><![CDATA[

            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 numsalarie) as nombre_salaries,
                    sum(montant_brut),
                    sum(nombre_heures)
                FROM (
                    SELECT
                        COALESCE(t_entreprises.oid,0) AS entreprise_id,
                        0 as etablissement_id,
                        (date_part('year', t_hcum.datehist)::text||lpad(date_part('month', t_hcum.datehist), 2, '0'))::numeric as mois,
                        numsalarie,
                        sum(round((CASE WHEN ENTITE = 8 THEN VALEURCUMUL ELSE 0 END)::numeric,2))::numeric as montant_brut,
                        sum(round((CASE WHEN ENTITE = 84 THEN VALEURCUMUL ELSE 0 END)::numeric,2))::numeric as nombre_heures
                    FROM prod_sage.t_hcum
                        LEFT JOIN rh.t_entreprises ON t_entreprises.code_original IN (SELECT rhp_in('siren'))
                    WHERE 1=1
                        AND date_part('year', t_hcum.datehist) >= to_char(rhp('rhprovider_start')::date, 'YYYY')::int
                        AND date_part('year', t_hcum.datehist) <= date_part('year', now() + interval '5 years')
                    GROUP BY 1,2,3,4
                    HAVING sum(round((CASE WHEN entite IN (3, 4, 6, 7, 8, 84, 86) THEN valeurcumul ELSE 0 END)::numeric,2))::numeric != 0) as subq
                group by 1,2,3
            ;

            ]]></sqlcmd>
        </NODE>
		<NODE label="Chiffrier - 2/3 (mode paramétré)">
            <condition><![CDATA[
                
            -- Historique de paie paramétrée.
            select valeur = 1
            from rh.t_divers
            where code = 'OPT_STD_HP'
            ;

            ]]></condition>
			<sqlcmd><![CDATA[

			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 numsalarie) as nombre_salaries,
					sum(montant_brut),
					sum(nombre_heures)
				FROM (
					SELECT
						COALESCE(t_entreprises.oid,0) AS entreprise_id,
						0 as etablissement_id,
						(date_part('year', t_hcum.datehist)::text||lpad(date_part('month', t_hcum.datehist), 2, '0'))::numeric as mois,
						numsalarie,
						sum(round((CASE WHEN p_cumul AND p_brut THEN VALEURCUMUL ELSE 0 END)::numeric,2))::numeric as montant_brut,
						sum(round((CASE WHEN p_cumul AND p_heures_payees THEN VALEURCUMUL ELSE 0 END)::numeric,2))::numeric as nombre_heures
					FROM prod_sage.t_hcum
                        JOIN rh.t_rubriques ON t_rubriques.code_original = 'C'||lpad(entite, 3, '000')
						LEFT JOIN rh.t_entreprises ON t_entreprises.code_original IN (SELECT rhp_in('siren'))
					WHERE 1=1
						AND date_part('year', t_hcum.datehist) >= to_char(rhp('rhprovider_start')::date, 'YYYY')::int
						AND date_part('year', t_hcum.datehist) <= date_part('year', now() + interval '5 years')
					GROUP BY 1,2,3,4
					HAVING sum(round((CASE WHEN entite IN (3, 4, 6, 7, 8, 84, 86) THEN valeurcumul ELSE 0 END)::numeric,2))::numeric != 0) as subq
				group by 1,2,3
			;

			]]></sqlcmd>
		</NODE>
        <NODE label="Chiffrier - 3/3 (commun)">
            <sqlcmd><![CDATA[

            -- Ajout de la ligne chiffrier (production) à 0 pour le mois en cours si besoin.
            INSERT INTO rh.p_chiffrier_production (entreprise_id, etablissement_id, mois, nombre_salaries, montant_brut, nombre_heures)
                SELECT
                    entreprise_id,
                    etablissement_id,
                    mois_paie_encours,
                    0,0,0
                FROM w_periode, rh.p_chiffrier_production
                WHERE mois_paie_encours NOT IN (SELECT mois FROM rh.p_chiffrier_production GROUP BY 1)
                GROUP BY 1,2,3
            ;

            ]]></sqlcmd>
        </NODE>
		<NODE label="Pré-traitements">
			<sqlcmd><![CDATA[

            -- Pre-traitement de t_hst_contrat car il se peut que des dates de début soient > aux dates de fin.
            DROP TABLE IF EXISTS w_hst_contrat_0
            ;

            CREATE TEMP TABLE w_hst_contrat_0 AS
                SELECT *
                FROM prod_sage.t_hst_contrat
            ;

            UPDATE w_hst_contrat_0 SET
                datedebutcontrat = datefincontrat,
                datefincontrat = datedebutcontrat
            WHERE datedebutcontrat > datefincontrat
            ;

			-- Préparation contrats (pb chevauchement)
			DROP TABLE IF EXISTS w_hst_contrat
			;

			CREATE TEMP TABLE w_hst_contrat AS
				WITH hst_cnt as (
                    SELECT
                        -- nettoie l'historique (infoencours = 0) de manière séquentielle.
                        case when lead(datedebutcontrat) over w = datedebutcontrat then true else false end as to_ex1, -- date de début suivante identique à celle de la ligne actuelle
                        -- nettoie l'historique (infoencours = 0) par rapport à la ligne infoencours.
                        case when last_value(datedebutcontrat) over w <= datedebutcontrat and infoencours = 0 then true else false end as to_ex2, -- date infoencours <= date ligne actuelle
                        *
                    FROM w_hst_contrat_0
                    where 1=1
                        and datedebutcontrat is not null -- la date de début doit être renseignée.
                        and case when infoencours = 0 and datefincontrat is null then false else true end -- l'historique doit avoir des des dates de fin.
                    window w as (partition by numsalarie order by infoencours, datedebutcontrat, datehist rows between UNBOUNDED PRECEDING and UNBOUNDED following)),
                hst_soc as (
                    SELECT
                        -- nettoie l'historique (infoencours = 0) de manière séquentielle.
                        case when lead(datedepart) over w = datedepart then true else false end as to_ex1, -- date de début suivante identique à celle de la ligne actuelle
                        -- nettoie l'historique (infoencours = 0) par rapport à la ligne infoencours.
                        case when last_value(datedepart) over w <= datedepart and infoencours = 0 then true else false end as to_ex2, -- date infoencours <= date ligne actuelle
                        *
                    FROM prod_sage.t_hst_infossociete
                    where 1=1
                        and datedepart is not null -- la date de début doit être renseignée.
                        and case when infoencours = 0 and datedepart is null then false else true end -- l'historique doit avoir des des dates d'embauche.
                    window w as (partition by numsalarie order by infoencours, datedepart, datehist rows between UNBOUNDED PRECEDING and UNBOUNDED following))
                -- selection avec correction des dates de fin chevauchantes.
                select
                    rank() OVER (ORDER BY hst_cnt.numsalarie, hst_cnt.infoencours, datedebutcontrat, hst_cnt.datehist) as sequence,
                    hst_cnt.numsalarie::text||'-'::text||rank() OVER (PARTITION BY hst_cnt.numsalarie ORDER BY hst_cnt.infoencours, datedebutcontrat, hst_cnt.datehist) as cti_cnt,
                    datedebutcontrat::date as date_debut,
                    (case when lead(datedebutcontrat) over w <= datefincontrat then lead(datedebutcontrat) over w - '1 day'::interval else coalesce(datefincontrat, '2099-12-31'::date) end)::date as date_fin,
                    coalesce(hst_soc.codemotifdepart, chr(1) || '*') as soc_codemotifdepart,
                    hst_cnt.*
                from hst_cnt
                    left join hst_soc on 1=1
                        and hst_soc.numsalarie = hst_cnt.numsalarie
                        and hst_soc.datedepart = hst_cnt.datefincontrat
                        AND NOT hst_soc.to_ex1
                        AND NOT hst_soc.to_ex2
                where 1=1
                    AND NOT hst_cnt.to_ex1
                    AND NOT hst_cnt.to_ex2
                window w as (PARTITION BY hst_cnt.numsalarie ORDER BY hst_cnt.infoencours, datedebutcontrat, hst_cnt.datehist)
			;

            CREATE INDEX i_hst_contrat_numsalarie ON w_hst_contrat USING btree(numsalarie);
            CREATE INDEX i_hst_contrat_dates      ON w_hst_contrat USING btree(date_debut, date_fin);

			-- Salaries
			DROP TABLE IF EXISTS w_sal_ets
			;

			CREATE TEMP TABLE w_sal_ets AS
				with hst_pre as (
                    select
                        numsalarie,
                        coalesce(dateentree, datedebut) as dateentree,
                        datehist,
                        codeetab,
                        datesortie,
                        infoencours
                    FROM prod_sage.t_hst_etablissement)
                , hst_corr as (
                    select
                        numsalarie,
                        coalesce(case when infoencours = 1 and dateentree is null then greatest(lag(datehist) over w, lag(dateentree) over w) + '1 day'::interval else dateentree end, '1900-01-01'::date) as dateentree,
                        datehist,
                        codeetab,
                        datesortie,
                        infoencours
                    FROM hst_pre
                    where not (infoencours = 0 and dateentree is null) -- On exclu les historiques (infoencours = 0) avec une dateentree nulle.
                    window w as (partition by numsalarie order by infoencours, dateentree, datehist rows between UNBOUNDED PRECEDING and UNBOUNDED following))
                , hst_ets as (
                    select
                        lead(dateentree) over w,
                        case when lead(dateentree) over w = dateentree then true else false end as to_ex1,
                        case when last_value(dateentree) over w <= dateentree and infoencours = 0 then true else false end as to_ex2
                        ,*
                    FROM hst_corr
                    where dateentree is not null
                    window w as (partition by numsalarie order by infoencours, dateentree, datehist rows between UNBOUNDED PRECEDING and UNBOUNDED following))
                select
                    rank() OVER (ORDER BY numsalarie, infoencours, dateentree, datehist) as sequence,
                    numsalarie::text||'-'::text||rank() OVER w as cti_ets,
                    case when rank() OVER w = 1
                        then '1900-01-01'::date
                        else dateentree::date
                        end as date_debut,
                    case when rank() OVER wd = 1 
                        then '2099-12-31'::date
                        else (case when lead(dateentree) over w <= coalesce(datesortie, '2099-12-31'::date) then lead(dateentree) over w - '1 day'::interval else coalesce(datesortie, '2099-12-31'::date) end)::date
                        end as date_fin,
                    min(dateentree::date) over wu as date_entree_ets,
                    max(coalesce(datesortie::date, '2099-12-31'::date)) over wu as date_sortie_ets,
                    *
                from hst_ets
                where 1=1
                    AND NOT to_ex1
                    AND NOT to_ex2
                window  w  as (PARTITION BY numsalarie ORDER BY infoencours, dateentree, datehist),
                        wd as (PARTITION BY numsalarie ORDER BY infoencours desc, dateentree desc, datehist desc),
                        wu as (PARTITION BY numsalarie)
			;

            CREATE INDEX i_sal_ets_numsalarie ON w_sal_ets USING btree(numsalarie);
            CREATE INDEX i_sal_ets_dates      ON w_sal_ets USING btree(date_debut, date_fin);

            -- Historique des affectations. On ne se base plus que sur la date de début.
            DROP TABLE IF EXISTS w_hst_aff
            ;

            CREATE TEMP TABLE w_hst_aff AS
                with hst_corr as (
                    select
                        coalesce(case when infoencours = 1 and datedebut is null then greatest(lag(datehist) over w, lag(datedebut) over w) + '1 day'::interval else datedebut end, '1900-01-01'::date) as datedebut,
                        numsalarie,
                        datehist,
                        infoencours,
                        departement,
                        service,
                        unite,
                        categorie,
                        emploioccupe,
                        qualification,
                        niveau,
                        coefficient,
                        indice
                    FROM prod_sage.t_hst_affectation
                    where true
                        and not (infoencours = 0 and datedebut is null) -- Mais on exclu les historiques (infoencours = 0) avec une datedebut nulle.
                    window w as (partition by numsalarie order by infoencours, datedebut, datehist rows between UNBOUNDED PRECEDING and UNBOUNDED following))
                , hst_aff as (
                    select
                        lead(datedebut) over w,
                        case when lead(datedebut) over w = datedebut then true else false end as to_ex1,
                        case when last_value(datedebut) over w <= datedebut and infoencours = 0 then true else false end as to_ex2
                        ,*
                    FROM hst_corr
                    window w as (partition by numsalarie order by infoencours, datedebut, datehist rows between UNBOUNDED PRECEDING and UNBOUNDED following))
                select
                    rank() OVER (ORDER BY numsalarie, infoencours, datedebut, datehist) as sequence,
                    numsalarie::text||'-'::text||rank() OVER w as cti_aff,
                    case when rank() OVER w = 1
                        then '1900-01-01'::date
                        else datedebut::date
                        end as date_debut,
                    case when rank() OVER wd = 1 
                        then '2099-12-31'::date
                        else lead(datedebut) over w - '1 day'::interval
                        end as date_fin,
                    *
                from hst_aff
                where 1=1
                    AND NOT to_ex1
                    AND NOT to_ex2
                window  w  as (PARTITION BY numsalarie ORDER BY infoencours, datedebut, datehist),
                        wd as (PARTITION BY numsalarie ORDER BY infoencours desc, datedebut desc, datehist desc),
                        wu as (PARTITION BY numsalarie)
            ;

            CREATE INDEX i_hst_aff_numsalarie ON w_hst_aff USING btree(numsalarie);
            CREATE INDEX i_hst_aff_dates      ON w_hst_aff USING btree(date_debut, date_fin);

            -- Historique des postes.
            DROP TABLE IF EXISTS w_hst_pst
            ;

            CREATE TEMP TABLE w_hst_pst AS
                with hst_corr as (
                    select
                        coalesce(case when infoencours = 1 and datedebut is null then greatest(lag(datehist) over w, lag(datedebut) over w) + '1 day'::interval else datedebut end, '1900-01-01'::date) as datedebut,
                        numsalarie,
                        datehist,
                        infoencours,
                        codeposte
                    FROM prod_sage.t_hst_poste
                    where true
                        and not (infoencours = 0 and datedebut is null) -- Mais on exclu les historiques (infoencours = 0) avec une datedebut nulle.
                        and trim(codeposte) is distinct from ''
                    window w as (partition by numsalarie order by infoencours, datehist, datedebut rows between UNBOUNDED PRECEDING and UNBOUNDED following))
                , hst_pst as (
                    select
                        lead(datedebut) over w,
                        case when lead(datedebut) over w = datedebut then true else false end as to_ex1,
                        case when last_value(datedebut) over w <= datedebut and infoencours = 0 then true else false end as to_ex2
                        ,*
                    FROM hst_corr
                    window w as (partition by numsalarie order by infoencours, datehist, datedebut rows between UNBOUNDED PRECEDING and UNBOUNDED following))
                select
                    rank() OVER (ORDER BY numsalarie, infoencours, datedebut, datehist) as sequence,
                    numsalarie::text||'-'::text||rank() OVER w as cti_pst,
                    case when rank() OVER w = 1
                        then '1900-01-01'::date
                        else datedebut::date
                        end as date_debut,
                    case when rank() OVER wd = 1 
                        then '2099-12-31'::date
                        else lead(datedebut) over w - '1 day'::interval
                        end as date_fin,
                    *
                from hst_pst
                where 1=1
                    AND NOT to_ex1
                    AND NOT to_ex2
                window  w  as (PARTITION BY numsalarie ORDER BY infoencours, datedebut, datehist),
                        wd as (PARTITION BY numsalarie ORDER BY infoencours desc, datedebut desc, datehist desc),
                        wu as (PARTITION BY numsalarie)
            ;

            CREATE INDEX i_hst_pst_numsalarie ON w_hst_pst USING btree(numsalarie);
            CREATE INDEX i_hst_pst_dates      ON w_hst_pst USING btree(date_debut, date_fin);


            -- Historique des affections au travers des bulletins.
            DROP TABLE IF EXISTS w_hst_affbul
            ;

            CREATE TEMP TABLE w_hst_affbul AS
                with temp_affbul as (
                    select
                        numsalarie,
                        datehist::date,
                        case when typedubulletin != 0 then base.cti_first_day(datehist::date) else datehist::date end as datehist_cti, -- Permet de revenir vers un cas standard de bulletin exceptionnel émi le 1er du mois.
                        debutpaiement::date,
                        finpaiement::date,
                        departement,
                        service,
                        unite,
                        categorie,
                        codeetab,
                        typedubulletin
                    from prod_sage.t_haff
                    where datehist != '2069-09-16'::date) -- TOUS les datehist à 2069-09-16 n'ont aucune données renseignées.
                select
                    numsalarie,
                    numsalarie::text||'-'::text||rank() OVER w AS cti_affbul,
                    datehist,
                    typedubulletin,
                    coalesce(lag(datehist_cti + 1) over w, base.cti_first_day(datehist_cti)) as date_debut,
                    datehist_cti as date_fin,
                    debutpaiement::date,
                    finpaiement::date,
                    departement,
                    service,
                    unite,
                    categorie,
                    codeetab
                from temp_affbul
                window w as (partition by numsalarie order by datehist_cti, typedubulletin)
            ;

            CREATE INDEX i_hst_affbul_numsalarie ON w_hst_affbul USING btree(numsalarie);
            CREATE INDEX i_hst_affbul_dates      ON w_hst_affbul USING btree(date_debut, date_fin);

            -- Historique des bulletins (basé sur l'historique des cumuls t_hcum + w_periode pour le mois en cours).
            DROP TABLE IF EXISTS w_hst_bul
            ;

            CREATE TEMP TABLE w_hst_bul AS
                with w_hcum as (
                        select
                            numsalarie,
                            datehist::date,
                            case when typedubulletin != 0 then base.cti_first_day(datehist::date) else datehist::date end as datehist_cti, -- Permet de revenir vers un cas standard de bulletin exceptionnel émi le 1er du mois.
                            typedubulletin,
                            max(case when codeconstante = 'ETP' then VALEURCUMUL else null end) as cumul_68,
                            max(case when codeconstante = 'HORAIRE' then VALEURCUMUL else null end) as cumul_81
                        from prod_sage.t_hcum
                            join prod_sage.t_cst on 1=1
                                AND typeconstante = 6
                                AND t_cst.CodeOperande1 = t_hcum.entite
                        where datehist != '2069-09-16'::date -- TOUS les datehist à 2069-09-16 n'ont aucune données renseignées.
                        group by 1,2,3,4
                    union
                        select
                            numsalarie,
                            date_paie_encours as datehist,
                            date_paie_encours as datehist_cti,
                            0 as typedubulletin,
                            null as cumul_68,
                            null as cumul_81
                        from prod_sage.t_bnssal
                            join w_periode on true
                        where t_bnssal.valeurmontantsalarial != 0 -- repris depuis l'historique de la paie.
                        group by 1,2,3,4
                    union
                        select
                            numsalarie,
                            date_paie_encours as datehist,
                            date_paie_encours as datehist_cti,
                            0 as typedubulletin,
                            null as cumul_68,
                            null as cumul_81
                        FROM prod_sage.t_cotsal
                            join w_periode on true
                        WHERE false
                            OR t_cotsal.valeurmontantsal != 0
                            or t_cotsal.valeurmontantpatronal != 0
                        group by 1,2,3,4)
                , w_hcum2 as (
                    select 
                        numsalarie,
                        numsalarie::text||'-'::text||rank() OVER w AS cti_bul,
                        coalesce(cumul_68, -- si la valeur est renseignée sur la ligne courante, on la prend.
                            (max(case when cumul_68 is null then null else ARRAY[extract(epoch from datehist_cti)::numeric, cumul_68] end) over wb)[2], -- sinon on prend la valeur renseignée la plus proche dans le passé
                            (min(case when cumul_68 is null then null else ARRAY[extract(epoch from datehist_cti)::numeric, cumul_68] end) over wf)[2], -- sinon on prend la valeur renseignée la plus proche dans le futur
                            null -- sinon on prend null
                        ) as cumul_68,
                        coalesce(cumul_81, -- si la valeur est renseignée sur la ligne courante, on la prend.
                            (max(case when cumul_81 is null then null else ARRAY[extract(epoch from datehist_cti)::numeric, cumul_81] end) over wb)[2], -- sinon on prend la valeur renseignée la plus proche dans le passé
                            (min(case when cumul_81 is null then null else ARRAY[extract(epoch from datehist_cti)::numeric, cumul_81] end) over wf)[2], -- sinon on prend la valeur renseignée la plus proche dans le futur
                            null -- sinon on prend null
                        ) as cumul_81,
                        datehist,
                        datehist_cti,
                        typedubulletin,
                        coalesce(lag(datehist_cti + 1) over w, base.cti_first_day(datehist_cti)) as date_debut,
                        datehist_cti as date_fin
                    from w_hcum
                    window w as (partition by numsalarie order by datehist_cti, typedubulletin),
                        wb as (PARTITION BY numsalarie ORDER BY datehist_cti, typedubulletin rows unbounded preceding), -- sélectionne les lignes précédentes
                        wf as (PARTITION BY numsalarie ORDER BY datehist_cti, typedubulletin rows between current row and unbounded following)) -- sélectionne les lignes suivantes
                select
                    numsalarie,
                    cti_bul,
                    cumul_68,
                    cumul_81,
                    coalesce(
                        CASE 
                            WHEN sage_temps_travail.valeur = 'ETP' THEN cumul_68 -- Pour calculer un ETP contrat théorique, on prend la valeur ETP si non nulle...
                            WHEN sage_temps_travail.valeur = 'HORAIRE' THEN case when round(cumul_81::numeric, 2) = 151.67 then 1.0 else round(cumul_81::numeric, 2) / 151.67 end
                        END,
                        CASE 
                            WHEN sage_temps_travail.valeur = 'HORAIRE' THEN case when round(cumul_81::numeric, 2) = 151.67 then 1.0 else round(cumul_81::numeric, 2) / 151.67 end
                            WHEN sage_temps_travail.valeur = 'ETP' THEN cumul_68 -- ... sinon on prend le nombre d'heures contrat...
                        END,
                        1.0) as etp_contrat, -- ... sinon on met 1 par défaut.
                    datehist,
                    datehist_cti,
                    typedubulletin,
                    date_debut,
                    date_fin
                from w_hcum2
                    join (SELECT valeur FROM rh.t_divers WHERE code = 'SAGE_TEMPS_TRAVAIL') as sage_temps_travail on true
            ;

            CREATE INDEX i_hst_bul_numsalarie ON w_hst_bul USING btree(numsalarie);
            CREATE INDEX i_hst_bul_dates      ON w_hst_bul USING btree(date_debut, date_fin);

            -- Historique codes insee
            DROP TABLE IF EXISTS w_hst_insee
            ;

            CREATE TEMP TABLE w_hst_insee AS
                with hst_insee as (
                    select
                        lead(datedebut) over w,
                        case when lead(datedebut) over w = datedebut then true else false end as to_ex1,
                        case when last_value(datedebut) over w <= datedebut and infoencours = 0 then true else false end as to_ex2
                        ,*
                    FROM prod_sage.t_hst_dadsu
                    WHERE case when infoencours = 0 and datedebut is null then false else true end -- on exclu de facto les datedebut null pour les infos pas en cours.
                    window w as (partition by numsalarie order by infoencours, datedebut, datehist rows between UNBOUNDED PRECEDING and UNBOUNDED following))
                select
                    rank() OVER (ORDER BY numsalarie, infoencours, datedebut, datehist) as sequence,
                    numsalarie::text||'-'::text||rank() OVER w as cti_insee,
                    numsalarie,
                    coalesce(lag(datedebut::date + 1) over w, '0001-01-01'::date) as date_debut,
                    coalesce(datedebut::date, '2099-12-31'::date) as date_fin,
                    coalesce(nullif(codeinsee, ''), -- si la valeur est renseignée sur la ligne courante, on la prend.
                        (max(ARRAY[case when codeinsee = '' then null else coalesce(datedebut::date, '2099-12-31'::date)::text end, nullif(codeinsee, '')::text]) over wb)[2], -- sinon on prend la valeur renseignée la plus proche dans le passé
                        (min(ARRAY[case when codeinsee = '' then null else coalesce(datedebut::date, '2099-12-31'::date)::text end, nullif(codeinsee, '')::text]) over wf)[2], -- sinon on prend la valeur renseignée la plus proche dans le futur
                        null -- sinon on prend null
                    ) as codeinsee
                from hst_insee
                where 1=1
                    AND NOT to_ex1
                    AND NOT to_ex2
                window w as (PARTITION BY numsalarie ORDER BY infoencours, datedebut, datehist),
                wb as (PARTITION BY numsalarie ORDER BY infoencours, datedebut, datehist rows unbounded preceding), -- sélectionne les lignes précédentes
                wf as (PARTITION BY numsalarie ORDER BY infoencours, datedebut, datehist rows between current row and unbounded following) -- sélectionne les lignes suivantes
            ;

            CREATE INDEX i_hst_insee_numsalarie ON w_hst_insee USING btree(numsalarie);
            CREATE INDEX i_hst_insee_dates      ON w_hst_insee USING btree(date_debut, date_fin);

            -- Identification des dates limites pour chaque salariés (pour des raisons de performances).
            -- Basé sur les contrats et les bulletins (historique des cumuls t_hcum).
            DROP TABLE IF EXISTS w_lim_sal
            ;

            CREATE TEMP TABLE w_lim_sal AS
                select
                    numsalarie,
                    matriculesalarie as matricule,
                    min(date_debut) as date_debut,
                    max(date_fin) as date_fin
                from (
                        select
                            numsalarie,
                            min(date_debut) as date_debut,
                            coalesce(nullif(max(date_fin), '2099-12-31'::date), max(date_paie_encours)) as date_fin -- 2099-12-31 correspond à "contrat en cours" => on met le mois de paie en cours (et surtout pas current_date).
                        from w_hst_contrat, w_periode
                        group by 1
                    UNION ALL
                        select
                            numsalarie,
                            min(date_debut) as date_debut,
                            max(date_fin) as date_fin
                        from w_hst_bul
                        group by 1
                    ) as subq
                    join prod_sage.t_sal on t_sal.sa_compteurnumero = subq.numsalarie
                group by 1,2
            ;

            CREATE INDEX i_lim_sal_numsalarie ON w_lim_sal USING btree(numsalarie);
            CREATE INDEX i_lim_sal_dates      ON w_lim_sal USING btree(date_debut, date_fin);

            DROP TABLE IF EXISTS w_evt_mois
            ;

            CREATE TEMP TABLE w_evt_mois AS
                with raw_data as(
                    select
                        w_lim_sal.numsalarie,
                        w_lim_sal.matricule,
                        cti_cnt, -- contrat
                        cti_ets, -- ets.
                        cti_aff, -- affectations
                        cti_pst, -- postes
                        cti_affbul, -- affectations bulletins
                        cti_bul, -- bulletins
                        cti_insee, -- insee
                        p_calendrier.date
                    from base.p_calendrier
                        join w_lim_sal on p_calendrier.date between w_lim_sal.date_debut and w_lim_sal.date_fin
                        left join w_hst_contrat on 1=1
                            and w_hst_contrat.numsalarie = w_lim_sal.numsalarie
                            and p_calendrier.date between w_hst_contrat.date_debut and w_hst_contrat.date_fin
                        left join w_sal_ets on 1=1
                            and w_sal_ets.numsalarie = w_lim_sal.numsalarie
                            and p_calendrier.date between w_sal_ets.date_debut and w_sal_ets.date_fin
                        left join w_hst_insee on 1=1
                            and w_hst_insee.numsalarie = w_lim_sal.numsalarie
                            and p_calendrier.date between w_hst_insee.date_debut and w_hst_insee.date_fin
                        left join w_hst_aff on 1=1
                            and w_hst_aff.numsalarie = w_lim_sal.numsalarie
                            and p_calendrier.date between w_hst_aff.date_debut and w_hst_aff.date_fin
                        left join w_hst_pst on 1=1
                            and w_hst_pst.numsalarie = w_lim_sal.numsalarie
                            and p_calendrier.date between w_hst_pst.date_debut and w_hst_pst.date_fin
                        left join w_hst_affbul on 1=1
                            and w_hst_affbul.numsalarie = w_lim_sal.numsalarie
                            and p_calendrier.date between w_hst_affbul.date_debut and w_hst_affbul.date_fin
                        left join w_hst_bul on 1=1
                            and w_hst_bul.numsalarie = w_lim_sal.numsalarie
                            and p_calendrier.date between w_hst_bul.date_debut and w_hst_bul.date_fin
                    where 1!=1
                        or cti_cnt is not null -- on ne conserve que les évenements ou il y a un contrat OU
                        or cti_bul is not null -- un bulletin
                    ),
                clustering as (
                    select
                        numsalarie,
                        matricule,
                        cti_cnt,
                        cti_ets,
                        cti_aff,
                        cti_pst,
                        cti_affbul,
                        cti_bul,
                        cti_insee,
                        date,
                        case when lag(coalesce(cti_cnt, '')||coalesce(cti_ets, '')||coalesce(cti_aff, '')||coalesce(cti_pst, '')||coalesce(cti_affbul, '')||coalesce(cti_bul, '')||coalesce(cti_insee, '')) over w
                            = coalesce(cti_cnt, '')||coalesce(cti_ets, '')||coalesce(cti_aff, '')||coalesce(cti_pst, '')||coalesce(cti_affbul, '')||coalesce(cti_bul, '')||coalesce(cti_insee, '') then null else true end as new_cluster
                    from raw_data
                    window w as (partition by numsalarie order by date)),
                assigned_clustering as (
                    select
                        numsalarie,
                        matricule,
                        cti_cnt,
                        cti_ets,
                        cti_aff,
                        cti_pst,
                        cti_affbul,
                        cti_bul,
                        cti_insee,
                        date,
                        to_char(date, 'YYYYMM')::int as mois,
                        count(new_cluster) over (order by numsalarie, date rows unbounded preceding) as cluster_id
                    from clustering)
                select
                    numsalarie,
                    matricule,
                    cti_cnt,
                    cti_ets,
                    cti_aff,
                    cti_pst,
                    cti_affbul,
                    cti_bul,
                    cti_insee,
                    mois, -- FIXME PAS SUR PAS SUR PAS SUR PAS SUR PAS SUR PAS SUR PAS SUR PAS SUR PAS SUR PAS SUR PAS SUR PAS SUR 
                    min(date) AS date_debut,
                    max(date) AS date_fin
                from assigned_clustering
                group by 1,2,3,4,5,6,7,8,9,10, cluster_id
            ;

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

            DROP TABLE IF EXISTS w_profils
            ;

            CREATE TEMP TABLE w_profils AS
                select
                    row_number() over () as row_id,
                    0 as profil_id,
                    0 as contrat_id,
                    0 as contrat_mois_id,
                    0 as salarie_id,
                    w_evt_mois.numsalarie,
                    w_evt_mois.matricule,
                    w_evt_mois.mois,
                    w_evt_mois.date_debut,
                    w_evt_mois.date_fin,
                    coalesce(w_hst_affbul.codeetab, w_sal_ets.codeetab) AS codeetab,
                    -- **** contrat ****
                    w_hst_contrat.cti_cnt,
                    coalesce(w_hst_contrat.cti_cnt, -- si la valeur est renseignée sur la ligne courante, on la prend.
                        (max(case when w_hst_contrat.cti_cnt is null then null else ARRAY[extract(epoch from w_evt_mois.date_debut)::text, w_hst_contrat.cti_cnt] end) over wb)[2], -- sinon on prend la valeur renseignée la plus proche dans le passé
                        (min(case when w_hst_contrat.cti_cnt is null then null else ARRAY[extract(epoch from w_evt_mois.date_debut)::text, w_hst_contrat.cti_cnt] end) over wf)[2], -- sinon on prend la valeur renseignée la plus proche dans le futur
                        null -- sinon on prend null. Ne devrait pas arriver.
                    ) as cti_cnt_all, -- cti_cnt mais renseigné avec les valeurs précédentes ou suivantes lorsque hors période de contrat. Utile pour p_contrats_mois.
                    w_hst_contrat.date_debut as cnt_date_debut,
                    w_hst_contrat.date_fin as cnt_date_fin,
                    -- **** ets. ****
                    w_sal_ets.cti_ets,
                    w_sal_ets.date_entree_ets,
                    w_sal_ets.date_sortie_ets,
                    -- **** affectations ****
                    w_hst_aff.cti_aff,
                    -- **** postes ****
                    w_hst_pst.cti_pst,
                    -- **** affectations bulletins ****
                    w_hst_affbul.cti_affbul,
                    w_hst_affbul.unite, -- utilisé plus tard UNIQUEMENT pour le modèle comptable.
                    w_hst_affbul.categorie, -- utilisé plus tard UNIQUEMENT pour le modèle comptable.
                    w_hst_affbul.debutpaiement as bul_date_debut,
                    w_hst_affbul.finpaiement as bul_date_fin,
                    -- **** bulletins ****
                    w_hst_bul.cti_bul,
                    --w_hst_bul.date_debut as bul_date_debut,
                    --w_hst_bul.date_fin as bul_date_fin,
                    w_hst_bul.cumul_68,
                    w_hst_bul.cumul_81,
                    w_hst_bul.etp_contrat,
                    coalesce(w_hst_affbul.typedubulletin, w_hst_bul.typedubulletin) as typedubulletin,
                    coalesce(w_hst_affbul.datehist, w_hst_bul.datehist) as datehist,
                    case when w_hst_contrat.cti_cnt is null then 1 else 0 end as est_hors_periode,
                    -- **** insee ****
                    w_hst_insee.cti_insee,
                    -- **** code original ****
                    chr(1)||'*' AS cadre_emploi_code_original, -- public
                    chr(1)||'*' AS categorie_conge_code_original, -- public
                    coalesce(lower(w_hst_insee.codeinsee), chr(1)||'*') AS categorie_socio_professionnelle_code_original,
                    chr(1)||'*' AS categorie_statutaire_code_original, -- public
                    (SELECT CASE 
                        WHEN valeur = 'QUALIFICATION' THEN coalesce(w_hst_aff.qualification, chr(1)||'*')
                        WHEN valeur = 'POSTE' THEN coalesce(w_hst_pst.codeposte, chr(1)||'*')
                        ELSE coalesce(substr(md5(w_hst_aff.emploioccupe), 1, 5), chr(1)||'*') END FROM rh.t_divers WHERE code = 'SAGE_EMPLOI') AS code_emploi_code_original,
                    chr(1)||'*' AS commission_paritaire_code_original, -- public
                    chr(1)||'*' AS compte_salarie_code_original, -- public
                    chr(1)||'*' AS filiere_code_original, -- public
                    (SELECT CASE 
                        WHEN valeur = 'UNITE' THEN coalesce(w_hst_aff.unite, w_hst_affbul.unite, chr(1)||'*')
                        ELSE coalesce(w_hst_aff.coefficient, chr(1)||'*') END FROM rh.t_divers WHERE code = 'SAGE_GRILLE') AS grille_code_original,
                    coalesce(substr(md5(w_hst_aff.emploioccupe), 1, 5), chr(1)||'*') AS grille_groupe_code_original,
                    chr(1)||'*' AS groupe_cotisant_code_original,
                    chr(1)||'*' AS lettre_budgetaire_code_original, -- public
                    -- Utile pour les bulletins émis en fin de mois et/ou hors période de contrat (car le motif de début de contrat n'est pas reporté dans l'historique des bulletins) :
                    coalesce(w_hst_contrat.codemotifdecontrat, -- si la valeur est renseignée sur la ligne courante, on la prend.
                        (max(case when w_hst_contrat.codemotifdecontrat is null then null else ARRAY[extract(epoch from w_evt_mois.date_debut)::text, w_hst_contrat.codemotifdecontrat] end) over wb)[2], -- sinon on prend la valeur renseignée la plus proche dans le passé
                        (min(case when w_hst_contrat.codemotifdecontrat is null then null else ARRAY[extract(epoch from w_evt_mois.date_debut)::text, w_hst_contrat.codemotifdecontrat] end) over wf)[2], -- sinon on prend la valeur renseignée la plus proche dans le futur
                        chr(1)||'*' -- sinon on prend N/R. Ne devrait pas arriver.
                    ) as motif_debut_code_original,
                    -- Utile pour les bulletins émis en fin de mois et/ou hors période de contrat (car le motif de fin de contrat n'est pas reporté dans l'historique des bulletins) :
                    coalesce(w_hst_contrat.soc_codemotifdepart, -- si la valeur est renseignée sur la ligne courante, on la prend.
                        (max(case when w_hst_contrat.soc_codemotifdepart is null then null else ARRAY[extract(epoch from w_evt_mois.date_debut)::text, w_hst_contrat.soc_codemotifdepart] end) over wb)[2], -- sinon on prend la valeur renseignée la plus proche dans le passé
                        (min(case when w_hst_contrat.soc_codemotifdepart is null then null else ARRAY[extract(epoch from w_evt_mois.date_debut)::text, w_hst_contrat.soc_codemotifdepart] end) over wf)[2], -- sinon on prend la valeur renseignée la plus proche dans le futur
                        chr(1)||'*' -- sinon on prend N/R. Ne devrait pas arriver.
                    ) as motif_fin_code_original,
                    (SELECT CASE 
                        WHEN valeur = 'UNITE' THEN coalesce(w_hst_aff.unite, w_hst_affbul.unite, chr(1)||'*')
                        WHEN valeur = 'DEPARTEMENT' THEN coalesce(w_hst_aff.departement, w_hst_affbul.departement, chr(1)||'*')
                        WHEN valeur = 'EMPLOI' THEN coalesce(substr(md5(w_hst_aff.emploioccupe), 1, 5), chr(1)||'*')
                        WHEN valeur = 'POSTE' THEN coalesce(w_hst_pst.codeposte, chr(1)||'*')
                        ELSE coalesce(w_hst_aff.qualification, chr(1)||'*') END FROM rh.t_divers WHERE code = 'SAGE_QUALIFICATION') AS qualification_code_original,
                    chr(1)||'*' AS section_analytique_code_original,
                    chr(1)||'*' AS section_analytique_paie_code_original,
                    (SELECT CASE 
                        WHEN valeur = 'DEPARTEMENT' THEN coalesce(w_hst_aff.departement, w_hst_affbul.departement, chr(1)||'*')
                        WHEN valeur = 'UNITE' THEN coalesce(w_hst_aff.unite, w_hst_affbul.unite, chr(1)||'*')
                        ELSE coalesce(w_hst_aff.service, w_hst_affbul.service, chr(1)||'*') END FROM rh.t_divers WHERE code = 'SAGE_SERVICE') AS service_code_original,
                    chr(1)||'*' AS societe_interim_code_original,
                    coalesce(w_hst_aff.departement, w_hst_affbul.departement, chr(1)||'*') AS specialite_code_original,
                    (SELECT CASE 
                        WHEN valeur = 'CATEGORIE' THEN coalesce(w_hst_aff.categorie, w_hst_affbul.categorie, chr(1)||'*')
                        WHEN valeur = 'INDICE' THEN coalesce(w_hst_aff.indice, chr(1)||'*') -- indice n'existe pas dans t_haff (= w_hst_affbul).
                        WHEN valeur = 'NIVEAU' THEN coalesce(w_hst_aff.niveau, chr(1)||'*') -- niveau n'existe pas dans t_haff (= w_hst_affbul).
                        ELSE coalesce(w_hst_aff.categorie, w_hst_affbul.categorie, chr(1)||'*') END FROM rh.t_divers WHERE code = 'SAGE_STATUT') AS statut_code_original,
                    -- Utile pour les bulletins émis en fin de mois et/ou hors période de contrat (car le type de contrat n'est pas reporté dans l'historique des bulletins) :
                    coalesce(w_hst_contrat.codenaturedecontrat, -- si la valeur est renseignée sur la ligne courante, on la prend.
                        (max(case when w_hst_contrat.codenaturedecontrat is null then null else ARRAY[extract(epoch from w_evt_mois.date_debut)::text, w_hst_contrat.codenaturedecontrat] end) over wb)[2], -- sinon on prend la valeur renseignée la plus proche dans le passé
                        (min(case when w_hst_contrat.codenaturedecontrat is null then null else ARRAY[extract(epoch from w_evt_mois.date_debut)::text, w_hst_contrat.codenaturedecontrat] end) over wf)[2], -- sinon on prend la valeur renseignée la plus proche dans le futur
                        chr(1)||'*' -- sinon on prend N/R. Ne devrait pas arriver.
                    ) as type_contrat_code_original,
                    (SELECT CASE WHEN valeur = 'VALEURCUMUL_81' THEN coalesce(to_char(round(w_hst_bul.cumul_81::numeric, 3), '000.000'), chr(1)||'*') ELSE coalesce(w_hst_aff.unite, w_hst_affbul.unite, chr(1)||'*') END FROM rh.t_divers WHERE code = 'SAGE_TYPE_HORAIRE') AS type_horaire_code_original,
                    coalesce(
                        case when w_hst_bul.etp_contrat = 1 then 'TC' else 'TP'||(w_hst_bul.etp_contrat * 100)::int::text end,
                        chr(1)||'*') AS type_temps_travail_code_original,
                    chr(1)||'*' AS unite_fonctionnelle_code_original -- public
                from w_evt_mois
                    left join w_hst_contrat on w_hst_contrat.cti_cnt = w_evt_mois.cti_cnt
                    left join w_sal_ets on w_sal_ets.cti_ets = w_evt_mois.cti_ets
                    left join w_hst_insee on w_hst_insee.cti_insee = w_evt_mois.cti_insee
                    left join w_hst_aff on w_hst_aff.cti_aff = w_evt_mois.cti_aff
                    left join w_hst_pst on w_hst_pst.cti_pst = w_evt_mois.cti_pst
                    left join w_hst_affbul on w_hst_affbul.cti_affbul = w_evt_mois.cti_affbul
                    left join w_hst_bul on w_hst_bul.cti_bul = w_evt_mois.cti_bul
                window wb as (PARTITION BY w_evt_mois.numsalarie ORDER BY w_evt_mois.date_debut rows unbounded preceding), -- sélectionne les lignes précédentes
                    wf as (PARTITION BY w_evt_mois.numsalarie ORDER BY w_evt_mois.date_debut rows between current row and unbounded following) -- sélectionne les lignes suivantes
            ;

            -- Suppression des données établissements non concernés.
            DELETE FROM w_profils
            WHERE w_profils.codeetab NOT IN (SELECT codeetab from w_ets)
            ;

			]]></sqlcmd>
		</NODE>
        <NODE name="PROFIL" type="common" />
		<NODE label="Salariés">
			<sqlcmd><![CDATA[

			DROP TABLE IF EXISTS w_salaries
			;

			CREATE TEMP TABLE w_salaries AS
				SELECT
					rhp('finess') AS finess,
					t_sal.nom AS nom,
                    t_sal.prenom AS prenom,
                    coalesce(t_hst_famille.datenaissance::date, '1900-01-01'::date) AS date_naissance,
                    CASE WHEN t_sal.civilite = 0
                        THEN 'M'
                        ELSE 'F'
                    END AS sexe,
                    w_profils.matricule AS matricule,
                    lower(coalesce(t_sal.numerodebadge, '')) AS matricule_planning,
                    w_profils.matricule AS code,
                    w_profils.matricule AS code_original,
                    coalesce((max(distinct array[extract(epoch from w_profils.date_fin), t_etablissements.entreprise_id]))[2], 0) AS entreprise_id,
                    coalesce(t_nationalites.oid,0) AS nationalite_id,
                    coalesce(t_codes_postaux.oid,0) AS code_postal_id,
                    t_sal.nomjeunefille AS nom_naissance,
                    coalesce(t_situations_famille.oid, 0) AS situation_famille_id,
		            t_sal.rue1 AS adresse1,
					t_sal.rue2 AS adresse2,
                    coalesce(t_hst_secu.nosecu||t_hst_secu.cle, identifiantepargne||cleidentifiantepargne) as nir,
                    (MAX(distinct array[w_profils.date_fin::text, profil_id::text]))[2]::bigint AS profil_id,
                    MIN(cnt_date_debut) AS date_debut, -- utilisé pour la partie "Dernier contrat" du détail salarié
                    MAX(cnt_date_fin) AS date_fin, -- utilisé pour la partie "Dernier contrat" du détail salarié
                    MIN(w_profils.date_entree_ets) as date_entree_ets,
                    MAX(w_profils.date_sortie_ets) 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 w_profils
                    JOIN prod_sage.t_sal ON w_profils.numsalarie = t_sal.sa_compteurnumero
                    LEFT JOIN prod_sage.t_hst_famille ON t_hst_famille.numsalarie = w_profils.numsalarie
                    LEFT JOIN prod_sage.t_hst_secu ON t_hst_secu.numsalarie = t_sal.sa_compteurnumero  and t_hst_secu.infoencours = 1
                    LEFT JOIN prod_sage.t_hst_nationalite ON t_hst_nationalite.numsalarie = w_profils.numsalarie
                    LEFT JOIN rh.t_codes_postaux ON t_codes_postaux.code = t_sal.codepostal
                    LEFT JOIN prod_sage.t_eta ON t_eta.codeetab = w_profils.codeetab
                    LEFT JOIN rh.t_etablissements ON t_etablissements.code_original = t_eta.siren||t_eta.nic
                    LEFT JOIN rh.t_situations_famille ON t_situations_famille.code_original = t_hst_famille.situationfamille
                    LEFT JOIN rh.t_nationalites ON t_nationalites.code_original = t_hst_nationalite.codenationalite
                WHERE 1=1
                    AND t_hst_nationalite.infoencours = 1
                    AND t_hst_famille.infoencours = 1
                GROUP BY 1,2,3,4,5,6,7,8,9, 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_profils
            SET salarie_id = p_salaries.oid
            FROM rh.p_salaries
            WHERE w_profils.matricule = p_salaries.matricule
            ;

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

			TRUNCATE rh.p_contrats
			;

			ALTER SEQUENCE rh.s_contrats RESTART WITH 1
			;

			INSERT INTO rh.p_contrats(
					salarie_id,
					date_debut,
					date_fin,
					numero_contrat,
					code_original,
					etablissement_id,
					profil_id)
				SELECT
					p_salaries.oid AS salarie_id,
					w_profils.cnt_date_debut AS date_debut,
					w_profils.cnt_date_fin AS date_fin,
					w_profils.cti_cnt AS numero_contrat,
					w_profils.cti_cnt AS code_original,
					coalesce((max(distinct array[extract(epoch from w_profils.date_fin), t_etablissements.oid]))[2], 0)AS etablissement_id,
                    coalesce((max(distinct array[extract(epoch from w_profils.date_fin), w_profils.profil_id]))[2], 0) as profil_id
				FROM w_profils
                    JOIN rh.p_salaries ON p_salaries.code_original = w_profils.matricule
					LEFT JOIN prod_sage.t_eta ON t_eta.codeetab = w_profils.codeetab
					LEFT JOIN rh.t_etablissements ON t_etablissements.code_original = t_eta.siren||t_eta.nic
                WHERE cti_cnt is not null
                GROUP BY 1,2,3,4,5
			;

            -- Màj de l'ancienneté.
            UPDATE rh.p_contrats
            SET
                anciennete_anterieure_jours = subq.anciennete_anterieure_jours,
                anciennete_anterieure_calculee_mois = subq.anciennete_anterieure_calculee_mois
            FROM (
                select
                    numero_contrat,
                    coalesce(sum(date_fin - date_debut + 1) over w, 0) AS anciennete_anterieure_jours,
                    coalesce(sum(date_fin - date_debut + 1) over w / 30::numeric, 0) AS anciennete_anterieure_calculee_mois
                from rh.p_contrats
                window w as (partition by salarie_id order by date_debut rows between UNBOUNDED PRECEDING and 1 preceding)) AS subq
            WHERE 1=1
                AND p_contrats.numero_contrat = subq.numero_contrat
            ;

            -- #correction des dates de sortie ets. à effectuer depuis les contrats.
            UPDATE rh.p_salaries SET
                date_sortie_ets = date_fin_contrat
            FROM (SELECT salarie_id, max(date_fin) AS date_fin_contrat from rh.p_contrats group by 1) AS s
            WHERE 1=1
                AND p_salaries.oid = s.salarie_id
                AND date_sortie_ets != date_fin_contrat
                AND (select valeur = '1' from rh.t_divers where code = 'CORRECTION_DS_ETS')
            ;

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

			TRUNCATE rh.p_contrats_mois
			;

			ALTER SEQUENCE rh.s_contrats_mois RESTART WITH 1
			;

            DROP TABLE IF EXISTS w_contrats_mois
            ;

            CREATE TEMP TABLE w_contrats_mois AS
				SELECT
                    nextval('rh.s_contrats_mois'::regclass) as contrat_mois_id,
					p_salaries.oid AS salarie_id,
					p_contrats.oid AS contrat_id,
					w_profils.profil_id,
					w_profils.mois AS mois_activite,
					w_profils.date_debut,
					w_profils.date_fin,
					CASE WHEN p_salaries.date_entree_ets BETWEEN w_profils.date_debut AND w_profils.date_fin THEN 1 ELSE 0 END AS nombre_entrees,
					CASE WHEN p_salaries.date_sortie_ets BETWEEN w_profils.date_debut AND w_profils.date_fin THEN 1 ELSE 0 END AS nombre_departs,
					CASE WHEN w_profils.cnt_date_debut BETWEEN w_profils.date_debut AND w_profils.date_fin THEN 1 ELSE 0 END AS nombre_debut_contrat,
					CASE WHEN w_profils.cnt_date_fin BETWEEN w_profils.date_debut AND w_profils.date_fin THEN 1 ELSE 0 END AS nombre_fin_contrat,
					w_profils.est_hors_periode,
					CASE WHEN base.cti_first_day(w_profils.date_debut) BETWEEN w_profils.cnt_date_debut AND w_profils.cnt_date_fin THEN 1 ELSE 0 END AS present_debut_mois,
					CASE WHEN base.cti_last_day(w_profils.date_fin) BETWEEN w_profils.cnt_date_debut AND w_profils.cnt_date_fin THEN 1 ELSE 0 END AS present_fin_mois,
					case when cti_cnt IS NOT NULL then w_profils.etp_contrat -- Il n'y a pas d'ETP contrat ni d'anciennetés pour les contrats_mois hors période.
					  * (
							(least(w_profils.date_fin, w_profils.cnt_date_fin) - greatest(w_profils.date_debut, w_profils.cnt_date_debut) + 1)::numeric
							/
                            (base.cti_last_day(to_date(w_profils.mois, 'YYYYMM')) - to_date(w_profils.mois, 'YYYYMM') + 1)::numeric
						) else 0 end AS equivalent_temps_plein,
					base.cti_age(least(w_profils.date_fin, w_profils.cnt_date_fin), coalesce(p_salaries.date_naissance, '1962-04-18'::date), 'ny') AS age_id,
					least(w_profils.date_fin, w_profils.cnt_date_fin)::date - coalesce(p_salaries.date_naissance, '1962-04-18'::date) AS age_jours,
					case when cti_cnt IS NOT NULL then p_contrats.anciennete_anterieure_jours
						+ (w_profils.date_fin - w_profils.cnt_date_debut)
						+ 1
					else 0 end AS anciennete_jours,
					case when cti_cnt IS NOT NULL then base.cti_age(date_trunc('month', w_profils.date_fin::date)::date, date_trunc('month', w_profils.cnt_date_debut)::date, 'nm')
						+ greatest(p_contrats.anciennete_anterieure_mois, p_contrats.anciennete_anterieure_calculee_mois) + 1 else 0 end AS anciennete_mois,
					case when cti_cnt IS NOT NULL then floor((base.cti_age(date_trunc('month', w_profils.date_fin::date)::date, date_trunc('month', w_profils.cnt_date_debut)::date, 'nm')
						+ greatest(p_contrats.anciennete_anterieure_mois, p_contrats.anciennete_anterieure_calculee_mois) + 1) / 12) else 0 end AS anciennete_annee_id,
                    coalesce(t_etablissements.oid, p_contrats.etablissement_id, 0) as etablissement_id,
                    array_agg(w_profils.row_id) as array_row_id -- array des profils.
				FROM w_profils
                    JOIN rh.p_salaries ON w_profils.matricule = p_salaries.matricule
                    LEFT JOIN rh.p_contrats ON p_contrats.code_original = w_profils.cti_cnt_all
                    LEFT JOIN prod_sage.t_eta ON t_eta.codeetab = w_profils.codeetab
                    LEFT JOIN rh.t_etablissements on t_etablissements.code_original = t_eta.siren||t_eta.nic
                WHERE false -- Il faut au moins un contrat ou un bulletin.
                    OR cti_cnt IS NOT NULL
                    OR cti_bul IS NOT NULL
				GROUP BY 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21
			;

            -- On renseigne les id de contrats de w_profils.
            UPDATE w_profils
            SET contrat_id = subq.contrat_id,
                contrat_mois_id = subq.contrat_mois_id
            FROM (
                select
                    unnest(array_row_id) as row_id,
                    contrat_mois_id,
                    contrat_id
                from w_contrats_mois) as subq
            WHERE w_profils.row_id = subq.row_id
            ;

            INSERT INTO rh.p_contrats_mois(
                oid,
                salarie_id,
                contrat_id,
				profil_id,
                mois_activite,
                date_debut,
                date_fin,
                nombre_entrees,
                nombre_departs,
                nombre_debut_contrat,
                nombre_fin_contrat,
                est_hors_periode, -- bulletins de paie hors période de contrat.
                present_debut_mois,
                present_fin_mois,
                equivalent_temps_plein,
                age_id,
                age_jours,
                anciennete_jours,
                anciennete_mois,
                anciennete_annee_id,
                etablissement_id)
                SELECT
                    contrat_mois_id,
                    salarie_id,
                    contrat_id,
					profil_id,
                    mois_activite,
                    date_debut,
                    date_fin,
                    nombre_entrees,
                    nombre_departs,
                    nombre_debut_contrat,
                    nombre_fin_contrat,
                    est_hors_periode,
                    present_debut_mois,
                    present_fin_mois,
                    equivalent_temps_plein,
                    age_id,
                    age_jours,
                    anciennete_jours,
                    anciennete_mois,
                    anciennete_annee_id,
                    etablissement_id
                FROM w_contrats_mois
            ;

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

			]]></sqlcmd>
		</NODE>
        <NODE label="Historique de la paie - 1/3 (mode classique)">
            <condition><![CDATA[
                
            -- Historique de paie classique.
            select valeur = 0
            from rh.t_divers
            where code = 'OPT_STD_HP'
            ;

            ]]></condition>
            <sqlcmd><![CDATA[

            DROP TABLE IF EXISTS w_hp
            ;

            -- BRUT et od (paie cloturee)
            CREATE TEMP TABLE w_hp AS
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    t_hbns.datehist AS date,
                    t_hbns.typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', t_hbns.datehist)::text||lpad(date_part('month', t_hbns.datehist), 2, '0'))::numeric AS mois,
                    t_rub.coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    t_hbns.valeurbase::numeric AS base,
                    t_hbns.valeurnombre::numeric AS nombre,
                    0 as heure_contrat,
                    0 as heure_payee,
                    0 as heure_travaillee, 
                    0 as masse_salariale,
                    (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) *
                        (CASE WHEN 1!=1
                            OR t_rubriques.code_calcul IN ('3', '4')
                            OR t_rub.dasavnat = 1
                            OR t_rub.coderubrique >= 79900
                        THEN 0
                        ELSE t_hbns.valeurmontant END)::numeric AS montant_brut,
                    (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) *
                        (CASE WHEN 1!=1
                            OR t_rubriques.code_calcul NOT IN ('3')
                            OR t_rub.coderubrique >= 79900
                        THEN 0
                        ELSE t_hbns.valeurmontant END)::numeric AS montant_frais_imposables,
                    t_hbns.valeurtaux::numeric AS taux_sal,
                    0::numeric AS montant_sal,
                    0::numeric AS taux_pat,
                    0::numeric AS montant_pat,
                    ((CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * CASE WHEN t_rub.coderubrique > 19990 AND t_rub.dasavnat != 1 THEN t_hbns.valeurmontant ELSE 0 END)::numeric AS od_net,
                    0 as od_net_p,
                    (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) *
                        (CASE WHEN 1!=1
                            OR t_rub.dasavnat = 1 AND montantdequivalence = 0
                            OR t_rubriques.code_calcul = '4'
                        THEN t_hbns.valeurmontant
                        ELSE 0 END)::numeric AS avt_nat,
                    0 AS net_imposable,
                    0 AS net_a_payer,
                    0 AS nombre_provisions,
					0 AS montant_provisions,
					0 AS montant_masse_salariale_provisionnee,
                    t_rub.nodordre AS ordre,
                    0 AS type_rub
                FROM prod_sage.t_hbns
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = t_hbns.numsalarie
                        AND t_hbns.datehist between w_profils.date_debut and w_profils.date_fin
                    JOIN prod_sage.t_rub ON t_rub.coderubrique = t_hbns.coderubrique
                    JOIN rh.t_rubriques ON t_rubriques.code_original = t_rub.coderubrique
                WHERE 1=1
                    AND t_hbns.datehist >= rhp('rhprovider_start')::date
                    AND t_rub.imprimable NOT IN (1, 3)
                    AND t_hbns.valeurmontant != 0 
                    and t_rubriques.code_calcul NOT IN ('9')
            ;

            -- BRUT et od (paie non cloturee)
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    date_paie_encours AS date,
                    0 as typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', date_paie_encours)::text||lpad(date_part('month', date_paie_encours), 2, '0'))::numeric AS mois,
                    t_rub.coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    T_BNSSAL.valeurbase::numeric AS base,
                    T_BNSSAL.valeurnombre::numeric AS nombre,
                    0 as heure_contrat,
                    0 as heure_payee,
                    0 as heure_travaillee,
                    0 as masse_salariale,
                    (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN t_rubriques.code_calcul IN ('3', '4') OR t_rub.dasavnat = 1 OR t_rub.coderubrique = '9' OR t_rub.coderubrique >= 79900 THEN 0 ELSE T_BNSSAL.VALEURMONTANTSALARIAL END) AS montant_brut,
                    (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN t_rubriques.code_calcul NOT IN ('3') OR t_rub.coderubrique = '9' OR t_rub.coderubrique >= 79900 THEN 0 ELSE T_BNSSAL.VALEURMONTANTSALARIAL END) AS montant_frais_imposables,
                    T_BNSSAL.VALEURTAUXSALARIAL AS taux_sal,
                    0 AS montant_sal,
                    0 AS taux_pat,
                    0 AS montant_pat,
                    (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * CASE WHEN t_rub.coderubrique > 19990 AND t_rub.dasavnat != 1 THEN T_BNSSAL.VALEURMONTANTSALARIAL ELSE 0 END AS od_net,
                    0 as od_net_p,
                    (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * CASE WHEN t_rub.dasavnat = 1 AND montantdequivalence = 0  OR t_rubriques.code_calcul = '4' THEN T_BNSSAL.VALEURMONTANTSALARIAL ELSE 0 END AS avt_nat,
                    0 AS net_imposable,
                    0 AS net_a_payer,
                    0 AS nombre_provisions,
					0 AS montant_provisions,
					0 AS montant_masse_salariale_provisionnee
                    t_rub.nodordre AS ordre,
                    0 AS type_rub
                FROM prod_sage.T_BNSSAL
                    JOIN w_periode ON 1=1
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = T_BNSSAL.numsalarie
                        AND date_paie_encours between w_profils.date_debut and w_profils.date_fin
                    JOIN prod_sage.t_rub ON t_rub.coderubrique = T_BNSSAL.coderubrique
                    JOIN rh.t_rubriques ON t_rubriques.code_original = t_rub.coderubrique
                WHERE 1=1
                    AND t_rub.imprimable NOT IN (1, 3)
                    AND T_BNSSAL.VALEURMONTANTSALARIAL != 0 
                    and t_rubriques.code_calcul NOT IN ('9')
            ;

            -- Cotisations (mois clotures)
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    t_hcot.datehcot AS date,
                    t_hcot.typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', t_hcot.datehcot)::text||lpad(date_part('month', t_hcot.datehcot), 2, '0'))::numeric AS mois,
                    t_rub.coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    t_hcot.valeursbase AS base,
                    t_hcot.valeursnombre AS nombre,
                    0 as heure_contrat,
                    0 as heure_payee,
                    0 as heure_travaillee,
                    0 as masse_salariale,
                    0 AS montant_brut,
                    0 AS montant_frais_imposables,
                    t_hcot.valeurstauxsalarial AS taux_sal,
                    (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * t_hcot.valeursmontantsalarial AS montant_sal,
                    t_hcot.valeurstauxpatronal AS taux_pat,
                    (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * t_hcot.valeursmontantpatronal AS montant_pat,
                    0 AS od_net,
                    0 as od_net_p,
                    0 AS avt_nat,
                    0 AS net_imposable,
                    0 AS net_a_payer,
                    0 AS nombre_provisions,
					0 AS montant_provisions,
					0 AS montant_masse_salariale_provisionnee,
                    t_rub.nodordre AS ordre,
                    1 AS type_rub
                FROM prod_sage.t_hcot
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = t_hcot.numsalarie
                        AND t_hcot.datehcot between w_profils.date_debut and w_profils.date_fin
                    JOIN prod_sage.t_rub ON t_rub.coderubrique = t_hcot.coderubrique
                    JOIN rh.t_rubriques ON t_rubriques.code_original = t_rub.coderubrique
                WHERE true
                    AND t_hcot.datehcot >= rhp('rhprovider_start')::date
                    AND t_rub.imprimable != 1
                    AND (t_hcot.valeursmontantsalarial != 0 OR t_hcot.valeursmontantpatronal != 0)
            ;

            -- Cotisations (mois non clotures)
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    date_paie_encours AS date,
                    0 as typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', date_paie_encours)::text||lpad(date_part('month', date_paie_encours), 2, '0'))::numeric AS mois,
                    t_rub.coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    T_COTSAL.valeurbase AS base,
                    T_COTSAL.valeurnombre AS nombre,
                    0 as heure_contrat,
                    0 as heure_payee,
                    0 as heure_travaillee,
                    0 as masse_salariale,
                    0 AS montant_brut,
                    0 AS montant_frais_imposables,
                    T_COTSAL.VALEURTAUXSAL AS taux_sal,
                    (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * T_COTSAL.VALEURMONTANTSAL AS montant_sal,
                    T_COTSAL.VALEURTAUXPATRONAL AS taux_pat,
                    (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * T_COTSAL.VALEURMONTANTPATRONAL AS montant_pat,
                    0 AS od_net,
                    0 as od_net_p,
                    0 AS avt_nat,
                    0 AS net_imposable,
                    0 AS net_a_payer,
                    0 AS nombre_provisions,
					0 AS montant_provisions,
					0 AS montant_masse_salariale_provisionnee,
                    t_rub.nodordre AS ordre,
                    1 AS type_rub
                FROM prod_sage.T_COTSAL
                    JOIN w_periode ON 1=1
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = T_COTSAL.numsalarie
                        AND date_paie_encours between w_profils.date_debut and w_profils.date_fin
                    JOIN prod_sage.t_rub ON t_rub.coderubrique = T_COTSAL.coderubrique
                    JOIN rh.t_rubriques ON t_rubriques.code_original = t_rub.coderubrique
                WHERE t_rub.imprimable != 1 AND
                    (T_COTSAL.VALEURMONTANTSAL != 0 OR T_COTSAL.VALEURMONTANTPATRONAL != 0)
            ;

            -- Cumuls paie cloturee
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    t_hcum.datehist AS date,
                    t_hcum.typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', t_hcum.datehist)::text||lpad(date_part('month', t_hcum.datehist), 2, '0'))::numeric AS mois,
                    0 AS coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    CASE WHEN ENTITE IN (84, 86) THEN t_hcum.VALEURCUMUL ELSE 0 END AS base,
                    CASE WHEN ENTITE IN (84, 86) THEN t_hcum.VALEURCUMUL ELSE 0 END AS nombre,
                    0 as heure_contrat,
                    0 as heure_payee,
                    0 as heure_travaillee,
                    0 as masse_salariale,
                    0 AS montant_brut,
                    0 AS montant_frais_imposables,
                    0 AS taux_sal,
                    0 AS montant_sal,
                    0 AS taux_pat,
                    0 AS montant_pat,
                    0 AS od_net,
                    0 as od_net_p,
                    0 AS avt_nat,
                    CASE WHEN ENTITE = 4 THEN t_hcum.VALEURCUMUL ELSE 0 END AS net_imposable,
                    CASE WHEN ENTITE = 3 THEN t_hcum.VALEURCUMUL ELSE 0 END AS net_a_payer,
                    0 AS nombre_provisions,
					0 AS montant_provisions,
					0 AS montant_masse_salariale_provisionnee,
                    t_rubriques.rang_edition AS ordre,
                    2 AS type_rub
                FROM prod_sage.t_hcum
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = t_hcum.numsalarie
                        AND t_hcum.datehist between w_profils.date_debut and w_profils.date_fin
                    JOIN rh.t_rubriques ON t_rubriques.code_original = 'C' || lpad(t_hcum.ENTITE, 3, '0')
                WHERE true
                    AND t_hcum.datehist >= rhp('rhprovider_start')::date
                    AND ENTITE IN (3, 4, 84, 86)
            ;

            -- Cumuls paie non cloturee
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    date_paie_encours AS date,
                    0 as typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', date_paie_encours)::text||lpad(date_part('month', date_paie_encours), 2, '0'))::numeric AS mois,
                    0 AS coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    CASE WHEN OPCSTCUMUL in (84, 86) THEN T_CUMSAL.VALEURCUMINTERMEDIAIRE ELSE 0 END AS base,
                    CASE WHEN OPCSTCUMUL in (84, 86) THEN T_CUMSAL.VALEURCUMINTERMEDIAIRE ELSE 0 END AS nombre,
                    0 as heure_contrat,
                    0 as heure_payee,
                    0 as heure_travaillee,
                    0 as masse_salariale,
                    0 AS montant_brut,
                    0 AS montant_frais_imposables,
                    0 AS taux_sal,
                    0 AS montant_sal,
                    0 AS taux_pat,
                    0 AS montant_pat,
                    0 AS od_net,
                    0 as od_net_p,
                    0 AS avt_nat,
                    CASE WHEN OPCSTCUMUL = 4 THEN T_CUMSAL.VALEURCUMINTERMEDIAIRE ELSE 0 END AS net_imposable,
                    CASE WHEN OPCSTCUMUL = 3 THEN T_CUMSAL.VALEURCUMINTERMEDIAIRE ELSE 0 END AS net_a_payer,
                    0 AS nombre_provisions,
					0 AS montant_provisions,
					0 AS montant_masse_salariale_provisionnee,
                    t_rubriques.rang_edition AS ordre,
                    2 AS type_rub
                FROM prod_sage.T_CUMSAL
                    JOIN w_periode ON 1=1
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = T_CUMSAL.numsalarie
                        AND date_paie_encours between w_profils.date_debut and w_profils.date_fin
                    JOIN rh.t_rubriques ON t_rubriques.code_original = 'C' || lpad(T_CUMSAL.OPCSTCUMUL, 3, '0')
                WHERE OPCSTCUMUL IN (3, 4, 84, 86)
            ;

            -- Suppression des bulletins composés uniquement des 3 (ou 4) rubriques de cumul :
            --  * 3 (net à payer),
            --  * 4 (net imposable),
            --  * 86 (heures payées),
            --  * [84 (heures travaillées)]
            -- toutes à 0.
            DELETE FROM w_hp
            USING (
                select
                    matricule,
                    date
                from w_hp
                group by 1,2
                having 1=1
                    AND sum(base) = 0
                    AND sum(net_imposable) = 0 
                    AND sum(net_a_payer) = 0
                    AND count(*) in (3, 4)
                ) AS subq
            WHERE 1=1
                AND w_hp.matricule = subq.matricule
                AND w_hp.date = subq.date
            ;

            ]]></sqlcmd>
        </NODE>
        <NODE label="Historique de la paie - 1/3 (mode paramétré)">
            <condition><![CDATA[
                
            -- Historique de paie paramétré.
            select valeur = 1
            from rh.t_divers
            where code = 'OPT_STD_HP'
            ;

            ]]></condition>
            <sqlcmd><![CDATA[

            DROP TABLE IF EXISTS w_hp
            ;

            -- BRUT et od (paie cloturee)
            CREATE TEMP TABLE w_hp AS
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    t_hbns.datehist AS date,
                    t_hbns.typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', t_hbns.datehist)::text||lpad(date_part('month', t_hbns.datehist), 2, '0'))::numeric AS mois,
                    t_rub.coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    t_rubriques.c_base
                        * case when @t_rubriques.c_base != 1 then coalesce(w_hst_bul.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_base THEN (CASE s_base
                                WHEN 0 THEN t_hbns.valeurnombre::numeric
                                WHEN 1 THEN t_hbns.valeurbase::numeric
                                WHEN 3 THEN t_hbns.valeurmontant::numeric
                                WHEN 5 THEN t_hbns.valeurmontant::numeric
                            END) else 0 end AS base,
                    t_rubriques.c_nombre
                        * case when @t_rubriques.c_nombre != 1 then coalesce(w_hst_bul.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_nombre THEN (CASE s_nombre
                                WHEN 0 THEN t_hbns.valeurnombre::numeric
                                WHEN 1 THEN t_hbns.valeurbase::numeric
                                WHEN 3 THEN t_hbns.valeurmontant::numeric
                                WHEN 5 THEN t_hbns.valeurmontant::numeric
                            END) else 0 end AS nombre,
                    t_rubriques.c_heures_contrat
                        * case when @t_rubriques.c_heures_contrat != 1 then coalesce(w_hst_bul.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_heures_contrat
                            then (CASE s_heures_contrat
                                WHEN 0 THEN t_hbns.valeurnombre::numeric
                                WHEN 1 THEN t_hbns.valeurbase::numeric
                                WHEN 3 THEN t_hbns.valeurmontant::numeric
                                WHEN 5 THEN t_hbns.valeurmontant::numeric
                            END)
                            else 0 end
                        AS heure_contrat,
                    t_rubriques.c_heures_payees
                        * case when @t_rubriques.c_heures_payees != 1 then coalesce(w_hst_bul.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_heures_payees
                            then (CASE s_heures_payees
                                WHEN 0 THEN t_hbns.valeurnombre::numeric
                                WHEN 1 THEN t_hbns.valeurbase::numeric
                                WHEN 3 THEN t_hbns.valeurmontant::numeric
                                WHEN 5 THEN t_hbns.valeurmontant::numeric
                            END)
                            else 0 end
                        AS heure_payee,
                    t_rubriques.c_heures_travaillees
                        * case when @t_rubriques.c_heures_travaillees != 1 then coalesce(w_hst_bul.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_heures_travaillees
                            then (CASE s_heures_travaillees
                                    WHEN 0 THEN t_hbns.valeurnombre::numeric
                                    WHEN 1 THEN t_hbns.valeurbase::numeric
                                    WHEN 3 THEN t_hbns.valeurmontant::numeric
                                    WHEN 5 THEN t_hbns.valeurmontant::numeric
                                END)
                            else 0 end
                        AS heure_travaillee,
                    t_rubriques.c_masse_salariale * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_masse_salariale      THEN t_hbns.valeurmontant::numeric else 0 end) AS masse_salariale,
                    t_rubriques.c_brut * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_brut                 THEN t_hbns.valeurmontant::numeric else 0 end) AS montant_brut,
                    t_rubriques.c_frais_imposables * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (case when p_frais_imposables     then t_hbns.valeurmontant::numeric else 0 end) AS montant_frais_imposables,
                    t_rubriques.coefficient_txs * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (case when p_cotisation_salarie   then t_hbns.valeurtaux::numeric    else 0 end) AS taux_sal,
                    t_rubriques.c_cotisation_salarie * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (case when p_cotisation_salarie   then t_hbns.valeurmontant::numeric else 0 end) AS montant_sal,
                    t_rubriques.coefficient_txp * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (case when p_cotisation_patronale then t_hbns.valeurtaux::numeric    else 0 end) AS taux_pat,
                    t_rubriques.c_cotisation_patronale * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (case when p_cotisation_patronale then t_hbns.valeurmontant::numeric else 0 end) AS montant_pat,
                    t_rubriques.c_od_net_salarie * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_od_net_salarie       THEN t_hbns.valeurmontant::numeric ELSE 0 END) AS od_net,
                    t_rubriques.c_od_net_patronale * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_od_net_patronale     THEN t_hbns.valeurmontant::numeric ELSE 0 END) AS od_net_p,
                    t_rubriques.c_avantage_nature * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_avantage_nature      THEN t_hbns.valeurmontant::numeric ELSE 0 END) AS avt_nat,
                    t_rubriques.c_net_imposable * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_net_imposable        THEN t_hbns.valeurmontant::numeric ELSE 0 END) AS net_imposable,
                    t_rubriques.c_net_a_payer * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_net_a_payer          THEN t_hbns.valeurmontant::numeric ELSE 0 END) AS net_a_payer,
                    t_rubriques.c_nombre_provisions * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_nombre_provisions
                            then (CASE s_nombre_provisions
                                    WHEN 0 THEN t_hbns.valeurnombre::numeric
                                    WHEN 1 THEN t_hbns.valeurbase::numeric
                                    WHEN 3 THEN t_hbns.valeurmontant::numeric
                                    WHEN 5 THEN t_hbns.valeurmontant::numeric
                                END)
                            else 0 end
                        AS nombre_provisions,
                    t_rubriques.c_montant_provisions * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_montant_provisions
                            then (CASE s_montant_provisions
                                    WHEN 0 THEN t_hbns.valeurnombre::numeric
                                    WHEN 1 THEN t_hbns.valeurbase::numeric
                                    WHEN 3 THEN t_hbns.valeurmontant::numeric
                                    WHEN 5 THEN t_hbns.valeurmontant::numeric
                                END)
                            else 0 end
                        AS montant_provisions,
                    t_rubriques.c_masse_salariale_provisionnee * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_masse_salariale_provisionnee
                            then (CASE s_masse_salariale_provisionnee
                                    WHEN 0 THEN t_hbns.valeurnombre::numeric
                                    WHEN 1 THEN t_hbns.valeurbase::numeric
                                    WHEN 3 THEN t_hbns.valeurmontant::numeric
                                    WHEN 5 THEN t_hbns.valeurmontant::numeric
                                END)
                            else 0 end
                        AS masse_salariale_provisionnee,
                    t_rub.nodordre AS ordre,
                    0 AS type_rub
                FROM prod_sage.t_hbns
                    JOIN w_hst_bul ON 1=1
                        AND w_hst_bul.numsalarie = t_hbns.numsalarie
                        AND w_hst_bul.datehist = t_hbns.datehist
                        AND w_hst_bul.typedubulletin = t_hbns.typedubulletin
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = t_hbns.numsalarie
                        AND w_hst_bul.datehist_cti between w_profils.date_debut and w_profils.date_fin
                        AND w_profils.typedubulletin = t_hbns.typedubulletin
                    JOIN prod_sage.t_rub ON t_rub.coderubrique = t_hbns.coderubrique
                    JOIN rh.t_rubriques ON t_rubriques.code_original = t_rub.coderubrique
                where 1=1
                    AND t_hbns.datehist >= rhp('rhprovider_start')::date
                    -- Filtrer les lignes générées systématiquement tous les mois par Sage pour chaque salarié même s'il n'y a rien.
                    AND (false
                        OR t_hbns.valeurmontant != 0
                        OR t_hbns.valeurnombre != 0)
                    AND (false
                        OR p_nombre
                        OR p_base
                        OR p_heures_contrat
                        OR p_heures_payees
                        OR p_heures_travaillees
                        OR p_masse_salariale
                        OR p_brut
                        OR p_avantage_nature
                        OR p_frais_imposables
                        OR p_cotisation_salarie
                        OR p_cotisation_patronale
                        OR p_od_net_salarie
                        OR p_od_net_patronale
                        OR p_net_imposable
                        OR p_net_a_payer
                        OR p_nombre_provisions
                        OR p_montant_provisions
                        OR p_masse_salariale_provisionnee)
            ;

            -- BRUT et od (paie non cloturee)
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    date_paie_encours AS date,
                    0 as typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', date_paie_encours)::text||lpad(date_part('month', date_paie_encours), 2, '0'))::numeric AS mois,
                    t_rub.coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    t_rubriques.c_base
                        * case when @t_rubriques.c_base != 1 then coalesce(w_profils.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_base THEN (CASE s_base
                                    WHEN 0 THEN t_bnssal.valeurnombre::numeric
                                    WHEN 1 THEN t_bnssal.valeurbase::numeric
                                    WHEN 3 THEN t_bnssal.valeurmontantsalarial::numeric
                                    WHEN 5 THEN t_bnssal.valeurmontantsalarial::numeric
                                END) else 0 end AS base,
                    t_rubriques.c_nombre
                        * case when @t_rubriques.c_nombre != 1 then coalesce(w_profils.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_nombre THEN (CASE s_nombre
                                    WHEN 0 THEN t_bnssal.valeurnombre::numeric
                                    WHEN 1 THEN t_bnssal.valeurbase::numeric
                                    WHEN 3 THEN t_bnssal.valeurmontantsalarial::numeric
                                    WHEN 5 THEN t_bnssal.valeurmontantsalarial::numeric
                                END) else 0 end AS nombre,
                    t_rubriques.c_heures_contrat
                        * case when @t_rubriques.c_heures_contrat != 1 then coalesce(w_profils.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_heures_contrat
                            then (CASE s_heures_contrat
                                WHEN 0 THEN t_bnssal.valeurnombre::numeric
                                WHEN 1 THEN t_bnssal.valeurbase::numeric
                                WHEN 3 THEN t_bnssal.valeurmontantsalarial::numeric
                                WHEN 5 THEN t_bnssal.valeurmontantsalarial::numeric
                            END)
                            else 0 end
                        AS heure_contrat,
                    t_rubriques.c_heures_payees
                        * case when @t_rubriques.c_heures_payees != 1 then coalesce(w_profils.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_heures_payees
                            then (CASE s_heures_payees
                                WHEN 0 THEN t_bnssal.valeurnombre::numeric
                                WHEN 1 THEN t_bnssal.valeurbase::numeric
                                WHEN 3 THEN t_bnssal.valeurmontantsalarial::numeric
                                WHEN 5 THEN t_bnssal.valeurmontantsalarial::numeric
                            END)
                            else 0 end
                        AS heure_payee,
                    t_rubriques.c_heures_travaillees
                        * case when @t_rubriques.c_heures_travaillees != 1 then coalesce(w_profils.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_heures_travaillees
                            then (CASE s_heures_travaillees
                                    WHEN 0 THEN t_bnssal.valeurnombre::numeric
                                    WHEN 1 THEN t_bnssal.valeurbase::numeric
                                    WHEN 3 THEN t_bnssal.valeurmontantsalarial::numeric
                                    WHEN 5 THEN t_bnssal.valeurmontantsalarial::numeric
                                END)
                            else 0 end
                        AS heure_travaillee,
                    t_rubriques.c_masse_salariale * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_masse_salariale      THEN t_bnssal.valeurmontantsalarial::numeric else 0 end) AS masse_salariale,
                    t_rubriques.c_brut * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_brut                 THEN t_bnssal.valeurmontantsalarial::numeric else 0 end) AS montant_brut,
                    t_rubriques.c_frais_imposables * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (case when p_frais_imposables     then t_bnssal.valeurmontantsalarial::numeric else 0 end) AS montant_frais_imposables,
                    t_rubriques.coefficient_txs * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (case when p_cotisation_salarie   then t_bnssal.valeurtauxsalarial::numeric    else 0 end) AS taux_sal,
                    t_rubriques.c_cotisation_salarie * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (case when p_cotisation_salarie   then t_bnssal.valeurmontantsalarial::numeric else 0 end) AS montant_sal,
                    t_rubriques.coefficient_txp * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (case when p_cotisation_patronale then 0                                       else 0 end) AS taux_pat,
                    t_rubriques.c_cotisation_patronale * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (case when p_cotisation_patronale then 0                                       else 0 end) AS montant_pat,
                    t_rubriques.c_od_net_salarie * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_od_net_salarie       THEN t_bnssal.valeurmontantsalarial::numeric ELSE 0 END) AS od_net,
                    t_rubriques.c_od_net_patronale * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_od_net_patronale     then 0                                       ELSE 0 END) AS od_net_p,
                    t_rubriques.c_avantage_nature * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_avantage_nature      THEN t_bnssal.valeurmontantsalarial::numeric ELSE 0 END) AS avt_nat,
                    t_rubriques.c_net_imposable * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_net_imposable        THEN t_bnssal.valeurmontantsalarial::numeric ELSE 0 END) AS net_imposable,
                    t_rubriques.c_net_a_payer * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_net_a_payer          THEN t_bnssal.valeurmontantsalarial::numeric ELSE 0 END) AS net_a_payer,
                    t_rubriques.c_nombre_provisions * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_nombre_provisions
                            then (CASE s_nombre_provisions
                                    WHEN 0 THEN t_bnssal.valeurnombre::numeric
                                    WHEN 1 THEN t_bnssal.valeurbase::numeric
                                    WHEN 3 THEN t_bnssal.valeurmontantsalarial::numeric
                                    WHEN 5 THEN t_bnssal.valeurmontantsalarial::numeric
                                END)
                            else 0 end
                        AS nombre_provisions,
                    t_rubriques.c_montant_provisions * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_montant_provisions
                            then (CASE s_montant_provisions
                                    WHEN 0 THEN t_bnssal.valeurnombre::numeric
                                    WHEN 1 THEN t_bnssal.valeurbase::numeric
                                    WHEN 3 THEN t_bnssal.valeurmontantsalarial::numeric
                                    WHEN 5 THEN t_bnssal.valeurmontantsalarial::numeric
                                END)
                            else 0 end
                        AS montant_provisions,
                    t_rubriques.c_masse_salariale_provisionnee * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_masse_salariale_provisionnee
                            then (CASE s_masse_salariale_provisionnee
                                    WHEN 0 THEN t_bnssal.valeurnombre::numeric
                                    WHEN 1 THEN t_bnssal.valeurbase::numeric
                                    WHEN 3 THEN t_bnssal.valeurmontantsalarial::numeric
                                    WHEN 5 THEN t_bnssal.valeurmontantsalarial::numeric
                                END)
                            else 0 end
                        AS masse_salariale_provisionnee,
                    t_rub.nodordre AS ordre,
                    0 AS type_rub
                FROM prod_sage.t_bnssal
                    JOIN w_periode ON 1=1
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = t_bnssal.numsalarie
                        AND date_paie_encours between w_profils.date_debut and w_profils.date_fin
                    JOIN prod_sage.t_rub ON t_rub.coderubrique = t_bnssal.coderubrique
                    JOIN rh.t_rubriques ON t_rubriques.code_original = t_rub.coderubrique
                where 1=1
                    -- Filtrer les lignes générées systématiquement tous les mois par Sage pour chaque salarié même s'il n'y a rien.
                    AND (false
                        OR t_bnssal.valeurmontantsalarial != 0
                        OR t_bnssal.valeurnombre != 0)
                    AND (false
                        OR p_nombre
                        OR p_base
                        OR p_heures_contrat
                        OR p_heures_payees
                        OR p_heures_travaillees
                        OR p_masse_salariale
                        OR p_brut
                        OR p_avantage_nature
                        OR p_frais_imposables
                        OR p_cotisation_salarie
                        OR p_cotisation_patronale
                        OR p_od_net_salarie
                        OR p_od_net_patronale
                        OR p_net_imposable
                        OR p_net_a_payer
                        OR p_nombre_provisions
                        OR p_montant_provisions
                        OR p_masse_salariale_provisionnee)
            ;

            -- Cotisations (mois clotures)
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    t_hcot.datehcot AS date,
                    t_hcot.typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', t_hcot.datehcot)::text||lpad(date_part('month', t_hcot.datehcot), 2, '0'))::numeric AS mois,
                    t_rub.coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    t_rubriques.c_base
                        * case when @t_rubriques.c_base != 1 then coalesce(w_hst_bul.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_base THEN (CASE s_base
                            WHEN 0 THEN t_hcot.valeursnombre::numeric
                            WHEN 1 THEN t_hcot.valeursbase::numeric
                            WHEN 2 THEN t_hcot.valeurstauxsalarial::numeric
                            WHEN 3 THEN t_hcot.valeursmontantsalarial::numeric
                            WHEN 4 THEN t_hcot.valeurstauxpatronal::numeric
                            WHEN 5 THEN t_hcot.valeursmontantpatronal::numeric
                            WHEN 6 THEN t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                            WHEN 7 THEN t_hcot.valeursmontantsalarial::numeric - t_hcot.valeursmontantpatronal::numeric
                            WHEN 8 THEN -t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                        END) else 0 end AS base,
                    t_rubriques.c_nombre
                        * case when @t_rubriques.c_nombre != 1 then coalesce(w_hst_bul.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_nombre THEN (CASE s_nombre
                            WHEN 0 THEN t_hcot.valeursnombre::numeric
                            WHEN 1 THEN t_hcot.valeursbase::numeric
                            WHEN 2 THEN t_hcot.valeurstauxsalarial::numeric
                            WHEN 3 THEN t_hcot.valeursmontantsalarial::numeric
                            WHEN 4 THEN t_hcot.valeurstauxpatronal::numeric
                            WHEN 5 THEN t_hcot.valeursmontantpatronal::numeric
                            WHEN 6 THEN t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                            WHEN 7 THEN t_hcot.valeursmontantsalarial::numeric - t_hcot.valeursmontantpatronal::numeric
                            WHEN 8 THEN -t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                        END) else 0 end AS nombre,
                    t_rubriques.c_heures_contrat * CASE WHEN p_heures_contrat THEN t_hcot.valeursnombre::numeric else 0 end AS heure_contrat,
                    t_rubriques.c_heures_payees * CASE WHEN p_heures_payees THEN t_hcot.valeursnombre::numeric else 0 end AS heure_payee,
                    t_rubriques.c_heures_travaillees * CASE WHEN p_heures_travaillees THEN t_hcot.valeursnombre::numeric else 0 end AS heure_travaillee,
                    t_rubriques.c_masse_salariale * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (CASE WHEN p_masse_salariale      THEN t_hcot.valeursmontantpatronal::numeric else 0 end) AS masse_salariale,
                    t_rubriques.c_brut * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (CASE WHEN p_brut                 THEN t_hcot.valeursmontantsalarial::numeric else 0 end) AS montant_brut,
                    t_rubriques.c_frais_imposables * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (case when p_frais_imposables     then t_hcot.valeursmontantsalarial::numeric else 0 end) AS montant_frais_imposables,
                    t_rubriques.coefficient_txs * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (case when p_cotisation_salarie   then t_hcot.valeurstauxsalarial::numeric    else 0 end) AS taux_sal,
                    t_rubriques.c_cotisation_salarie * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (case when p_cotisation_salarie   then t_hcot.valeursmontantsalarial::numeric else 0 end) AS montant_sal,
                    t_rubriques.coefficient_txp * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (case when p_cotisation_patronale then t_hcot.valeurstauxpatronal::numeric    else 0 end) AS taux_pat,
                    t_rubriques.c_cotisation_patronale * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (case when p_cotisation_patronale then t_hcot.valeursmontantpatronal::numeric else 0 end) AS montant_pat,
                    t_rubriques.c_od_net_salarie * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (CASE WHEN p_od_net_salarie       THEN t_hcot.valeursmontantsalarial::numeric ELSE 0 END) AS od_net,
                    t_rubriques.c_od_net_patronale * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (CASE WHEN p_od_net_patronale     THEN t_hcot.valeursmontantpatronal::numeric ELSE 0 END) AS od_net_p,
                    t_rubriques.c_avantage_nature * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (CASE WHEN p_avantage_nature      THEN t_hcot.valeursmontantsalarial::numeric ELSE 0 END) AS avt_nat,
                    t_rubriques.c_net_imposable * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * CASE WHEN p_net_imposable THEN (CASE s_net_imposable
                            WHEN 0 THEN t_hcot.valeursnombre::numeric
                            WHEN 1 THEN t_hcot.valeursbase::numeric
                            WHEN 2 THEN t_hcot.valeurstauxsalarial::numeric
                            WHEN 3 THEN t_hcot.valeursmontantsalarial::numeric
                            WHEN 4 THEN t_hcot.valeurstauxpatronal::numeric
                            WHEN 5 THEN t_hcot.valeursmontantpatronal::numeric
                            WHEN 6 THEN t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                            WHEN 7 THEN t_hcot.valeursmontantsalarial::numeric - t_hcot.valeursmontantpatronal::numeric
                            WHEN 8 THEN -t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                        END) ELSE 0 END AS net_imposable,
                    t_rubriques.c_net_a_payer * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_net_a_payer          THEN t_hcot.valeursmontantsalarial::numeric ELSE 0 END) AS net_a_payer,
                    t_rubriques.c_nombre_provisions * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_nombre_provisions
                            then (CASE s_nombre_provisions
                                WHEN 0 THEN t_hcot.valeursnombre::numeric
                                WHEN 1 THEN t_hcot.valeursbase::numeric
                                WHEN 2 THEN t_hcot.valeurstauxsalarial::numeric
                                WHEN 3 THEN t_hcot.valeursmontantsalarial::numeric
                                WHEN 4 THEN t_hcot.valeurstauxpatronal::numeric
                                WHEN 5 THEN t_hcot.valeursmontantpatronal::numeric
                                WHEN 6 THEN t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                                WHEN 7 THEN t_hcot.valeursmontantsalarial::numeric - t_hcot.valeursmontantpatronal::numeric
                                WHEN 8 THEN -t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                                END)
                            else 0 end
                        AS nombre_provisions,
                    t_rubriques.c_montant_provisions * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_montant_provisions
                            then (CASE s_montant_provisions
                                WHEN 0 THEN t_hcot.valeursnombre::numeric
                                WHEN 1 THEN t_hcot.valeursbase::numeric
                                WHEN 2 THEN t_hcot.valeurstauxsalarial::numeric
                                WHEN 3 THEN t_hcot.valeursmontantsalarial::numeric
                                WHEN 4 THEN t_hcot.valeurstauxpatronal::numeric
                                WHEN 5 THEN t_hcot.valeursmontantpatronal::numeric
                                WHEN 6 THEN t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                                WHEN 7 THEN t_hcot.valeursmontantsalarial::numeric - t_hcot.valeursmontantpatronal::numeric
                                WHEN 8 THEN -t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                                END)
                            else 0 end
                        AS montant_provisions,
                    t_rubriques.c_masse_salariale_provisionnee * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_masse_salariale_provisionnee
                            then (CASE s_masse_salariale_provisionnee
                                WHEN 0 THEN t_hcot.valeursnombre::numeric
                                WHEN 1 THEN t_hcot.valeursbase::numeric
                                WHEN 2 THEN t_hcot.valeurstauxsalarial::numeric
                                WHEN 3 THEN t_hcot.valeursmontantsalarial::numeric
                                WHEN 4 THEN t_hcot.valeurstauxpatronal::numeric
                                WHEN 5 THEN t_hcot.valeursmontantpatronal::numeric
                                WHEN 6 THEN t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                                WHEN 7 THEN t_hcot.valeursmontantsalarial::numeric - t_hcot.valeursmontantpatronal::numeric
                                WHEN 8 THEN -t_hcot.valeursmontantsalarial::numeric + t_hcot.valeursmontantpatronal::numeric
                                END)
                            else 0 end
                        AS masse_salariale_provisionnee,
                    t_rub.nodordre AS ordre,
                    1 AS type_rub
                FROM prod_sage.t_hcot
                    JOIN w_hst_bul ON 1=1
                        AND w_hst_bul.numsalarie = t_hcot.numsalarie
                        AND w_hst_bul.datehist = t_hcot.datehcot
                        AND w_hst_bul.typedubulletin = t_hcot.typedubulletin
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = t_hcot.numsalarie
                        AND w_hst_bul.datehist_cti between w_profils.date_debut and w_profils.date_fin
                        AND w_profils.typedubulletin = t_hcot.typedubulletin
                    JOIN prod_sage.t_rub ON t_rub.coderubrique = t_hcot.coderubrique
                    JOIN rh.t_rubriques ON t_rubriques.code_original = t_rub.coderubrique
                WHERE true
                    AND t_hcot.datehcot >= rhp('rhprovider_start')::date
                    -- Filtrer les lignes générées systématiquement tous les mois par Sage pour chaque salarié même s'il n'y a rien.
                    AND (false
                        OR t_hcot.valeursnombre != 0
                        OR t_hcot.valeursmontantsalarial != 0
                        OR t_hcot.valeursmontantpatronal != 0)
                    AND (false
                        OR p_nombre
                        OR p_base
                        OR p_heures_contrat
                        OR p_heures_payees
                        OR p_heures_travaillees
                        OR p_masse_salariale
                        OR p_brut
                        OR p_avantage_nature
                        OR p_frais_imposables
                        OR p_cotisation_salarie
                        OR p_cotisation_patronale
                        OR p_od_net_salarie
                        OR p_od_net_patronale
                        OR p_net_imposable
                        OR p_net_a_payer
                        OR p_nombre_provisions
                        OR p_montant_provisions
                        OR p_masse_salariale_provisionnee)
            ;

            -- Cotisations (mois non clotures)
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    date_paie_encours AS date,
                    0 as typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', date_paie_encours)::text||lpad(date_part('month', date_paie_encours), 2, '0'))::numeric AS mois,
                    t_rub.coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    t_rubriques.c_base
                        * case when @t_rubriques.c_base != 1 then coalesce(w_profils.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_base THEN (CASE s_base
                            WHEN 0 THEN t_cotsal.valeurnombre::numeric
                            WHEN 1 THEN t_cotsal.valeurbase::numeric
                            WHEN 2 THEN t_cotsal.valeurtauxsal::numeric
                            WHEN 3 THEN t_cotsal.valeurmontantsal::numeric
                            WHEN 4 THEN t_cotsal.valeurtauxpatronal::numeric
                            WHEN 5 THEN t_cotsal.valeurmontantpatronal::numeric
                            WHEN 6 THEN t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                            WHEN 7 THEN t_cotsal.valeurmontantsal::numeric - t_cotsal.valeurmontantpatronal::numeric
                            WHEN 8 THEN -t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                        END) else 0 end AS base,
                    t_rubriques.c_nombre
                        * case when @t_rubriques.c_nombre != 1 then coalesce(w_profils.etp_contrat, 1.0) else 1.0 end
                        * CASE WHEN p_nombre THEN (CASE s_nombre
                            WHEN 0 THEN t_cotsal.valeurnombre::numeric
                            WHEN 1 THEN t_cotsal.valeurbase::numeric
                            WHEN 2 THEN t_cotsal.valeurtauxsal::numeric
                            WHEN 3 THEN t_cotsal.valeurmontantsal::numeric
                            WHEN 4 THEN t_cotsal.valeurtauxpatronal::numeric
                            WHEN 5 THEN t_cotsal.valeurmontantpatronal::numeric
                            WHEN 6 THEN t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                            WHEN 7 THEN t_cotsal.valeurmontantsal::numeric - t_cotsal.valeurmontantpatronal::numeric
                            WHEN 8 THEN -t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                        END) else 0 end AS nombre,
                    t_rubriques.c_heures_contrat * CASE WHEN p_heures_contrat THEN t_cotsal.valeurnombre::numeric else 0 end AS heure_contrat,
                    t_rubriques.c_heures_payees * CASE WHEN p_heures_payees THEN t_cotsal.valeurnombre::numeric else 0 end AS heure_payee,
                    t_rubriques.c_heures_travaillees * CASE WHEN p_heures_travaillees THEN t_cotsal.valeurnombre::numeric else 0 end AS heure_travaillee,
                    t_rubriques.c_masse_salariale * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (CASE WHEN p_masse_salariale      THEN t_cotsal.valeurmontantpatronal::numeric else 0 end) AS masse_salariale,
                    t_rubriques.c_brut * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (CASE WHEN p_brut                 THEN t_cotsal.valeurmontantsal::numeric      else 0 end) AS montant_brut,
                    t_rubriques.c_frais_imposables * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (case when p_frais_imposables     then t_cotsal.valeurmontantsal::numeric      else 0 end) AS montant_frais_imposables,
                    t_rubriques.coefficient_txs * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (case when p_cotisation_salarie   then t_cotsal.valeurtauxsal::numeric         else 0 end) AS taux_sal,
                    t_rubriques.c_cotisation_salarie * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (case when p_cotisation_salarie   then t_cotsal.valeurmontantsal::numeric      else 0 end) AS montant_sal,
                    t_rubriques.coefficient_txp * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (case when p_cotisation_patronale then t_cotsal.valeurtauxpatronal::numeric    else 0 end) AS taux_pat,
                    t_rubriques.c_cotisation_patronale * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (case when p_cotisation_patronale then t_cotsal.valeurmontantpatronal::numeric else 0 end) AS montant_pat,
                    t_rubriques.c_od_net_salarie * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (CASE WHEN p_od_net_salarie       THEN t_cotsal.valeurmontantsal::numeric      ELSE 0 END) AS od_net,
                    t_rubriques.c_od_net_patronale * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (CASE WHEN p_od_net_patronale     THEN t_cotsal.valeurmontantpatronal::numeric ELSE 0 END) AS od_net_p,
                    t_rubriques.c_avantage_nature * (CASE WHEN t_rub.gain = 1 THEN -1 ELSE 1 END) * (CASE WHEN p_avantage_nature      THEN t_cotsal.valeurmontantsal::numeric      ELSE 0 END) AS avt_nat,
                    t_rubriques.c_net_imposable * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * CASE WHEN p_net_imposable THEN (CASE s_net_imposable
                            WHEN 0 THEN t_cotsal.valeurnombre::numeric
                            WHEN 1 THEN t_cotsal.valeurbase::numeric
                            WHEN 2 THEN t_cotsal.valeurtauxsal::numeric
                            WHEN 3 THEN t_cotsal.valeurmontantsal::numeric
                            WHEN 4 THEN t_cotsal.valeurtauxpatronal::numeric
                            WHEN 5 THEN t_cotsal.valeurmontantpatronal::numeric
                            WHEN 6 THEN t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                            WHEN 7 THEN t_cotsal.valeurmontantsal::numeric - t_cotsal.valeurmontantpatronal::numeric
                            WHEN 8 THEN -t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                        END) ELSE 0 END AS net_imposable,
                    t_rubriques.c_net_a_payer * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END) * (CASE WHEN p_net_a_payer          THEN t_cotsal.valeurmontantsal::numeric      ELSE 0 END) AS net_a_payer,
                    t_rubriques.c_nombre_provisions * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_nombre_provisions
                            then (CASE s_nombre_provisions
                                WHEN 0 THEN t_cotsal.valeurnombre::numeric
                                WHEN 1 THEN t_cotsal.valeurbase::numeric
                                WHEN 2 THEN t_cotsal.valeurtauxsal::numeric
                                WHEN 3 THEN t_cotsal.valeurmontantsal::numeric
                                WHEN 4 THEN t_cotsal.valeurtauxpatronal::numeric
                                WHEN 5 THEN t_cotsal.valeurmontantpatronal::numeric
                                WHEN 6 THEN t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                                WHEN 7 THEN t_cotsal.valeurmontantsal::numeric - t_cotsal.valeurmontantpatronal::numeric
                                WHEN 8 THEN -t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                                END)
                            else 0 end
                        AS nombre_provisions,
                    t_rubriques.c_montant_provisions * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_montant_provisions
                            then (CASE s_montant_provisions
                                WHEN 0 THEN t_cotsal.valeurnombre::numeric
                                WHEN 1 THEN t_cotsal.valeurbase::numeric
                                WHEN 2 THEN t_cotsal.valeurtauxsal::numeric
                                WHEN 3 THEN t_cotsal.valeurmontantsal::numeric
                                WHEN 4 THEN t_cotsal.valeurtauxpatronal::numeric
                                WHEN 5 THEN t_cotsal.valeurmontantpatronal::numeric
                                WHEN 6 THEN t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                                WHEN 7 THEN t_cotsal.valeurmontantsal::numeric - t_cotsal.valeurmontantpatronal::numeric
                                WHEN 8 THEN -t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                                END)
                            else 0 end
                        AS montant_provisions,
                    t_rubriques.c_masse_salariale_provisionnee * (CASE WHEN t_rub.gain = 1 THEN 1 ELSE -1 END)
                        * CASE WHEN p_masse_salariale_provisionnee
                            then (CASE s_masse_salariale_provisionnee
                                WHEN 0 THEN t_cotsal.valeurnombre::numeric
                                WHEN 1 THEN t_cotsal.valeurbase::numeric
                                WHEN 2 THEN t_cotsal.valeurtauxsal::numeric
                                WHEN 3 THEN t_cotsal.valeurmontantsal::numeric
                                WHEN 4 THEN t_cotsal.valeurtauxpatronal::numeric
                                WHEN 5 THEN t_cotsal.valeurmontantpatronal::numeric
                                WHEN 6 THEN t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                                WHEN 7 THEN t_cotsal.valeurmontantsal::numeric - t_cotsal.valeurmontantpatronal::numeric
                                WHEN 8 THEN -t_cotsal.valeurmontantsal::numeric + t_cotsal.valeurmontantpatronal::numeric
                                END)
                            else 0 end
                        AS masse_salariale_provisionnee,
                    t_rub.nodordre AS ordre,
                    1 AS type_rub
                FROM prod_sage.t_cotsal
                    JOIN w_periode ON 1=1
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = T_COTSAL.numsalarie
                        AND date_paie_encours between w_profils.date_debut and w_profils.date_fin
                    JOIN prod_sage.t_rub ON t_rub.coderubrique = T_COTSAL.coderubrique
                    JOIN rh.t_rubriques ON t_rubriques.code_original = t_rub.coderubrique
                WHERE true
                    -- Filtrer les lignes générées systématiquement tous les mois par Sage pour chaque salarié même s'il n'y a rien.
                    AND (false
                        OR t_cotsal.valeurnombre != 0
                        OR t_cotsal.valeurmontantsal != 0
                        OR t_cotsal.valeurmontantpatronal != 0)
                    AND (false
                        OR p_nombre
                        OR p_base
                        OR p_heures_contrat
                        OR p_heures_payees
                        OR p_heures_travaillees
                        OR p_masse_salariale
                        OR p_brut
                        OR p_avantage_nature
                        OR p_frais_imposables
                        OR p_cotisation_salarie
                        OR p_cotisation_patronale
                        OR p_od_net_salarie
                        OR p_od_net_patronale
                        OR p_net_imposable
                        OR p_net_a_payer
                        OR p_nombre_provisions
                        OR p_montant_provisions
                        OR p_masse_salariale_provisionnee)
            ;

            -- Cumuls paie cloturee
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    t_hcum.datehist AS date,
                    t_hcum.typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', t_hcum.datehist)::text||lpad(date_part('month', t_hcum.datehist), 2, '0'))::numeric AS mois,
                    0 AS coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    t_rubriques.c_base                  * CASE WHEN p_base                  THEN t_hcum.valeurcumul::numeric else 0 end AS base,
                    t_rubriques.c_nombre                * CASE WHEN p_nombre                THEN t_hcum.valeurcumul::numeric else 0 end AS nombre,
                    t_rubriques.c_heures_contrat        * CASE WHEN p_heures_contrat        THEN t_hcum.valeurcumul::numeric else 0 end AS heure_contrat,
                    t_rubriques.c_heures_payees         * CASE WHEN p_heures_payees         THEN t_hcum.valeurcumul::numeric else 0 end AS heure_payee,
                    t_rubriques.c_heures_travaillees    * CASE WHEN p_heures_travaillees    THEN t_hcum.valeurcumul::numeric else 0 end AS heure_travaillee,
                    t_rubriques.c_masse_salariale       * CASE WHEN p_masse_salariale       THEN t_hcum.valeurcumul::numeric else 0 end AS masse_salariale,
                    t_rubriques.c_brut                  * CASE WHEN p_brut                  THEN t_hcum.valeurcumul::numeric else 0 end AS montant_brut,
                    t_rubriques.c_frais_imposables      * case when p_frais_imposables      then t_hcum.valeurcumul::numeric else 0 end AS montant_frais_imposables,
                    t_rubriques.coefficient_txs         * case when p_cotisation_salarie    then t_hcum.valeurcumul::numeric else 0 end AS taux_sal,
                    t_rubriques.c_cotisation_salarie    * case when p_cotisation_salarie    then t_hcum.valeurcumul::numeric else 0 end AS montant_sal,
                    t_rubriques.coefficient_txp         * case when p_cotisation_patronale  then t_hcum.valeurcumul::numeric else 0 end AS taux_pat,
                    t_rubriques.c_cotisation_patronale  * case when p_cotisation_patronale  then t_hcum.valeurcumul::numeric else 0 end AS montant_pat,
                    t_rubriques.c_od_net_salarie        * CASE WHEN p_od_net_salarie        THEN t_hcum.valeurcumul::numeric ELSE 0 END AS od_net,
                    t_rubriques.c_od_net_patronale      * CASE WHEN p_od_net_patronale      THEN t_hcum.valeurcumul::numeric ELSE 0 END AS od_net_p,
                    t_rubriques.c_avantage_nature       * CASE WHEN p_avantage_nature       THEN t_hcum.valeurcumul::numeric ELSE 0 END AS avt_nat,
                    t_rubriques.c_net_imposable         * CASE WHEN p_net_imposable         THEN t_hcum.valeurcumul::numeric ELSE 0 END AS net_imposable,
                    t_rubriques.c_net_a_payer           * CASE WHEN p_net_a_payer           THEN t_hcum.valeurcumul::numeric ELSE 0 END AS net_a_payer,
                    t_rubriques.c_nombre_provisions             * CASE WHEN p_nombre_provisions             THEN t_hcum.valeurcumul::numeric ELSE 0 END AS nombre_provisions,
                    t_rubriques.c_montant_provisions            * CASE WHEN p_montant_provisions            THEN t_hcum.valeurcumul::numeric ELSE 0 END AS montant_provisions,
                    t_rubriques.c_masse_salariale_provisionnee  * CASE WHEN p_masse_salariale_provisionnee  THEN t_hcum.valeurcumul::numeric ELSE 0 END AS masse_salariale_provisionnee,
                    t_rubriques.rang_edition AS ordre,
                    2 AS type_rub
                FROM prod_sage.t_hcum
                    JOIN w_hst_bul ON 1=1
                        AND w_hst_bul.numsalarie = t_hcum.numsalarie
                        AND w_hst_bul.datehist = t_hcum.datehist
                        AND w_hst_bul.typedubulletin = t_hcum.typedubulletin
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = t_hcum.numsalarie
                        AND w_hst_bul.datehist_cti between w_profils.date_debut and w_profils.date_fin
                        AND w_profils.typedubulletin = t_hcum.typedubulletin
                    JOIN rh.t_rubriques ON t_rubriques.code_original = 'C' || lpad(t_hcum.entite, 3, '0')
                WHERE true 
                    AND t_hcum.datehist >= rhp('rhprovider_start')::date
                    AND (false
                        OR p_base
                        OR p_nombre
                        OR p_heures_contrat
                        OR p_heures_payees
                        OR p_heures_travaillees
                        OR p_masse_salariale
                        OR p_brut
                        OR p_avantage_nature
                        OR p_frais_imposables
                        OR p_cotisation_salarie
                        OR p_cotisation_patronale
                        OR p_od_net_salarie
                        OR p_od_net_patronale
                        OR p_net_imposable
                        OR p_net_a_payer
                        OR p_nombre_provisions
                        OR p_montant_provisions
                        OR p_masse_salariale_provisionnee)
            ;

            -- Cumuls paie non cloturee
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    date_paie_encours AS date,
                    0 as typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', date_paie_encours)::text||lpad(date_part('month', date_paie_encours), 2, '0'))::numeric AS mois,
                    0 AS coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    t_rubriques.c_base                  * CASE WHEN p_base                  THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS base,
                    t_rubriques.c_nombre                * CASE WHEN p_nombre                THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS nombre,
                    t_rubriques.c_heures_contrat        * CASE WHEN p_heures_contrat        THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS heure_contrat,
                    t_rubriques.c_heures_payees         * CASE WHEN p_heures_payees         THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS heure_payee,
                    t_rubriques.c_heures_travaillees    * CASE WHEN p_heures_travaillees    THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS heure_travaillee,
                    t_rubriques.c_masse_salariale       * CASE WHEN p_masse_salariale       THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS masse_salariale,
                    t_rubriques.c_brut                  * CASE WHEN p_brut                  THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS montant_brut,
                    t_rubriques.c_frais_imposables      * case when p_frais_imposables      then t_cumsal.valeurcumintermediaire::numeric else 0 end AS montant_frais_imposables,
                    t_rubriques.coefficient_txs         * case when p_cotisation_salarie    then t_cumsal.valeurcumintermediaire::numeric else 0 end AS taux_sal,
                    t_rubriques.c_cotisation_salarie    * case when p_cotisation_salarie    then t_cumsal.valeurcumintermediaire::numeric else 0 end AS montant_sal,
                    t_rubriques.coefficient_txp         * case when p_cotisation_patronale  then t_cumsal.valeurcumintermediaire::numeric else 0 end AS taux_pat,
                    t_rubriques.c_cotisation_patronale  * case when p_cotisation_patronale  then t_cumsal.valeurcumintermediaire::numeric else 0 end AS montant_pat,
                    t_rubriques.c_od_net_salarie        * CASE WHEN p_od_net_salarie        THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS od_net,
                    t_rubriques.c_od_net_patronale      * CASE WHEN p_od_net_patronale      THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS od_net_p,
                    t_rubriques.c_avantage_nature       * CASE WHEN p_avantage_nature       THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS avt_nat,
                    t_rubriques.c_net_imposable         * CASE WHEN p_net_imposable         THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS net_imposable,
                    t_rubriques.c_net_a_payer           * CASE WHEN p_net_a_payer           THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS net_a_payer,
                    t_rubriques.c_nombre_provisions             * CASE WHEN p_nombre_provisions             THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS nombre_provisions,
                    t_rubriques.c_montant_provisions            * CASE WHEN p_montant_provisions            THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS montant_provisions,
                    t_rubriques.c_masse_salariale_provisionnee  * CASE WHEN p_masse_salariale_provisionnee  THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS masse_salariale_provisionnee,
                    t_rubriques.rang_edition AS ordre,
                    2 AS type_rub
                FROM prod_sage.t_cumsal
                    JOIN w_periode ON 1=1
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = t_cumsal.numsalarie
                        AND date_paie_encours between w_profils.date_debut and w_profils.date_fin
                    JOIN rh.t_rubriques ON t_rubriques.code_original = 'C' || lpad(t_cumsal.opcstcumul, 3, '0')
                WHERE false
                    OR p_base
                    OR p_nombre
                    OR p_heures_contrat
                    OR p_heures_payees
                    OR p_heures_travaillees
                    OR p_masse_salariale
                    OR p_brut
                    OR p_avantage_nature
                    OR p_frais_imposables
                    OR p_cotisation_salarie
                    OR p_cotisation_patronale
                    OR p_od_net_salarie
                    OR p_od_net_patronale
                    OR p_net_imposable
                    OR p_net_a_payer
                    OR p_nombre_provisions
                    OR p_montant_provisions
                    OR p_masse_salariale_provisionnee
            ;

            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    t_hcum.datehist AS date,
                    t_hcum.typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', t_hcum.datehist)::text||lpad(date_part('month', t_hcum.datehist), 2, '0'))::numeric AS mois,
                    0 AS coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    t_rubriques.c_base                  * CASE WHEN p_base                  THEN t_hcum.valeurcumul::numeric else 0 end AS base,
                    t_rubriques.c_nombre                * CASE WHEN p_nombre                THEN t_hcum.valeurcumul::numeric else 0 end AS nombre,
                    t_rubriques.c_heures_contrat        * CASE WHEN p_heures_contrat        THEN t_hcum.valeurcumul::numeric else 0 end AS heure_contrat,
                    t_rubriques.c_heures_payees         * CASE WHEN p_heures_payees         THEN t_hcum.valeurcumul::numeric else 0 end AS heure_payee,
                    t_rubriques.c_heures_travaillees    * CASE WHEN p_heures_travaillees    THEN t_hcum.valeurcumul::numeric else 0 end AS heure_travaillee,
                    t_rubriques.c_masse_salariale       * CASE WHEN p_masse_salariale       THEN t_hcum.valeurcumul::numeric else 0 end AS masse_salariale,
                    t_rubriques.c_brut                  * CASE WHEN p_brut                  THEN t_hcum.valeurcumul::numeric else 0 end AS montant_brut,
                    t_rubriques.c_frais_imposables      * case when p_frais_imposables      then t_hcum.valeurcumul::numeric else 0 end AS montant_frais_imposables,
                    t_rubriques.coefficient_txs         * case when p_cotisation_salarie    then t_hcum.valeurcumul::numeric else 0 end AS taux_sal,
                    t_rubriques.c_cotisation_salarie    * case when p_cotisation_salarie    then t_hcum.valeurcumul::numeric else 0 end AS montant_sal,
                    t_rubriques.coefficient_txp         * case when p_cotisation_patronale  then t_hcum.valeurcumul::numeric else 0 end AS taux_pat,
                    t_rubriques.c_cotisation_patronale  * case when p_cotisation_patronale  then t_hcum.valeurcumul::numeric else 0 end AS montant_pat,
                    t_rubriques.c_od_net_salarie        * CASE WHEN p_od_net_salarie        THEN t_hcum.valeurcumul::numeric ELSE 0 END AS od_net,
                    t_rubriques.c_od_net_patronale      * CASE WHEN p_od_net_patronale      THEN t_hcum.valeurcumul::numeric ELSE 0 END AS od_net_p,
                    t_rubriques.c_avantage_nature       * CASE WHEN p_avantage_nature       THEN t_hcum.valeurcumul::numeric ELSE 0 END AS avt_nat,
                    t_rubriques.c_net_imposable         * CASE WHEN p_net_imposable         THEN t_hcum.valeurcumul::numeric ELSE 0 END AS net_imposable,
                    t_rubriques.c_net_a_payer           * CASE WHEN p_net_a_payer           THEN t_hcum.valeurcumul::numeric ELSE 0 END AS net_a_payer,
                    t_rubriques.c_nombre_provisions             * CASE WHEN p_nombre_provisions             THEN t_hcum.valeurcumul::numeric ELSE 0 END AS nombre_provisions,
                    t_rubriques.c_montant_provisions            * CASE WHEN p_montant_provisions            THEN t_hcum.valeurcumul::numeric ELSE 0 END AS montant_provisions,
                    t_rubriques.c_masse_salariale_provisionnee  * CASE WHEN p_masse_salariale_provisionnee  THEN t_hcum.valeurcumul::numeric ELSE 0 END AS masse_salariale_provisionnee,
                    t_rubriques.rang_edition AS ordre,
                    2 AS type_rub
                FROM prod_sage.t_hcum
                    JOIN w_hst_bul ON 1=1
                        AND w_hst_bul.numsalarie = t_hcum.numsalarie
                        AND w_hst_bul.datehist = t_hcum.datehist
                        AND w_hst_bul.typedubulletin = t_hcum.typedubulletin
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = t_hcum.numsalarie
                        AND w_hst_bul.datehist_cti between w_profils.date_debut and w_profils.date_fin
                        AND w_profils.typedubulletin = t_hcum.typedubulletin
                    JOIN prod_sage.t_cst ON 1=1
                        AND typeconstante = 6
                        AND t_cst.CodeOperande1 = t_hcum.entite
                    JOIN rh.t_rubriques ON t_rubriques.code_original = t_cst.CodeConstante
                WHERE true 
                    AND t_hcum.datehist >= rhp('rhprovider_start')::date
                    AND t_hcum.valeurcumul::numeric != 0
                    AND (false
                        OR p_base
                        OR p_nombre
                        OR p_heures_contrat
                        OR p_heures_payees
                        OR p_heures_travaillees
                        OR p_masse_salariale
                        OR p_brut
                        OR p_avantage_nature
                        OR p_frais_imposables
                        OR p_cotisation_salarie
                        OR p_cotisation_patronale
                        OR p_od_net_salarie
                        OR p_od_net_patronale
                        OR p_net_imposable
                        OR p_net_a_payer
                        OR p_nombre_provisions
                        OR p_montant_provisions
                        OR p_masse_salariale_provisionnee)
            ;

            -- Cumuls paie non cloturee
            INSERT INTO w_hp
                SELECT
                    w_profils.contrat_mois_id,
                    w_profils.contrat_id,
                    w_profils.salarie_id,
                    w_profils.profil_id,
                    w_profils.matricule AS code_original,
                    w_profils.matricule AS matricule,
                    w_profils.numsalarie,
                    w_profils.unite,
                    w_profils.categorie,
                    date_paie_encours AS date,
                    0 as typedubulletin,
                    w_profils.bul_date_debut as date_debut,
                    w_profils.bul_date_fin as date_fin,
                    (date_part('year', date_paie_encours)::text||lpad(date_part('month', date_paie_encours), 2, '0'))::numeric AS mois,
                    0 AS coderubrique,
                    t_rubriques.oid AS rub_id,
                    t_rubriques.code_original AS rub_code,
                    t_rubriques.texte AS rub_texte,
                    t_rubriques.c_base                  * CASE WHEN p_base                  THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS base,
                    t_rubriques.c_nombre                * CASE WHEN p_nombre                THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS nombre,
                    t_rubriques.c_heures_contrat        * CASE WHEN p_heures_contrat        THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS heure_contrat,
                    t_rubriques.c_heures_payees         * CASE WHEN p_heures_payees         THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS heure_payee,
                    t_rubriques.c_heures_travaillees    * CASE WHEN p_heures_travaillees    THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS heure_travaillee,
                    t_rubriques.c_masse_salariale       * CASE WHEN p_masse_salariale       THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS masse_salariale,
                    t_rubriques.c_brut                  * CASE WHEN p_brut                  THEN t_cumsal.valeurcumintermediaire::numeric else 0 end AS montant_brut,
                    t_rubriques.c_frais_imposables      * case when p_frais_imposables      then t_cumsal.valeurcumintermediaire::numeric else 0 end AS montant_frais_imposables,
                    t_rubriques.coefficient_txs         * case when p_cotisation_salarie    then t_cumsal.valeurcumintermediaire::numeric else 0 end AS taux_sal,
                    t_rubriques.c_cotisation_salarie    * case when p_cotisation_salarie    then t_cumsal.valeurcumintermediaire::numeric else 0 end AS montant_sal,
                    t_rubriques.coefficient_txp         * case when p_cotisation_patronale  then t_cumsal.valeurcumintermediaire::numeric else 0 end AS taux_pat,
                    t_rubriques.c_cotisation_patronale  * case when p_cotisation_patronale  then t_cumsal.valeurcumintermediaire::numeric else 0 end AS montant_pat,
                    t_rubriques.c_od_net_salarie        * CASE WHEN p_od_net_salarie        THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS od_net,
                    t_rubriques.c_od_net_patronale      * CASE WHEN p_od_net_patronale      THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS od_net_p,
                    t_rubriques.c_avantage_nature       * CASE WHEN p_avantage_nature       THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS avt_nat,
                    t_rubriques.c_net_imposable         * CASE WHEN p_net_imposable         THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS net_imposable,
                    t_rubriques.c_net_a_payer           * CASE WHEN p_net_a_payer           THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS net_a_payer,
                    t_rubriques.c_nombre_provisions             * CASE WHEN p_nombre_provisions             THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS nombre_provisions,
                    t_rubriques.c_montant_provisions            * CASE WHEN p_montant_provisions            THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS montant_provisions,
                    t_rubriques.c_masse_salariale_provisionnee  * CASE WHEN p_masse_salariale_provisionnee  THEN t_cumsal.valeurcumintermediaire::numeric ELSE 0 END AS masse_salariale_provisionnee,
                    t_rubriques.rang_edition AS ordre,
                    2 AS type_rub
                FROM prod_sage.t_cumsal
                    JOIN w_periode ON 1=1
                    JOIN w_profils ON 1=1
                        AND w_profils.numsalarie = t_cumsal.numsalarie
                        AND date_paie_encours between w_profils.date_debut and w_profils.date_fin
                    JOIN prod_sage.t_cst ON 1=1
                        AND typeconstante = 6
                        AND t_cst.CodeOperande1 = t_cumsal.opcstcumul
                    JOIN rh.t_rubriques ON t_rubriques.code_original = t_cst.CodeConstante
                WHERE true
                    AND t_cumsal.valeurcumintermediaire::numeric != 0
                    AND (false
                        OR p_base
                        OR p_nombre
                        OR p_heures_contrat
                        OR p_heures_payees
                        OR p_heures_travaillees
                        OR p_masse_salariale
                        OR p_brut
                        OR p_avantage_nature
                        OR p_frais_imposables
                        OR p_cotisation_salarie
                        OR p_cotisation_patronale
                        OR p_od_net_salarie
                        OR p_od_net_patronale
                        OR p_net_imposable
                        OR p_net_a_payer
                        OR p_nombre_provisions
                        OR p_montant_provisions
                        OR p_masse_salariale_provisionnee)
            ;

            ]]></sqlcmd>
        </NODE>
        <NODE label="Historique de la paie - 2/3 (commun) ">
            <sqlcmd><![CDATA[

            CREATE INDEX i_w_hp_1 ON w_hp USING btree (rub_code)
            ;

            -- Association rubriques / comptes
            DROP TABLE IF EXISTS w_RUB_CPG
            ;

            CREATE TEMP TABLE w_RUB_CPG AS
                SELECT
                    CODERUBRIQUE,
                    MAX(COALESCE(COMPTEGENERAL,'')) AS COMPTEGENERAL,
                    0::bigint AS compte_id
                FROM prod_sage.T_RUB
                    LEFT JOIN prod_sage.T_MOD ON 1!=1
                        OR CODEELEMENT = to_char(CODERUBRIQUE,'FM0000')
                        OR CODEELEMENT = to_char(CODERUBRIQUE,'FM000')
                        OR CODEELEMENT = to_char(CODERUBRIQUE,'FM00')
                        OR CODEELEMENT = to_char(CODERUBRIQUE,'FM0')
                    LEFT JOIN prod_sage.T_ECR ON 1=1
                        AND T_MOD.NOLIEN = T_ECR.NOLIEN
                        AND T_MOD.NOLIGNE = T_ECR.NOLIGNE
                        AND COMPTEGENERAL BETWEEN '6' AND '79999999'
                GROUP BY 1
            ;

            UPDATE w_RUB_CPG
            SET COMPTEGENERAL = T_ECR.COMPTEGENERAL
            FROM prod_sage.T_MOD
                JOIN prod_sage.T_ECR ON T_MOD.NOLIEN = T_ECR.NOLIEN AND T_MOD.NOLIGNE = T_ECR.NOLIGNE
            WHERE w_RUB_CPG.COMPTEGENERAL = '' AND
                CODEELEMENT = 'BRUT' AND
                CODERUBRIQUE IN (
                    SELECT CODERUBRIQUE
                    FROM prod_sage.T_HBNS
                    GROUP BY 1)
            ;

            UPDATE w_RUB_CPG
            SET COMPTEGENERAL = T_ECR.COMPTEGENERAL
            FROM prod_sage.T_MOD
                JOIN prod_sage.T_ECR ON T_MOD.NOLIEN = T_ECR.NOLIEN AND T_MOD.NOLIGNE = T_ECR.NOLIGNE
            WHERE w_RUB_CPG.COMPTEGENERAL = '' AND
                CODEELEMENT = 'BRUT' AND
                CODERUBRIQUE IN (
                    SELECT CODERUBRIQUE
                    FROM prod_sage.T_BNSSAL
                    GROUP BY 1)
            ;

            UPDATE w_RUB_CPG
            SET compte_id = t_compte.oid
            FROM rh.t_compte
            WHERE COMPTEGENERAL = t_compte.code_original
            ;

            CREATE INDEX i_RUB_CPG_1
            ON w_RUB_CPG
            USING btree (CODERUBRIQUE)
            ;
            
            
            -- Modèle comptable complet
            DROP TABLE IF EXISTS w_MOD_SAUF
            ;
            CREATE TEMP TABLE w_MOD_SAUF AS
                SELECT NOLIEN, NOLIGNE
                FROM prod_sage.T_MOD 
                WHERE CODEELEMENT = 'BRUT'
                GROUP BY 1,2
            ;
            
            DROP TABLE IF EXISTS w_SEL
            ;
            CREATE TEMP TABLE w_SEL AS
                SELECT 
                    T_MOD.NOLIEN,
                    T_MOD.NOLIGNE,
                    COMPTEGENERAL,
                    base.cti_group_array3(DISTINCT CASE WHEN AJOUT = 1 OR w_MOD_SAUF.NOLIEN IS NULL THEN T_RUB.CODERUBRIQUE ELSE 0 END) AS RUBRIQUES,
                    base.cti_group_array3(DISTINCT CASE WHEN AJOUT <> 1 AND w_MOD_SAUF.NOLIEN IS NOT NULL THEN T_RUB.CODERUBRIQUE ELSE 0 END) AS RUBRIQUES_SAUF,
                    MAX(CASE WHEN NUMERO = 4 THEN BORNEINF ELSE NULL END) AS BORNEINF_CATEGORIE,
                    MAX(CASE WHEN NUMERO = 4 THEN BORNESUP ELSE NULL END) AS BORNESUP_CATEGORIE,
                    
                    MAX(CASE WHEN NUMERO = 3 THEN BORNEINF ELSE NULL END) AS BORNEINF_UNITE,
                    MAX(CASE WHEN NUMERO = 3 THEN BORNESUP ELSE NULL END) AS BORNESUP_UNITE,
                    
                    MAX(CASE WHEN NUMERO = 9 THEN BORNEINF ELSE NULL END) AS BORNEINF_MATRICULE,
                    MAX(CASE WHEN NUMERO = 9 THEN BORNESUP ELSE NULL END) AS BORNESUP_MATRICULE
                FROM prod_sage.T_MOD 
                    LEFT JOIN w_MOD_SAUF ON W_MOD_SAUF.NOLIEN = T_MOD.NOLIEN AND
                                W_MOD_SAUF.NOLIGNE = T_MOD.NOLIGNE
                    JOIN prod_sage.T_ECR ON T_MOD.NOLIEN = T_ECR.NOLIEN AND
                        T_MOD.NOLIGNE = T_ECR.NOLIGNE AND
                        COMPTEGENERAL BETWEEN '6' AND '799999'
                    JOIN prod_sage.T_SEL ON T_MOD.NOLIEN = T_SEL.NOLIEN
                        AND T_MOD.NOLIGNE = T_SEL.NOLIGNE
                    JOIN prod_sage.t_CRITERESSEL ON t_CRITERESSEL.IDSEL = T_SEL.IDSEL
                    LEFT JOIN prod_sage.T_RUB ON (CODEELEMENT = T_RUB.CODERUBRIQUE OR TYPEELEMENT = 2 AND CODEELEMENT = 'BRUT' AND 
                                T_RUB.CODERUBRIQUE IN (SELECT coderubrique FROM prod_sage.T_RUB WHERE TYPERUBRIQUE = 1))
                GROUP BY 1,2,3
            ;

            UPDATE w_SEL SET
                BORNEINF_CATEGORIE = COALESCE(BORNEINF_CATEGORIE,''),
                BORNESUP_CATEGORIE = COALESCE(BORNESUP_CATEGORIE,'99999999'),
                BORNEINF_UNITE = COALESCE(BORNEINF_UNITE,''),
                BORNESUP_UNITE = COALESCE(BORNESUP_UNITE,'99999999')
            ;

            
            DROP TABLE IF EXISTS w_HP_CPT;
            CREATE TEMP TABLE w_HP_CPT AS
            SELECT NUMSALARIE, UNITE, CATEGORIE, CODERUBRIQUE, ''::text AS COMPTEGENERAL, NULL::bigint AS compte_id
            FROM w_hp 
            WHERE CODERUBRIQUE <> 0
            GROUP BY 1,2,3,4
            ;

            UPDATE w_HP_CPT
            SET COMPTEGENERAL = w_SEL.COMPTEGENERAL
            FROM w_SEL
            WHERE w_hp_CPT.CODERUBRIQUE = ANY(w_SEL.RUBRIQUES) AND
                w_hp_CPT.CODERUBRIQUE <> ALL(w_SEL.RUBRIQUES_SAUF)  AND
                UNITE BETWEEN BORNEINF_UNITE AND  BORNESUP_UNITE AND
                CATEGORIE BETWEEN BORNEINF_CATEGORIE AND  BORNESUP_CATEGORIE
            ;

            UPDATE w_HP_CPT
            SET compte_id = t_compte.oid
            FROM rh.t_compte
            WHERE COMPTEGENERAL = t_compte.code
            ;
            
            CREATE INDEX i_HP_CPT_1
            ON w_HP_CPT
            USING btree (NUMSALARIE)
            ;

            -- 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,
                nombre_provisions,
				montant_provisions,
				montant_masse_salariale_provisionnee)
                SELECT
                    w_hp.matricule||date::date||typedubulletin::text as code_original,
                    date_part('year', age(date, date_naissance)) AS age_id,
                    base,
                    nombre,
                    contrat_id,
                    contrat_mois_id,
                    w_hp.date_debut,
                    w_hp.date_fin,
                    date::date AS date_paie,
                    w_hp.mois AS mois_activite,
                    w_hp.mois AS mois_paie,
                    heure_contrat,
                    heure_payee,
                    heure_travaillee,
                    avt_nat AS montant_avantage_nature,
                    montant_brut AS montant_brut,
                    masse_salariale as montant_masse_salariale,
                    montant_pat AS montant_cotisation_patronale,
                    montant_sal AS montant_cotisation_salarie,
                    montant_frais_imposables,
                    net_a_payer AS montant_net_a_payer_salarie,
                    net_imposable AS montant_net_imposable_salarie,
                    od_net AS montant_od_net_salarie,
                    0 AS organisme_cotisation_id,
                    w_hp.profil_id,
                    t_rubriques.oid AS rubrique_id,
                    COALESCE(w_HP_CPT.compte_id, w_RUB_CPG.compte_id,0) AS compte_id,
                    p_salaries.oid,
                    taux_pat AS taux_cotisation_patronale,
                    taux_sal AS taux_cotisation_salarie,
                    nombre_provisions,
					montant_provisions,
					masse_salariale_provisionnee AS montant_masse_salariale_provisionnee
                FROM w_hp
                    JOIN rh.p_salaries ON p_salaries.matricule = w_hp.matricule
                    JOIN rh.t_rubriques ON t_rubriques.code_original = w_hp.rub_code
                    LEFT JOIN w_HP_CPT ON 
                        w_hp.NUMSALARIE = w_HP_CPT.NUMSALARIE AND
                        w_hp.UNITE = w_HP_CPT.UNITE AND
                        w_hp.CATEGORIE = w_HP_CPT.CATEGORIE AND
                        w_hp.CODERUBRIQUE = w_HP_CPT.CODERUBRIQUE
                    LEFT JOIN w_RUB_CPG ON w_hp.rub_code = w_RUB_CPG.CODERUBRIQUE
                WHERE t_rubriques.p_detail
            ;

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

            ]]></sqlcmd>
        </NODE>
        <NODE label="Historique de la paie - 3/3 (mode classique)">
            <condition><![CDATA[
                
            -- Historique de paie classique.
            select valeur = 0
            from rh.t_divers
            where code = 'OPT_STD_HP'
            ;

            ]]></condition>
            <sqlcmd><![CDATA[

            -- 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
                    t_sal.matriculesalarie AS matricule,
                    t_hcum.datehist::date AS date,
                    (date_part('year', t_hcum.datehist)::text||lpad(date_part('month', t_hcum.datehist), 2, '0'))::numeric AS mois,
                    round(sum(CASE WHEN ENTITE = 5 THEN t_hcum.VALEURCUMUL  ELSE 0 END)::numeric,2) AS hcum_avantage_nature,
                    round(sum(CASE WHEN ENTITE = 8 THEN t_hcum.VALEURCUMUL  ELSE 0 END)::numeric,2) AS hcum_brut,
                    round(sum(CASE WHEN ENTITE = 6 THEN t_hcum.VALEURCUMUL  ELSE 0 END)::numeric,2) AS hcum_cotisation_patronale,
                    round(sum(CASE WHEN ENTITE = 7 THEN t_hcum.VALEURCUMUL  ELSE 0 END)::numeric,2) AS hcum_cotisation_salarie,
                    0::numeric AS hcum_frais_imposables,
                    round(sum(CASE WHEN ENTITE = 3 THEN t_hcum.VALEURCUMUL  ELSE 0 END)::numeric,2) AS hcum_net_a_payer_salarie,
                    round(sum(CASE WHEN ENTITE = 4 THEN t_hcum.VALEURCUMUL  ELSE 0 END)::numeric,2) AS hcum_net_imposable_salarie,
                    0::numeric AS montant_od_net_salarie,
                FROM prod_sage.t_hcum
                    JOIN prod_sage.t_sal ON t_sal.sa_compteurnumero = t_hcum.numsalarie
                WHERE t_hcum.datehist >= rhp('rhprovider_start')::date
                GROUP BY 1,2,3
            ;

            -- 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 (
                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_masse_salariale,
                montant_avantage_nature,
                montant_brut,
                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,
                nombre_provisions,
                montant_provisions,
                montant_masse_salariale_provisionnee)
                SELECT
                    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,
                    0 as heure_contrat,
                    0 as heure_payee,
                    0 as heure_travaillee,
                    0 as montant_masse_salariale,
                    COALESCE(hcum_avantage_nature,0) - subq.montant_avantage_nature AS montant_avantage_nature,
                    COALESCE(hcum_brut,0) - subq.montant_brut AS montant_brut,
                    0 AS montant_cotisation_patronale,
                    0 AS montant_cotisation_salarie,
                    0 AS montant_frais_imposables,
                    COALESCE(hcum_net_a_payer_salarie,0) - subq.montant_net_a_payer_salarie AS montant_net_a_payer_salarie,
                    COALESCE(hcum_net_imposable_salarie,0) - subq.montant_net_imposable_salarie AS montant_net_imposable_salarie,
                    0 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,
                    0 AS nombre_provisions,
					0 AS montant_provisions,
					0 AS montant_masse_salariale_provisionnee
                FROM (
                    SELECT
                        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,
                        sum(montant_avantage_nature) AS montant_avantage_nature,
                        sum(montant_brut) AS montant_brut,
                        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,
                        0 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,
                        0 AS nombre_provisions,
                        0 AS montant_provisions,
                        0 AS montant_masse_salariale_provisionnee
                    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, 17,18,19,20) AS subq
                JOIN rh.p_salaries ON p_salaries.oid = subq.salarie_id
                JOIN w_totaux ON 1=1
                    AND w_totaux.matricule = p_salaries.matricule
                    AND w_totaux.date = subq.date_paie
            WHERE 1!=1
                OR COALESCE(hcum_avantage_nature,0) - subq.montant_avantage_nature <> 0
                OR COALESCE(hcum_brut,0) - subq.montant_brut <> 0
                OR COALESCE(hcum_net_a_payer_salarie,0) - subq.montant_net_a_payer_salarie <> 0
                OR COALESCE(hcum_net_imposable_salarie,0) - subq.montant_net_imposable_salarie <> 0
            ;

            -- Insérer pour chaque bulletin une ligne qui va faire le compte avec le total (rubrique 'C006' nommée 'Ecart cumulé patronal')
            INSERT INTO rh.p_historique_paie
                (
                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_masse_salariale,
                montant_avantage_nature,
                montant_brut,
                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,
                nombre_provisions,
                montant_provisions,
                montant_masse_salariale_provisionnee
                )
                SELECT
                    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,
                    0 as heure_contrat,
                    0 as heure_payee,
                    0 as heure_travaillee,
                    0 as montant_masse_salariale,
                    0 AS montant_avantage_nature,
                    0 AS montant_brut,
                    COALESCE(hcum_cotisation_patronale,0) - subq.montant_cotisation_patronale AS montant_cotisation_patronale,
                    0 AS montant_cotisation_salarie,
                    0 AS montant_frais_imposables,
                    0 AS montant_net_a_payer_salarie,
                    0 AS montant_net_imposable_salarie,
                    0 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 = 'C006') AS rubrique_id,
                    0 AS compte_id,
                    subq.salarie_id AS salarie_id,
                    0 AS taux_cotisation_patronale,
                    0 AS taux_cotisation_salarie,
                    0 AS nombre_provisions,
                    0 AS montant_provisions,
                    0 AS montant_masse_salariale_provisionnee
                FROM (
                    SELECT
                        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,
                        sum(montant_avantage_nature) AS montant_avantage_nature,
                        sum(montant_brut) AS montant_brut,
                        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,
                        0 AS montant_od_net_salarie,
                        p_historique_paie.organisme_cotisation_id,
                        p_historique_paie.profil_id,
                        (SELECT oid FROM rh.t_rubriques WHERE code = 'C006'),
                        p_historique_paie.salarie_id,
                        0 AS taux_cotisation_patronale,
                        0 AS taux_cotisation_salarie,
                        0 AS nombre_provisions,
                        0 AS montant_provisions,
                        0 AS montant_masse_salariale_provisionnee
                    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, 17,18,19,20) AS subq
                    JOIN rh.p_salaries ON p_salaries.oid = subq.salarie_id
                    JOIN w_totaux ON 1=1
                        AND w_totaux.matricule = p_salaries.matricule
                        AND w_totaux.date = subq.date_paie
                WHERE 1!=1
                    OR COALESCE(hcum_cotisation_patronale,0) - subq.montant_cotisation_patronale <> 0
            ;

            -- Insérer pour chaque bulletin une ligne qui va faire le compte avec le total (rubrique 'C007' nommée 'Ecart cumulé cotisations salariales')
            INSERT INTO rh.p_historique_paie
                (
                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_masse_salariale,
                montant_avantage_nature,
                montant_brut,
                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,
                nombre_provisions,
                montant_provisions,
                montant_masse_salariale_provisionnee)
                SELECT
                    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,
                    0 as heure_contrat,
                    0 as heure_payee,
                    0 as heure_travaillee,
                    0 as montant_masse_salariale,
                    0 AS montant_avantage_nature,
                    0 AS montant_brut,
                    0 AS montant_cotisation_patronale,
                    COALESCE(hcum_cotisation_salarie,0) - subq.montant_cotisation_salarie AS montant_cotisation_salarie,
                    0 AS montant_frais_imposables,
                    0 AS montant_net_a_payer_salarie,
                    0 AS montant_net_imposable_salarie,
                    0 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 = 'C007') AS rubrique_id,
                    0 AS compte_id,
                    subq.salarie_id AS salarie_id,
                    0 AS taux_cotisation_patronale,
                    0 AS taux_cotisation_salarie,
                    0 AS nombre_provisions,
                    0 AS montant_provisions,
                    0 AS montant_masse_salariale_provisionnee
                FROM (
                    SELECT
                        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,
                        sum(montant_avantage_nature) AS montant_avantage_nature,
                        sum(montant_brut) AS montant_brut,
                        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,
                        0 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,
                        0 AS nombre_provisions,
                        0 AS montant_provisions,
                        0 AS montant_masse_salariale_provisionnee
                    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, 17,18,19,20) AS subq
                    JOIN rh.p_salaries ON p_salaries.oid = subq.salarie_id
                    JOIN w_totaux ON 1=1
                        AND w_totaux.matricule = p_salaries.matricule
                        AND w_totaux.date = subq.date_paie
                WHERE 1!=1
                    OR COALESCE(hcum_cotisation_salarie,0) - subq.montant_cotisation_salarie <> 0
            ;

            -- Supprimer les C000 qui contrepassent exactement
            DROP TABLE IF EXISTS w_historique_paie_c000
            ;

            CREATE TEMP TABLE w_historique_paie_c000 AS
                SELECT
                    contrat_mois_id,
                    mois_paie,
                    SUM(montant_brut) AS montant_brut_c000,
                    MIN(rubrique_id) AS rubrique_c000_id
                FROM rh.p_historique_paie
                WHERE rubrique_id IN (SELECT oid FROM rh.t_rubriques WHERE code = 'C000')
                GROUP BY 1,2
                HAVING SUM(montant_brut) <> 0
            ;

            DROP TABLE IF EXISTS w_historique_paie_frais
            ;

            CREATE TEMP TABLE w_historique_paie_frais AS
                SELECT
                    p_historique_paie.contrat_mois_id,
                    p_historique_paie.mois_paie,
                    rubrique_c000_id,
                    MIN(rubrique_id) AS rubrique_frais_id
                FROM rh.p_historique_paie
                JOIN w_historique_paie_c000 ON
                    p_historique_paie.contrat_mois_id = w_historique_paie_c000.contrat_mois_id AND
                    p_historique_paie.mois_paie = w_historique_paie_c000.mois_paie AND
                    p_historique_paie.montant_brut = 0 - w_historique_paie_c000.montant_brut_c000
                GROUP BY 1,2,3
                HAVING count(*) = 1
            ;

            UPDATE rh.p_historique_paie
            SET
                montant_frais_imposables = CASE WHEN rubrique_id = rubrique_frais_id THEN montant_brut ELSE 0 END,
                montant_brut = 0
            FROM w_historique_paie_frais
            WHERE 1=1
                AND p_historique_paie.contrat_mois_id = w_historique_paie_frais.contrat_mois_id
                AND p_historique_paie.mois_paie = w_historique_paie_frais.mois_paie
                AND p_historique_paie.rubrique_id IN (rubrique_frais_id, rubrique_c000_id)
            ;

            ]]></sqlcmd>
        </NODE>
		<NODE label="Historique de la paie - 3/3 (mode paramétré)">
            <condition><![CDATA[
                
            -- Historique de paie paramétré.
            select valeur = 1
            from rh.t_divers
            where code = 'OPT_STD_HP'
            ;

            ]]></condition>
            <sqlcmd><![CDATA[

            -- 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_avantage_nature) as total_avantage_nature,
                    bool_or(p_cumul and p_brut) as total_brut,
                    bool_or(p_cumul and p_masse_salariale) as total_masse_salariale,
                    bool_or(p_cumul and p_cotisation_patronale) as total_cot_pat,
                    bool_or(p_cumul and p_cotisation_salarie) as total_cot_sal,
                    bool_or(p_cumul and p_net_a_payer) as total_payer,
                    bool_or(p_cumul and p_net_imposable) as total_imposable,
                    bool_or(p_cumul and p_heures_contrat) as total_h_contrat,
                    bool_or(p_cumul and p_heures_payees) as total_h_payees,
                    bool_or(p_cumul and p_heures_travaillees) as total_h_travaillees
                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
                    t_sal.matriculesalarie||w_hst_bul.datehist::date||w_hst_bul.typedubulletin::text as code_original,
                    p_salaries.matricule,
                    w_hst_bul.datehist::date as date,
                    to_char(w_hst_bul.datehist::date, 'YYYYMM') as mois,
                    round(sum(case when p_cumul then avt_nat else 0 end), 2) AS hcum_avantage_nature,
                    round(sum(case when p_cumul then montant_brut else 0 end), 2) AS hcum_brut,
                    round(sum(case when p_cumul then masse_salariale else 0 end), 2) AS hcum_masse_salariale,
                    round(sum(case when p_cumul then montant_pat else 0 end), 2) AS hcum_cotisation_patronale,
                    round(sum(case when p_cumul then montant_sal else 0 end), 2) AS hcum_cotisation_salarie,
                    0::numeric AS hcum_frais_imposables,
                    round(sum(case when p_cumul then net_a_payer else 0 end), 2) AS hcum_net_a_payer_salarie,
                    round(sum(case when p_cumul then net_imposable else 0 end), 2) AS hcum_net_imposable_salarie,
                    sum(case when p_cumul then heure_contrat else 0 end) AS hcum_heures_contrat,
                    sum(case when p_cumul then heure_payee else 0 end) AS hcum_heures_payees,
                    sum(case when p_cumul then heure_travaillee else 0 end) AS hcum_heures_travaillees,
                    0::numeric AS montant_od_net_salarie,
                    0::numeric AS nombre_provisions,
                    0::numeric AS montant_provisions,
                    0::numeric AS montant_masse_salariale_provisionnee
                FROM w_hst_bul
                    JOIN prod_sage.t_sal ON t_sal.sa_compteurnumero = w_hst_bul.numsalarie
                    JOIN rh.p_salaries ON p_salaries.matricule = t_sal.matriculesalarie
		            LEFT JOIN w_hp ON 1=1
                        AND w_hp.numsalarie     = w_hst_bul.numsalarie
                        AND w_hp.date           = w_hst_bul.datehist
                        AND w_hp.typedubulletin = w_hst_bul.typedubulletin
                    LEFT JOIN rh.t_rubriques ON t_rubriques.code_original = w_hp.rub_code
                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,
                nombre_provisions,
                montant_provisions,
                montant_masse_salariale_provisionnee)
				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,
					0 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,
                    0 AS nombre_provisions,
                    0 AS montant_provisions,
                    0 AS montant_masse_salariale_provisionnee
				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,
						0 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,
                        0 AS nombre_provisions,
                        0 AS montant_provisions,
                        0 AS montant_masse_salariale_provisionnee
					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) 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_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
					w_profils.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
					JOIN w_profils ON w_profils.contrat_mois_id = p_contrats_mois.oid
				GROUP BY 1,2,3,4,5
			;

			]]></sqlcmd>
		</NODE>
		<NODE label="Arrêts de travail">
			<sqlcmd><![CDATA[

			-- Création d'une table temporaire contenant 1 contrat pour 1 arret
			DROP TABLE IF EXISTS w_arrets_mois
			;

			CREATE TEMP TABLE w_arrets_mois AS
				SELECT
					idghrsal AS code_original,
					t_sal.matriculesalarie AS matricule,
					coalesce(t_ghrsal.motif, chr(1) || '*') AS motif,
					to_char(t_ghrsal.periodedebut::date, 'YYYYMM')::numeric AS mois_activite,
					t_ghrsal.periodedebut::date AS date_debut,
					t_ghrsal.periodefin::date AS date_fin,
					LEAST(valeur,99999) AS nb_jours,
					(t_ghrsal.periodefin::date + '1 day'::interval)::date AS date_reprise,
					0 AS no_contrat
				FROM prod_sage.t_ghrsal
					JOIN prod_sage.t_sal ON t_sal.sa_compteurnumero = t_ghrsal.numsalarie
                WHERE nullif(trim(t_ghrsal.motif), '') is not null
			;

			-- Lorsque plusieurs arrêts consécutifs de même motif, on n'en fait plus qu'un.
			DROP TABLE IF EXISTS w_arrets
			;

			CREATE TEMP TABLE w_arrets AS
				SELECT
					code_original,
					matricule,
					motif,
					min(mois_activite) AS mois_activite,
					min(date_debut) AS date_debut,
					max(date_fin) AS date_fin,
					sum(nb_jours) AS nb_jours,
					max(date_reprise) AS date_reprise,
					0 AS no_contrat
				FROM w_arrets_mois
				GROUP BY 1,2,3
			;

			-- Lorsque plusieurs arrêts consécutifs de motifs différents, la date de reprise se situe au lendemain de la date de fin la plus récente.

            -- Alimentation des arrêts de travail
			TRUNCATE rh.p_arrets_travail
			;

			ALTER SEQUENCE rh.s_arrets_travail RESTART WITH 1
			;

			INSERT INTO rh.p_arrets_travail(
				salarie_id,
				contrat_id,
				mois_activite,
				date_debut,
				date_fin,
				date_reprise,
				motif_arret_id,
				precision_motif_arret_id,
				nb_jours
				)
				SELECT 
					p_salaries.oid,
					max(p_contrats.oid), -- on prend le max car il peut y avoir un changement de contrat pendant un arrêt.
					w_arrets.mois_activite,
					w_arrets.date_debut,
					w_arrets.date_fin,
					w_arrets.date_reprise,
					coalesce(t_motifs_arret.oid, 0) AS motif_arret_id,
					0 AS precision_motif_arret_id,
					w_arrets.nb_jours
				FROM w_arrets
					JOIN rh.p_salaries ON p_salaries.code_original = w_arrets.matricule
					LEFT JOIN rh.t_motifs_arret ON t_motifs_arret.code_original = w_arrets.motif
					JOIN rh.p_contrats ON 1=1
						AND p_contrats.salarie_id = p_salaries.oid
						AND base.cti_overlaps(w_arrets.date_debut, w_arrets.date_fin, p_contrats.date_debut, p_contrats.date_fin)
				GROUP BY 1,3,4,5,6,7,8,9
			;

            -- Ventilation mensuelle des arrêts de travail
			TRUNCATE rh.p_arrets_travail_mois
			;

			INSERT INTO rh.p_arrets_travail_mois(
				arret_travail_id,
				salarie_id,
				contrat_id,
				contrat_mois_id,
				mois_activite,
				nb_debut_arret,
				nb_fin_arret,
				nb_reprise_apres_arret,
				date_debut,
				date_fin,
				nb_jours,
				nb_arret
				)
				SELECT
					p_arrets_travail.oid AS arret_travail_id,
					p_arrets_travail.salarie_id AS salarie_id,
					p_arrets_travail.contrat_id AS contrat_id,
					(max(DISTINCT ARRAY[p_contrats_mois.date_fin - p_contrats_mois.date_debut, p_contrats_mois.oid]))[2] AS contrat_mois_id, -- On ratache l'arrêt au contrat le plus long dans le mois lorsque plusieurs contrat sur la même période.
					p_contrats_mois.mois_activite,
					CASE WHEN p_arrets_travail.date_debut BETWEEN min(p_contrats_mois.date_debut) AND max(p_contrats_mois.date_fin) THEN 1 ELSE 0 END AS nombre_debut_arret,
					CASE WHEN p_arrets_travail.date_fin BETWEEN min(p_contrats_mois.date_debut) AND max(p_contrats_mois.date_fin) THEN 1 ELSE 0 END AS nombre_fin_arret,
					CASE WHEN p_arrets_travail.date_reprise BETWEEN min(p_contrats_mois.date_debut) AND max(p_contrats_mois.date_fin) THEN 1 ELSE 0 END AS nb_reprise_apres_arret,
					min(GREATEST(p_contrats_mois.date_debut, p_arrets_travail.date_debut)) AS date_debut,
					max(LEAST(p_contrats_mois.date_fin, p_arrets_travail.date_fin)) AS date_fin,
					max(LEAST(p_contrats_mois.date_fin, p_arrets_travail.date_fin)::date) - min(GREATEST(p_contrats_mois.date_debut, p_arrets_travail.date_debut)::date) + 1 AS nb_jours,
					CASE WHEN base.cti_overlaps(p_arrets_travail.date_debut, p_arrets_travail.date_fin, p_contrats_mois.date_debut, p_contrats_mois.date_fin) THEN 1 ELSE 0 END AS nb_arret
				FROM rh.p_contrats_mois
					JOIN rh.p_arrets_travail ON 1=1
						AND p_contrats_mois.contrat_id = p_arrets_travail.contrat_id
						AND base.cti_overlaps(p_arrets_travail.date_debut, p_arrets_travail.date_reprise, p_contrats_mois.date_debut, p_contrats_mois.date_fin)
				GROUP BY 1,2,3,5,p_arrets_travail.date_debut,p_arrets_travail.date_fin,p_arrets_travail.date_reprise,12
				ORDER BY 9
			;

			-- Suppression des nb_reprise_apres_arret lorsqu'un arrêt suit un autre arrêt.
			update rh.p_arrets_travail_mois
			set nb_reprise_apres_arret = 0
			from (
				select 
					t1.arret_travail_id,
					t1.mois_activite
				from rh.p_arrets_travail_mois as t1
					join rh.p_arrets_travail ON p_arrets_travail.oid = t1.arret_travail_id
					left join rh.p_arrets_travail_mois as t2 ON 1=1
						AND t1.salarie_id = t2.salarie_id
						AND t1.arret_travail_id != t2.arret_travail_id
				WHERE t1.nb_reprise_apres_arret = 1
				GROUP BY 1,2
				HAVING min(case when p_arrets_travail.date_reprise between t2.date_debut and t2.date_fin then 0 else 1 end) = 0
				) as subq
			where 1=1
				and p_arrets_travail_mois.arret_travail_id = subq.arret_travail_id
				and p_arrets_travail_mois.mois_activite = subq.mois_activite
			;

			]]></sqlcmd>
		</NODE>
		<NODE label="Visites Médicales">
			<sqlcmd><![CDATA[

			-- Création d'une table temporaire
			DROP TABLE IF EXISTS w_visites
			;

			CREATE TEMP TABLE w_visites AS
				SELECT
					t_sal.matriculesalarie AS matricule,
					datevisite::date as date,
					((date_part('year', datevisite))::text || lpad (date_part('month', datevisite),2,'0'))::numeric AS mois_activite,
                    '' as motif
				FROM prod_sage.t_hst_medecine
                    JOIN prod_sage.t_sal ON t_sal.sa_compteurnumero = t_hst_medecine.numsalarie
				WHERE 1=1
					AND datevisite IS NOT NULL
					AND datevisite >= '2008-01-01'
				GROUP BY 1,2,3,4
			;

			-- Peuplement de rh.p_visites_medicales
			TRUNCATE rh.p_visites_medicales
			;

			ALTER SEQUENCE rh.s_visites_medicales RESTART WITH 1
			;

			INSERT INTO rh.p_visites_medicales(
				salarie_id,
				contrat_id,
				contrat_mois_id,
				mois_activite,
				date,
				motif_visite_id)
				SELECT
                    p_salaries.oid,
                    p_contrats_mois.contrat_id,
                    p_contrats_mois.oid,
                    w_visites.mois_activite,
                    w_visites.date,
                    coalesce(t_motifs_visite.oid, 0)
				FROM w_visites
					JOIN rh.p_salaries ON p_salaries.matricule = w_visites.matricule
					JOIN rh.p_contrats_mois ON 1=1
                        AND p_contrats_mois.salarie_id = p_salaries.oid
						AND	w_visites.date BETWEEN p_contrats_mois.date_debut AND p_contrats_mois.date_fin
					LEFT JOIN rh.t_motifs_visite ON t_motifs_visite.code_original = w_visites.motif
			;

			]]></sqlcmd>
		</NODE>
		<NODE label="Accidents du travail">
			<sqlcmd><![CDATA[

			-- Création d'une table temporaire
			DROP TABLE IF EXISTS w_accident
			;

			CREATE TEMP TABLE w_accident AS
				SELECT
					t_sal.matriculesalarie AS matricule,
					dateaccident::date as date,
					(date_part('year', dateaccident)::text || lpad(date_part('month', dateaccident),2,'0'))::numeric AS mois_activite
				FROM prod_sage.t_hst_accidenttravail
                    JOIN prod_sage.t_sal ON t_sal.sa_compteurnumero = t_hst_accidenttravail.numsalarie
				WHERE dateaccident IS NOT NULL
				GROUP BY 1,2,3
			;

			-- Peuplement de rh.p_accident_travail
			TRUNCATE rh.p_accident_travail
			;

			ALTER SEQUENCE rh.s_accident_travail RESTART WITH 1
			;

			INSERT INTO rh.p_accident_travail(
				salarie_id,
				contrat_id,
				contrat_mois_id,
				mois_activite,
				date,
				accident_circonstance_id,
				accident_lieu_id,
				accident_nature_id,
				accident_siege_id)
				SELECT
                    p_salaries.oid,
                    p_contrats_mois.contrat_id,
                    p_contrats_mois.oid,
                    w_accident.mois_activite,
                    w_accident.date,
                    0, 
                    0,
                    0,
                    0
				FROM w_accident
					JOIN rh.p_salaries ON p_salaries.matricule = w_accident.matricule
					JOIN rh.p_contrats_mois ON 1=1
                        AND p_contrats_mois.salarie_id = p_salaries.oid
						AND	w_accident.date BETWEEN p_contrats_mois.date_debut AND p_contrats_mois.date_fin
			;

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

			-- Pré-traitement
			DROP TABLE IF EXISTS w_formation
			;

			CREATE temp TABLE w_formation AS
				SELECT
					t_sal.matriculesalarie AS matricule,
					t_participant.codeformation,
					datefin::date AS date,
					(date_part('year',datefin)::text || lpad (date_part('month',datefin),2,'0'))::numeric AS mois_activite,
					nbheures AS nb_heures,
					nomintervenant AS organisateur
				FROM prod_sage.t_participant
                    JOIN prod_sage.t_sal ON t_sal.sa_compteurnumero = t_participant.numsalarie
					JOIN prod_sage.t_formdatessessions ON t_formdatessessions.codeformation = t_participant.codeformation
					JOIN prod_sage.t_formation ON t_formation.codeformation = t_participant.codeformation
				GROUP BY 1,2,3,4,5,6
			;

			-- Peuplement de rh.p_formations
			TRUNCATE rh.p_formations
			;

			ALTER SEQUENCE rh.s_formations RESTART WITH 1
			;

			INSERT INTO rh.p_formations (
				salarie_id,
                contrat_id,
                contrat_mois_id,
				formation_id,
				formation_date,
				mois_activite,
				nb_heures,
				organisateur)
				SELECT
					p_salaries.oid,
                    p_contrats_mois.contrat_id,
                    p_contrats_mois.oid,
					coalesce(t_liste_formations.oid, 0),
					w_formation.date,
					w_formation.mois_activite,
					w_formation.nb_heures,
					w_formation.organisateur
				FROM w_formation
					JOIN rh.p_salaries ON p_salaries.matricule = w_formation.matricule
                    JOIN rh.p_contrats_mois ON 1=1
                        AND p_contrats_mois.salarie_id = p_salaries.oid
                        AND w_formation.date BETWEEN p_contrats_mois.date_debut AND p_contrats_mois.date_fin
					LEFT JOIN rh.t_liste_formations ON w_formation.codeformation = t_liste_formations.code
				ORDER BY 1,2,3,4
			;

			]]></sqlcmd>
		</NODE>
        <NODE label="Handicap 2">
			<condition><![CDATA[
				select count(*) = 1
				from information_schema.columns
				where 1=1
					AND table_schema = 'prod_sage'
					AND table_name = 't_hst_medecine'
					AND lower(column_name) = 'statutboeth'
				;

			]]></condition>
			<NODE label="insertion données handicap">
				<sqlcmd><![CDATA[

				TRUNCATE rh.p_handicap2
				;
				
				INSERT INTO rh.p_handicap2(
						salarie_id
						,statut_boeth 
						,taux_ipp
						,deb_validite
						,fin_validite
						,cat_invalide_pension 
					)
					SELECT p_salaries.oid
						,statutboeth
						,t_sal.tauxinvalidite
                        ,coalesce(to_date(t_sal.cotorepdate, 'YYYY-MM-DD'), '00010101'::date)
						,coalesce(to_date(t_sal.cotorepdatefin, 'YYYY-MM-DD'), '20991231'::date)
						,cotorepcategorie
					FROM rh.p_salaries
						JOIN prod_sage.t_sal ON p_salaries.matricule = t_sal.matriculesalarie
						JOIN prod_sage.t_hst_medecine ON t_sal.sa_compteurnumero = t_hst_medecine.numsalarie
						and infoencours = 1
					WHERE 1 = 1
						and travailleurhandicape = 1
				;
				
				]]></sqlcmd>
			</NODE>
		</NODE>
	</NODE>
	<NODE name="POST" label="POST-TRAITEMENTS">
		<NODE name="DIVERS" type="common"/>
		<NODE label="Mise à jour de la table Divers (mois en cours)">
			<sqlcmd><![CDATA[

			-- Màj du mois non clôturé.
			DELETE FROM rh.t_divers
			WHERE code = 'MOIS_EN_COURS'
			;

			INSERT INTO rh.t_divers(
				code,
  				texte,
  				valeur,
  				valeur_date,
  				description)
			VALUES(
				'MOIS_EN_COURS',
				'Mois en cours (non clôturé).',
				(SELECT to_char(date_paie_encours, 'YYYYMM') FROM w_periode),
				(SELECT date_paie_encours FROM w_periode),
				'Mois en cours (non clôturé).'
				)
			;
			
			]]></sqlcmd>
		</NODE>
		<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>
