Commit 1e09178b authored by Laurent Lécluse's avatar Laurent Lécluse
Browse files

Ajout de la formule de calcul de l'INSA de Lyon

parent 98dfaf1a
......@@ -2,6 +2,12 @@
## Nouveautés
* Nouvelles formules de calcul :
* Université Jean Monnet (Saint-Étienne)
* Université Côté d'azur (Nice)
* Université Rennes 2
* INSA de Lyon
## Corrections de bugs
* Corrections coquilles dans l'administration.
......@@ -16,7 +22,7 @@
* Edition possible des types de ressources (paie état, ressources propres etc...)
* Edition des règles de validations (volume horaire / type intervenant)
* Edition des types d'activites des centres de coûts (pilotage, enseignement, accueil etc..)
* L'export CSV des services affiche maintenant les heures non payées avec chaque motif dans des lignes distinctes, ventilées par type d'intervention (CM/TD/TP)
* Par défaut, les pièces jointes ne sont plus demandées si l'intervenant ne fait que des heures non payables dans son service. Possibilité de les forcer en obligatoire dans l'admin si on le souhaite.
......
......@@ -8,20 +8,22 @@
* @var $viewFile string
*/
$formuleTestIntervenantId = 2;
$formuleTestIntervenantId = 3;
$save = false;
$save = true;
$structureUniversité = 'Université';
$vhdata = "STAPS Oui Non Oui 100,00 % 0,00 % 0,00 % CM 1,50 1,50 1,00 1,25 40,00 60,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 1,50 60,00 60,00 60,00 60,00 0,00 1,88 0,00
STAPS Oui Non Oui 85,00 % 0,00 % 15,00 % TD 1,00 1,00 1,00 1,00 35,00 29,75 0,00 5,25 0,00 0,00 0,00 0,00 0,00 0,00 1,00 35,00 35,00 95,00 35,00 0,00 1,00 0,00
Langues Non Non Oui 100,00 % 0,00 % 0,00 % TP 0,67 0,67 1,00 1,00 40,00 26,67 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,67 26,67 26,67 121,67 26,67 0,00 0,67 0,00
STAPS Oui Non Oui 100,00 % 0,00 % 0,00 % Référentiel 1,00 1,00 1,00 1,00 25,00 0,00 0,00 0,00 25,00 0,00 0,00 0,00 0,00 0,00 1,00 0,00 25,00 146,67 25,00 0,00 1,00 0,00
ISSTO Non Non Oui 90,00 % 0,00 % 10,00 % TP 0,67 0,67 1,00 1,00 30,00 18,00 0,00 2,00 0,00 0,00 0,00 0,00 0,00 0,00 0,67 20,00 20,00 166,67 20,00 0,00 0,67 0,00
Langues Non Non Oui 45,00 % 5,00 % 50,00 % TD 1,00 1,00 1,40 1,40 20,00 11,40 1,27 12,67 0,00 1,20 0,13 1,33 0,00 0,00 1,40 28,00 28,00 192,00 25,33 1,90 1,40 2,67
Université Non Non Oui 100,00 % 0,00 % 0,00 % Référentiel 1,00 1,00 1,00 1,00 40,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 40,00 1,00 0,00 40,00 192,00 0,00 40,00 1,00 40,00
$structureUniversité = 'INSA';
$vhdata = "Dept1 Oui Non Oui 100,00 % 0,00 % 0,00 % CM 1,50 1,50 1,00 1,00 25,00 24,78 0,00 0,00 0,00 12,72 0,00 0,00 0,00 0,00
Dept1 Oui Non Oui 100,00 % 0,00 % 0,00 % TD 1,00 1,00 1,00 1,00 43,00 28,42 0,00 0,00 0,00 14,58 0,00 0,00 0,00 0,00
Dept1 Oui Non Oui 100,00 % 0,00 % 0,00 % TP 1,00 0,67 1,00 1,00 172,00 113,68 0,00 0,00 0,00 38,88 0,00 0,00 0,00 0,00
Dept1 Oui Non Oui 100,00 % 0,00 % 0,00 % Référentiel 1,00 1,00 1,00 1,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00
Dept4 Non Non Oui 80,00 % 10,00 % 10,00 % CM 1,50 1,50 1,00 1,00 8,00 6,34 0,79 0,79 0,00 3,26 0,41 0,41 0,00 0,00
Dept4 Non Non Oui 85,00 % 0,00 % 15,00 % TD 1,00 1,00 1,00 1,00 22,00 12,36 0,00 2,18 0,00 6,34 0,00 1,12 0,00 0,00
Dept1 Oui Non Oui 50,00 % 0,00 % 50,00 % TD 1,00 1,00 1,00 1,00 2,00 0,66 0,00 0,66 0,00 0,34 0,00 0,34 0,00 0,00
INSA Non Non Oui 100,00 % 0,00 % 0,00 % TD 1,00 1,00 1,00 1,00 2,00 1,32 0,00 0,00 0,00 0,68 0,00 0,00 0,00 0,00
INSA Non Non Oui 100,00 % 0,00 % 0,00 % Référentiel 1,00 1,00 1,00 1,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00
";
......
CREATE OR REPLACE PACKAGE BODY FORMULE_INSA_LYON AS
decalageLigne NUMERIC DEFAULT 20;
/* Stockage des valeurs intermédiaires */
TYPE t_cell IS RECORD (
valeur FLOAT,
enCalcul BOOLEAN DEFAULT FALSE
);
TYPE t_cells IS TABLE OF t_cell INDEX BY PLS_INTEGER;
TYPE t_coll IS RECORD (
cells t_cells
);
TYPE t_colls IS TABLE OF t_coll INDEX BY VARCHAR2(50);
feuille t_colls;
debugLine NUMERIC;
PROCEDURE dbg( val CLOB ) IS
BEGIN
ose_formule.volumes_horaires.items(debugLine).debug_info :=
ose_formule.volumes_horaires.items(debugLine).debug_info || val;
END;
PROCEDURE dbgi( val CLOB ) IS
BEGIN
ose_formule.intervenant.debug_info := ose_formule.intervenant.debug_info || val;
END;
PROCEDURE dbgDump( val CLOB ) IS
BEGIN
dbg('<div class="dbg-dump">' || val || '</div>');
END;
PROCEDURE dbgCell( c VARCHAR2, l NUMERIC, val FLOAT ) IS
ligne NUMERIC;
BEGIN
ligne := l;
IF l <> 0 THEN
ligne := ligne + decalageLigne;
END IF;
dbgi( '[cell|' || c || '|' || ligne || '|' || val );
END;
PROCEDURE dbgCalc( fncName VARCHAR2, c VARCHAR2, res FLOAT ) IS
BEGIN
dbgi( '[calc|' || fncName || '|' || c || '|' || res );
END;
FUNCTION cell( c VARCHAR2, l NUMERIC DEFAULT 0 ) RETURN FLOAT IS
val FLOAT;
BEGIN
IF feuille.exists(c) THEN
IF feuille(c).cells.exists(l) THEN
IF feuille(c).cells(l).enCalcul THEN
raise_application_error( -20001, 'Dépendance cyclique : la cellule [' || c || ';' || l || '] est déjà en cours de calcul');
END IF;
RETURN feuille(c).cells(l).valeur;
END IF;
END IF;
feuille(c).cells(l).enCalcul := true;
val := calcCell( c, l );
IF ose_formule.debug_actif THEN
dbgCell( c, l, val );
END IF;
feuille(c).cells(l).valeur := val;
feuille(c).cells(l).enCalcul := false;
RETURN val;
END;
FUNCTION mainCell( libelle VARCHAR2, c VARCHAR2, l NUMERIC ) RETURN FLOAT IS
val FLOAT;
BEGIN
debugLine := l;
val := cell(c,l);
RETURN val;
END;
FUNCTION calcFnc( fncName VARCHAR2, c VARCHAR2 ) RETURN FLOAT IS
val FLOAT;
cellRes FLOAT;
BEGIN
IF feuille.exists('__' || fncName || '__' || c || '__') THEN
IF feuille('__' || fncName || '__' || c || '__').cells.exists(1) THEN
RETURN feuille('__' || fncName || '__' || c || '__').cells(1).valeur;
END IF;
END IF;
CASE
-- Liste des fonctions supportées
WHEN fncName = 'total' THEN
val := 0;
FOR l IN 1 .. ose_formule.volumes_horaires.length LOOP
val := val + COALESCE(cell(c, l),0);
END LOOP;
WHEN fncName = 'max' THEN
val := NULL;
FOR l IN 1 .. ose_formule.volumes_horaires.length LOOP
cellRes := cell(c,l);
IF val IS NULL OR val < cellRes THEN
val := cellRes;
END IF;
END LOOP;
-- fin de la liste des fonctions supportées
ELSE
raise_application_error( -20001, 'La formule "' || fncName || '" n''existe pas!');
END CASE;
IF ose_formule.debug_actif THEN
dbgCalc(fncName, c, val );
END IF;
feuille('__' || fncName || '__' || c || '__').cells(1).valeur := val;
RETURN val;
END;
FUNCTION calcVersion RETURN NUMERIC IS
BEGIN
RETURN 1;
END;
FUNCTION notInStructs( v VARCHAR2 DEFAULT NULL ) RETURN BOOLEAN IS
BEGIN
RETURN COALESCE(v,' ') NOT IN ('KE8','UP10');
END;
FUNCTION calcCell( c VARCHAR2, l NUMERIC ) RETURN FLOAT IS
vh ose_formule.t_volume_horaire;
i ose_formule.t_intervenant;
v NUMERIC;
val FLOAT;
BEGIN
v := calcVersion;
i := ose_formule.intervenant;
IF l > 0 THEN
vh := ose_formule.volumes_horaires.items(l);
END IF;
CASE
-- AV13=SOMME($AS:$AS)
WHEN c = 'AV13' AND v >= 1 THEN
RETURN calcFnc('total', 'AS');
-- AW13=SOMME($AT:$AT)
WHEN c = 'AW13' AND v >= 1 THEN
RETURN calcFnc('total', 'AT');
-- AX13=AV13+AW13
WHEN c = 'AX13' AND v >= 1 THEN
RETURN cell('AV13') + cell('AW13');
-- AV14=SI($AX13>0;AV13/$AX13;0)
WHEN c = 'AV14' AND v >= 1 THEN
IF cell('AX13') > 0 THEN
RETURN cell('AV13') / cell('AX13');
ELSE
RETURN 0;
END IF;
-- AW14=SI($AX13>0;AW13/$AX13;0)
WHEN c = 'AW14' AND v >= 1 THEN
IF cell('AX13') > 0 THEN
RETURN cell('AW13') / cell('AX13');
ELSE
RETURN 0;
END IF;
-- AX14=SI($AX13>0;AX13/$AX13;0)
WHEN c = 'AX14' AND v >= 1 THEN
IF cell('AX13') > 0 THEN
RETURN cell('AX13') / cell('AX13');
ELSE
RETURN 0;
END IF;
-- AH15=SOMME(AG:AG)
WHEN c = 'AH15' AND v >= 1 THEN
RETURN calcFnc('total', 'AG');
-- AN15=SOMME(AM:AM)
WHEN c = 'AN15' AND v >= 1 THEN
RETURN calcFnc('total', 'AM');
-- AV15=MIN(i_service_du*AV14;AV13)
WHEN c = 'AV15' AND v >= 1 THEN
RETURN LEAST(i.service_du * cell('AV14'), cell('AV13'));
-- AW15=MIN(i_service_du*AW14;AW13)
WHEN c = 'AW15' AND v >= 1 THEN
RETURN LEAST(i.service_du * cell('AW14'), cell('AW13'));
-- AX15=MIN(i_service_du*AX14;AX13)
WHEN c = 'AX15' AND v >= 1 THEN
RETURN LEAST(i.service_du * cell('AX14'), cell('AX13'));
-- AH16=MIN(AH15;i_service_du)
WHEN c = 'AH16' AND v >= 1 THEN
RETURN LEAST(cell('AH15'), i.service_du);
-- AN16=MIN(AN15;AH17)
WHEN c = 'AN16' AND v >= 1 THEN
RETURN LEAST(cell('AN15'), cell('AH17'));
-- AV16=AV13+AW15-i_service_du
WHEN c = 'AV16' AND v >= 1 THEN
RETURN cell('AV13') + cell('AW15') - i.service_du;
-- AW16=AW13-AW15
WHEN c = 'AW16' AND v >= 1 THEN
RETURN cell('AW13') - cell('AW15');
-- AX16=SI(AX12>i_service_du;AV16+AW16*2/3;0)
WHEN c = 'AX16' AND v >= 1 THEN
IF cell('AX12') > i.service_du THEN
RETURN cell('AV16') + cell('AW16') * 2 / 3;
ELSE
RETURN 0;
END IF;
-- AH17=i_service_du-AH16
WHEN c = 'AH17' AND v >= 1 THEN
RETURN i.service_du - cell('AH16');
-- AN17=AH17-AN16
WHEN c = 'AN17' AND v >= 1 THEN
RETURN cell('AH17') - cell('AN16');
-- BB19=SOMME(BA:BA)
WHEN c = 'BB19' AND v >= 1 THEN
RETURN calcFnc('total', 'BA');
-- T=SI($H20="Référentiel";0;$AI20*E20)
WHEN c = 'T' AND v >= 1 THEN
IF vh.volume_horaire_ref_id IS NOT NULL THEN
RETURN 0;
ELSE
RETURN cell('AI',l) * vh.taux_fi;
END IF;
-- U=SI($H20="Référentiel";0;$AI20*F20)
WHEN c = 'U' AND v >= 1 THEN
IF vh.volume_horaire_ref_id IS NOT NULL THEN
RETURN 0;
ELSE
RETURN cell('AI',l) * vh.taux_fa;
END IF;
-- V=SI($H20="Référentiel";0;$AI20*G20)
WHEN c = 'V' AND v >= 1 THEN
IF vh.volume_horaire_ref_id IS NOT NULL THEN
RETURN 0;
ELSE
RETURN cell('AI',l) * vh.taux_fc;
END IF;
-- W=SI($H20="Référentiel";$AO20;0)
WHEN c = 'W' AND v >= 1 THEN
IF vh.volume_horaire_ref_id IS NOT NULL THEN
RETURN cell('AO',l);
ELSE
RETURN 0;
END IF;
-- X=SI($H20="Référentiel";0;$AK20*E20)
WHEN c = 'X' AND v >= 1 THEN
IF vh.volume_horaire_ref_id IS NOT NULL THEN
RETURN 0;
ELSE
RETURN cell('AK',l) * vh.taux_fi;
END IF;
-- Y=SI($H20="Référentiel";0;$AK20*F20)
WHEN c = 'Y' AND v >= 1 THEN
IF vh.volume_horaire_ref_id IS NOT NULL THEN
RETURN 0;
ELSE
RETURN cell('AK',l) * vh.taux_fa;
END IF;
-- Z=SI($H20="Référentiel";0;$AK20*G20)
WHEN c = 'Z' AND v >= 1 THEN
IF vh.volume_horaire_ref_id IS NOT NULL THEN
RETURN 0;
ELSE
RETURN cell('AK',l) * vh.taux_fc;
END IF;
-- AA=0
WHEN c = 'AA' AND v >= 1 THEN
RETURN 0;
-- AB=SI($H20="Référentiel";$AQ20;0)
WHEN c = 'AB' AND v >= 1 THEN
IF vh.volume_horaire_ref_id IS NOT NULL THEN
RETURN cell('AQ',l);
ELSE
RETURN 0;
END IF;
-- AD=SI(ESTERREUR(I20);1;I20)
WHEN c = 'AD' AND v >= 1 THEN
RETURN vh.taux_service_du;
-- AE=SI(ESTERREUR(J20);1;J20)
WHEN c = 'AE' AND v >= 1 THEN
RETURN vh.taux_service_compl;
-- AG=SI($D20="Oui";SI($H20<>"Référentiel";$M20*$AD20;0);0)
WHEN c = 'AG' AND v >= 1 THEN
IF vh.service_statutaire THEN
IF vh.volume_horaire_ref_id IS NULL THEN
RETURN vh.heures * cell('AD', l);
ELSE
RETURN 0;
END IF;
ELSE
RETURN 0;
END IF;
-- AH=SI(AH$15>0;AG20/AH$15;0)
WHEN c = 'AH' AND v >= 1 THEN
IF cell('AH15') > 0 THEN
RETURN cell('AG',l) / cell('AH15');
ELSE
RETURN 0;
END IF;
-- AI=AH$16*AH20
WHEN c = 'AI' AND v >= 1 THEN
RETURN cell('AH16') * cell('AH',l);
-- AJ=SI(AH$17=0;(AG20-AI20)/$AD20;0)
WHEN c = 'AJ' AND v >= 1 THEN
IF cell('AH17') = 0 THEN
RETURN (cell('AG',l) - cell('AI',l)) / cell('AD', l);
ELSE
RETURN 0;
END IF;
-- AK=SI(i_depassement_service_du_sans_hc="Non";AJ20*$AE20;0)
WHEN c = 'AK' AND v >= 1 THEN
IF NOT i.depassement_service_du_sans_hc THEN
RETURN cell('AJ',l) * cell('AE',l);
ELSE
RETURN 0;
END IF;
-- AM=SI($D20="Oui";SI($H20="Référentiel";$M20;0);0)
WHEN c = 'AM' AND v >= 1 THEN
IF vh.service_statutaire THEN
IF vh.volume_horaire_ref_id IS NOT NULL THEN
RETURN vh.heures;
ELSE
RETURN 0;
END IF;
ELSE
RETURN 0;
END IF;
-- AN=SI(AN$15>0;AM20/AN$15;0)
WHEN c = 'AN' AND v >= 1 THEN
IF cell('AN15') > 0 THEN
RETURN cell('AM',l) / cell('AN15');
ELSE
RETURN 0;
END IF;
-- AO=AN$16*AN20
WHEN c = 'AO' AND v >= 1 THEN
RETURN cell('AN16') * cell('AN',l);
-- AP=SI(AN$17=0;(AM20-AO20)/$AD20;0)
WHEN c = 'AP' AND v >= 1 THEN
IF cell('AN17') = 0 THEN
RETURN (cell('AM',l) - cell('AO',l)) / cell('AD', l);
ELSE
RETURN 0;
END IF;
-- AQ=SI(i_depassement_service_du_sans_hc="Non";AP20*$AE20;0)
WHEN c = 'AQ' AND v >= 1 THEN
IF NOT i.depassement_service_du_sans_hc THEN
RETURN cell('AP',l) * cell('AE',l);
ELSE
RETURN 0;
END IF;
-- AS=SI($D20="Oui";SI(OU($H20="CM";$H20="TD");$M20*$AD20;0);0)
WHEN c = 'AS' AND v >= 1 THEN
IF vh.service_statutaire THEN
IF vh.type_intervention_code IN ('CM','TD') THEN
RETURN vh.heures * cell('AD', l);
ELSE
RETURN 0;
END IF;
ELSE
RETURN 0;
END IF;
-- AT=SI($D20="Oui";SI($H20="TP";$M20*$AD20;0);0)
WHEN c = 'AT' AND v >= 1 THEN
IF vh.service_statutaire THEN
IF vh.type_intervention_code IN ('TP') THEN
RETURN vh.heures * cell('AD', l);
ELSE
RETURN 0;
END IF;
ELSE
RETURN 0;
END IF;
-- AZ=SI(AZ19+AT20>i_service_du;i_service_du;AZ19+AT20)
WHEN c = 'AZ' AND v >= 1 THEN
IF cell('AZ',l-1) + cell('AT',l) > i.service_du THEN
RETURN i.service_du;
ELSE
RETURN cell('AZ',l-1) + cell('AT',l);
END IF;
-- BA=AZ20-AZ19
WHEN c = 'BA' AND v >= 1 THEN
RETURN cell('AZ',l) - cell('AZ',l-1);
-- BC=SI(AZ19+AT20<i_service_du;0;((AZ19+AT20)-i_service_du)/AD20)
WHEN c = 'BC' AND v >= 1 THEN
IF cell('AZ',l-1) + cell('AT',l) < i.service_du THEN
RETURN 0;
ELSE
RETURN ((cell('AZ',l-1) + cell('AT',l)) - i.service_du) / cell('AD', l);
END IF;
-- BD=SI(ESTERREUR(J20);1;J20)
WHEN c = 'BD' AND v >= 1 THEN
RETURN vh.taux_service_compl;
-- BE=SI(OU($BB$19<i_service_du;i_depassement_service_du_sans_hc="Oui");0;(BC20+SI(D20<>"Oui";M20;0))*BD20)
WHEN c = 'BE' AND v >= 1 THEN
IF cell('BB19') < i.service_du OR i.depassement_service_du_sans_hc THEN
RETURN 0;
ELSE
IF NOT vh.service_statutaire THEN
RETURN (cell('BC',l) + vh.heures) * cell('BD', l);
ELSE
RETURN (cell('BC',l) + 0) * cell('BD', l);