Rapport avancé - Affectation - Ratio des personnes disponibles selon leur contrat de travail, par équipe, dans les vues d'affectations

Description
Un indicateur intéressant du fonctionnement d'un atelier peut être le nombre de personnes, engagées sous un certain contrat de travail, encore disponibles par rapport à l'ensemble. Par exemple, on pourrait imaginer que si le nombre de personnes en CDI disponibles passe sous la barre des 5% de l'ensemble des CDI, il est temps de contacter des intérimaires. Ce rapport affiche donc par atelier et pour chaque poste horaire, dans les vues d'affectations, le ratio entre le nombre de personnes disponible et l'effectif total (pour un certain contrat de travail). Les personnes considérées comme disponibles
· n'ont pas de conflit avec un évènement
· ne sont pas encore affectées
· font partie d'une équipe postée pour l'atelier et le poste horaire considéré
Dans l'exemple suivant, si le seuil est dépassé, la valeur est affichée. Dans le cas contraire, un tiret est affiché dans la cellule. Les cellules vides le sont parce qu'il n'y a pas d'équipe postée à cet endroit.


Notons qu'il est possible de faire des variantes de ce rapport en se basant sur les autres exemples de cette documentation (considérer 2 contrats en même temps, visualiser par équipes, visualiser dans une autre vue, ...)

Configuration de base
Placez d'abord une brique "Rapport temporel" avec en période "Jour".


Pour rendre le rapport visible dans les vues d'affectation, placez "Affectation par ligne" et "Affectation par personne" dans l'onglet "Vues" de la brique "Rapport temporel".


Ajoutez ensuite à cette première brique une brique "Tableau de synthèse". Utilisez "Formule" comme source ainsi que dans les cellule. Choisissez le positionnement du contenu des cellules comme bon vous semble.


Dans les onglets "Paramètres", "Lignes" et "Colonnes" de la brique "Tableau de synthèse", on définie les formules à utiliser ainsi que les entêtes du rapport. Choisissez "Atelier" et "Poste horaire" en lignes et "Début" en colonnes. N'oubliez pas de sélectionner la génération des lignes et des colonnes vides.


En ce qui concerne la formule, sa forme générique est

string ToDisplay;
double ratio;
double dispo;

IList<Team> teams = Source.TeamCalendar.GetTeamCalendars(Properties.TeamCalendar.Team == Headers._Team & Properties.TeamCalendar.Optional != true).Where( Properties.Allocation.ShiftOccurence.ShiftTemplate == Headers._ShiftTemplate & Properties.Allocation.ShiftOccurence.Optional != true ).Select( Properties.TeamCalendar.Team ).GetItems();

double total = (double)Source.Personnel.Where(Properties.Personnel.WorkContractType.In_(Values.WorkContractType._CCCCC)).Count;

if(total == 0.0)
{
ToDisplay = "div by 0";
}
else
{
if(teams.Count < 1)
{
ToDisplay = "";
}
else
{
if(Source.Allocation.Count < 1)
{
dispo = (double)Source.Personnel.Where(Properties.Personnel.Teams[ Properties.Team.This.In( teams )] & Properties.Personnel.WorkContractType.In_(Values.WorkContractType._CCCCC)).Available(AvailableMode.UnavailableIfAtLeastOneEvent, NotAvailLimitMode.TakeIntoAccountNotAvailLimit).Count;
}
else
{
dispo = (double)Source.Personnel.Where(Properties.Personnel.Teams[ Properties.Team.This.In( teams )] & Properties.Personnel.WorkContractType.In_(Values.WorkContractType._CCCCC) & !Properties.Personnel.This.In_(Source.Allocation.Select(Properties.Allocation.Personnel).Distinct())).Available(AvailableMode.UnavailableIfAtLeastOneEvent, NotAvailLimitMode.TakeIntoAccountNotAvailLimit).Count;
}
ratio = dispo/total;
if(ratio <= SSSSS)
{
ToDisplay = Math.Round(ratio, NNNNN).ToString();
}
else
{
ToDisplay = "-";
}
}
}

ToDisplay



