<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
<ROOT>
|
|
<NODE name="PROD" label="Synchronisation données">
|
|
<NODE label="Import planning">
|
|
<sqlcmd><![CDATA[
|
|
|
|
DROP TABLE IF EXISTS w_structure;
|
|
CREATE TEMP TABLE w_structure AS
|
|
SELECT
|
|
societe.id AS societe_id,
|
|
batiment_id,
|
|
etage.id as etage_id,
|
|
COALESCE(NULLIF(batiment.nom,''),'NR') AS batiment_texte,
|
|
COALESCE(NULLIF(etage.nom,''),'NR') AS etage_texte,
|
|
societe.id || '|' || batiment_id || '|' || etage.id::text AS code_original,
|
|
COALESCE(NULLIF(societe.code,''),'NR') || '|' || COALESCE(batiment.id::text,'NR') || '|' || etage.id::text AS code,
|
|
COALESCE(NULLIF(societe.libelle,''),'NR') || '|' || COALESCE(NULLIF(batiment.nom,''),'NR') || '|' || COALESCE(NULLIF(etage.nom,''),'NR') AS texte
|
|
FROM
|
|
prod_expert_sante.societe,
|
|
prod_expert_sante.batiment
|
|
JOIN prod_expert_sante.etage ON batiment_id = batiment.id
|
|
--WHERE societe.id IN (SELECT DISTINCT planning_code FROM rh.t_etablissements)
|
|
;
|
|
|
|
|
|
DROP TABLE IF EXISTS w_cycle;
|
|
CREATE TEMP TABLE w_cycle AS
|
|
SELECT
|
|
id, utilisateur_id,
|
|
poste_id,
|
|
date_debut,
|
|
COALESCE(date_fin,lead(date_debut) OVER (PARTITION BY utilisateur_id, date_fin ORDER BY date_debut) - interval '1 day','2099-12-31') as date_fin,
|
|
COALESCE(date_fin,lead(date_debut) OVER (PARTITION BY utilisateur_id, date_fin ORDER BY date_debut) - interval '1 day','2099-12-31') as date_fin_cor,
|
|
cycle_id_remplacant,
|
|
rh_salarie_societe_id,
|
|
commentaire_arret
|
|
FROM prod_expert_sante.cycle
|
|
;
|
|
|
|
-- overlap
|
|
DROP TABLE IF EXISTS w_cycle_overlap;
|
|
CREATE TEMP TABLE w_cycle_overlap AS
|
|
SELECT overlap.id,
|
|
overlap.utilisateur_id,
|
|
overlap.poste_id,
|
|
overlap.date_debut,
|
|
overlap.date_fin,
|
|
overlap.date_fin_cor,
|
|
overlap.cycle_id_remplacant,
|
|
overlap.rh_salarie_societe_id,
|
|
overlap.commentaire_arret,
|
|
w_cycle.id as cycle_ref
|
|
FROM w_cycle
|
|
JOIN w_cycle overlap ON overlap.utilisateur_id = w_cycle.utilisateur_id AND overlap.date_debut BETWEEN w_cycle.date_debut and w_cycle.date_fin_cor AND overlap.id > w_cycle.id
|
|
order by overlap.utilisateur_id, overlap.date_debut
|
|
;
|
|
-- maj fin de période si overlap
|
|
UPDATE w_cycle
|
|
SET
|
|
date_fin_cor = sub.date_debut - '1 day'::interval
|
|
FROM (SELECT cycle_ref, min(date_debut) AS date_debut FROM w_cycle_overlap GROUP BY 1) sub
|
|
WHERE cycle_ref = id
|
|
;
|
|
|
|
INSERT INTO w_cycle
|
|
SELECT
|
|
w_cycle.id,
|
|
w_cycle.utilisateur_id,
|
|
w_cycle.poste_id,
|
|
w_cycle_overlap.date_fin_cor + interval '1 day',
|
|
w_cycle.date_fin,
|
|
COALESCE(LEAD(w_cycle_overlap.date_debut) OVER (PARTITION BY cycle_ref ORDER BY w_cycle_overlap.date_debut, w_cycle_overlap.id) - interval '1 day',w_cycle.date_fin),
|
|
w_cycle.cycle_id_remplacant,
|
|
w_cycle.rh_salarie_societe_id,
|
|
w_cycle.commentaire_arret
|
|
FROM w_cycle
|
|
join w_cycle_overlap on cycle_ref = w_cycle.id order by w_cycle.utilisateur_id ,w_cycle.date_debut, w_cycle_overlap.id;
|
|
|
|
DELETE FROM w_cycle where date_fin_cor < date_debut;
|
|
CREATE INDEX w_cycle_i ON w_cycle USING btree (id);
|
|
CREATE INDEX w_cycle_i2 ON w_cycle USING btree (poste_id);
|
|
|
|
--maj des matricule planning si non renseignés
|
|
UPDATE rh.p_salaries
|
|
SET matricule_planning = matricule
|
|
WHERE matricule_planning = ''
|
|
;
|
|
|
|
-- insertion des matricule non présents ou présent sans la bonne personne
|
|
INSERT INTO rh.p_salaries(
|
|
finess,
|
|
nom,
|
|
prenom,
|
|
sexe,
|
|
matricule,
|
|
matricule_planning,
|
|
code,
|
|
code_original,
|
|
entreprise_id
|
|
)
|
|
SELECT
|
|
'Planning' AS finess,
|
|
base.cti_soundex_nom((MAX(ARRAY[utilisateur.id::text, utilisateur.nom::text]))[2]),
|
|
base.cti_soundex_prenom((MAX(ARRAY[utilisateur.id::text, utilisateur.prenom::text]))[2]),
|
|
CASE WHEN (MAX(ARRAY[utilisateur.id, genre]))[2] NOT IN (1,4) THEN 'F' ELSE 'M' END,
|
|
'PLA_' || utilisateur.matricule,
|
|
utilisateur.matricule AS matricule_planning,
|
|
'PLA_' || utilisateur.matricule,
|
|
'PLA_' || utilisateur.matricule,
|
|
COALESCE(sub.entreprise_id,0)
|
|
FROM prod_expert_sante.utilisateur
|
|
LEFT JOIN (SELECT entreprise_id FROM rh.t_etablissements JOIN rh.t_divers ON t_divers.code = 'EXPERT_SOCIETE_DEFAULT' AND valeur = planning_code) sub ON 1=1
|
|
LEFT JOIN rh.p_salaries ON p_salaries.matricule_planning = utilisateur.matricule
|
|
WHERE utilisateur.matricule != ''
|
|
AND utilisateur.id IN (SELECT utilisateur_id FROM w_cycle)
|
|
AND 'PLA_' || utilisateur.matricule NOT IN (SELECT code_original FROM rh.p_salaries)
|
|
GROUP BY 5,6,7,8,9
|
|
HAVING MAX(p_salaries.oid) IS NULL OR (
|
|
base.cti_soundex_nom((MAX(ARRAY[utilisateur.id::text, utilisateur.nom::text]))[2]) != base.cti_soundex_nom(upper(MAX(p_salaries.nom))) AND
|
|
base.cti_soundex_prenom((MAX(ARRAY[utilisateur.id::text, utilisateur.prenom::text]))[2]) != base.cti_soundex_prenom(upper(MAX(p_salaries.prenom)))
|
|
)
|
|
ORDER BY 5;
|
|
|
|
-- maj des anciens matricule planning plus utilisés (matricule sans PLA)
|
|
UPDATE rh.p_salaries
|
|
SET matricule_planning = 'OLD_' || p_salaries.matricule_planning
|
|
FROM (
|
|
SELECT matricule_planning, MAX(CASE WHEN matricule NOT LIKE 'PLA_%' THEN oid ELSE 0 END) as salarie_id
|
|
FROM rh.p_salaries
|
|
GROUP BY 1 HAVING count(*) > 1
|
|
) sub
|
|
WHERE oid = salarie_id
|
|
AND p_salaries.matricule_planning NOT LIKE 'OLD_%'
|
|
;
|
|
|
|
-- Màj des Etablissements
|
|
-- UPDATE rh.t_etablissements
|
|
-- SET planning_code = code
|
|
-- ;
|
|
|
|
-- /!\ planning_code est à paramétrer dans la table listant les établissements.
|
|
|
|
-- Recensement des salariés et établissements.
|
|
DROP TABLE IF EXISTS w_sal_pla
|
|
;
|
|
CREATE TEMP TABLE w_sal_pla AS
|
|
SELECT
|
|
p_salaries.oid AS salarie_id,
|
|
p_salaries.matricule_planning AS matricule,
|
|
t_entreprises.code_original AS entreprise_code_original,
|
|
t_etablissements.code_original AS etablissement_code_original,
|
|
t_entreprises.code AS entreprise_code,
|
|
t_entreprises.planning_code AS entreprise_planning_code,
|
|
t_etablissements.code AS etablissement_code,
|
|
t_etablissements.planning_code as etablissement_planning_code, -- Pour cas 3 Sage
|
|
lpad(t_entreprises.code, 3, '0') || lpad(t_etablissements.code, 3, '0') || p_salaries.matricule AS matricule_planning, -- Pour cas 2 SHS
|
|
lpad(t_entreprises.planning_code, 3, '0') || lpad(t_etablissements.planning_code, 3, '0') || substr(p_salaries.matricule, 1, 5) AS matricule_planning_conso, -- Pour cas 5 SHS consolidé
|
|
ltrim(p_salaries.matricule, '0') AS matricule_trim, -- Pour cas 1 Cegid
|
|
''::text AS salarie_corr
|
|
FROM rh.p_salaries
|
|
-- Il faut absoluement faire le produit cartésien matricule/établissement même si un salarié n'a jamais travaillé dans un des établissement.
|
|
-- En effet, ce traitement pourrait ne pas remonter les données associées.
|
|
JOIN rh.t_entreprises ON t_entreprises.oid = p_salaries.entreprise_id
|
|
JOIN rh.t_etablissements ON t_etablissements.entreprise_id = p_salaries.entreprise_id AND t_etablissements.planning_code != ''
|
|
WHERE 1=1
|
|
AND salarie_fusionne_id = 0
|
|
-- Uniquement les établissements avec planning_code renseigné dans le cas où l'établissement est en mode manuel.
|
|
GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12
|
|
ORDER BY 1,2,3
|
|
;
|
|
|
|
-- Gestion des salariés fusionnés.
|
|
INSERT INTO w_sal_pla
|
|
SELECT
|
|
w_sal_pla.salarie_id,
|
|
p_salaries.matricule,
|
|
w_sal_pla.entreprise_code_original,
|
|
w_sal_pla.etablissement_code_original,
|
|
w_sal_pla.entreprise_code,
|
|
w_sal_pla.entreprise_planning_code,
|
|
w_sal_pla.etablissement_code,
|
|
w_sal_pla.etablissement_planning_code,
|
|
lpad(w_sal_pla.entreprise_code, 3, '0') || lpad(w_sal_pla.etablissement_code, 3, '0') || p_salaries.matricule AS matricule_planning,
|
|
lpad(w_sal_pla.entreprise_planning_code, 3, '0') || lpad(w_sal_pla.etablissement_planning_code, 3, '0') || substr(p_salaries.matricule, 1, 5) AS matricule_planning_conso,
|
|
ltrim(p_salaries.matricule, '0') AS matricule_trim,
|
|
''::text AS salarie_corr
|
|
FROM w_sal_pla
|
|
JOIN rh.p_salaries ON salarie_fusionne_id = w_sal_pla.salarie_id
|
|
WHERE salarie_fusionne_id != 0
|
|
;
|
|
|
|
-- INSERT INTO rh.p_salaries (code, code_original, nom)
|
|
-- lorsque nom ne correspond pas, changer le matricule
|
|
--UPDATE w_sal_pla SET
|
|
-- matricule_planning = etablissement_code_original || matricule
|
|
--WHERE etablissement_code LIKE '%-%'
|
|
;
|
|
|
|
-- Alimenter le champ w_sal_pla.salarie_corr.
|
|
UPDATE w_sal_pla SET
|
|
salarie_corr = matricule
|
|
;
|
|
|
|
-- Création d'index.
|
|
CREATE INDEX w_sal_pla_i_matricule ON w_sal_pla USING btree (matricule)
|
|
;
|
|
CREATE INDEX w_sal_pla_i_matricule_planning ON w_sal_pla USING btree (matricule_planning)
|
|
;
|
|
CREATE INDEX w_sal_pla_i_matricule_trim ON w_sal_pla USING btree (matricule_trim)
|
|
;
|
|
|
|
DROP TABLE IF EXISTS w_plan_base;
|
|
CREATE TEMP TABLE w_plan_base AS
|
|
SELECT
|
|
w_cycle.id,
|
|
COALESCE(NULLIF(salarie_societe.matricule,''),utilisateur.matricule) as matricule,
|
|
rh_societe_id,
|
|
w_cycle.utilisateur_id,
|
|
w_cycle.date_debut,
|
|
w_cycle.date_fin,
|
|
commentaire_arret,
|
|
courant.date,
|
|
courant.date as date_orig,
|
|
poste_id,
|
|
profession_rh_id,
|
|
etage_id,
|
|
rh_salarie_societe_id,
|
|
type_poste.code,
|
|
CASE WHEN heure_debut != '' THEN left(heure_debut,2)::numeric + right(heure_debut,2)::numeric / 60 ELSE 0 END AS heure_debut,
|
|
CASE WHEN heure_fin != '' THEN left(heure_fin,2)::numeric + right(heure_fin,2)::numeric / 60 ELSE 0 END AS heure_fin,
|
|
left(temps_travail,2)::numeric + right(temps_travail,2)::numeric / 60 as temps_travail,
|
|
temps_pause,
|
|
impacte_compteur_nuit,
|
|
impacte_compteur_heures_ferie,
|
|
impacte_totaux_planning,
|
|
roulement.renfort as roulement_renfort,
|
|
poste.renfort as poste_renfort,
|
|
cycle_id_remplacant,
|
|
type_poste.id AS type_poste_id,
|
|
rank() OVER (PARTITION BY w_cycle.utilisateur_id, courant.date ORDER BY w_cycle.id) as rank,
|
|
last_value(w_cycle.id) OVER (PARTITION BY w_cycle.utilisateur_id, courant.date) as last
|
|
FROM w_cycle
|
|
JOIN prod_expert_sante.utilisateur ON utilisateur_id = utilisateur.id
|
|
left join prod_expert_sante.salarie_societe on rh_salarie_societe_id = salarie_societe.id
|
|
join base.p_calendrier courant on courant.date between date_debut AND COALESCE(date_fin_cor, now())
|
|
join prod_expert_sante.poste on poste_id = poste.id
|
|
join base.p_calendrier debut on debut.date = poste.date_debut
|
|
join base.v_calendrier_indicateurs_1 ON courant.date = v_calendrier_indicateurs_1.date
|
|
join prod_expert_sante.roulement on roulement_id = roulement.id
|
|
join prod_expert_sante.modele_roulement on poste.roulement_id = modele_roulement.roulement_id
|
|
AND num_jour = courant.jour_semaine
|
|
AND num_semaine = 1 + (debut_semaine - 1 + courant.iso_semaine - debut.iso_semaine + 52 * (date_part('year',courant.date)::numeric - date_part('year', debut.date)::numeric))%nb_semaines
|
|
left join prod_expert_sante.type_poste on (type_poste.id = modele_roulement.type_poste_id and (nb_jour_ouvre = 1 or type_poste_jf = 0)) or (nb_jour_ouvre = 0 AND type_poste_jf != 0 AND type_poste_jf = type_poste.id)
|
|
WHERE courant.date > '[ENV_PLANNING_DATEDEBUT]'
|
|
;
|
|
|
|
CREATE INDEX w_plan_base_mat ON w_plan_base USING btree (matricule);
|
|
|
|
-- croisement avec les contrats et les personnes
|
|
|
|
DROP SEQUENCE IF EXISTS w_cptres1_seq
|
|
;
|
|
|
|
CREATE TEMP SEQUENCE w_cptres1_seq
|
|
;
|
|
|
|
DROP TABLE IF EXISTS w_cptres1
|
|
;
|
|
-- temps travail = temps du initial
|
|
CREATE TEMP TABLE w_cptres1 AS
|
|
SELECT
|
|
nextval('w_cptres1_seq') as cptres1_id,
|
|
w_plan_base.utilisateur_id,
|
|
w_plan_base.matricule,
|
|
salarie_id,
|
|
null::bigint AS contrat_id,
|
|
null::bigint AS contrat_mois_id,
|
|
date,
|
|
date_orig,
|
|
temps_travail AS temps_orig,
|
|
profession_rh_id,
|
|
etage_id,
|
|
rh_societe_id,
|
|
''::text AS motif_absence_id,
|
|
temps_travail::numeric AS temps_du_initial,
|
|
0::numeric AS temps_du,
|
|
0::numeric AS temps_valide,
|
|
0::numeric AS temps_absence,
|
|
type_poste_id
|
|
FROM w_plan_base
|
|
LEFT JOIN prod_expert_sante.absence_salarie ON w_plan_base.id = absence_salarie.cycle_id AND date_orig BETWEEN absence_salarie.date_debut AND absence_salarie.date_fin
|
|
LEFT JOIN prod_expert_sante.motif_absence ON motif_absence.id = motif_absence_id
|
|
JOIN w_sal_pla ON w_sal_pla.matricule = w_plan_base.matricule
|
|
WHERE 1=1
|
|
AND COALESCE(absence_non_reelle,0) != 1
|
|
AND w_plan_base.id = last
|
|
ORDER BY 2,7
|
|
;
|
|
|
|
|
|
|
|
-- absences (note dans table pas d'heure de debut ni de fin)
|
|
INSERT INTO w_cptres1
|
|
SELECT
|
|
nextval('w_cptres1_seq') as cptres1_id,
|
|
w_plan_base.utilisateur_id,
|
|
w_plan_base.matricule,
|
|
salarie_id,
|
|
null::bigint AS contrat_id,
|
|
null::bigint AS contrat_mois_id,
|
|
date,
|
|
date_orig,
|
|
temps_travail AS temps_orig,
|
|
profession_rh_id,
|
|
etage_id,
|
|
rh_societe_id,
|
|
motif_absence_id,
|
|
0 AS temps_du_initial,
|
|
CASE WHEN absence_non_reelle = 0 THEN temps_travail ELSE 0 END AS temps_du,
|
|
0 AS temps_valide,
|
|
CASE WHEN absence_non_reelle = 0 THEN temps_travail ELSE 0 END AS temps_absence,
|
|
type_poste_id
|
|
FROM w_plan_base
|
|
JOIN prod_expert_sante.absence_salarie ON w_plan_base.id = absence_salarie.cycle_id AND date_orig BETWEEN absence_salarie.date_debut AND absence_salarie.date_fin
|
|
JOIN prod_expert_sante.motif_absence ON motif_absence.id = motif_absence_id
|
|
JOIN w_sal_pla ON w_sal_pla.matricule = w_plan_base.matricule
|
|
WHERE 1=1 AND
|
|
validee = 1
|
|
ORDER BY 2,7
|
|
;
|
|
|
|
-- pas d'absence => valide sur dernier cycle prevu
|
|
INSERT INTO w_cptres1
|
|
SELECT
|
|
nextval('w_cptres1_seq') as cptres1_id,
|
|
w_plan_base.utilisateur_id,
|
|
w_plan_base.matricule,
|
|
salarie_id,
|
|
null::bigint AS contrat_id,
|
|
null::bigint AS contrat_mois_id,
|
|
date,
|
|
date_orig,
|
|
temps_travail AS temps_orig,
|
|
profession_rh_id,
|
|
etage_id,
|
|
rh_societe_id,
|
|
motif_absence_id,
|
|
0 AS temps_du_initial,
|
|
temps_travail AS temps_du,
|
|
temps_travail AS temps_valide,
|
|
0 AS temps_absence,
|
|
type_poste_id
|
|
FROM w_plan_base
|
|
LEFT JOIN prod_expert_sante.absence_salarie ON w_plan_base.id = absence_salarie.cycle_id AND date_orig BETWEEN absence_salarie.date_debut AND absence_salarie.date_fin
|
|
JOIN w_sal_pla ON w_sal_pla.matricule = w_plan_base.matricule
|
|
WHERE 1=1
|
|
AND absence_salarie.id IS NULL
|
|
AND w_plan_base.id = last
|
|
--AND validee = 1
|
|
ORDER BY 2,7
|
|
;
|
|
|
|
|
|
|
|
-- heures supplémentaires - comment utiliser type_heure_supplemntaire_id ?
|
|
INSERT INTO w_cptres1
|
|
SELECT
|
|
nextval('w_cptres1_seq') as cptres1_id,
|
|
heure_supplementaire.utilisateur_id,
|
|
utilisateur.matricule,
|
|
salarie_id,
|
|
null::bigint AS contrat_id,
|
|
null::bigint AS contrat_mois_id,
|
|
jour,
|
|
jour AS date_orig,
|
|
0 AS temps_orig,
|
|
profession_rh_id,
|
|
etage_id,
|
|
null,
|
|
-1,
|
|
0 AS temps_du_initial,
|
|
CASE WHEN sens = '+' then 1 ELSE -1 END * (left(heure,2)::numeric + right(heure,2)::numeric / 60) AS temps_du,
|
|
CASE WHEN sens = '+' then 1 ELSE -1 END * (left(heure,2)::numeric + right(heure,2)::numeric / 60) AS temps_valide,
|
|
0 AS temps_absence,
|
|
0 as type_poste_id
|
|
FROM prod_expert_sante.heure_supplementaire
|
|
--LEFT JOIN prod_expert_sante.salarie_societe_dis on heure_supplementaire.utilisateur_id = salarie_societe_dis.utilisateur_id AND visible = 1
|
|
JOIN prod_expert_sante.utilisateur ON heure_supplementaire.utilisateur_id = utilisateur.id
|
|
JOIN prod_expert_sante.poste ON poste_id = poste.id
|
|
JOIN w_sal_pla ON w_sal_pla.matricule = utilisateur.matricule
|
|
LEFt JOIN rh.t_divers ON code = 'EXPERT_SOCIETE_DEFAULT'
|
|
WHERE jour > '[ENV_PLANNING_DATEDEBUT]'
|
|
--AND payable = 1
|
|
;
|
|
|
|
|
|
/* UPDATE w_cptres1
|
|
SET rh_societe_id = salarie_societe_dis.rh_societe_id
|
|
FROM prod_expert_sante.salarie_societe_dis
|
|
WHERE salarie_societe_dis.utilisateur_id = w_cptres1.utilisateur_id
|
|
AND w_cptres1.rh_societe_id IS NULL
|
|
;*/
|
|
|
|
SELECT base.cti_execute('INSERT INTO rh.t_divers (code, valeur, description)
|
|
VALUES
|
|
(''EXPERT_SOCIETE_DEFAULT'',''0'',''id societe expert à affecter aux salaries par defaut'')',1)
|
|
WHERE (SELECT count(*) FROM rh.t_divers WHERE code = 'EXPERT_SOCIETE_DEFAULT') = 0
|
|
;
|
|
|
|
UPDATE w_cptres1
|
|
SET rh_societe_id = valeur::int
|
|
FROM rh.t_divers
|
|
WHERE t_divers.code = 'EXPERT_SOCIETE_DEFAULT'
|
|
AND rh_societe_id IS NULL
|
|
;
|
|
|
|
|
|
DELETE FROM w_cptres1 WHERE temps_du_initial = 0 AND temps_valide = 0 AND temps_absence = 0 AND temps_du = 0;
|
|
CREATE INDEX w_cptres1_i_date ON w_cptres1 USING btree (date_orig)
|
|
;
|
|
CREATE INDEX w_cptres1_i_salarie_id ON w_cptres1 USING btree (salarie_id)
|
|
;
|
|
|
|
VACUUM ANALYSE w_cptres1
|
|
;
|
|
|
|
|
|
|
|
-- Association aux contrats et contrat_mois.
|
|
-- En général, les heures planning sont effectuées AVANT un contrat/paie à cause du décallage avec la paie :
|
|
-- => les heures effectuées en fin de mois sont à associer avec le mois suivant.
|
|
with w_asso as (
|
|
select
|
|
cptres1_id,
|
|
(max(array[extract(epoch from p_contrats_mois.date_debut), p_contrats_mois.contrat_id]))[2] as contrat_id,
|
|
(max(array[extract(epoch from p_contrats_mois.date_debut), p_contrats_mois.oid]))[2] as contrat_mois_id
|
|
from w_cptres1
|
|
join rh.p_contrats_mois on 1=1
|
|
and p_contrats_mois.salarie_id = w_cptres1.salarie_id
|
|
and w_cptres1.date_orig between p_contrats_mois.date_debut and p_contrats_mois.date_fin -- Sélection des contrats pendant heures planning.
|
|
WHERE 1!=1
|
|
OR w_cptres1.contrat_id is null
|
|
OR w_cptres1.contrat_mois_id is null
|
|
group by 1)
|
|
UPDATE w_cptres1 SET
|
|
contrat_id = w_asso.contrat_id,
|
|
contrat_mois_id = w_asso.contrat_mois_id
|
|
FROM w_asso
|
|
WHERE w_cptres1.cptres1_id = w_asso.cptres1_id
|
|
;
|
|
|
|
with w_asso as (
|
|
select
|
|
cptres1_id,
|
|
(min(array[extract(epoch from p_contrats_mois.date_debut), p_contrats_mois.contrat_id]))[2] as contrat_id,
|
|
(min(array[extract(epoch from p_contrats_mois.date_debut), p_contrats_mois.oid]))[2] as contrat_mois_id
|
|
from w_cptres1
|
|
join rh.p_contrats_mois on 1=1
|
|
and p_contrats_mois.salarie_id = w_cptres1.salarie_id
|
|
and p_contrats_mois.date_debut > w_cptres1.date_orig -- Sélection des contrats APRES heures planning.
|
|
WHERE 1!=1
|
|
OR w_cptres1.contrat_id is null
|
|
OR w_cptres1.contrat_mois_id is null
|
|
group by 1)
|
|
UPDATE w_cptres1 SET
|
|
contrat_id = w_asso.contrat_id,
|
|
contrat_mois_id = w_asso.contrat_mois_id
|
|
FROM w_asso
|
|
WHERE w_cptres1.cptres1_id = w_asso.cptres1_id
|
|
AND w_cptres1.contrat_mois_id is null
|
|
|
|
;
|
|
/*
|
|
with w_asso as (
|
|
select
|
|
cptres1_id,
|
|
(max(array[extract(epoch from p_contrats_mois.date_debut), p_contrats_mois.contrat_id]))[2] as contrat_id,
|
|
(max(array[extract(epoch from p_contrats_mois.date_debut), p_contrats_mois.oid]))[2] as contrat_mois_id
|
|
from w_cptres1
|
|
join rh.p_contrats_mois on 1=1
|
|
and p_contrats_mois.salarie_id = w_cptres1.salarie_id
|
|
and p_contrats_mois.date_debut < w_cptres1.date_orig -- Sélection des contrats AVANT heures planning.
|
|
WHERE 1!=1
|
|
OR w_cptres1.contrat_id is null
|
|
OR w_cptres1.contrat_mois_id is null
|
|
group by 1)
|
|
UPDATE w_cptres1 SET
|
|
contrat_id = w_asso.contrat_id,
|
|
contrat_mois_id = w_asso.contrat_mois_id
|
|
FROM w_asso
|
|
WHERE w_cptres1.cptres1_id = w_asso.cptres1_id
|
|
AND w_cptres1.contrat_mois_id is null
|
|
;
|
|
*/
|
|
-- Création d'index.
|
|
CREATE INDEX w_cptres1_i_contrat_id ON w_cptres1 USING btree (contrat_id)
|
|
;
|
|
CREATE INDEX w_cptres1_i_contrat_mois_id ON w_cptres1 USING btree (contrat_mois_id)
|
|
;
|
|
|
|
|
|
-- Alimentation des tables de paramètres.
|
|
|
|
|
|
|
|
-- Màj des Services du Planning.
|
|
INSERT INTO rh.t_planning_service(code_original, code, texte, texte_court, service_id)
|
|
WITH services AS (
|
|
SELECT
|
|
id,
|
|
id::text as code,
|
|
nom,
|
|
etage_id
|
|
FROM prod_expert_sante.service
|
|
WHERE id != 0
|
|
GROUP BY 1,2,3,4
|
|
UNION ALL
|
|
SELECT
|
|
'0' AS id,
|
|
'NR' AS code,
|
|
'Non renseigné' as texte,
|
|
null as etage_id
|
|
)
|
|
SELECT id , id, nom, LEFT(nom,50), (select oid from rh.t_classes where code = 'PLANIV3') as classe_id
|
|
FROM services
|
|
WHERE id NOT IN (SELECT code_original FROM rh.t_planning_service WHERE code_original IS NOT NULL)
|
|
AND (etage_id IN (SELECT etage_id FROM w_cptres1 GROUP BY 1) OR etage_id IS NULL)
|
|
GROUP BY 1,2,3,4
|
|
;
|
|
|
|
|
|
INSERT INTO rh.t_planning_niveau(code_original, code, texte, texte_court)
|
|
SELECT
|
|
code_original,
|
|
code,
|
|
texte,
|
|
left(texte,50)
|
|
FROM w_structure
|
|
WHERE code_original NOT IN (SELECT code_original FROM rh.t_planning_niveau WHERE code_original IS NOT NULL)
|
|
AND split_part(code_original,'|',3) IN (SELECT etage_id FROM w_cptres1 GROUP BY 1)
|
|
;
|
|
|
|
-- Màj des Qualifications du Planning. (competence)
|
|
INSERT INTO rh.t_planning_qualification(code_original, code, texte, texte_court)
|
|
SELECT
|
|
ID,
|
|
ID,
|
|
NOM,
|
|
NOM
|
|
FROM prod_expert_sante.RH_PROFESSION
|
|
WHERE 1=1
|
|
AND ID IN (SELECT profession_rh_id FROM w_cptres1)
|
|
AND ID NOT IN (SELECT code_original FROM rh.t_planning_qualification WHERE code_original IS NOT NULL)
|
|
;
|
|
|
|
-- Màj des Types d'absences du Planning. (ch)
|
|
INSERT INTO rh.t_planning_type_absence(code_original, code, texte, texte_court)
|
|
SELECT
|
|
id,
|
|
code,
|
|
nom,
|
|
left(nom,50)
|
|
FROM prod_expert_sante.motif_absence
|
|
WHERE 1=1
|
|
AND id IN (SELECT motif_absence_id FROM w_cptres1 GROUP BY 1)
|
|
AND id NOT IN (SELECT code_original FROM rh.t_planning_type_absence WHERE code_original IS NOT NULL)
|
|
;
|
|
|
|
-- Màj des Codes Horaires du Planning.
|
|
INSERT INTO rh.t_planning_code_horaire(code_original, code, texte, texte_court)
|
|
SELECT
|
|
id,
|
|
code,
|
|
nom,
|
|
LEFT(nom,50)
|
|
FROM prod_expert_sante.type_poste
|
|
WHERE 1=1
|
|
AND id IN (SELECT DISTINCT type_poste_id FROM w_cptres1)
|
|
AND id NOT IN (SELECT code_original FROM rh.t_planning_code_horaire WHERE code_original IS NOT NULL)
|
|
;
|
|
|
|
|
|
-- Création d'une table Entreprise/Etablissement.
|
|
DROP TABLE IF EXISTS w_entets
|
|
;
|
|
|
|
CREATE TEMP TABLE w_entets AS
|
|
SELECT
|
|
ets.oid as etablissement_id,
|
|
ent.planning_code||ets.planning_code as entets_code
|
|
from rh.t_entreprises as ent
|
|
join rh.t_etablissements as ets on ets.entreprise_id = ent.oid
|
|
Where 1=1
|
|
and ent.oid != 0
|
|
and ets.oid != 0
|
|
;
|
|
|
|
|
|
|
|
-- Alimentation de la table de mouvement.
|
|
-- Alimentation de la table de mouvement.
|
|
TRUNCATE rh.p_planning_mouvement
|
|
;
|
|
INSERT INTO rh.p_planning_mouvement(
|
|
salarie_id,
|
|
contrat_id,
|
|
contrat_mois_id,
|
|
date,
|
|
semaine,
|
|
mois,
|
|
etablissement_id, -- @todo à renseigner en fonction du paramétrage dans t_divers.
|
|
service_id,
|
|
qualification_id,
|
|
type_absence_id,
|
|
niveau_id,
|
|
temps_du,
|
|
temps_du_initial,
|
|
temps_valide,
|
|
temps_absence,
|
|
code_horaire_id)
|
|
SELECT
|
|
salarie_id,
|
|
contrat_id,
|
|
contrat_mois_id,
|
|
date_orig,
|
|
to_char(date_orig, 'IYYYIW'::text)::numeric AS semaine,
|
|
to_char(date_orig, 'YYYYMM'::text)::numeric AS mois,
|
|
coalesce(w_entets.etablissement_id, 0) as etablissement_id,
|
|
coalesce(t_planning_service.oid, 0) AS service_id,
|
|
coalesce(t_planning_qualification.oid, 0) AS qualification_id,
|
|
coalesce(t_planning_type_absence.oid, 0) AS type_absence_id,
|
|
coalesce(t_planning_niveau.oid, 0) as niveau_id,
|
|
temps_valide + temps_absence,
|
|
temps_du_initial,
|
|
temps_valide,
|
|
temps_absence,
|
|
COALESCE(t_planning_code_horaire.oid,0)
|
|
FROM w_cptres1
|
|
LEFT JOIN rh.t_planning_service ON t_planning_service.code_original = w_cptres1.etage_id
|
|
LEFT JOIN rh.t_planning_qualification ON t_planning_qualification.code_original = w_cptres1.profession_rh_id
|
|
LEFT JOIN rh.t_planning_type_absence ON t_planning_type_absence.code_original = w_cptres1.motif_absence_id
|
|
LEFT JOIN w_entets ON w_entets.entets_code = 1 -- w_cptres1.entets_code
|
|
LEFT JOIN rh.t_planning_niveau ON split_part(t_planning_niveau.code_original,'|',3) = w_cptres1.etage_id AND split_part(t_planning_niveau.code_original,'|',1) = w_cptres1.rh_societe_id
|
|
LEFT JOIN rh.t_planning_code_horaire ON t_planning_code_horaire.code_original = w_cptres1.type_poste_id
|
|
LEFT JOIN rh.t_divers VENTIL_JOUR ON VENTIL_JOUR.code = 'VENTIL_JOUR'
|
|
;
|
|
|
|
VACUUM ANALYSE rh.p_planning_mouvement
|
|
;
|
|
|
|
]]></sqlcmd>
|
|
</NODE>
|
|
</NODE>
|
|
<NODE name="POST" label="Post traitements">
|
|
<sqlcmd><![CDATA[
|
|
|
|
-- Lorsqu'il n'y a pas de liaison entre les Qualifications Paie/Planning,
|
|
-- essayer de faire un rapprochement par le code ET le libellé.
|
|
UPDATE rh.t_planning_qualification SET
|
|
qualification_id = t_qualifications.oid
|
|
FROM rh.t_qualifications
|
|
WHERE 1=1
|
|
AND t_qualifications.code = t_planning_qualification.code
|
|
AND t_planning_qualification.qualification_id = 0
|
|
AND substr(t_planning_qualification.texte, 1, 10) = substr(t_qualifications.texte, 1, 10)
|
|
;
|
|
|
|
-- Report des Qualification Paie sur Qualification Planning.
|
|
UPDATE rh.t_planning_qualification SET
|
|
qualification_code = t_qualifications.code,
|
|
qualification_texte = t_qualifications.texte_court,
|
|
qualification_section_id = t_qualifications.section_id,
|
|
qualification_section_code = t_qualifications.section_code,
|
|
qualification_section_texte = t_qualifications.section_texte
|
|
FROM rh.t_qualifications
|
|
WHERE 1=1
|
|
AND t_planning_qualification.qualification_id = t_qualifications.oid
|
|
AND (1!=1
|
|
OR qualification_code IS DISTINCT FROM t_qualifications.code
|
|
OR qualification_texte IS DISTINCT FROM t_qualifications.texte_court
|
|
OR qualification_section_id IS DISTINCT FROM t_qualifications.section_id
|
|
OR qualification_section_code IS DISTINCT FROM t_qualifications.section_code
|
|
OR qualification_section_texte IS DISTINCT FROM t_qualifications.section_texte)
|
|
;
|
|
|
|
-- Report des Services Paie sur Services Planning.
|
|
UPDATE rh.t_planning_service SET
|
|
service_code = t_services.code,
|
|
service_texte = t_services.texte_court,
|
|
service_section_id = t_services.section_id,
|
|
service_section_code = t_services.section_code,
|
|
service_section_texte = t_services.section_texte
|
|
FROM rh.t_services
|
|
WHERE 1=1
|
|
AND t_planning_service.service_id = t_services.oid
|
|
AND (1!=1
|
|
OR service_code IS DISTINCT FROM t_services.code
|
|
OR service_texte IS DISTINCT FROM t_services.texte_court
|
|
OR service_section_id IS DISTINCT FROM t_services.section_id
|
|
OR service_section_code IS DISTINCT FROM t_services.section_code
|
|
OR service_section_texte IS DISTINCT FROM t_services.section_texte)
|
|
;
|
|
|
|
-- Création des 3 classes de niveaux.
|
|
DROP TABLE IF EXISTS w_classes
|
|
;
|
|
|
|
CREATE TEMP TABLE w_classes AS
|
|
with classe_table as (
|
|
select 'PLANIV1' as code, '[DICT.RH.NIVEAU1#1]' as texte, 1 as sequence
|
|
UNION ALL
|
|
select 'PLANIV2' as code, '[DICT.RH.NIVEAU2#1]' as texte, 2 as sequence
|
|
UNION ALL
|
|
select 'PLANIV3' as code, '[DICT.RH.NIVEAU3#1]' as texte, 3 as sequence)
|
|
SELECT code, texte, table_id, 0 as is_cti, sequence
|
|
FROM classe_table, (select oid as table_id from rh.t_listes_tables where code = 'PNI' LIMIT 1) as subq
|
|
;
|
|
|
|
INSERT INTO rh.t_classes (code, texte, table_id, is_cti, sequence)
|
|
SELECT code, texte, table_id, is_cti, sequence
|
|
FROM w_classes
|
|
WHERE code NOT IN (SELECT code FROM rh.t_classes WHERE code is not null)
|
|
;
|
|
|
|
UPDATE rh.t_classes set
|
|
texte = w_classes.texte
|
|
FROM w_classes
|
|
WHERE true
|
|
and w_classes.code = t_classes.code
|
|
and w_classes.texte is distinct from t_classes.texte
|
|
;
|
|
|
|
-- Nettoyage du contenu
|
|
delete from rh.t_classes_sections_elements
|
|
where section_id in (
|
|
select s.oid from rh.t_classes as c
|
|
join rh.t_classes_sections as s on s.classe_id = c.oid
|
|
where c.code IN ('PLANIV1', 'PLANIV2', 'PLANIV3'))
|
|
;
|
|
|
|
-- Création des 3 classes de niveaux.
|
|
DROP TABLE IF EXISTS w_classes
|
|
;
|
|
|
|
CREATE TEMP TABLE w_classes AS
|
|
with classe_table as (
|
|
select 'PLANIV1' as code, '[DICT.RH.NIVEAU1#1]' as texte, 1 as sequence
|
|
UNION ALL
|
|
select 'PLANIV2' as code, '[DICT.RH.NIVEAU2#1]' as texte, 2 as sequence
|
|
UNION ALL
|
|
select 'PLANIV3' as code, '[DICT.RH.NIVEAU3#1]' as texte, 3 as sequence)
|
|
SELECT code, texte, table_id, 0 as is_cti, sequence
|
|
FROM classe_table, (select oid as table_id from rh.t_listes_tables where code = 'PNI' LIMIT 1) as subq
|
|
;
|
|
|
|
insert into rh.t_classes (code, texte, table_id, is_cti, sequence)
|
|
select code, texte, table_id, is_cti, sequence
|
|
FROM w_classes
|
|
where code NOT in (select code from rh.t_classes where code is not null)
|
|
;
|
|
|
|
update rh.t_classes set
|
|
texte = w_classes.texte
|
|
FROM w_classes
|
|
WHERE true
|
|
and w_classes.code = t_classes.code
|
|
and w_classes.texte is distinct from t_classes.texte
|
|
;
|
|
|
|
-- Nettoyage du contenu
|
|
delete from rh.t_classes_sections_elements
|
|
where section_id in (
|
|
select s.oid from rh.t_classes as c
|
|
join rh.t_classes_sections as s on s.classe_id = c.oid
|
|
where c.code IN ('PLANIV1', 'PLANIV2', 'PLANIV3'))
|
|
;
|
|
|
|
-- Mise à jour des sections Niveau 1.
|
|
DROP TABLE IF EXISTS w_clasec_1
|
|
;
|
|
|
|
-- avec soit la structure ayant le code établissements soit la structure racine
|
|
CREATE TEMP TABLE w_clasec_1 AS
|
|
SELECT
|
|
split_part(code,'|',1) as code,
|
|
split_part(texte,'|',1) as texte,
|
|
(select oid from rh.t_classes where code = 'PLANIV1') as classe_id
|
|
FROM w_structure
|
|
WHERE code = (SELECT MAX(planning_code) FROM rh.t_etablissements WHERE planning_code != '')
|
|
GROUP BY 1,2,3
|
|
;
|
|
|
|
INSERT INTO rh.t_classes_sections(code, texte, classe_id)
|
|
SELECT
|
|
code,
|
|
texte,
|
|
classe_id
|
|
FROM w_clasec_1
|
|
WHERE code = (SELECT MAX(planning_code) FROM rh.t_etablissements WHERE planning_code != '')
|
|
and code not in (select code from rh.t_classes_sections where t_classes_sections.classe_id = w_clasec_1.classe_id and code is not null)
|
|
;
|
|
|
|
UPDATE rh.t_classes_sections set
|
|
texte = w_clasec_1.texte
|
|
FROM w_clasec_1
|
|
WHERE true
|
|
AND w_clasec_1.classe_id = t_classes_sections.classe_id
|
|
AND w_clasec_1.code = t_classes_sections.code
|
|
AND w_clasec_1.texte is distinct from t_classes_sections.texte
|
|
;
|
|
|
|
-- Mise à jour du contenu des sections Niveau 1.
|
|
INSERT INTO rh.t_classes_sections_elements (section_id, to_id)
|
|
SELECT
|
|
t_classes_sections.oid AS section_id,
|
|
t_planning_niveau.oid AS to_id
|
|
FROM rh.t_classes
|
|
join rh.t_classes_sections on t_classes_sections.classe_id = t_classes.oid
|
|
join rh.t_planning_niveau on split_part(code_original, '|', 1) = t_classes_sections.code
|
|
WHERE t_classes.code = 'PLANIV1'
|
|
group by 1,2
|
|
;
|
|
|
|
-- Mise à jour des sections Niveau 2.
|
|
DROP TABLE IF EXISTS w_clasec_2
|
|
;
|
|
|
|
|
|
CREATE TEMP TABLE w_clasec_2 AS
|
|
SELECT
|
|
split_part(code,'|',2) as code,
|
|
split_part(texte,'|',2) as texte,
|
|
(select oid from rh.t_classes where code = 'PLANIV2') as classe_id
|
|
FROM w_structure
|
|
GROUP BY 1,2,3
|
|
;
|
|
|
|
INSERT INTO rh.t_classes_sections(code, texte, classe_id)
|
|
SELECT code, texte, classe_id
|
|
from w_clasec_2
|
|
where 1=1
|
|
and classe_id = (select oid from rh.t_classes where code = 'PLANIV2')
|
|
and code not in (select code from rh.t_classes_sections where t_classes_sections.classe_id = w_clasec_2.classe_id and code is not null)
|
|
group by 1,2,3
|
|
;
|
|
|
|
UPDATE rh.t_classes_sections set
|
|
texte = w_clasec_2.texte
|
|
FROM w_clasec_2
|
|
WHERE true
|
|
and w_clasec_2.classe_id = t_classes_sections.classe_id
|
|
and w_clasec_2.code = t_classes_sections.code
|
|
and w_clasec_2.texte is distinct from t_classes_sections.texte
|
|
;
|
|
|
|
-- Mise à jour du contenu des sections Niveau 2.
|
|
INSERT INTO rh.t_classes_sections_elements (section_id, to_id)
|
|
SELECT
|
|
t_classes_sections.oid AS section_id,
|
|
t_planning_niveau.oid AS to_id
|
|
FROM rh.t_classes
|
|
join rh.t_classes_sections on t_classes_sections.classe_id = t_classes.oid
|
|
join w_clasec_2 on true
|
|
and w_clasec_2.classe_id = t_classes.oid
|
|
and w_clasec_2.code = t_classes_sections.code
|
|
join rh.t_planning_niveau on split_part(t_planning_niveau.code_original, '|', 2) = w_clasec_2.code
|
|
WHERE t_classes.code = 'PLANIV2'
|
|
group by 1,2
|
|
;
|
|
|
|
-- Mise à jour des sections Niveau 3.
|
|
DROP TABLE IF EXISTS w_clasec_3
|
|
;
|
|
|
|
CREATE TEMP TABLE w_clasec_3 AS
|
|
SELECT
|
|
split_part(code,'|',3) as code,
|
|
split_part(texte,'|',3) as texte,
|
|
(select oid from rh.t_classes where code = 'PLANIV3') as classe_id
|
|
FROM w_structure
|
|
GROUP BY 1,2,3
|
|
;
|
|
|
|
INSERT INTO rh.t_classes_sections(code, texte, classe_id)
|
|
SELECT code, texte, classe_id
|
|
from w_clasec_3
|
|
where 1=1
|
|
and classe_id = (select oid from rh.t_classes where code = 'PLANIV3')
|
|
and code not in (select code from rh.t_classes_sections where t_classes_sections.classe_id = w_clasec_3.classe_id and code is not null)
|
|
group by 1,2,3
|
|
;
|
|
|
|
update rh.t_classes_sections set
|
|
texte = w_clasec_3.texte
|
|
FROM w_clasec_3
|
|
WHERE true
|
|
and w_clasec_3.classe_id = t_classes_sections.classe_id
|
|
and w_clasec_3.code = t_classes_sections.code
|
|
and w_clasec_3.texte is distinct from t_classes_sections.texte
|
|
;
|
|
|
|
-- Mise à jour du contenu des sections Niveau 3.
|
|
INSERT INTO rh.t_classes_sections_elements (section_id, to_id)
|
|
SELECT
|
|
t_classes_sections.oid AS section_id,
|
|
t_planning_niveau.oid AS to_id
|
|
FROM rh.t_classes
|
|
join rh.t_classes_sections on t_classes_sections.classe_id = t_classes.oid
|
|
join w_clasec_3 on true
|
|
and w_clasec_3.classe_id = t_classes.oid
|
|
and w_clasec_3.code = t_classes_sections.code
|
|
join rh.t_planning_niveau on split_part(t_planning_niveau.code_original, '|', 3) = w_clasec_3.code
|
|
WHERE t_classes.code = 'PLANIV3'
|
|
group by 1,2
|
|
;
|
|
|
|
SELECT rh.cti_update_schema_classes('*ALL')
|
|
;
|
|
|
|
-- Recensement des oid utilisés.
|
|
INSERT INTO rh.p_oids (code_table, oid)
|
|
SELECT 'planning_service', service_id
|
|
FROM rh.p_planning_mouvement
|
|
WHERE service_id NOT IN (SELECT oid FROM rh.p_oids WHERE code_table = 'planning_service')
|
|
GROUP BY 1,2
|
|
;
|
|
|
|
INSERT INTO rh.p_oids (code_table, oid)
|
|
SELECT 'planning_qualification', qualification_id
|
|
FROM rh.p_planning_mouvement
|
|
WHERE qualification_id NOT IN (SELECT oid FROM rh.p_oids WHERE code_table = 'planning_qualification')
|
|
GROUP BY 1,2
|
|
;
|
|
|
|
INSERT INTO rh.p_oids (code_table, oid)
|
|
SELECT 'planning_niveau', niveau_id
|
|
FROM rh.p_planning_mouvement
|
|
WHERE niveau_id NOT IN (SELECT oid FROM rh.p_oids WHERE code_table = 'planning_niveau')
|
|
GROUP BY 1,2
|
|
;
|
|
|
|
INSERT INTO rh.p_oids (code_table, oid)
|
|
SELECT 'planning_type_absence', type_absence_id
|
|
FROM rh.p_planning_mouvement
|
|
WHERE type_absence_id NOT IN (SELECT oid FROM rh.p_oids WHERE code_table = 'planning_type_absence')
|
|
GROUP BY 1,2
|
|
;
|
|
|
|
]]></sqlcmd>
|
|
</NODE>
|
|
</ROOT>
|