Skip to content

Commit

Permalink
Merge pull request #14 from openfisca/refactor-regimes
Browse files Browse the repository at this point in the history
Refactor regimes
  • Loading branch information
benjello authored Nov 16, 2024
2 parents 69ca113 + b20f374 commit 95f44c7
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 164 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

# 3.0.0 [#14](https://github.com/openfisca/openfisca-tunisia-pension/pull/14)

* Évolution du système socio-fiscal.
* Périodes concernées : toutes.
* Zones impactées : `variables/regimes`.
* Détails :
- Sépare les régimes dans différents répertoires

# 3.0.0 [#13](https://github.com/openfisca/openfisca-tunisia-pension/pull/13)

* Amélioration technique.
Expand Down
30 changes: 30 additions & 0 deletions openfisca_tunisia_pension/variables/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'''Helper functions'''


import bottleneck
from numpy import minimum as min_


def pension_generique(trimestres_valides, sal_ref, age, taux_annuite_base, taux_annuite_supplemetaire, duree_stage,
age_elig, periode_remplacement_base, plaf_taux_pension, smig):
taux_pension = (
(trimestres_valides < 4 * periode_remplacement_base) * (trimestres_valides / 4) * taux_annuite_base
+ (trimestres_valides >= 4 * periode_remplacement_base) * (
taux_annuite_base * periode_remplacement_base
+ (trimestres_valides / 4 - periode_remplacement_base) * taux_annuite_supplemetaire
)
)
montant = min_(taux_pension, plaf_taux_pension) * sal_ref
return montant


def mean_over_k_largest(vector, k):
'''Return the mean over the k largest values of a vector'''
if k == 0:
return 0

if k <= len(vector):
return vector.sum() / len(vector)

z = -bottleneck.partition(-vector, kth = k)
return z.sum() / k
163 changes: 0 additions & 163 deletions openfisca_tunisia_pension/variables/pension.py

This file was deleted.

65 changes: 65 additions & 0 deletions openfisca_tunisia_pension/variables/rsa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import functools
from numpy import (
apply_along_axis,
maximum as max_,
vstack,
)

from openfisca_core import periods
from openfisca_core.model_api import *
from openfisca_tunisia_pension.entities import Individu


class salaire_reference_rsa(Variable):
value_type = float
entity = Individu
label = 'Salaires de référence du régime des salariés agricoles'
definition_period = YEAR

def formula(individu, period):
# TODO: gérer le nombre d'année
# TODO: plafonner les salaires à 2 fois le smag de l'année d'encaissement
base_declaration_rsa = 180
base_liquidation_rsa = 300

n = 3
mean_over_largest = functools.partial(mean_over_k_largest, k = n)
salaire = apply_along_axis(
mean_over_largest,
axis = 0,
arr = vstack([
individu('salaire', period = periods.period('year', year))
for year in range(period.start.year, period.start.year - n, -1)
]),
)
salaire_refererence = salaire * base_liquidation_rsa / base_declaration_rsa
return salaire_refererence


class pension_rsa(Variable):
value_type = float
entity = Individu
label = 'Salaires de référence du régime des salariés agricoles'
definition_period = YEAR

def formula(individu, period, parameters):
rsa = parameters.retraite.rsa(period)
taux_annuite_base = rsa.taux_annuite_base
taux_annuite_supplemetaire = rsa.taux_annuite_supplemetaire
duree_stage = rsa.stage_requis
age_elig = rsa.age_legal
periode_remplacement_base = rsa.periode_remplacement_base
plaf_taux_pension = rsa.plaf_taux_pension
smag = parameters(period).marche_travail.smag * 25
duree_stage_validee = trimestres_valides > 4 * duree_stage
pension_min = rsa.pension_min
salaire_reference = individu('salaire_reference_rsa', period)

montant = pension_generique(trimestres_valides, sal_ref, age, taux_annuite_base, taux_annuite_supplemetaire,
duree_stage, age_elig, periode_remplacement_base, plaf_taux_pension, smag)

elig_age = age > age_elig
elig = duree_stage_validee * elig_age * (salaire_reference > 0)
montant_percu = max_(montant, pension_min * smag)
pension = elig * montant_percu
return pension
80 changes: 80 additions & 0 deletions openfisca_tunisia_pension/variables/rsna.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import functools
from numpy import (
apply_along_axis,
logical_not as not_,
maximum as max_,
vstack,
)

from openfisca_core.model_api import *
from openfisca_tunisia_pension.entities import Individu
from openfisca_tunisia_pension.variables.helpers import mean_over_k_largest, pension_generique


class salaire_reference_rsna(Variable):
value_type = float
entity = Individu
label = 'Salaires de référence du régime des salariés non agricoles'
definition_period = YEAR

def formula(individu, period):
# TODO: gérer le nombre d'année n
# TODO: plafonner les salaires à 6 fois le smig de l'année d'encaissement
n = 10
mean_over_largest = functools.partial(mean_over_k_largest, k = n)
salaire_refererence = apply_along_axis(
mean_over_largest,
axis = 0,
arr = vstack([
individu('salaire', period = year)
for year in range(period.start.year, period.start.year - n, -1)
]),
)
return salaire_refererence


class pension_rsna(Variable):
value_type = float
entity = Individu
label = 'Pension des affiliés au régime des salariés non agricoles'
definition_period = YEAR

def formula(individu, period, parameters):
trimestres_valides = individu('trimestres_valides', period = period)
salaire_reference = individu('salaire_reference_rsna', period = period)
age = individu('age', period = period)

rsna = parameters(period).retraite.rsna
taux_annuite_base = rsna.taux_annuite_base
taux_annuite_supplemetaire = rsna.taux_annuite_supplemetaire
duree_stage = rsna.stage_derog
age_eligible = rsna.age_dep_anticip
periode_remplacement_base = rsna.periode_remplacement_base
plaf_taux_pension = rsna.plaf_taux_pension
smig = parameters(period).marche_travail.smig_48h

pension_min_sup = rsna.pension_minimale.sup
pension_min_inf = rsna.pension_minimale.inf

stage = trimestres_valides > 4 * duree_stage
pension_minimale = (
stage * pension_min_sup + not_(stage) * pension_min_inf
)
montant = pension_generique(
trimestres_valides,
salaire_reference,
age,
taux_annuite_base,
taux_annuite_supplemetaire,
duree_stage,
age_eligible,
periode_remplacement_base,
plaf_taux_pension,
smig,
)
# eligibilite
eligibilite_age = age > age_eligible
eligibilite = stage * eligibilite_age * (salaire_reference > 0)
# plafonnement
montant_pension_percu = max_(montant, pension_minimale * smig)
return eligibilite * montant_pension_percu
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "OpenFisca-Tunisia-Pension"
version = "3.0.0"
version = "4.0.0"
description = "OpenFisca Rules as Code model for Tunisia pensions."
readme = "README.md"
keywords = ["microsimulation", "tax", "benefit", "pension", "rac", "rules-as-code", "tunisia"]
Expand Down

0 comments on commit 95f44c7

Please sign in to comment.