Scripts

Les scripts permettent de programmer des calculs nécessitant un traitement plus complexe que ce que permet l’interface utilisateur standard. Ce derniers s’adressent à des administrateurs capablent d’utiliser le langage de script JEXL et qui ont une très bonne connaissance du fonctionnement du moteur de salaire.

Attention:

avec un script il est possible de prendre complètement le pas sur les résultats du calcul de salaire, y compris des lignes automatiques. Il peut en résulter des erreurs menant à l’annonce de résultats erronnés auprès des différentes institutions.



Configuration (SAL02 / UNI25)

Un script de salaire peut être créé dans la tâche UNI25. Il est recommandé de le nommer SAL24_<ligne> car la tâche UNI25 peut également contenir d’autres scripts n’ayant aucun rapport avec le moteur de salaire.

Il est important de préciser les tâches SAL02 et SAL24, ainsi que 2 Jexl comme langage. Une fois le script enregistré, il peut être lié à la ligne dans le SAL02.

SAL02

Une fois la liaison effectuée, le moteur de salaire exécutera le script pour toutes les lignes (excepté si la ligne est de type inutilisé ou bloqué).


Exécution

Lorsqu’un script est mentionné dans SAL02, il est exécuté en dernier, après que toutes les autres opérations (calcul automatique, opérations, plafonnage, …) ont été effectuées. Il lui est ainsi possible de récupérer les données calculées et de les modifier. C’est donc ensuite au développeur du script de prendre en compte toutes les contraintes souhaitées.

SAL02

Dans l’exemple ci-dessous, le résultat du calcul automatique de la ligne L10 est modifié par le script. Cela se fait en utilisant simplement les variables génériques et les variables de script.


Exemples avancés

La référence sur la syntaxe JEXL se trouve ici.

Exemple 1

Ce script calcule le taux horaire de l’employé en utilisant une moyenne de nombre de semaine sur 4 ans et le salaire annuel (avec ou sans 13ème selon la configuration de la page Code calcul) et de son taux d’activité.

if(results["B10"] != null) {
    let salaireMensuel = results["B10"].AMOUNT;
    let heuresMensuelles = results["A50"].AMOUNT;
    let tauxActivite = results["A12"].AMOUNT;
    
    let codesCalcul = employee.getUniqueActivePage("CODEMSAI", computationPeriod.start, "FM_PAGE_START_DATE", "FM_PAGE_END_DATE");
    let code13e = codesCalcul.get("COD13E");
    let nbMois = code13e=="" || code13e=="0" ? 12 : 13;

    let nbSemainesAnnuellesAvg = 52.178; //moyenne du nb de semaines par année sur 4 ans
    let heuresAnnuelles = nbSemainesAnnuellesAvg * heuresMensuelles * tauxActivite / 100.0;
    let salaireAnnuel = salaireMensuel * nbMois;
    let tauxHoraire = salaireAnnuel / heuresAnnuelles;
    
    context.addMessage("Heures annuelles: {0} = {1} * {2} * {3} / 100", heuresAnnuelles, nbSemainesAnnuellesAvg, heuresMensuelles, tauxActivite);
    context.addMessage("Salaire annuel: {0} = {1} * {2}", salaireAnnuel, salaireMensuel, nbMois);
    context.addMessage("Taux horaire: {0} = {1} / {2}", tauxHoraire, salaireAnnuel, heuresAnnuelles);

    output.SUBJECT = salaireAnnuel;
    output.NUMBER = heuresAnnuelles;
    output.AMOUNT = tauxHoraire;
} else {
    //pas de salaire annuel, alors utilise directement la valeur de la page salaire
    let pageSalaire = employee.getUniqueActivePage("SALAIRE", computationPeriod.start, "FM_PAGE_START_DATE", "FM_PAGE_END_DATE");
    output.AMOUNT = pageSalaire.get("SALAIREHORAIRE");
}

Exemple 2

Ce script calcule le nombre d’années de présence par rapport au mois d’avril en fonction de la date de début de la page SALAIRE actuelle. Si une personne change de poste au 1er janvier, l’augmentation de salaire au mois d’avril est ignorée. Il ne faut donc pas prendre la date d’entrée (physique) de l’empoyé.

let entryPage = employee.getUniqueActivePage("ENTREESSORTIES", computationPeriod.start, "FM_PAGE_START_DATE", "FM_PAGE_END_DATE");
let salaryPage = employee.getUniqueActivePage("SALAIRE", computationPeriod.start, "FM_PAGE_START_DATE", "FM_PAGE_END_DATE");
if(entryPage!=null && salaryPage!=null) {

    //on prend bien la date de début de la page SALAIRE car c'est celle
    //qui fait foi pour les augmentations
    let salaryPageStartDate = salaryPage.getDate("FM_PAGE_START_DATE");

    //par contre pour la date de sortie, prendre celle des pages Entrées/Sorties
    let salaryPageEndDate = entryPage.getDate("FM_PAGE_END_DATE");

    //on prend la date de début de la page SALAIRE
    let startDate = salaryPageStartDate;

    let currentYear = parse:asString(computationPeriod.start, "yyyy");
    let aprilStartStr = "01.04."+currentYear;
    let aprilStart = parse:asDate(aprilStartStr, "dd.MM.yyyy");
    let startLimit = parse:asDate("01.10."+(currentYear-1));
    let exitLimit = parse:asDate("01.05."+currentYear, "dd.MM.yyyy");

    //on ajoute 1 au nombre de mois car lors du calcul d'avril, il
    //faut prendre en compte avril y compris
    var adder = parse:asString(startDate, "dd")=="01" ? 1 : 0;
    if(salaryPageStartDate>=startLimit) {
        adder = -1;
        context.addMessage("The employee has less than 6 months of contract");
    } else if(salaryPageEndDate!=null && salaryPageEndDate<exitLimit) {
        adder = -7;
        context.addMessage("The contract of the employee is cancelled");
    }

    let nbMonths = period:monthsDiff(startDate, aprilStart);
    let nbYears = (nbMonths+adder) / 12.0;
    context.addMessage("Nb months from {0} to {1} : {2}", parse:asString(startDate, "dd.MM.yyyy"), parse:asString(aprilStart, "dd.MM.yyyy"), nbMonths);
    context.addMessage("Nb years: {0} = ({1} + {2}) / 12", nbYears, nbMonths, adder);

    let compMonth = parse:asString(computationPeriod.start, "MM");
    let nbYearsAprilInit = ((compMonth<"04") ? nbYears-1 : nbYears);
    if(nbYearsAprilInit<0) { nbYearsAprilInit = 0; }
    let nbYearsApril = nbYearsAprilInit;

    //récupération du nombres d'année initiales dans SAL04
    let previousYears = output.get("NUMBER");
    if(previousYears!=null) { nbYearsApril = previousYears + nbYearsAprilInit; }
    context.addMessage("Nb years since April ({3}): {0} = {1} + {2} ", nbYearsApril, previousYears, nbYearsAprilInit, compMonth);

    output.NUMBER = nbYearsApril;
    output.AMOUNT = math:round(nbYearsApril.doubleValue());
}

