Prototype d’outil de calcul d’ETP consommés, qui permet de calculer un nombre d’ETP en fonction d’une plage de dates et d’une quotité de travail.
Modèle ici :
https://grist.incubateur.anct.gouv.fr/o/docs/doc/o2tVfZ1Wx6H2
Lien de téléchargement direct :
Ex - calcul ETP.grist (188 Ko)
Projet créé dans le cadre d’une formation et pour un besoin RH les responsables ayant besoin d’un outil pour orienter dans les arbitrages de suppléance. Ce document grist n’a pas vocation à remplacer l’outil de gestion RH, mais d’avoir un visu rapide sur les ETP en fonction d’une plage de dates.
Il peut nécessiter des ajustements/corrections car certains paramètres n’ont pas été pris en compte (année bissextile par ex). N’hésitez-pas à affiner et proposer une version plus évoluée du modèle
Utilisation
- Dans la table
Présences, placez vous sur une ligne déjà existante, et copiez la liste de mois que vous voyez dans la vue de la tableETP - Sur une nouvelle ligne de la table
Présences, ajouter un identifiant, une plage de dates et une quotité - Dans la table
ETPdans la colonneIdentifiant, choisissez l’identifiant précédemment créé (vous pouvez faire un ctrl +D pour le dupliquer sur plusieurs lignes d’un coup) et dans la colonneMoiscollez la liste de mois
Vous pouvez vous préparer des lignes « en avance » pour ne pas avoir à faire ce process à chaque fois. Il doit par ailleurs être possible de le faire semi-automatiquement avec un bouton d’action par ex.
Fonctionnement
Il fonctionne de la manière suivante :
- une table
Présencesdans laquelle on indique la date de début et de fin de travail, la quotité, et un identifiant (pourrait être calculé automatiquement) pour chaque ligne. La colonneliste mois travaillésretourne la liste des mois couverts par la plage de dates
Formule de calcul de la liste des mois travaillés (c’est une formule python récupérée d’un exemple et adaptée, et qui peut peut-être être améliorée)
date1 = str($Date_debut)
date2 = str($Date_fin)
y0 = int( date1.split('-')[0] )
y1 = int( date2.split('-')[0] )
m0 = int( date1.split('-')[1] ) - 1
m1 = int( date2.split('-')[1] ) - 1
months = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']
result = []
start = m0
for y in range(y0, y1+1):
for m in range(start,12):
result.append( str( months[m % 12]))
if y == y1 and (m % 12) == m1:
break
start = 0
return result
- calcul du nombre de jours travaillés
= date_fin - date_debut + 1
Pour chaque mois, il faudra aller chercher l’info sur le premier et dernier jour couvert par la plage de dates (par ex, une plage du 1er avril au 25 juin, donnera pour le mois de mai date_fin = 31/05/26 et date_debut = 01/05/26)
La formule finale est :
import datetime
# Récupérer info ligne pour l'id et le mois
ligne = Presences.lookupOne(identifiant=$Identifiant.identifiant)
mois = $Mois2
date_debut = ligne.Date_debut
date_fin = ligne.Date_fin
liste_mois = ligne.liste_mois_travailles
quotite = ligne.Quotite
# Si le mois actuel fait partie de la liste
if mois in liste_mois:
# Trouver le premier et dernier jour du mois
# Il sera utilisé pour déterminer date_debut et date_fin
annee = str(date_debut.year)
# Le dernier jour peut-être le 30, 31 ou 28
dernier_jour = Calendrier.lookupOne(Mois=mois).Dernier_jour_mois
# Dernier jour (date en entier ex "30/03/16")
dernier_jour = annee + mois + dernier_jour
dernier_jour = datetime.datetime.strptime(dernier_jour, "%Y%m%d").date()
# Un mois commence toujours par 01
premier_jour = annee + mois + "01"
premier_jour = datetime.datetime.strptime(premier_jour, "%Y%m%d").date()
# L'intervalle couvre-t-il le mois suivant ?
# Si oui, la date de fin = le dernier jour du mois
if list(liste_mois).index(mois) != (len(list(liste_mois)) - 1):
date_fin = dernier_jour
# L'intervalle couvre-t-il le mois précédent ?
# Si oui, la date de début = le premier jour du mois
if list(liste_mois).index(mois) != 0:
date_debut = premier_jour
# Nb jours travaillés
nb_trav = (date_fin - date_debut).days + 1
return nb_trav
else:
return None
- calcul du nombre d’ETP
Le calcul consiste à trouver le nombre de jours travaillés au prorata, car en RH on considère un nombre max de jours RH égal à 30. Puis de calculer le nombre d’ETP qui sera :
nombre_jours_travaillés * quotité / nombre_jours_RH
Ex de calcul :
du 1er au 27 février
27 jours * 30 jours % 28 jours = 28,93 (une personne qui travaille jusqu’au 27 a travaillé l’équivalent de 28,93 jours, si on ramène à un mois de 30jours)
ETP = 28,93 / 30 = 0,96
du 1er au 31 mars
jours * 31 j * 30j % 31j = 30 (une personne qui travaille jusqu’au 31 a travaillé l’équivalent de 30j si on ramène à un mois de 30jours)
ETP = 30 / 30 = 1
du 1er au 30 mars
jours * 30 j * 30j % 31j = 29,03 (une personne qui travaille jusqu’au 30 a travaillé l’équivalent de 29,03j si on ramène à un mois de 30jours)
ETP = 29,03 / 30 = 0,97
Formule finale :
import datetime
# Récupérer info ligne pour l'id et le mois
ligne = Presences.lookupOne(identifiant=$Identifiant.identifiant)
mois = $Mois2
date_debut = ligne.Date_debut
date_fin = ligne.Date_fin
liste_mois = ligne.liste_mois_travailles
quotite = ligne.Quotite
# Si le mois actuel fait partie de la liste
if mois in liste_mois:
# Trouver le premier et dernier jour du mois
# Il sera utilisé pour déterminer date_debut et date_fin
annee = str(date_debut.year)
# Le dernier jour peut-être le 30, 31 ou 28
dernier_jour = Calendrier.lookupOne(Mois=mois).Dernier_jour_mois
# Dernier jour (date en entier ex "30/03/16")
dernier_jour = annee + mois + dernier_jour
dernier_jour = datetime.datetime.strptime(dernier_jour, "%Y%m%d").date()
# Premier jour - le mois commence toujours par 01
premier_jour = annee + mois + "01"
premier_jour = datetime.datetime.strptime(premier_jour, "%Y%m%d").date()
# L'intervalle couvre-t-il le mois suivant ?
# Si oui, la date de fin = le dernier jour du mois
if list(liste_mois).index(mois) != (len(list(liste_mois)) - 1):
date_fin = dernier_jour
# L'intervalle couvre-t-il le mois précédent ?
# Si oui, la date de début = le premier jour du mois
if list(liste_mois).index(mois) != 0:
date_debut = premier_jour
# Nb jours travaillés
nb_trav = (date_fin - date_debut).days + 1
# Nb jours travaillés au prorata
# (on considère le "nombre de jours RH" toujours = 30)
nb_jours_RH = 30
nb_trav = nb_trav * nb_jours_RH / int(dernier_jour.strftime('%d'))
#retourne l'ETP, au prorata de 30 jours
# ex du 1er au 27 février quot 1 : 28 jours * 30 jours % 29jours = 28,96
return float(nb_trav) * quotite / nb_jours_RH
else:
return None

