-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Intégration du calcul de la rente d'accident du travail #1270
Conversation
e23a615
to
c6a1a01
Compare
rente_at = parameters(period).accident_travail.rente.taux | ||
age = individu('age', period) | ||
rente_accident_travail_rachat = individu('rente_accident_travail_rachat', period) | ||
conversion_rente_capetal = rente_at.capital_representatif[age] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conversion_rente_capetal -> conversion_rente_capital
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Morendil Je travaille sur le débogage :d .
class demande_rachat(Variable): | ||
value_type = bool | ||
entity = Individu | ||
label = u"Le victime demande le rachat partiel de la rente" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Le victime -> La victime
Merci @mtifarine! J'ai indiqué encore une coquille, mais pas encore commencé une relecture en détail. Est-ce que tu as terminé le travail sur cette PR et est-elle prête pour relecture ? |
Oui @Morendil, tu peux commencer la relecture. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merci pour ce travail qui a certainement demandé pas mal d'analyse des textes.
J'ai un certain nombre de remarques et de changements qui me semblent s'imposer, toutefois il est possible que j'ai mal interprété le code ou les textes référencés, n'hésite pas à revenir vers moi si nécessaire.
@@ -6,6 +6,186 @@ | |||
class rente_accident_travail(Variable): | |||
value_type = float | |||
entity = Individu | |||
label = u"Montant mensuel de la rente d’accident du travail" | |||
label = u"Montant mensuel ou trimestriel de la rente d’accident du travail" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cette annotation prête à confusion. Le versement est mensuel ou trimestriel en fonction du taux d'incapacité, mais cette variation est sans conséquence pour le calcul effectué par OpenFisca qui devra bien être celui du montant mensuel, car la période de définition de la variable est le mois.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Morendil
Exactement, le versement est mensuel ou trimestriel en fonction du taux d'incapacité. Donc, je ne sais pas si, dans ce cas, on calcule le montant mensuel au lieu de calculer le montant du versement ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oui on calcule le montant mensuel.
rente_accident_travail_salarie = individu('rente_accident_travail_salarie', period) | ||
rente_accident_travail_exploitant_agricole = individu('rente_accident_travail_exploitant_agricole', period) | ||
|
||
return max_(rente_accident_travail_salarie, rente_accident_travail_exploitant_agricole) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je ne comprends pas bien pourquoi on utilise ici le max
de ces deux calculs, alors qu'on s'attendrait à voir un aiguillage en fonction du statut.
Je suppose que c'est parce qu'on n'a pas modélisé le statut d'exploitant agricole, qui n'est représenté par aucune variable existante; mais cela ne me semble pas très satisfaisant de prendre le maximum ici et d'utiliser tns_benefice_exploitant_agricole
comme un indicateur du statut dans la formule du cas agricole.
Si on utilise tns_benefice_exploitant_agricole
comme un indicateur de statut, il vaut mieux l'exploiter ici comme condition d'aiguillage au lieu de prendre le max.
Une solution plus pérenne consisterait à introduire une variable renseignant sur le statut d'activité de la personne, mais c'est un débat en cours. Pour l'instant je recommande donc la solution ci-dessus.
montant_rente_accident_travail = where(rente_accident_travail_rachat != 0, rente_accident_travail_apres_rachat, | ||
rente_accident_travail_base) | ||
rente_accident_travail_verse = select([taux_incapacite < 0.1, taux_incapacite < 0.5, taux_incapacite >= 0.5], | ||
[0, montant_rente_accident_travail / 4, montant_rente_accident_travail / 12]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cet aiguillage ne me semble pas correct, pour les raisons évoquées dans la remarque sur le label
de rente_accident_travail
. La périodicité du versement n'a pas d'incidence sur le montant qui doit rester mensuel pour correspondre à la définition de la variable.
montant_rente_accident_travail = where(rente_accident_travail_rachat != 0, rente_accident_travail_apres_rachat, | ||
rente_accident_travail_base) | ||
rente_accident_travail_verse = select([taux_incapacite < 0.3, taux_incapacite >= 0.3], | ||
[0, montant_rente_accident_travail / 12] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Même remarque que ci-dessus quant à la périodicité et au montant.
def formula(individu, period, parameters): | ||
indem_at = parameters(period).accident_travail.rente.taux | ||
taux_incapacite = individu('taux_accident_travail', period) | ||
return select( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Plutôt qu'un select il vaudrait mieux implémenter cela sous la forme d'un barème de type SingleAmountTaxScale (cf. #1258 pour un exemple d'utilisation).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Morendil pour un barème de type SingleAmountTaxScale, les thresholds doivent être des entiers naturels pour donner les valeurs correctes?
J'ai testé les thresholds du barème avec des valeurs décimales [0.01, 0.02 , ..., 0.1] mais cela ne ne donne pas le bon résultat, par contre, lorsque je les ai remplacés par des valeurs entières [1, 2, ...,10], ça donne le bon résultat.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mtifarine Cela semble être dû à un bug dans Numpy… C'est très étonnant, 99% des cas dans ma carrière ou j'ai invoqué "un bug dans le compilateur" j'avais tort, mais le cas de test semble indiscutable :
>>> import numpy as np
>>> np.digitize([7], np.array([-np.inf,0.,0.01,0.02,0.03,0.04,0.05,0.06,0.07,0.08,0.09,0.10,np.inf])*100)
array([8])
>>> np.digitize([6], np.array([-np.inf,0.,0.01,0.02,0.03,0.04,0.05,0.06,0.07,0.08,0.09,0.10,np.inf])*100)
array([8])
Malheureusement, ce bug ne semble pas être corrigé dans les versions plus récentes que celle que nous utilisons.
Je pense que ta solution contourne élégamment le problème!
tests/formulas/rente_at.yaml
Outdated
rente_accident_travail: 1216.67 | ||
pcrtp: 559.26 | ||
|
||
- name: "Cas 6: Victime non salarié agricol, taux d'IPP < 30%, pas de rente ou d'indemnité" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agricol -> agricole
tests/formulas/rente_at.yaml
Outdated
@@ -0,0 +1,204 @@ | |||
- name: "Cas 1: Victime salarié, taux d'IPP < 10%, versement d'une indemnité en capital" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
salarié -> salariée
description: Salaire minimum des rentes | ||
reference: "https://www.legifrance.gouv.fr/affichCodeArticle.do?cidTexte=LEGITEXT000006073189&idArticle=LEGIARTI000006743072&dateTexte=&categorieLien=cid" | ||
unit: currency | ||
values: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On trouve un historique plus complet de ces valeurs ici: http://www.securite-sociale.fr/7-Montants-des-prestations-accidents-du-travail-a-compter-du-1er-avril-2016-indemnisation-de-l
Si tu veux bien les intégrer ça serait top, à défaut ça serait bien de conserver ce lien en commentaire
reference: "https://www.legifrance.gouv.fr/affichCodeArticle.do?cidTexte=LEGITEXT000006073189&idArticle=LEGIARTI000006743072&dateTexte=&categorieLien=cid" | ||
unit: currency | ||
values: | ||
1954-09-01: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ici ça me paraît compliqué de laisser une valeurs en francs sans préciser l'unité monétaire ! Je serais plutôt favorable à ce qu'on intègre les valeurs depuis 2002 et qu'on abandonne celles en francs.
salaire = max_(salaire_net, tns_benefice_exploitant_agricole) | ||
salaire_net_base = max_(rente_at.salaire_net.salaire_minimum, salaire) | ||
|
||
return rente_at.salaire_net.salaire_minimum * rente_at.salaire_net.bareme.calc( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Très bonne idée l'utilisation du barème ici!
@mtifarine Pas de changement demandé pour rente_accident_travail_salaire_utile
, les remarques ci-dessous sont pour @sandcha pour amorcer une réflexion.
Je me demande si on peut encore améliorer la lisibilité de ce calcul, c'est dommage d'avoir ce max effectué ligne 188. Mais je crois qu'il faudrait une modification dans Core pour cela.
Idéalement on ferait porter tout le calcul sur le barème, en multipliant par salaire
au lieu de multiplier par le paramètre "salaire minimum".
Si on avait un test pour cette variable, je m'attendrais à voir les valeurs suivantes; soit "U" la valeur de rente_accident_travail_salaire_utile
pour janvier 2019 et "S" mon salaire pour l'année 2018:
- si S est inférieur à 18520, alors U est 18520
- si S est entre 18520 et 18520 * 2, alors U est égal à S
- si S est entre 18520 * 2 et 18520 * 8, alors U est égal à 18520 * 2 + (S-18520 * 2)/3
- si S est supérieur à 18520 * 8, alors U est égal à (18520 * 2)+(18520 * 8-18520 * 2)/3 soit 18520 * 4
Le problème est qu'on ne sait pas spécifier une tranche avec un minimum il me semble.
@mtifarine On fait la revue de cette PR avec @sandcha aujourd'hui, on reprend la main pour pousser éventuellement des commits d'amélioration à la marge (typos etc) et on te fait signe s'il y a quelque chose de plus substantiel à faire. |
41e04fd
to
f7825ed
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merci @mtifarine !
Retour principal : besoin de mise à jour de parameters/accident_travail/rente/taux/capital_representatif
@@ -0,0 +1,22 @@ | |||
description: Barème utilisé pour la détermination de rente_accident_travail_salaire_utile (cf. formule) | |||
reference: https://www.legifrance.gouv.fr/affichCodeArticle.do;jsessionid=7392B9902E4B974EAE8783FAF2D69849.tplgfr30s_1?idArticle=LEGIARTI000006750376&cidTexte=LEGITEXT000006073189&dateTexte=20180823 | |||
unit: currency |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unit: currency | |
metadata: | |
threshold_unit: /1 | |
rate_unit: /1 |
@@ -0,0 +1,307 @@ | |||
description: Barème servant à la détermination du capital représentatif des rentes d'accidents du travail | |||
reference: "https://www.legifrance.gouv.fr/affichTexte.do?cidTexte=JORFTEXT000030308553&categorieLien=id" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Il semble que ce texte ait été abrogé en faveur de cet arrêté du 19 décembre 2016 (en € 😍).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C'est l'expert qui nous a donné cette référence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, que fait-on ? @mtifarine tu demandes l'avis de l'expert sur la base des nouvelles informations fournies par @sandcha ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pour info: @JenniferTelep
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merci @mtifarine pour l'info complémentaire ! Des informations erronées circulent à ce sujet, au point que certaines personnes ont porté l'affaire devant les tribunaux.
@JenniferTelep @MehdiBenHnin Lors de notre rencontre avec @ThibaultCCMSA fin 2018 j'avais évoqué une demande de notre part, qui nous permettrait je pense d'être plus efficace lors des revues de PR: est-ce que vous voudriez bien partager avec nous les fiches d'analyse produites par les experts métiers lorsque vous ouvrez un sujet ? Je fais l'hypothèse que ce type d'information fournie par les experts est présente dans la fiche d'analyse, et en avoir connaissance nous éviterait peut-être de remettre en question des éléments qui peuvent sembler surprenants mais sont en fait validés par l'expertise métier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Morendil je m'avance peut-être, @JenniferTelep @MehdiBenHnin arrêtez moi si je dis une bêtise, mais il me semble que c'est bien ce qui est prévu à partir de maintenant pour toutes les prochaines demandes.
Nous créérons une issue au moment de commencer à travailler sur une tache et les fiches y seront associées.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@frtomas Top, merci!
|
||
def formula(individu, period, parameters): | ||
rente_at = parameters(period).accident_travail.rente.taux | ||
age = max_(individu('age', period), 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As-tu rencontré un cas où l'âge était négatif/indéterminé (ce serait un bug dans l'appelant 🤔) ?
Supprimer lemax
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avant, j'avais un problème mais maintenant non, donc je vais supprimer le max.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certaines checks ont échoué, où l'âge = -1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
En effet, dans cmuc_fiab.yaml
, "CMU-C: N°1 refus CMUC, accord ACS - 2018-05".
Dans cette situation il y a un enfant né le 2018-01-01 et pour qui on évalue des variables en 2017. A mon sens c'est une erreur dans le test, et on peut le faire passer en corrigeant cette date de naissance en 2017-01-01.
Si on souhaite corriger cette erreur de façon plus globale, il me semble qu'il vaudrait mieux s'assurer directement dans la variable age
qu'elle renvoie un résultat supérieur ou égal à 0, et on peut embarquer ça dans une autre PR.
Donc @mtifarine je t'invite plutôt à corriger le test en question pour l'instant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pour l'age , si je me rappelle bien il y a des allocations pour des enfants à naître et qui ont donc un âge négatif ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Morendil
Toujours le même problème, même après la correction du test en question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Effectivement cette date de naissance n'est pas fausse en soi, comme le dit @benjello cela concerne des allocations pour enfants à naître.
Le problème étant que plus loin dans le code, on utilise cet age comme un index :
conversion_rente_capital = rente_at.capital_representatif[age]
et aucune valeur n'existe pour un age négatif.
Ce max permet d’éviter ce problème sans fausser les résultats.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mtifarine Oui c'est maintenant un autre test qui échoue: test_mes_aides_5530fbb7d421717116602458.yaml
comme indiqué dans l'intégration continue. Malheureusement l'outil de test de Core n'est pas assez robuste face à ce type d'erreurs, il sort au premier échec. J'ai créé une issue pour ce sujet.
Effectivement à la lecture de ce test ça me paraît logique qu'on rétablisse ce max_
ici dans la mesure où d'autres tests sont concernés par cette difficulté. Cette notion "d'âge négatif" me semble quand même problématique.
Par ailleurs je m'aperçois que la valeur 0 n'est pas une valeur par défaut raisonnable pour ce paramètre pour age < 16. Ainsi nous avons une division par zéro dans rente_accident_travail_apres_rachat
ligne 122, que le where
ne peut pas éviter en raison de la nature vectorielle du calcul. Il vaudrait mieux ne garder que les valeurs > 0 dans le paramètre et utiliser dans ce cas max_(age, 16)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Le problème existe (en production) pour les personnes âgées de plus de 100 ans. Mais j'ai l'intuiton que l'âge utilisé n'est pas le bon, en effet je pensais que l'âge utilisé dans le barème serait l'âge au moment de l'accident de travail ? (ou peut-être que c'est l'âge de la demande de passage en capital et là ça serait bon). À voir. #1327
@@ -0,0 +1,307 @@ | |||
description: Barème servant à la détermination du capital représentatif des rentes d'accidents du travail | |||
reference: "https://www.legifrance.gouv.fr/affichTexte.do?cidTexte=JORFTEXT000030308553&categorieLien=id" | |||
unit: currency |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pour les valeurs en euros, on peut indiquer :
currency-EUR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Les valeurs du capital representatif sont des coefficients et ne sont pas des valeurs en euros.
@Morendil reste-t-il d'autres points bloquants sur cette PR ? |
@frtomas Non, on devrait pouvoir merger dans l'après-midi. |
@mtifarine J'ai rebasé et simplifié un peu l'historique de la branche, et corrigé aussi la présence d'un commit de merge résultant de ce qu'on s'est apparemment un peu marché sur les pieds vers la fin. @sandcha m'a signalé tout à l'heure que j'ai effectué des rebase et push-force sur cette PR, et que ce n'était pas une habitude courante jusqu'ici. Pour moi l'avantage de rebaser en cours de route c'est que je suis certain que la PR contient bien les évolutions les plus récentes et que le résultat des tests est donc pertinent, mais je vais essayer d'être plus explicite quand je le fais et de le faire moins souvent. L'inconvénient c'est que quand tu reprends une branche après qu'une autre personne ait fait un rebase et push-force, il ne faut surtout pas faire un Généralement je fais ça comme suit:
Cela revient à supprimer la branche locale, et la checkout à nouveau depuis Github. |
Ok @Morendil, merci! |
Intégration du calcul de la rente d'accident du travail
Évolution du système socio-fiscal.
Périodes concernées : toutes.
Zones impactées :
model/revenus/remplacement/rente_accident_travail
.parameters/accident_travail/rente/salaire_net/bareme
.parameters/accident_travail/rente/salaire_net/salaire_minimum
.parameters/accident_travail/rente/taux/bareme
.parameters/accident_travail/rente/taux/capital_representatif
.parameters/accident_travail/rente/taux/indemnite_accident_travail
.parameters/accident_travail/rente/taux/pcrtp
.parameters/accident_travail/rente/taux/taux_minimum
.Détails :
rente_accident_travail
.rente_accident_travail_salarie
rente_accident_travail_exploitant_agricole
indemnite_accident_travail
rente_accident_travail_base
demande_rachat
rente_accident_travail_apres_rachat
rente_accident_travail_rachat
pcrtp_nombre_actes_assistance
pcrtp
rente_accident_travail_salaire_utile