Exemple 3

Calcule la prime de fidélité versée chaque année, à la date d’entrée de l’employé. Elle augmente de 50.- chaque année avec un plafond de 500.-. Si l’employé est à moins de 50%, alors l’augementation est de 25.- par année.

if(periodIndex==1) {
    let salaryPage = employee.getUniqueActivePage("SALAIRE", computationPeriod.start, "FM_PAGE_START_DATE", "FM_PAGE_END_DATE");
    if(salaryPage!=null) {
        let primeDateStart = salaryPage.getDate("PRIMEFIDELITEDATE");

        let computeMonth = parse:asString(computationPeriod.start, "MM");
        let hiredMonth = parse:asString(primeDateStart, "MM");
        if(computeMonth == hiredMonth) {
            let nbYears = results["A16"].AMOUNT; //sera un chiffre rond, calculé dans la ligne A16
            let workRate = results["A12"].AMOUNT; //on prend le montant de la ligne A12
            if(nbYears!=null && workRate!=null) {
                let finalNumber = nbYears;
                let finalSubject = (workRate<50 ? 25 : 50); //25.- ou 50.- selon le taux d'activité
                var finalAmount = finalSubject * finalNumber;
                if(finalAmount>500) { finalAmount = 500; } //plafonnage

                output.NUMBER = finalNumber;
                output.SUBJECT = finalSubject;
                output.AMOUNT = finalAmount;
            } else {
                if(nbYears==null) { context.addMessage("Missing line A16"); }
                if(workRate==null) { context.addMessage("Missing line A12"); }
            }
        }
    }
}

Debugger un script

La manière la plus simple de débugger un script de salaire est d’ajouter des context.addMessage afin de pouvoir voir quels sont les outputs qui sont générés. Il faut ensuite lancer le calcul de salaire (de préférence sur un employé) en activant la coche “Récupérer le log des calculs détaillés”.

SAL24

Cela permet de récupérer le fichier contenant tous les détails des calculs, y compris les messages qui ont été définis dans les scripts.

SAL24

En cas de crash, généralement il est possible d’en comprendre la cause dans la fenêtre de log qui s’ouvre après le calcul en SAL24. Sinon, il sera nécessaire d’accéder aux logs du serveur afin de savoir plus précisément le problème rencontré.


Variables disponibles

Ce chapitre détaille les variables disponibles dans un script de salaire:

  • employee (SalempEmployee): Accès aux données de l’employé.
  • input (Map): Variables d’entrées (voir variables.
  • output (Map): Variables de sortie (voir variables.
  • computationPeriod (Period): Période de calcul. Les date de début/fin seront toujours comprises entre le début et la fin du mois.
  • hiredPeriod (Period): Période d’engagement de l’employé. Pour les employés dont le calcul est forcé, cette valeur est nulle.
  • periodIndex (Integer): Index de la période calculée. Commence à 1 (chaque mois) et s’incrément pour chaque sous-période dans le mois.
  • line (SalaryLine): Ligne de salaire courante.
  • plan (SalaryPlan): Plan de salaire.
  • results (Map): Résultats des calculs des lignes précédentes (calcul en cours). Il est possible d’utiliser une référence multi-contrats.
  • cumul (Map): Accès aux différents cumuls.
  • constants (Map): Accès aux différentes constantes (SAL03).
  • context (SalaryLineContext): Context de calcul courant. Permet également d’ajouter des messages pour débugger.

Variables spéciales SAINet:

  • CURRENT_DOMAIN: domaine courant
  • CURRENT_SITE: site courant (déprécié)
  • COMPUTE_YEAR: année du calcul
  • COMPUTE_MONTH: mois du calcul (peut être supérieure à 12 pour les période extra-anuelles -mois 13-)
  • PAGE_STRUCTURE: nom de la page structure dans le cadre d’une ligne multi-contrats (STRUCTURE, STRUCTURE2, …). Dans les autres cas, cette variable contient toujours STRUCTURE.
  • PAGE_SALAIRE: nom de la page salaire dans le cadre d’une ligne multi-contrats (SALAIRE, SALAIRE2, …). Dans les autres cas, cette variable contient toujours SALAIRE.

Les variables input et outputpermettent d’accéder (ou de modifier) les informations standards des lignes de salaires. Il est par exemple possible d’avoir le script suivant:

output.AMOUNT = input.SUBJECT * results["A17"].AMOUNT;