· CCCCC est le type de contrat de travail étudié
· SSSSS est le seuil en dessous duquel une valeur va s'afficher
· NNNNN est le nombre de décimales souhaité pour le ratio
Notons que les décimales s'écrivent avec un point.
Dans le cas où le dénominateur du ratio s'avérerait nul, le message d'erreur "div by 0" serait affiché dans le rapport.
Sélection du type de contrat
Le morceau de code Properties.Personnel.WorkContractType.In_( Values.WorkContractType._CCCCC ) sert à prendre en considération un contrat CCCCC, cette dernière valeur étant définie dans la configuration des listes. Il ne faut pas oublier l'underscore ( le "_" ) devant la description des imputations.
On aura ainsi dans notre exemple pour Contrat_1 : Charge.In_( Values.Charge._Contrat_1 )
Il faut cependant rester prudent dans certains cas car la description du contrat qui est tapée dans la formule n'est pas considérée comme un String. Il faut donc faire attention avec les contrat donc la description contient des espaces ou des caractères spéciaux comme des opérateurs mathématiques (ex. "-", "/"", ...). Ces caractères seront remplacés dans la formule par des underscores ("_"). Pour éviter tout problème, il est conseillé d'utiliser l'IntelliSense de l'éditeur de formule, celui-ci permettant l'auto-complétion. Concrètement, pour choisir un contrat, lorsque vous tapez le point après Values.WorkContractType, une liste des contrat existants apparaît, reste à choisir celui voulu.
Pour analyser plusieurs types de contrat, il suffit de les ajouter dans la liste des arguments de la fonction In_(). Par exemple pour 3 contrats : Properties.Personnel.WorkContractType.In_( Values.WorkContractType._A , Values.WorkContractType._B , Values.WorkContractType._C )
Avant de taper le point


Après avoir tapé le point


On peut observer la correspondance avec les contrats définis dans la configuration de l'application


Formule
Dans notre exemple, on s'intéressait aux contrats "Contrat_1" avec un seuil de 0.5 et 2 décimales. Ceci correspond à la formule suivante

string ToDisplay;
double ratio;
double dispo;

IList<Team> teams = Source.TeamCalendar.GetTeamCalendars(Properties.TeamCalendar.Team == Headers._Team & Properties.TeamCalendar.Optional != true).Where( Properties.Allocation.ShiftOccurence.ShiftTemplate == Headers._ShiftTemplate & Properties.Allocation.ShiftOccurence.Optional != true ).Select( Properties.TeamCalendar.Team ).GetItems();

double total = (double)Source.Personnel.Where(Properties.Personnel.WorkContractType.In_(Values.WorkContractType._Contrat_1)).Count;

if(total == 0.0)
{
ToDisplay = "div by 0";
}
else
{
if(teams.Count < 1)
{
ToDisplay = "";
}
else
{
if(Source.Allocation.Count < 1)
{
dispo = (double)Source.Personnel.Where(Properties.Personnel.Teams[ Properties.Team.This.In( teams )] & Properties.Personnel.WorkContractType.In_(Values.WorkContractType._Contrat_1)).Available(AvailableMode.UnavailableIfAtLeastOneEvent, NotAvailLimitMode.TakeIntoAccountNotAvailLimit).Count;
}
else
{
dispo = (double)Source.Personnel.Where(Properties.Personnel.Teams[ Properties.Team.This.In( teams )] & Properties.Personnel.WorkContractType.In_(Values.WorkContractType._Contrat_1) & !Properties.Personnel.This.In_(Source.Allocation.Select(Properties.Allocation.Personnel).Distinct())).Available(AvailableMode.UnavailableIfAtLeastOneEvent, NotAvailLimitMode.TakeIntoAccountNotAvailLimit).Count;
}
ratio = dispo/total;
if(ratio <= 0.5)
{
ToDisplay = Math.Round(ratio, 2).ToString();
}
else
{
ToDisplay = "-";
}
}
}

ToDisplay



Pour d'autres façons de gérer les évènements dans l'analyse de la disponibilité des personnes, il faut jouer sur les paramètres de la fonction Available ( voir Available ).
Fichiers
image001.png
image002.png
image003.png
image004.png
image005.png
image006.png
image007.png
image008.png
image009.png