diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 182a42e..688f4aa 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,4 +1,5 @@ -Merci de contribuer à OpenFisca ! Effacez cette ligne ainsi que, pour chaque ligne ci-dessous, les cas ne correspondant pas à votre contribution :) + +Merci de contribuer à OpenFisca ! Effacez cette ligne ainsi que, pour chaque ligne ci-dessous, les cas ne correspondant pas à votre contribution : * Évolution du système socio-fiscal. | Amélioration technique. | Correction d'un crash. | Changement mineur. * Périodes concernées : toutes. | jusqu'au JJ/MM/AAAA. | à partir du JJ/MM/AAAA. diff --git a/.github/workflows/tax-benefit.yml b/.github/workflows/tax-benefit.yml new file mode 100644 index 0000000..6181748 --- /dev/null +++ b/.github/workflows/tax-benefit.yml @@ -0,0 +1,93 @@ +name: Validate, integrate & deploy to tax-benefit.org + +on: + - push + - workflow_dispatch + +jobs: + validate_yaml: + uses: tax-benefit/actions/.github/workflows/validate_yaml.yml@v2.1.0 + with: + parameters_path: "openfisca_tunisia_pension/parameters" + secrets: + token: ${{ secrets.CONTROL_CENTER_TOKEN }} + + # deploy_parameters: + # runs-on: ubuntu-latest + + # steps: + # - uses: actions/checkout@v4 + # - name: Clone Legislation Parameters Explorer + # run: git clone https://git.leximpact.dev/leximpact/legislation-parameters-explorer.git + # - name: Install Node.js version LTS + # uses: actions/setup-node@v4 + # with: + # node-version: 'lts/*' + # - name: Install viewer dependencies + # run: npm install + # working-directory: legislation-parameters-explorer/packages/viewer + # - name: Configure viewer + # run: | + # rm -f .env + # cat > .env << EOF + # # Customizations to apply to the site (theme, URLs…) + # CUSTOMIZATION="openfisca" + + # DBNOMICS_DATASET_CODE="openfisca_tunisia_pension" + # DBNOMICS_PROVIDER_CODE="OpenFisca" + # DBNOMICS_URL="https://db.nomics.world/" + + # EDITOR_URL="https://editor.parameters.tn.tax-benefit.org/" + + # EXPORT_CSV=true + # EXPORT_JSON=false + # EXPORT_XLSX=true + + # # Path of directory containing legislation parameters of country + # PARAMETERS_DIR="../../../openfisca_tunisia_pension/parameters/" + + # # Description of parameters remote repository + # PARAMETERS_AUTHOR_EMAIL="editor.parameters.tn@tax-benefit.org" + # PARAMETERS_AUTHOR_NAME="Éditeur des paramètres d'OpenFisca-Tunisia-Pension" + # PARAMETERS_BRANCH="main" + # PARAMETERS_FORGE_DOMAIN_NAME="github.com" + # PARAMETERS_FORGE_TYPE="GitHub" + # PARAMETERS_GROUP="openfisca" + # PARAMETERS_PROJECT="openfisca-tunisia-pension" + # PARAMETERS_PROJECT_DIR="openfisca_tunisia_pension/parameters" + + # SHOW_LAST_BREADCRUMB_ITEM = false + + # TABLE_OF_CONTENTS_DIR="../../../openfisca_tunisia_pension/tables/" + + # TITLE="OpenFisca-Tunisia-Pension - الجباية المفتوحة تونس" + + # # Path of file containing units used by French legislation parameters + # UNITS_FILE_PATH="../../../openfisca_tunisia_pension/units.yaml" + # EOF + # working-directory: legislation-parameters-explorer/packages/viewer + # - name: Initialize .svelte-kit directory of viewer + # run: npx svelte-kit sync + # working-directory: legislation-parameters-explorer/packages/viewer + # - name: Generate data of viewer + # run: npx tsx src/scripts/generate_data.ts + # working-directory: legislation-parameters-explorer/packages/viewer + # - name: Build viewer + # run: npm run build + # working-directory: legislation-parameters-explorer/packages/viewer + # - name: Configure ssh for deployment to server + # uses: tanmancan/action-setup-ssh-agent-key@1.0.0 + # with: + # ssh-auth-sock: /tmp/my_auth.sock + # ssh-private-key: ${{ secrets.PARAMETERS_EXPLORER_SSH_PRIVATE_KEY }} + # ssh-public-key: ${{ secrets.PARAMETERS_EXPLORER_SSH_KNOWN_HOSTS }} + # - name: Deploy to Server using rsync + # run: rsync -az --delete -e "ssh -J ssh-proxy@parameters.tn.tax-benefit.org:2222" build/ parameters.tn.tax-benefit.org@10.131.0.2:public_html/ + # working-directory: legislation-parameters-explorer/packages/viewer + + # deploy_simulator: + # uses: tax-benefit/actions/.github/workflows/deploy.yml@v2.1.0 + # with: + # python_package: "openfisca_tunisia_pension" + # secrets: + # token: ${{ secrets.CONTROL_CENTER_TOKEN }} diff --git a/.github/workflows/validate_yaml.yml b/.github/workflows/validate_yaml.yml new file mode 100644 index 0000000..c01770a --- /dev/null +++ b/.github/workflows/validate_yaml.yml @@ -0,0 +1,15 @@ +name: Validate YAML + +on: + push: + workflow_dispatch: + pull_request: + types: [opened, reopened] + +jobs: + validate_yaml: + uses: tax-benefit/actions/.github/workflows/validate_yaml.yml@v1 + with: + parameters_path: "openfisca_tunisia_pension/parameters" + secrets: + token: ${{ secrets.CONTROL_CENTER_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index e8aa793..940e78b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ # Changelog -# 3.0.0 [#14](https://github.com/openfisca/openfisca-tunisia-pension/pull/14) +# 5.0.0 [#15](https://github.com/openfisca/openfisca-tunisia-pension/pull/15) + +* Évolution du système socio-fiscal. +* Périodes concernées : toutes. +* Zones impactées : `variables/regimes/cnrps`. +* Détails : + - Introduit le régime de la CNRPS + + +# 4.0.0 [#14](https://github.com/openfisca/openfisca-tunisia-pension/pull/14) * Évolution du système socio-fiscal. * Périodes concernées : toutes. @@ -31,7 +40,7 @@ * Move parameters from xml format to yaml files tree ### 1.0.0 -* Renomme `nb_trim_val` en `trimestres_valides` +* Renomme `nb_trim_val` en `duree_assurance` * Utilisation de noms longs pour différent paramètres ## 0.9.2 diff --git a/README.md b/README.md index 0e7aeff..08d0fad 100644 --- a/README.md +++ b/README.md @@ -141,10 +141,10 @@ nosetests openfisca_tunisia_pension/tests/test_pension.py:test_rsna Le format d'un test yaml est décrit dans la [documentation officielle](https://doc.openfisca.fr/coding-the-legislation/writing_yaml_tests.html). -Ainsi, si vous souhaitez exécuter le test yaml `openfisca_tunisia_pension/tests/formulas/pension_rsna.yaml`, utilisez la commande : +Ainsi, si vous souhaitez exécuter le test yaml `openfisca_tunisia_pension/tests/formulas/rsna_pension.yaml`, utilisez la commande : ``` -openfisca-run-test -c openfisca_tunisia_pension openfisca_tunisia_pension/tests/formulas/pension_rsna.yaml +openfisca-run-test -c openfisca_tunisia_pension openfisca_tunisia_pension/tests/formulas/rsna_pension.yaml ``` ### Tout tester diff --git a/openfisca_tunisia_pension/__init__.py b/openfisca_tunisia_pension/__init__.py index 6b04e0a..93adb49 100644 --- a/openfisca_tunisia_pension/__init__.py +++ b/openfisca_tunisia_pension/__init__.py @@ -1,3 +1,38 @@ -from openfisca_tunisia_pension.tunisia_pension_taxbenefitsystem import TunisiaPensionTaxBenefitSystem +'''OpenFisca Tunisia Pension tax-benefit system.''' + + +import logging +import os + +from openfisca_core.taxbenefitsystems import TaxBenefitSystem + +from openfisca_tunisia_pension import entities +from openfisca_tunisia_pension.scripts_ast import script_ast + + +COUNTRY_DIR = os.path.dirname(os.path.abspath(__file__)) + +logging.getLogger('numba.core.ssa').disabled = True +logging.getLogger('numba.core.byteflow').disabled = True +logging.getLogger('numba.core.interpreter').disabled = True + +# Convert regimes classes to OpenFisca variables. +script_ast.main(verbose = False) + + +class TunisiaPensionTaxBenefitSystem(TaxBenefitSystem): + '''Tunisian pensions tax benefit system''' + CURRENCY = 'DT' + + def __init__(self): + super(TunisiaPensionTaxBenefitSystem, self).__init__(entities.entities) + + # We add to our tax and benefit system all the variables + self.add_variables_from_directory(os.path.join(COUNTRY_DIR, 'variables')) + + # We add to our tax and benefit system all the legislation parameters defined in the parameters files + parameters_path = os.path.join(COUNTRY_DIR, 'parameters') + self.load_parameters(parameters_path) + CountryTaxBenefitSystem = TunisiaPensionTaxBenefitSystem diff --git a/openfisca_tunisia_pension/parameters/marche_travail/indemnite_complementaire_provisoire.yaml b/openfisca_tunisia_pension/parameters/marche_travail/indemnite_complementaire_provisoire.yaml new file mode 100644 index 0000000..56a9d2e --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/indemnite_complementaire_provisoire.yaml @@ -0,0 +1,10 @@ +description: Indemnité Complémentaire Provisoire (ICP) - montant par mois +values: + 1981-04-07: + value: 10 +metadata: + unit: currency + reference: + 1981-04-07: + title: Décret n° 81-437 du 7 avril 1981 +documentation: Le smic est composé du salaire de base et de cette indemnité complémentaire provisoire et de sa majoration diff --git a/openfisca_tunisia_pension/parameters/marche_travail/index.yaml b/openfisca_tunisia_pension/parameters/marche_travail/index.yaml index febec99..9bbeab9 100644 --- a/openfisca_tunisia_pension/parameters/marche_travail/index.yaml +++ b/openfisca_tunisia_pension/parameters/marche_travail/index.yaml @@ -1 +1 @@ -description: Paramètres généraux +description: Salaires minimum diff --git a/openfisca_tunisia_pension/parameters/marche_travail/majoration_smig_40h_mensuel.yaml b/openfisca_tunisia_pension/parameters/marche_travail/majoration_smig_40h_mensuel.yaml new file mode 100644 index 0000000..b489a18 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/majoration_smig_40h_mensuel.yaml @@ -0,0 +1,9 @@ +description: Majoration du salaire minimum interprofessionnel garanti (Smig) au régime de 40h dans les secteurs non agricoles - montant par mois +values: + 1982-03-16: + value: 20 +metadata: + unit: currency + reference: + 1982-03-16: + title: Décret n° 82-501 du 16 mars 1982 diff --git a/openfisca_tunisia_pension/parameters/marche_travail/majoration_smig_48h_mensuel.yaml b/openfisca_tunisia_pension/parameters/marche_travail/majoration_smig_48h_mensuel.yaml new file mode 100644 index 0000000..8f447b7 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/majoration_smig_48h_mensuel.yaml @@ -0,0 +1,9 @@ +description: Majoration du Salaire minimum interprofessionnel garanti (Smig) au régime de 48h dans les secteurs non agricoles - montant par mois +values: + 1982-03-16: + value: 20.368 +metadata: + unit: currency + reference: + 1982-03-16: + title: Décret n° 82-501 du 16 mars 1982 diff --git a/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_40h_horaire.yaml b/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_40h_horaire.yaml new file mode 100644 index 0000000..9fde401 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_40h_horaire.yaml @@ -0,0 +1,29 @@ +description: salaire de base horaire - régime 40h par semaine +values: + 2008-07-01: + value: 1.084 + 2009-08-01: + value: 1.126 + 2010-07-01: + value: 1.183 + 2011-05-01: + value: 1.248 + 2012-07-01: + value: 1.324 + 2014-05-01: + value: 1.411 +metadata: + unit: currency + reference: + 2008-07-01: + title: Décret n°2008-2072 du 02 Juin 2008 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2008/2008F/046/TF200820723.pdf + 2009-08-01: + title: Décret n°2009-2257 du 14 Juillet 2009 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2009/2009F/062/TF200922573.pdf + 2010-07-01: + title: Décret n°2010-1746 du 17 Juillet 2010 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2010/2010F/058/TF201017463.pdf + 2011-05-01: + title: Décret n°2011-679 du 09 Juin 2011 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2011/2011F/042/TF20116793.pdf + 2012-07-01: + title: Décret n°2012-1981 du 20 Septembre 2012 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2012/2012F/077/TF201219813.pdf + 2014-05-01: + title: Décret n°2014-2907 du 11 Août 2014 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2014/2014F/066/Tf201429073.pdf diff --git a/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_40h_mensuel.yaml b/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_40h_mensuel.yaml new file mode 100644 index 0000000..5c9baf9 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_40h_mensuel.yaml @@ -0,0 +1,29 @@ +description: salaire de base mensuel - régime 40h par semaine +values: + 2008-07-01: + value: 187.88 + 2009-08-01: + value: 195.16 + 2010-07-01: + value: 205.04 + 2011-05-01: + value: 216.306 + 2012-07-01: + value: 229.479 + 2014-05-01: + value: 244.559 +metadata: + unit: currency + reference: + 2008-07-01: + title: Décret n°2008-2072 du 02 Juin 2008 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2008/2008F/046/TF200820723.pdf + 2009-08-01: + title: Décret n°2009-2257 du 14 Juillet 2009 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2009/2009F/062/TF200922573.pdf + 2010-07-01: + title: Décret n°2010-1746 du 17 Juillet 2010 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2010/2010F/058/TF201017463.pdf + 2011-05-01: + title: Décret n°2011-679 du 09 Juin 2011 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2011/2011F/042/TF20116793.pdf + 2012-07-01: + title: Décret n°2012-1981 du 20 Septembre 2012 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2012/2012F/077/TF201219813.pdf + 2014-05-01: + title: Décret n°2014-2907 du 11 Août 2014 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2014/2014F/066/Tf201429073.pdf diff --git a/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_48h_horaire.yaml b/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_48h_horaire.yaml new file mode 100644 index 0000000..48bd530 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_48h_horaire.yaml @@ -0,0 +1,29 @@ +description: salaire de base horaire - régime 48h par semaine +values: + 2008-07-01: + value: 1.065 + 2009-08-01: + value: 1.107 + 2010-07-01: + value: 1.164 + 2011-05-01: + value: 1.229 + 2012-07-01: + value: 1.305 + 2014-05-01: + value: 1.392 +metadata: + unit: currency + reference: + 2008-07-01: + title: Décret n°2008-2072 du 02 Juin 2008 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2008/2008F/046/TF200820723.pdf + 2009-08-01: + title: Décret n°2009-2257 du 14 Juillet 2009 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2009/2009F/062/TF200922573.pdf + 2010-07-01: + title: Décret n°2010-1746 du 17 Juillet 2010 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2010/2010F/058/TF201017463.pdf + 2011-05-01: + title: Décret n°2011-679 du 09 Juin 2011 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2011/2011F/042/TF20116793.pdf + 2012-07-01: + title: Décret n°2012-1981 du 20 Septembre 2012 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2012/2012F/077/TF201219813.pdf + 2014-05-01: + title: Décret n°2014-2907 du 11 Août 2014 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2014/2014F/066/Tf201429073.pdf diff --git a/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_48h_mensuel.yaml b/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_48h_mensuel.yaml new file mode 100644 index 0000000..cd281c3 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/salaire_de_base_48h_mensuel.yaml @@ -0,0 +1,29 @@ +description: salaire de base mensuel - régime 48h par semaine +values: + 2008-07-01: + value: 221.52 + 2009-08-01: + value: 230.256 + 2010-07-01: + value: 242.112 + 2011-05-01: + value: 255.632 + 2012-07-01: + value: 271.44 + 2014-05-01: + value: 289.536 +metadata: + unit: currency + reference: + 2008-07-01: + title: Décret n°2008-2072 du 02 Juin 2008 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2008/2008F/046/TF200820723.pdf + 2009-08-01: + title: Décret n°2009-2257 du 14 Juillet 2009 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2009/2009F/062/TF200922573.pdf + 2010-07-01: + title: Décret n°2010-1746 du 17 Juillet 2010 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2010/2010F/058/TF201017463.pdf + 2011-05-01: + title: Décret n°2011-679 du 09 Juin 2011 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2011/2011F/042/TF20116793.pdf + 2012-07-01: + title: Décret n°2012-1981 du 20 Septembre 2012 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2012/2012F/077/TF201219813.pdf + 2014-05-01: + title: Décret n°2014-2907 du 11 Août 2014 - http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2014/2014F/066/Tf201429073.pdf diff --git a/openfisca_tunisia_pension/parameters/marche_travail/smag.yaml b/openfisca_tunisia_pension/parameters/marche_travail/smag.yaml deleted file mode 100644 index 48738d9..0000000 --- a/openfisca_tunisia_pension/parameters/marche_travail/smag.yaml +++ /dev/null @@ -1,7 +0,0 @@ -description: SMAG journalier -unit: currency -values: - 2010-07-01: - value: 8.38 - 2011-07-01: - value: 9.0 diff --git a/openfisca_tunisia_pension/parameters/marche_travail/smag_journalier.yaml b/openfisca_tunisia_pension/parameters/marche_travail/smag_journalier.yaml new file mode 100644 index 0000000..50e3a63 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/smag_journalier.yaml @@ -0,0 +1,179 @@ +description: Salaire Minimum Agricole Garanti (SMAG) - montant par jour +values: + 1966-01-01: + value: 0.385 + 1968-05-01: + value: 0.5 + 1969-11-01: + value: 0.55 + 1971-05-01: + value: 0.6 + 1974-06-01: + value: 0.8 + 1975-06-01: + value: 0.9 + 1977-05-01: + value: 1.2 + 1978-05-01: + value: 1.332 + 1979-05-01: + value: 1.44 + 1980-02-01: + value: 1.483 + 1980-05-01: + value: 1.631 + 1981-04-01: + value: 2 + 1982-02-01: + value: 2.4 + 1983-01-01: + value: 2.64 + 1986-07-01: + value: 2.9 + 1987-11-01: + value: 3.05 + 1988-04-01: + value: 3.2 + 1989-08-01: + value: 3.315 + 1990-01-01: + value: 3.661 + 1991-08-01: + value: 3.761 + 1992-05-01: + value: 3.961 + 1992-08-01: + value: 4.061 + 1993-05-01: + value: 4.261 + 1993-08-01: + value: 4.361 + 1994-08-01: + value: 4.461 + 1995-05-01: + value: 4.661 + 1996-05-01: + value: 4.861 + 1996-09-09: + value: 4.961 + 1997-07-20: + value: 5.061 + 1997-11-07: + value: 5.209 + 1998-08-20: + value: 5.309 + 1999-05-01: + value: 5.509 + 1999-08-19: + value: 5.609 + 2000-05-01: + value: 5.809 + 2001-07-01: + value: 6.059 + 2002-07-01: + value: 6.259 + 2003-07-01: + value: 6.509 + 2004-07-01: + value: 6.709 + 2005-09-01: + value: 6.909 + 2006-07-01: + value: 7.129 + 2007-07-01: + value: 7.379 + 2008-07-01: + value: 7.749 + 2009-08-01: + value: 8.019 + 2010-07-01: + value: 8.38 + 2011-05-01: + value: 9 + 2012-07-01: + value: 10.608 + 2012-12-01: + value: 11.608 + 2014-08-11: + value: 12.304 + 2015-11-09: + value: 13 + 2017-06-05: + value: 13.736 + 2018-05-01: + value: 14.56 + 2019-05-01: + value: 15.504 +metadata: + unit: currency + reference: + 1990-01-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1991-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1992-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1992-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1993-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1993-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1994-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1995-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1996-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1996-09-09: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1997-07-20: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1997-11-07: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1998-08-20: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1999-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 1999-08-19: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2000-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2001-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2002-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2003-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2004-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2005-09-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2006-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2007-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2008-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2009-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2010-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmagFR.pdf + 2014-08-11: + title: Décret n°2014-2908 du 11 Août 2014 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2014/2014F/066/Tf201429083.pdf + 2015-11-09: + title: Décret n°2015-1763 du 09 Novembre 2015 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2015/2015F/091/Tf2015017623.pdf + 2017-06-05: + title: Décret n°2017-669 du 05 Juin 2017 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2017/2017F/045/Tf20176693.pdf + 2018-05-01: + title: Décret gouvernemental n°2018-673 du 07 août 2018 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2018/2018F/064/Tf20186723.pdf + 2019-05-01: + title: Décret gouvernemental n° 2019-455 du 28 mai 2019 + href: http://www.legislation.tn/fr/detailtexte/Décret%20Gouvernemental-num-2019-455-du----jort-2019-043__20190430045532?shorten=m5lK +documentation: |- + Salaire minimum agricole garanti par journée de travail effectif pour les travailleurs des deux sexes âgés de 18 ans au moins + الأجر الأدنى الفلاحي المضمون للعمال من الجنسين البالغين من العمر 18 سنة على الأقل عن كل يوم عمل فعلي diff --git a/openfisca_tunisia_pension/parameters/marche_travail/smig_40h.yaml b/openfisca_tunisia_pension/parameters/marche_travail/smig_40h.yaml deleted file mode 100644 index 749b185..0000000 --- a/openfisca_tunisia_pension/parameters/marche_travail/smig_40h.yaml +++ /dev/null @@ -1,43 +0,0 @@ -description: SMIG 40h -unit: currency -values: - 1995-05-01: - value: 105.024 - 1996-05-01: - value: 110.051 - 1996-09-09: - value: 112.132 - 1997-07-20: - value: 114.211 - 1997-11-08: - value: 119.237 - 1998-08-20: - value: 121.664 - 1999-05-01: - value: 126.691 - 1999-08-19: - value: 128.771 - 2000-05-11: - value: 133.795 - 2001-08-01: - value: 140.905 - 2002-07-01: - value: 146.799 - 2003-07-01: - value: 153.906 - 2004-07-01: - value: 159.8 - 2005-09-01: - value: 164.827 - 2006-07-01: - value: 170.721 - 2007-07-01: - value: 177.828 - 2008-07-01: - value: 187.88 - 2009-08-01: - value: 195.16 - 2010-07-01: - value: 205.04 - 2011-05-01: - value: 216.306 diff --git a/openfisca_tunisia_pension/parameters/marche_travail/smig_40h_horaire.yaml b/openfisca_tunisia_pension/parameters/marche_travail/smig_40h_horaire.yaml new file mode 100644 index 0000000..44708ed --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/smig_40h_horaire.yaml @@ -0,0 +1,150 @@ +description: Salaire minimum interprofessionnel garanti (Smig) horaire - régime 40h par semaine +values: + 1990-01-01: + value: 0.621 + 1991-08-01: + value: 0.633 + 1992-05-01: + value: 0.671 + 1992-08-01: + value: 0.683 + 1993-05-01: + value: 0.721 + 1993-08-01: + value: 0.733 + 1994-08-01: + value: 0.745 + 1995-05-01: + value: 0.779 + 1996-05-01: + value: 0.808 + 1996-09-09: + value: 0.82 + 1997-07-20: + value: 0.832 + 1997-11-07: + value: 0.861 + 1998-08-20: + value: 0.875 + 1999-05-01: + value: 0.904 + 1999-08-19: + value: 0.916 + 2000-05-01: + value: 0.945 + 2001-07-01: + value: 0.986 + 2002-07-01: + value: 1.02 + 2003-07-01: + value: 1.061 + 2004-07-01: + value: 1.095 + 2005-09-01: + value: 1.124 + 2006-07-01: + value: 1.158 + 2007-07-01: + value: 1.199 + 2008-07-01: + value: 1.257 + 2009-08-01: + value: 1.299 + 2010-07-01: + value: 1.356 + 2011-05-01: + value: 1.421 + 2012-07-01: + value: 1.497 + 2014-05-01: + value: 1.584 + 2015-05-01: + value: 1.671 + 2016-08-01: + value: 1.763 + 2018-05-01: + value: 1.866 + 2019-05-01: + value: 1.984 +metadata: + unit: currency + reference: + 1990-01-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1991-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1992-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1992-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1993-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1993-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1994-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1995-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1996-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1996-09-09: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1997-07-20: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1997-11-07: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1998-08-20: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1999-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1999-08-19: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2000-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2001-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2002-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2003-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2004-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2005-09-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2006-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2007-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2008-07-01: + title: Décret n°2008-2072 du 02 Juin 2008 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2008/2008F/046/TF200820723.pdf + 2009-08-01: + title: Décret n°2009-2257 du 14 Juillet 2009 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2009/2009F/062/TF200922573.pdf + 2010-07-01: + title: Décret n°2010-1746 du 17 Juillet 2010 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2010/2010F/058/TF201017463.pdf + 2011-05-01: + title: Décret n°2011-679 du 09 Juin 2011 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2011/2011F/042/TF20116793.pdf + 2012-07-01: + title: Décret n°2012-1981 du 20 Septembre 2012 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2012/2012F/077/TF201219813.pdf + 2014-05-01: + title: Décret n°2014-2907 du 11 Août 2014 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2014/2014F/066/Tf201429073.pdf + 2015-05-01: + title: Décret n°2015-1762 du 09 Novembre 2015 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2015/2015F/091/Tf2015017623.pdf + 2016-08-01: + title: Décret n°2017-668 du 05 Juin 2017 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2017/2017F/045/Tf20176683.pdf + 2018-05-01: + title: Décret gouvernemental n° 2018-672 du 07 août 2018 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2018/2018F/064/Tf20186723.pdf + 2019-05-01: + title: Décret gouvernemental n°2019-454 du 28 mai 2019 + href: http://www.legislation.tn/fr/detailtexte/Décret%20Gouvernemental-num-2019-454-du----jort-2019-043__20190430045432?shorten=m5lq +documentation: |- + Salaire minimum interprofessionnel garanti (Smig) dans les secteurs non agricoles pour les travailleurs des deux sexes âgés de 18 ans au moins + الأجر الأدنى المضمون لمختلف المهن في القطاعات غير الفلاحية للعمال من الجنسين البالغين من العمر 18 سنة على الأقل diff --git a/openfisca_tunisia_pension/parameters/marche_travail/smig_40h_mensuel.yaml b/openfisca_tunisia_pension/parameters/marche_travail/smig_40h_mensuel.yaml new file mode 100644 index 0000000..2414580 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/smig_40h_mensuel.yaml @@ -0,0 +1,165 @@ +description: Salaire minimum interprofessionnel garanti (Smig) mensuel - régime 40h par semaine +values: + 1975-06-01: + value: 25.133 + 1980-05-01: + value: 45.586 + 1982-02-01: + value: 45.586 + 1990-01-01: + value: 107.706 + 1991-08-01: + value: 109.706 + 1992-05-01: + value: 116.318 + 1992-08-01: + value: 118.398 + 1993-05-01: + value: 124.971 + 1993-08-01: + value: 127.051 + 1994-08-01: + value: 129.131 + 1995-05-01: + value: 135.024 + 1996-05-01: + value: 140.051 + 1996-09-09: + value: 142.131 + 1997-07-20: + value: 144.211 + 1997-11-07: + value: 149.237 + 1998-08-20: + value: 151.664 + 1999-05-01: + value: 156.691 + 1999-08-19: + value: 158.771 + 2000-05-01: + value: 163.798 + 2001-07-01: + value: 170.905 + 2002-07-01: + value: 176.799 + 2003-07-01: + value: 183.906 + 2004-07-01: + value: 189.8 + 2005-09-01: + value: 194.827 + 2006-07-01: + value: 200.721 + 2007-07-01: + value: 207.828 + 2008-07-01: + value: 217.88 + 2009-08-01: + value: 225.16 + 2010-07-01: + value: 235.04 + 2011-05-01: + value: 246.306 + 2012-07-01: + value: 259.479 + 2014-05-01: + value: 274.559 + 2015-05-01: + value: 289.639 + 2016-08-01: + value: 305.586 + 2018-05-01: + value: 323.439 + 2019-05-01: + value: 343.892 +metadata: + unit: currency + reference: + 1975-06-01: + title: Décret n°75-357 du 03 Juin 1975 + href: http://www.legislation.tn/sites/default/files/journal-officiel/1975/1975F/Jo03875.pdf + 1980-05-01: + title: Décret n°80-609 du 19 Mai 1980 + href: http://www.legislation.tn/sites/default/files/journal-officiel/1980/1980F/Jo03180.pdf + 1982-02-01: + title: Décret n°80-609 du 19 Mai 1980 + Décret n°82-501 du 16 Mars 1982 + href: http://www.legislation.tn/sites/default/files/journal-officiel/1982/1982F/Jo01982.pdf + 1990-01-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1991-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1992-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1992-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1993-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1993-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1994-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1995-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1996-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1996-09-09: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1997-07-20: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1997-11-07: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1998-08-20: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1999-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 1999-08-19: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2000-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2001-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2002-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2003-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2004-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2005-09-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2006-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2007-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig40FR.pdf + 2008-07-01: + title: Décret n°2008-2072 du 02 Juin 2008 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2008/2008F/046/TF200820723.pdf + 2009-08-01: + title: Décret n°2009-2257 du 14 Juillet 2009 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2009/2009F/062/TF200922573.pdf + 2010-07-01: + title: Décret n°2010-1746 du 17 Juillet 2010 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2010/2010F/058/TF201017463.pdf + 2011-05-01: + title: Décret n°2011-679 du 09 Juin 2011 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2011/2011F/042/TF20116793.pdf + 2012-07-01: + title: Décret n°2012-1981 du 20 Septembre 2012 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2012/2012F/077/TF201219813.pdf + 2014-05-01: + title: Décret n°2014-2907 du 11 Août 2014 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2014/2014F/066/Tf201429073.pdf + 2015-05-01: + title: Décret n°2015-1762 du 09 Novembre 2015 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2015/2015F/091/Tf2015017623.pdf + 2016-08-01: + title: Décret n°2017-668 du 05 Juin 2017 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2017/2017F/045/Tf20176683.pdf + 2018-05-01: + title: Décret gouvernemental n°2018-672 du 07 août 2018 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2018/2018F/064/Tf20186723.pdf + 2019-05-01: + title: Décret gouvernemental n°2019-454 du 28 mai 2019 + href: http://www.legislation.tn/fr/detailtexte/Décret%20Gouvernemental-num-2019-454-du----jort-2019-043__20190430045432?shorten=m5lq +documentation: |- + Salaire minimum interprofessionnel garanti dans les secteurs non agricoles pour les travailleurs des deux sexes âgés de 18 ans au moins + الأجر الأدنى المضمون لمختلف المهن في القطاعات غير الفلاحية للعمال من الجنسين البالغين من العمر 18 سنة على الأقل diff --git a/openfisca_tunisia_pension/parameters/marche_travail/smig_48h.yaml b/openfisca_tunisia_pension/parameters/marche_travail/smig_48h.yaml deleted file mode 100644 index 7ef4fba..0000000 --- a/openfisca_tunisia_pension/parameters/marche_travail/smig_48h.yaml +++ /dev/null @@ -1,43 +0,0 @@ -description: SMIG 48h -unit: currency -values: - 1995-05-01: - value: 123.76 - 1996-05-01: - value: 129.792 - 1996-09-09: - value: 131.872 - 1997-07-20: - value: 133.952 - 1997-11-08: - value: 139.984 - 1998-08-20: - value: 142.48 - 1999-05-01: - value: 148.512 - 1999-08-19: - value: 150.592 - 2000-05-11: - value: 156.624 - 2001-08-01: - value: 165.152 - 2002-07-01: - value: 172.224 - 2003-07-01: - value: 180.752 - 2004-07-01: - value: 187.824 - 2005-09-01: - value: 193.856 - 2006-07-01: - value: 200.928 - 2007-07-01: - value: 209.456 - 2008-07-01: - value: 221.52 - 2009-08-01: - value: 230.256 - 2010-07-01: - value: 242.111 - 2011-05-01: - value: 255.632 diff --git a/openfisca_tunisia_pension/parameters/marche_travail/smig_48h_horaire.yaml b/openfisca_tunisia_pension/parameters/marche_travail/smig_48h_horaire.yaml new file mode 100644 index 0000000..ce24891 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/smig_48h_horaire.yaml @@ -0,0 +1,186 @@ +description: Salaire minimum interprofessionnel garanti (Smig) horaire - régime 48h par semaine +values: + 1961-04-01: + value: 0.076 + 1966-01-01: + value: 0.084 + 1968-05-01: + value: 0.084 + 1971-05-01: + value: 0.104 + 1974-01-01: + value: 0.13 + 1975-06-01: + value: 0.145 + 1977-02-01: + value: 0.193 + 1978-05-01: + value: 0.21425 + 1979-05-01: + value: 0.232 + 1980-02-01: + value: 0.23896 + 1980-05-01: + value: 0.263 + 1981-04-01: + value: 0.311 + 1982-02-01: + value: 0.409 + 1983-01-01: + value: 0.457 + 1986-07-01: + value: 0.481 + 1987-11-01: + value: 0.505 + 1988-04-01: + value: 0.529 + 1989-08-01: + value: 0.543 + 1990-01-01: + value: 0.591 + 1991-08-01: + value: 0.601 + 1992-05-01: + value: 0.639 + 1992-08-01: + value: 0.649 + 1993-05-01: + value: 0.687 + 1993-08-01: + value: 0.697 + 1994-08-01: + value: 0.707 + 1995-05-01: + value: 0.741 + 1996-05-01: + value: 0.77 + 1996-09-09: + value: 0.78 + 1997-07-20: + value: 0.79 + 1997-11-07: + value: 0.819 + 1998-08-20: + value: 0.831 + 1999-05-01: + value: 0.86 + 1999-08-19: + value: 0.87 + 2000-05-01: + value: 0.899 + 2001-07-01: + value: 0.94 + 2002-07-01: + value: 0.974 + 2003-07-01: + value: 1.015 + 2004-07-01: + value: 1.049 + 2005-09-01: + value: 1.078 + 2006-07-01: + value: 1.112 + 2007-07-01: + value: 1.153 + 2008-07-01: + value: 1.211 + 2009-08-01: + value: 1.253 + 2010-07-01: + value: 1.31 + 2011-05-01: + value: 1.375 + 2012-07-01: + value: 1.451 + 2014-05-01: + value: 1.538 + 2015-05-01: + value: 1.625 + 2016-08-01: + value: 1.717 + 2018-05-01: + value: 1.82 + 2019-05-01: + value: 1.938 +metadata: + unit: currency + reference: + 1990-01-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1991-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1992-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1992-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1993-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1993-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1994-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1995-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1996-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1996-09-09: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1997-07-20: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1997-11-07: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1998-08-20: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1999-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1999-08-19: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2000-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2001-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2002-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2003-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2004-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2005-09-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2006-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2007-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2008-07-01: + title: Décret n°2008-2072 du 02 Juin 2008 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2008/2008F/046/TF200820723.pdf + 2009-08-01: + title: Décret n°2009-2257 du 14 Juillet 2009 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2009/2009F/062/TF200922573.pdf + 2010-07-01: + title: Décret n°2010-1746 du 17 Juillet 2010 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2010/2010F/058/TF201017463.pdf + 2011-05-01: + title: Décret n°2011-679 du 09 Juin 2011 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2011/2011F/042/TF20116793.pdf + 2012-07-01: + title: Décret n°2012-1981 du 20 Septembre 2012 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2012/2012F/077/TF201219813.pdf + 2014-05-01: + title: Décret n°2014-2907 du 11 Août 2014 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2014/2014F/066/Tf201429073.pdf + 2015-05-01: + title: Décret n°2015-1762 du 09 Novembre 2015 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2015/2015F/091/Tf2015017623.pdf + 2016-08-01: + title: Décret n°2017-668 du 05 Juin 2017 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2017/2017F/045/Tf20176683.pdf + 2018-05-01: + title: Décret gouvernemental n°2018-672 du 07 août 2018 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2018/2018F/064/Tf20186723.pdf + 2019-05-01: + title: Décret gouvernemental n°2019-454 du 28 mai 2019 + href: http://www.legislation.tn/fr/detailtexte/Décret%20Gouvernemental-num-2019-454-du----jort-2019-043__20190430045432?shorten=m5lq +documentation: |- + Salaire minimum interprofessionnel garanti (Smig) dans les secteurs non agricoles pour les travailleurs des deux sexes âgés de 18 ans au moins + الأجر الأدنى المضمون لمختلف المهن في القطاعات غير الفلاحية للعمال من الجنسين البالغين من العمر 18 سنة على الأقل diff --git a/openfisca_tunisia_pension/parameters/marche_travail/smig_48h_mensuel.yaml b/openfisca_tunisia_pension/parameters/marche_travail/smig_48h_mensuel.yaml new file mode 100644 index 0000000..8e2eb28 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/marche_travail/smig_48h_mensuel.yaml @@ -0,0 +1,165 @@ +description: Salaire minimum interprofessionnel garanti (Smig) mensuel - régime 48h par semaine +values: + 1975-06-01: + value: 30.16 + 1980-05-01: + value: 54.704 + 1982-02-01: + value: 54.704 + 1990-01-01: + value: 123.016 + 1991-08-01: + value: 125.016 + 1992-05-01: + value: 132.912 + 1992-08-01: + value: 134.992 + 1993-05-01: + value: 142.896 + 1993-08-01: + value: 144.976 + 1994-08-01: + value: 147.056 + 1995-05-01: + value: 154.128 + 1996-05-01: + value: 160.16 + 1996-09-09: + value: 162.24 + 1997-07-20: + value: 164.32 + 1997-11-07: + value: 170.352 + 1998-08-20: + value: 172.848 + 1999-05-01: + value: 178.88 + 1999-08-19: + value: 180.96 + 2000-05-01: + value: 186.992 + 2001-07-01: + value: 195.52 + 2002-07-01: + value: 202.592 + 2003-07-01: + value: 211.12 + 2004-07-01: + value: 218.192 + 2005-09-01: + value: 224.224 + 2006-07-01: + value: 231.296 + 2007-07-01: + value: 239.824 + 2008-07-01: + value: 251.888 + 2009-08-01: + value: 260.624 + 2010-07-01: + value: 272.48 + 2011-05-01: + value: 286 + 2012-07-01: + value: 301.808 + 2014-05-01: + value: 319.904 + 2015-05-01: + value: 338 + 2016-08-01: + value: 357.136 + 2018-05-01: + value: 378.56 + 2019-05-01: + value: 403.104 +metadata: + unit: currency + reference: + 1975-06-01: + title: Décret n°75-357 du 03 Juin 1975 + href: http://www.legislation.tn/sites/default/files/journal-officiel/1975/1975F/Jo03875.pdf + 1980-05-01: + title: Décret n°80-609 du 19 Mai 1980 + href: http://www.legislation.tn/sites/default/files/journal-officiel/1980/1980F/Jo03180.pdf + 1982-02-01: + title: Décret n°80-609 du 19 Mai 1980 + Décret n°82-501 du 16 Mars 1982 + href: http://www.legislation.tn/sites/default/files/journal-officiel/1982/1982F/Jo01982.pdf + 1990-01-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1991-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1992-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1992-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1993-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1993-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1994-08-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1995-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1996-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1996-09-09: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1997-07-20: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1997-11-07: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1998-08-20: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1999-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 1999-08-19: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2000-05-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2001-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2002-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2003-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2004-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2005-09-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2006-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2007-07-01: + href: http://www.social.tn/fileadmin/user1/doc/pdftravail/evosmig48FR.pdf + 2008-07-01: + title: Décret n°2008-2072 du 02 Juin 2008 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2008/2008F/046/TF200820723.pdf + 2009-08-01: + title: Décret n°2009-2257 du 14 Juillet 2009 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2009/2009F/062/TF200922573.pdf + 2010-07-01: + title: Décret n°2010-1746 du 17 Juillet 2010 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2010/2010F/058/TF201017463.pdf + 2011-05-01: + title: Décret n°2011-679 du 09 Juin 2011 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2011/2011F/042/TF20116793.pdf + 2012-07-01: + title: Décret n°2012-1981 du 20 Septembre 2012 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2012/2012F/077/TF201219813.pdf + 2014-05-01: + title: Décret n°2014-2907 du 11 Août 2014 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2014/2014F/066/Tf201429073.pdf + 2015-05-01: + title: Décret n°2015-1762 du 09 Novembre 2015 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2015/2015F/091/Tf2015017623.pdf + 2016-08-01: + title: Décret n°2017-668 du 05 Juin 2017 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2017/2017F/045/Tf20176683.pdf + 2018-05-01: + title: Décret gouvernemental n°2018-672 du 07 août 2018 + href: http://www.legislation.tn/sites/default/files/fraction-journal-officiel/2018/2018F/064/Tf20186723.pdf + 2019-05-01: + title: Décret gouvernemental n°2019-454 du 28 mai 2019 + href: http://www.legislation.tn/fr/detailtexte/Décret%20Gouvernemental-num-2019-454-du----jort-2019-043__20190430045432?shorten=m5lq +documentation: |- + Salaire minimum interprofessionnel garanti (Smig) dans les secteurs non agricoles pour les travailleurs des deux sexes âgés de 18 ans au moins + الأجر الأدنى المضمون لمختلف المهن في القطاعات غير الفلاحية للعمال من الجنسين البالغين من العمر 18 سنة على الأقل diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/cadre_commun.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/cadre_commun.yaml new file mode 100644 index 0000000..528d57e --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/cadre_commun.yaml @@ -0,0 +1,6 @@ +description: Age légal de de départ à la retraite pour le cadre commun de la CNRPS +values: + 1959-02-01: + value: 60 +metadata: + unit: year diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/cadres_actifs.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/cadres_actifs.yaml new file mode 100644 index 0000000..4ff4600 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/cadres_actifs.yaml @@ -0,0 +1,14 @@ +description: Age légal de de départ à la retraite pour certains cadres actifs et ouvriers +values: + 1959-02-01: + value: 55 +metadata: + unit: year +documentation: |- + Il s'agit + - des ouvriers exerçant dans le cadre commun des taches pénibles et insalubres soumis aux conditions prévues par le décret décret n° 1177 du 24 septembre 1985 + - les cadres actifs des forces de sécurité intérieure et de la garde nationale + - les cadres actifs exerçant dans : + - les sociétés de transport + - la Société nationale des chemins de fer tunisiens (SNCFT) + - la Société tunisienne de l’électricité et du gaz (STEG) diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/enseignants_du_superieur.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/enseignants_du_superieur.yaml new file mode 100644 index 0000000..1524ab0 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/enseignants_du_superieur.yaml @@ -0,0 +1,13 @@ +description: Age de départ à la retraite pour certains enseignants du supérieur +values: + 2019-04-01: + value: 65 +metadata: + unit: year +documentation: |- + Loi n° 2009-20 du 13 avril 2009, portant dispositions exceptionnelles relatives à la retraite des professeurs de l’enseignement supérieur + Les enseignants concernés sont: + - les professeurs de l’enseignement supérieur et les maîtres de conférences de l’enseignement supérieur rattachés aux établissements universitaires et aux établissements de recherche scientifique civils et militaires + - les professeurs hospitalo-universitaires et les maîtres de conférences agrégés hospitalo-universitaires + + Néanmoins, ils peuvent être maintenus en activité par décret jusqu’à l’âge de soixante-dix (70) ans au maximum. diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/index.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/index.yaml new file mode 100644 index 0000000..f852b9b --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/civil/index.yaml @@ -0,0 +1,7 @@ +description: Âge de départ à la retraite dans le service public civil +metadata: + short_label: Âge de départ des civils + order: + - cadre_commun + - cadre_actifs + - ensegnants_du_superieur diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/index.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/index.yaml new file mode 100644 index 0000000..879694e --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/age_legal/index.yaml @@ -0,0 +1,6 @@ +description: Âge de départ à la retraite +metadata: + short_label: Âge de départ + order: + - civil + - militaire diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/bareme_annuite.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/bareme_annuite.yaml new file mode 100644 index 0000000..363c3b3 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/bareme_annuite.yaml @@ -0,0 +1,33 @@ +description: Taux d'annuité par trimestre validé +brackets: +- threshold: + 1959-02-01: + value: 0 + rate: + 1959-02-01: + value: 0.005 +- threshold: + 1959-02-01: + value: 160 + 1985-01-01: + value: 40 + rate: + 1959-02-01: + value: 0 + 1985-01-01: + value: 0.0075 +- threshold: + 1985-01-01: + value: 80 + rate: + 1985-01-01: + value: 0.005 +- threshold: + 1985-01-01: + value: 160 + rate: + 1985-01-01: + value: 0 +metadata: + threshold_unit: trimestre + rate_unit: /1 diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/duree_de_service_minimale.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/duree_de_service_minimale.yaml new file mode 100644 index 0000000..87b2ce1 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/duree_de_service_minimale.yaml @@ -0,0 +1,6 @@ +description: Durée de service minimale requise pour prétendre à une pension de retraite +values: + 1974-01-01: + value: 15 +metadata: + unit: year diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/allocation_vieillesse.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/allocation_vieillesse.yaml new file mode 100644 index 0000000..cfce86e --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/allocation_vieillesse.yaml @@ -0,0 +1,9 @@ +description: Allocation de vieillesse (en parts du Smig) +values: + 1959-02-01: + value: 0.5 +metadata: + unit: Smig +documentation: + L'allocation de vieillesse est octroyée aux cotisants ne pouvant bénéficier d'une pension de retraite mais + qui justifient d'une période d'activité d'au moins 5 ans diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/duree_service_allocation_vieillesse.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/duree_service_allocation_vieillesse.yaml new file mode 100644 index 0000000..68d57e0 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/duree_service_allocation_vieillesse.yaml @@ -0,0 +1,6 @@ +description: Durée de service minimale requise pour prétendre à une allocation de vieillesse +values: + 1974-01-01: + value: 5 +metadata: + unit: year diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/index.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/index.yaml new file mode 100644 index 0000000..e978e81 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/index.yaml @@ -0,0 +1 @@ +description: Pension minimale (en part de Smig) diff --git a/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/minimum_garanti.yaml b/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/minimum_garanti.yaml new file mode 100644 index 0000000..1cf779a --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/cnrps/pension_minimale/minimum_garanti.yaml @@ -0,0 +1,8 @@ +description: Pension minimale garanti de la CNRPS +values: + 1974-01-01: + value: 0.66666 +metadata: + unit: Smig +documentation: + Pension minimale servie aux cotisants justifiant d'une durée suffisante pour prétendre à une pension de retraite diff --git a/openfisca_tunisia_pension/parameters/retraite/rsa/taux_annuite_supplemetaire.yaml b/openfisca_tunisia_pension/parameters/retraite/rsa/taux_annuite_supplementaire.yaml similarity index 100% rename from openfisca_tunisia_pension/parameters/retraite/rsa/taux_annuite_supplemetaire.yaml rename to openfisca_tunisia_pension/parameters/retraite/rsa/taux_annuite_supplementaire.yaml diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/age_dep_anticip.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/age_dep_anticip.yaml index 051cbd9..6d35e32 100644 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/age_dep_anticip.yaml +++ b/openfisca_tunisia_pension/parameters/retraite/rsna/age_dep_anticip.yaml @@ -1,4 +1,6 @@ description: Age minimum de départ à la retraite anticipée values: 1974-01-01: - value: 50.0 + value: 50 +metadata: + unit: year diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/age_legal.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/age_legal.yaml index 71c8a6e..efce31f 100644 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/age_legal.yaml +++ b/openfisca_tunisia_pension/parameters/retraite/rsna/age_legal.yaml @@ -1,4 +1,6 @@ description: Age légal de de départ à la retraite values: 1974-01-01: - value: 60.0 + value: 60 +metadata: + unit: year diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/bareme_annuite.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/bareme_annuite.yaml new file mode 100644 index 0000000..ff5af33 --- /dev/null +++ b/openfisca_tunisia_pension/parameters/retraite/rsna/bareme_annuite.yaml @@ -0,0 +1,26 @@ +description: Taux d'annuité par trimestre validé du régime des salariés non agricoles (RSNA) de la CNSS +brackets: +- threshold: + 1960-01-01: + value: 0 + rate: + 1960-01-01: + value: 0.01 +- threshold: + 1960-01-01: + value: 40 + rate: + 1960-01-01: + value: 0.005 +- threshold: + 1960-01-01: + value: 120 + rate: + 1960-01-01: + value: 0 +metadata: + threshold_unit: trimestre + rate_unit: /1 + reference: + 1960-01-01: + title: Loi n°60-33 du 14 Décembre 1960 instituant un régime d'invalidité de vieillesse et de survie et un régime d'allocation de vieillesse et de survie dans le secteur non agricole. diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/index.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/index.yaml index 25c6e14..697be71 100644 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/index.yaml +++ b/openfisca_tunisia_pension/parameters/retraite/rsna/index.yaml @@ -1 +1,10 @@ -description: Régime des salariés non agricoles +description: Régime des salariés non agricoles (RSNA) +metadata: + short_label: RSNA + order: + - age_legal + - age_dep_anticipe + - stage_requis + - stage_derog + - bareme_annuite + - pension_minimale diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/index.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/index.yaml index ad1832d..e978e81 100644 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/index.yaml +++ b/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/index.yaml @@ -1 +1 @@ -description: Pension minimale (en part de SMIG) +description: Pension minimale (en part de Smig) diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/inf.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/inf.yaml index 5f9da9c..5df32b9 100644 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/inf.yaml +++ b/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/inf.yaml @@ -3,3 +3,5 @@ unit: /1 values: 1974-01-01: value: 0.5 +metadata: + unit: smig diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/sup.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/sup.yaml index 285ec01..e258635 100644 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/sup.yaml +++ b/openfisca_tunisia_pension/parameters/retraite/rsna/pension_minimale/sup.yaml @@ -3,3 +3,5 @@ unit: /1 values: 1974-01-01: value: 0.66666 +metadata: + unit: smig diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/periode_remplacement_base.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/periode_remplacement_base.yaml deleted file mode 100644 index b7ef915..0000000 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/periode_remplacement_base.yaml +++ /dev/null @@ -1,4 +0,0 @@ -description: Période de remplacement de base -values: - 1974-01-01: - value: 10.0 diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/plaf_taux_pension.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/plaf_taux_pension.yaml deleted file mode 100644 index 4e7ab90..0000000 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/plaf_taux_pension.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: Plafonnement du taux de pension -unit: /1 -values: - 1974-01-01: - value: 0.8 diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/stage_derog.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/stage_derog.yaml index e72d94e..9e8b242 100644 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/stage_derog.yaml +++ b/openfisca_tunisia_pension/parameters/retraite/rsna/stage_derog.yaml @@ -1,4 +1,6 @@ description: Durée du stage dérogatoire values: 1974-01-01: - value: 5.0 + value: 5 +metadata: + unit: year diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/stage_requis.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/stage_requis.yaml index 9effa62..e80d608 100644 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/stage_requis.yaml +++ b/openfisca_tunisia_pension/parameters/retraite/rsna/stage_requis.yaml @@ -1,4 +1,6 @@ description: Durée normale du stage requis values: 1974-01-01: - value: 10.0 + value: 10 +metadata: + unit: year diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/taux_annuite_base.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/taux_annuite_base.yaml deleted file mode 100644 index f320ab2..0000000 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/taux_annuite_base.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: Taux d'annuité de base -unit: /1 -values: - 1974-01-01: - value: 0.04 diff --git a/openfisca_tunisia_pension/parameters/retraite/rsna/taux_annuite_supplemetaire.yaml b/openfisca_tunisia_pension/parameters/retraite/rsna/taux_annuite_supplemetaire.yaml deleted file mode 100644 index 88edad4..0000000 --- a/openfisca_tunisia_pension/parameters/retraite/rsna/taux_annuite_supplemetaire.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: Taux d'annuité supplémentaire -unit: /1 -values: - 1974-01-01: - value: 0.02 diff --git a/openfisca_tunisia_pension/regimes/__init__.py b/openfisca_tunisia_pension/regimes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/openfisca_tunisia_pension/regimes/cnrps.py b/openfisca_tunisia_pension/regimes/cnrps.py new file mode 100644 index 0000000..305262f --- /dev/null +++ b/openfisca_tunisia_pension/regimes/cnrps.py @@ -0,0 +1,151 @@ +'''Régime de la Caisse nationale de retraite et de prévoyance sociale (CNRPS).''' + + +from openfisca_core.model_api import * + + +from openfisca_tunisia_pension.entities import Individu +from openfisca_tunisia_pension.regimes.regime import AbstractRegimeEnAnnuites + + +from numpy import ( + apply_along_axis, + vstack, + ) + +from openfisca_tunisia_pension.tools import make_mean_over_consecutive_largest + + +# Avant 1985 + +# La pension d’ancienneté pour cette modalité le droit est acquis lorsque la double condition +# - de 60 ans d’âge +# - et 30ans de services effectifs civils ou militaires est remplie. +# Sont dispensés de la condition d’âge les agents : +# - admis à la retraite d’office ; +# - révoqués sans suspension des droits à la pension ; +# - licenciés pour suppression d’emplois; +# - admis à la retraite pour incapacité physique ; +# - admis à la retraite pour insuffisance professionnelle. + +# La pension proportionnelle, dont le droit est acquis : +# - Sans conditions d’âge ni de durée de services aux agents mis à la retraite pour incapacité physique imputable et non imputable aux services ; +# - Sans conditions de durée de services : +# - aux agents mis à la retraite pour limite d’âge ; +# - licenciés pour suppression d’emploi et ayant plus de 15ans de services ; +# - aux femmes mères de 3 enfants âgés de moins de 16 ans ; +# - Sans conditions d’âge +# - aux agents licenciés pour insuffisance professionnelle ; +# - Sur demande ou d’office aux agents de plus de 50 ans et plus de 20 ans de services. + + +# Après 1985 + +# Le départ à la retraite est prononcé : +# Lors de l'atteinte de l'âge légal de mise à retraite ; +# Avant l'atteinte de cet âge: +# a/ en cas d'invalidité physique ; +# b/ sur demande ; +# c/ en cas de démission ; +# d/ à l'initiative de l'employeur pour insuffisance professionnelle de l'agent ; +# e/ en cas de révocation ; +# f/ sur demande pour les mères de trois enfants; +# g/ d’office. + + +class RegimeCNRPS(AbstractRegimeEnAnnuites): + name = 'Régime des salariés non agricoles' + variable_prefix = 'cnrps' + parameters_prefix = 'cnrps' + + class eligible(Variable): + value_type = bool + entity = Individu + label = "L'individu est éligible à une pension CNRPS" + definition_period = YEAR + + def formula(individu, period, parameters): + duree_assurance = individu('regime_name_duree_assurance', period = period) + salaire_de_reference = individu('regime_name_salaire_de_reference', period = period) + age = individu('age', period = period) + cnrps = parameters(period).retraite.regime_name + duree_de_service_minimale_accomplie = duree_assurance > 4 * cnrps.duree_de_service_minimale + critere_age_verifie = age >= cnrps.age_legal.civil.cadre_commun + return duree_de_service_minimale_accomplie * critere_age_verifie * (salaire_de_reference > 0) + + class pension_minimale(Variable): + value_type = float + default_value = 0 # Pas de pension minimale par défaut, elle est à zéro + entity = Individu + definition_period = YEAR + label = 'Pension minimale' + + def formula(individu, period, parameters): + cnrps = parameters(period).retraite.regime_name + pension_minimale = cnrps.pension_minimale + duree_de_service_minimale = cnrps.duree_de_service_minimale + # TODO Annualiser le Smig + smig_annuel = 12 * parameters(period).marche_travail.smig_40h_mensuel + duree_assurance = individu('regime_name_duree_assurance', period) + return apply_thresholds( + duree_assurance / 4, + [ + pension_minimale.duree_service_allocation_vieillesse, + duree_de_service_minimale, + ], + [ + 0, + pension_minimale.allocation_vieillesse * smig_annuel, + pension_minimale.minimum_garanti * smig_annuel, + ] + + ) + + class salaire_de_reference_calcule_sur_demande(Variable): + value_type = bool + entity = Individu + label = "Le salaire de référence du régime de la CNRPS est calculé à la demande de l'agent sur ses meilleures années" + definition_period = ETERNITY + + class salaire_de_reference(Variable): + value_type = float + entity = Individu + label = 'Salaires de référence du régime de la CNRPS' + definition_period = YEAR + + # TODO: Il semblerait que c'était les 6 deniers mois en 2011 voir manuel CNRPS + def formula(individu, period): + '''3 dernières rémunérations ou les 2 plus élevées sur demande.''' + n = 40 + k = 2 + mean_over_largest = make_mean_over_consecutive_largest(k) + moyenne_2_salaires_plus_eleves = apply_along_axis( + mean_over_largest, + axis = 0, + arr = vstack([individu('regime_name_salaire_de_base', period = year, options = [ADD]) for year in range(period.start.year, period.start.year - n, -1)]), + ) + p = 3 + moyenne_3_derniers_salaires = sum( + individu('regime_name_salaire_de_base', period = year, options = [ADD]) + for year in range(period.start.year, period.start.year - p, -1) + ) / p + + salaire_refererence = where( + individu('regime_name_salaire_de_reference_calcule_sur_demande', period), + moyenne_2_salaires_plus_eleves, + moyenne_3_derniers_salaires, + ) + return salaire_refererence + + class bonifications(Variable): + value_type = float + entity = Individu + label = 'Bonifications' + definition_period = YEAR + + def formula(individu, period): + + return ( + individu('bonfication_retraite_pour_limite_d_age', period), + + individu('bonfication_retraite_avant_age_legal', period) + ) diff --git a/openfisca_tunisia_pension/regimes/regime.py b/openfisca_tunisia_pension/regimes/regime.py new file mode 100644 index 0000000..6eae8f3 --- /dev/null +++ b/openfisca_tunisia_pension/regimes/regime.py @@ -0,0 +1,212 @@ +'''Abstract regimes definition.''' + +import numpy as np + + +from openfisca_core.model_api import * +from openfisca_core.errors.variable_not_found_error import VariableNotFoundError + +# Import the Entities specifically defined for this tax and benefit system +from openfisca_tunisia_pension.entities import Individu + + +class AbstractRegime(object): + name = None + variable_prefix = None + parameters = None + + class cotisation(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'cotisation retraite employeur' + + def formula(individu, period, parameters): + NotImplementedError + + class duree_assurance(Variable): + value_type = int + entity = Individu + definition_period = YEAR + label = "Durée d'assurance (trimestres validés)" + + # def formula(individu, period, parameters): + # duree_assurance_validee = individu("regime_name_duree_assurance_validee", period) + # annee_de_liquidation = individu('regime_name_liquidation_date', period).astype('datetime64[Y]').astype(int) + 1970 + # majoration_duree_assurance = individu('regime_name_majoration_duree_assurance', period) + # return where( + # annee_de_liquidation == period.start.year, + # round_(duree_assurance_validee + majoration_duree_assurance), # On arrondi l'année de la liquidation + # duree_assurance_validee + # ) + + class liquidation_date(Variable): + value_type = date + entity = Individu + definition_period = ETERNITY + label = 'Date de liquidation' + default_value = date(2250, 12, 31) + + class majoration_pension(Variable): + value_type = int + entity = Individu + definition_period = MONTH + label = 'Majoration de pension' + + def formula(individu, period, parameters): + NotImplementedError + + class pension(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension' + + def formula(individu, period, parameters): + NotImplementedError + + class pension_brute(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension brute' + + def formula(individu, period, parameters): + NotImplementedError + + class pension_servie(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension servie' + + def formula(individu, period, parameters): + NotImplementedError + + +class AbstractRegimeEnAnnuites(AbstractRegime): + name = 'Régime en annuités' + variable_prefix = 'regime_en_annuites' + parameters = 'regime_en_annuites' + + class duree_assurance_annuelle(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = "Durée d'assurance (en trimestres validés l'année considérée)" + + class eligible(Variable): + value_type = bool + entity = Individu + label = "L'individu est éligible à une pension" + definition_period = YEAR + + def formula(individu, period, parameters): + NotImplementedError + + class pension(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension' + + def formula(individu, period): + pension_brute = individu('regime_name_pension_brute', period) + eligible = individu('regime_name_eligible', period) + try: + pension_minimale = individu('regime_name_pension_minimale', period) + except VariableNotFoundError: + pension_minimale = 0 + try: + pension_maximale = individu('regime_name_pension_maximale', period) + except (VariableNotFoundError, NotImplementedError): + return max_( + pension_brute, + pension_minimale + ) + return eligible * min_( + pension_maximale, + max_( + pension_brute, + pension_minimale + ) + ) + + class pension_brute(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension brute' + + def formula(individu, period, parameters): + taux_de_liquidation = individu('regime_name_taux_de_liquidation', period) + salaire_de_reference = individu('regime_name_salaire_de_reference', period) + return taux_de_liquidation * salaire_de_reference, + + class pension_maximale(Variable): + value_type = float + default_value = np.inf # Pas de pension maximale par défaut + entity = Individu + definition_period = YEAR + label = 'Pension maximale' + + def formula(individu, period, parameters): + NotImplementedError + + class pension_minimale(Variable): + value_type = float + # default_value = 0 # Pas de pension minimale par défaut, elle est à zéro + entity = Individu + definition_period = YEAR + label = 'Pension minimale' + + def formula(individu, period, parameters): + NotImplementedError + + class pension_servie(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension servie' + + def formula(individu, period, parameters): + annee_de_liquidation = individu('regime_name_liquidation_date', period).astype('datetime64[Y]').astype(int) + 1970 + # Raccouci pour arrêter les calculs dans le passé quand toutes les liquidations ont lieu dans le futur + if all(annee_de_liquidation > period.start.year): + return individu.empty_array() + last_year = period.last_year + pension_au_31_decembre_annee_precedente = individu('regime_name_pension_au_31_decembre', last_year) + revalorisation = parameters(period).regime_name.revalarisation_pension_servie + pension = individu('regime_name_pension_au_31_decembre', period) + return revalorise( + pension_au_31_decembre_annee_precedente, + pension, + annee_de_liquidation, + revalorisation, + period, + ) + + class salaire_de_base(Variable): + value_type = float + entity = Individu + definition_period = MONTH + label = 'Salaire de base (salaire brut)' + set_input = set_input_divide_by_period + + class salaire_de_reference(Variable): + value_type = float + entity = Individu + definition_period = ETERNITY + label = 'Salaire de référence' + + class taux_de_liquidation(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Taux de liquidation de la pension' + + def formula(individu, period, parameters): + bareme_annuite = parameters(period).retraite.regime_name.bareme_annuite + duree_assurance = individu('regime_name_duree_assurance', period) + taux_annuite = bareme_annuite.calc(duree_assurance) + return taux_annuite diff --git a/openfisca_tunisia_pension/regimes/rsa.py b/openfisca_tunisia_pension/regimes/rsa.py new file mode 100644 index 0000000..02823ed --- /dev/null +++ b/openfisca_tunisia_pension/regimes/rsa.py @@ -0,0 +1,86 @@ +'''Régime des salariés agricoles.''' + + +from openfisca_core.model_api import * +from openfisca_core import periods + +from openfisca_tunisia_pension.entities import Individu +from openfisca_tunisia_pension.regimes.regime import AbstractRegimeEnAnnuites + + +from numpy import ( + apply_along_axis, + maximum as max_, + vstack, + ) + + +from openfisca_tunisia_pension.tools import make_mean_over_largest +from openfisca_tunisia_pension.variables.helpers import pension_generique + + +class RegimeRSA(AbstractRegimeEnAnnuites): + name = 'Régime des salariés agricoles' + variable_prefix = 'rsa' + parameters_prefix = 'rsa' + + class salaire_reference(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 + + k = 3 + mean_over_largest = make_mean_over_largest(k) + 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(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(period).retraite.regime_name + taux_annuite_base = rsa.taux_annuite_base + taux_annuite_supplementaire = rsa.taux_annuite_supplementaire + 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 = duree_assurance > 4 * duree_stage + pension_min = rsa.pension_min + salaire_reference = individu('regime_name_salaire_reference', period) + + montant = pension_generique( + duree_assurance, + sal_ref, + taux_annuite_base, + taux_annuite_supplementaire, + duree_stage, + age_elig, + periode_remplacement_base, + plaf_taux_pension + ) + + 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 diff --git a/openfisca_tunisia_pension/regimes/rsna.py b/openfisca_tunisia_pension/regimes/rsna.py new file mode 100644 index 0000000..d7c2b3f --- /dev/null +++ b/openfisca_tunisia_pension/regimes/rsna.py @@ -0,0 +1,99 @@ +'''Régime des salariés non agricoles.''' + + +from openfisca_core.model_api import * + + +from openfisca_tunisia_pension.entities import Individu +from openfisca_tunisia_pension.regimes.regime import AbstractRegimeEnAnnuites +# from openfisca_tunisia_pension.tools import add_vectorial_timedelta, year_ + + +from numpy import ( + apply_along_axis, + vstack, + ) + + +from openfisca_tunisia_pension.tools import make_mean_over_largest + + +class RegimeRSNA(AbstractRegimeEnAnnuites): + name = 'Régime des salariés non agricoles' + variable_prefix = 'rsna' + parameters_prefix = 'rsna' + + class RSNATypesRaisonDepartAnticipe(Enum): + __order__ = 'non_concerne licenciement_economique usure_prematuree_organisme mere_3_enfants convenance_personnelle' + non_concerne = 'Non concerné' + # A partir de 50 ans : + licenciement_economique = 'Licenciement économique avec au minimum 60 mois de cotisations (20 trimestres)' + usure_prematuree_organisme = "Usure prématurée de l'organisme médicalement constatée avec au minimum 60 mois de cotisations (20 trimestres)" + mere_3_enfants = "Femme salariée, mère de 3 enfants en vie, justifiant d'au moins 180 mois de cotisations (60 trimestres)" + # A partir de 55 ans : + convenance_personnelle = 'Convenance personnelle, avec 360 mois de cotisations (120 trimestres)' + + class eligible(Variable): + value_type = bool + entity = Individu + label = "L'individu est éligible à une pension CNRPS" + definition_period = YEAR + + def formula(individu, period, parameters): + duree_assurance = individu('regime_name_duree_assurance', period = period) + salaire_de_reference = individu('regime_name_salaire_de_reference', period = period) + age = individu('age', period = period) + rsna = parameters(period).retraite.regime_name + duree_stage_accomplie = duree_assurance > 4 * rsna.stage_requis + critere_age_verifie = age >= rsna.age_legal + return duree_stage_accomplie * critere_age_verifie * (salaire_de_reference > 0) + + class pension_minimale(Variable): + value_type = float + default_value = 0 # Pas de pension minimale par défaut, elle est à zéro + entity = Individu + definition_period = YEAR + label = 'Pension minimale' + + def formula(individu, period, parameters): + rsna = parameters(period).retraite.regime_name + pension_minimale = rsna.pension_minimale + # TODO Annualiser le Smig + smig_annuel = 12 * parameters(period).marche_travail.smig_40h_mensuel + duree_assurance = individu('regime_name_duree_assurance', period) + # TODO: vérifier et corriger + return apply_thresholds( + duree_assurance / 4, + [ + rsna.stage_derog, + rsna.stage_requis, + ], + [ + 0, + pension_minimale.inf * smig_annuel, + pension_minimale.sup * smig_annuel, + ] + + ) + + class salaire_de_reference(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 + k = 10 + mean_over_largest = make_mean_over_largest(k = k) + n = 40 + salaire_refererence = apply_along_axis( + mean_over_largest, + axis = 0, + arr = vstack([ + individu('regime_name_salaire_de_base', period = year, options = [ADD]) + for year in range(period.start.year, period.start.year - n, -1) + ]), + ) + return salaire_refererence diff --git a/openfisca_tunisia_pension/scripts_ast/__init__.py b/openfisca_tunisia_pension/scripts_ast/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/openfisca_tunisia_pension/scripts_ast/script_ast.py b/openfisca_tunisia_pension/scripts_ast/script_ast.py new file mode 100644 index 0000000..c9aa253 --- /dev/null +++ b/openfisca_tunisia_pension/scripts_ast/script_ast.py @@ -0,0 +1,237 @@ +'''Generate openfisca variables of pension scheme.''' + +import ast +import copy +import logging +import os +import sys +from pathlib import Path + + +import openfisca_tunisia_pension +tunisia_pension_root = str(Path(openfisca_tunisia_pension.__file__).parent.parent) + + +log = logging.getLogger(__name__) + + +# tunisia_pension_root = pkg_resources.get_distribution('openfisca-tunisia-pension').location + +class RewriteRegimeFormula(ast.NodeTransformer): + parameters_prefix = None + variable_prefix = None + + def __init__(self, parameters_prefix, variable_prefix): + self.parameters_prefix = parameters_prefix + self.variable_prefix = variable_prefix + + def visit_Attribute(self, node): + node = self.generic_visit(node) + if type(node.attr) is str and node.attr.startswith('regime_name'): + new_attr = node.attr.replace('regime_name', self.parameters_prefix) + log.debug(f'Found attribute to replace: {node.attr} => {new_attr}') + node.attr = new_attr + return node + + def visit_Constant(self, node): + # Useless: node = self.generic_visit(node), because a constant has no + # sub-tree to visit. + if type(node.value) is str and node.value.startswith('regime_name'): + new_value = node.value.replace('regime_name', self.variable_prefix) + log.debug(f'Found parameter to replace: {node.value} => {new_value}') + node.value = new_value + return node + + +class RewriteRegimeVariableClass(ast.NodeTransformer): + parameters_prefix = None + variable_prefix = None + + def __init__(self, parameters_prefix, variable_prefix): + self.parameters_prefix = parameters_prefix + self.variable_prefix = variable_prefix + + def visit_ClassDef(self, node): + node.name = self.variable_prefix + '_' + node.name + node = self.generic_visit(node) + return node + + def visit_FunctionDef(self, node): + if node.name.startswith('formula'): + log.debug(f'Found formula: {node.name}') + node = RewriteRegimeFormula(self.parameters_prefix, self.variable_prefix).visit(node) + else: + node = self.generic_visit(node) + return node + + +def flatten_regime( + regime_class_node_by_name, + regime_class_node, + parameters_prefix, + variable_prefix, + existing_variables_name, + variables_node, + ): + new_variables_name = set() + for node in regime_class_node.body: + if type(node) is ast.ClassDef: + # Node is a variable. + if node.name not in existing_variables_name: + # Variable is not overriden by a subclass variable. + existing_variables_name.add(node.name) + new_variables_name.add(node.name) + + # Aplatit récursivement les variables la classe de base de cette classe Regime. + if regime_class_node.bases[0].id != 'object': + flatten_regime( + regime_class_node_by_name, + regime_class_node_by_name[regime_class_node.bases[0].id], + parameters_prefix, + variable_prefix, + existing_variables_name, + variables_node, + ) + + # Aplatit les variables de cette classe Regime. + for node in regime_class_node.body: + if type(node) is ast.ClassDef: + # Node is a variable. + if node.name in new_variables_name: + node = copy.deepcopy(node) + node = ast.fix_missing_locations(RewriteRegimeVariableClass( + parameters_prefix, + variable_prefix, + ).visit(node)) + variables_node.append(node) + + +def flatten_regimes(input_string, output_filename): + '''Creates regime variables. + + Args: + input_string (str): String to be processed by ast + output_filename (path): Destination of created variables code + ''' + # parser le texte du fichier en structure logique de type AST + input_node = ast.parse(input_string) + + # pour afficher un arbre AST faire une commande + # print(ast.dump(input_node, indent=4)) + + # créer un nouveau arbre AST vide qui va contenir le nouveau code + output_node = ast.Module(body=[], type_ignores=[]) + + # Crée un dictionnaire de toutes les classes contenant 'Regime' dans le nom. + regime_class_node_by_name = {} + for node in input_node.body: + if type(node) is ast.ClassDef and 'Regime' in node.name: + regime_class_node_by_name[node.name] = node + + # Recrée un AST en aplatissant les classes Regime + # (ie en en extrayant et renommant les variables OpenFisca). + variables_node = [] + for node in input_node.body: + if type(node) is ast.ClassDef and 'Regime' in node.name: + if 'Abstract' not in node.name: + parameters_prefix = get_regime_attribute(node, 'parameters_prefix') + variable_prefix = get_regime_attribute(node, 'variable_prefix') + flatten_regime( + regime_class_node_by_name, + node, + parameters_prefix, + variable_prefix, + set(), + variables_node, + ) + else: + output_node.body.append(node) + # Trie les variables OpenFisca par ordre alphabétique. + variables_node.sort(key = lambda variable_node: variable_node.name) + for variable_node in variables_node: + output_node.body.append(variable_node) + + # pour afficher le nouveau arbre AST faire une commande + # print(ast.dump(output_node, indent=4)) + + # convertir la structure logique de l'arbre AST en code python formatté (type string) + output_string = ast.unparse(output_node) + + # sauvegarder + with open(output_filename, 'w', encoding='utf-8') as file: + file.write(output_string) + + log.info(f'Result saved as {output_filename}') + + +def get_regime_attribute(regime_class_node, attribute): + '''Gets regime attribute. + + Args: + regime_class_node (ast.ClassDef): regime node + attribute (str): attribute name + + Returns: + [Any]: the attribute value + ''' + assert ( + isinstance(regime_class_node, ast.ClassDef) + and 'Regime' in regime_class_node.name + and 'Abstract' not in regime_class_node.name + ), f'{regime_class_node.name} is not a valid regime' + for sub_node in regime_class_node.body: + if isinstance(sub_node, ast.Assign): + for target in sub_node.targets: + if target.id == attribute: + assert isinstance(sub_node.value, ast.Constant), f'{sub_node.value} is not a constant' + return sub_node.value.value + + return None + + +def main(verbose = False): + regime_de_base = os.path.join( + tunisia_pension_root, + 'openfisca_tunisia_pension', + 'regimes', + 'regime.py' + ) + + regimes_files_by_name = { + name: { + 'input': os.path.join( + tunisia_pension_root, + 'openfisca_tunisia_pension', + 'regimes', + f'{name}.py' + ), + 'output': os.path.join( + tunisia_pension_root, + 'openfisca_tunisia_pension', + 'variables', + f'{name}.py' + ) + } + for name in [ + 'rsna', + 'rsa', + 'cnrps' + ] + } + + for _regime_name, regime_files in regimes_files_by_name.items(): + input_file_names = [ + regime_de_base, + regime_files['input'], + ] + input_string = '' + for input_filename in input_file_names: + with open(input_filename, encoding='utf-8') as file: + input_string += '\n' + file.read() + + logging.basicConfig(level = logging.DEBUG if verbose else logging.WARNING, stream = sys.stdout) + flatten_regimes(input_string, regime_files['output']) + + +if __name__ == '__main__': + main(verbose = True) diff --git a/openfisca_tunisia_pension/tools.py b/openfisca_tunisia_pension/tools.py new file mode 100644 index 0000000..a361a98 --- /dev/null +++ b/openfisca_tunisia_pension/tools.py @@ -0,0 +1,54 @@ +'''Tools.''' + + +from numba import float32, int64, jit +import numpy as np + + +def make_mean_over_largest(k): + def mean_over_largest(vector): + return mean_over_k_nonzero_largest(vector, k = int(k)) + + return mean_over_largest + + +def make_mean_over_consecutive_largest(k): + def mean_over_consecutive_largest(vector): + return mean_over_k_consecutive_largest(vector, k = int(k)) + + return mean_over_consecutive_largest + + +@jit(float32(float32[:], int64), nopython=True) +def mean_over_k_nonzero_largest(vector, k): + '''Return the mean over the k largest values of a vector.''' + if k == 0: + return 0 + nonzeros = (vector > 0.0).sum() + if k >= nonzeros: + return vector.sum() / (nonzeros + (nonzeros == 0)) + + z = -np.partition(-vector, kth = k) + upper_bound = min(k, nonzeros) + return z[:upper_bound].sum() / upper_bound + + +@jit(float32(float32[:], int64), nopython=True) +def mean_over_k_consecutive_largest(vector, k): + '''Return the mean over the k largest consecutive values of a vector.''' + if k == 0: + return 0 + nonzeros = (vector > 0.0).sum() + if k >= nonzeros: + return vector.sum() / (nonzeros + (nonzeros == 0)) + + if k == 1: + return vector.max() + + n = len(vector) + mean = np.zeros(n + 1 - k, dtype = np.float32) + for p in range(n + 1 - k): + for i in range(k): + mean[p] += vector[p + i] + mean[p] = mean[p] / k + return mean.max() diff --git a/openfisca_tunisia_pension/tunisia_pension_taxbenefitsystem.py b/openfisca_tunisia_pension/tunisia_pension_taxbenefitsystem.py deleted file mode 100644 index a844e21..0000000 --- a/openfisca_tunisia_pension/tunisia_pension_taxbenefitsystem.py +++ /dev/null @@ -1,25 +0,0 @@ -import glob -import os - -from openfisca_core.taxbenefitsystems import TaxBenefitSystem - -from openfisca_tunisia_pension import entities - -COUNTRY_DIR = os.path.dirname(os.path.abspath(__file__)) -EXTENSIONS_PATH = os.path.join(COUNTRY_DIR, 'extensions') -EXTENSIONS_DIRECTORIES = glob.glob(os.path.join(EXTENSIONS_PATH, '*/')) - - -class TunisiaPensionTaxBenefitSystem(TaxBenefitSystem): - '''Tunisian pensions tax benefit system''' - CURRENCY = 'DT' - - def __init__(self): - super(TunisiaPensionTaxBenefitSystem, self).__init__(entities.entities) - - # We add to our tax and benefit system all the variables - self.add_variables_from_directory(os.path.join(COUNTRY_DIR, 'variables')) - - # We add to our tax and benefit system all the legislation parameters defined in the parameters files - parameters_path = os.path.join(COUNTRY_DIR, 'parameters') - self.load_parameters(parameters_path) diff --git a/openfisca_tunisia_pension/units.yaml b/openfisca_tunisia_pension/units.yaml new file mode 100644 index 0000000..314c02f --- /dev/null +++ b/openfisca_tunisia_pension/units.yaml @@ -0,0 +1,34 @@ +- name: /1 + label: + one: pourcent + other: pourcents + ratio: true + short_label: "%" +- name: currency + label: + one: Dinar + other: Dinars + short_label: DT +- name: day + label: + one: jour + other: jours +- name: month + label: mois +- name: year + label: + one: année + other: années + short_label: + one: an + other: ans +- name: smig + label: + one: Smig + other: Smigs + # parameter: marche_travail.salaire_minimum.smig. + ratio: true +- name: trimestre + label: + one: trimestre + other: trimestres diff --git a/openfisca_tunisia_pension/variables/cnrps.py b/openfisca_tunisia_pension/variables/cnrps.py new file mode 100644 index 0000000..207a7d6 --- /dev/null +++ b/openfisca_tunisia_pension/variables/cnrps.py @@ -0,0 +1,185 @@ +"""Abstract regimes definition.""" +import numpy as np +from openfisca_core.model_api import * +from openfisca_core.errors.variable_not_found_error import VariableNotFoundError +from openfisca_tunisia_pension.entities import Individu +'Régime de la Caisse nationale de retraite et de prévoyance sociale (CNRPS).' +from openfisca_core.model_api import * +from openfisca_tunisia_pension.entities import Individu +from openfisca_tunisia_pension.regimes.regime import AbstractRegimeEnAnnuites +from numpy import apply_along_axis, vstack +from openfisca_tunisia_pension.tools import make_mean_over_consecutive_largest + +class cnrps_bonifications(Variable): + value_type = float + entity = Individu + label = 'Bonifications' + definition_period = YEAR + + def formula(individu, period): + return (individu('bonfication_retraite_pour_limite_d_age', period), +individu('bonfication_retraite_avant_age_legal', period)) + +class cnrps_cotisation(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'cotisation retraite employeur' + + def formula(individu, period, parameters): + NotImplementedError + +class cnrps_duree_assurance(Variable): + value_type = int + entity = Individu + definition_period = YEAR + label = "Durée d'assurance (trimestres validés)" + +class cnrps_duree_assurance_annuelle(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = "Durée d'assurance (en trimestres validés l'année considérée)" + +class cnrps_eligible(Variable): + value_type = bool + entity = Individu + label = "L'individu est éligible à une pension CNRPS" + definition_period = YEAR + + def formula(individu, period, parameters): + duree_assurance = individu('cnrps_duree_assurance', period=period) + salaire_de_reference = individu('cnrps_salaire_de_reference', period=period) + age = individu('age', period=period) + cnrps = parameters(period).retraite.cnrps + duree_de_service_minimale_accomplie = duree_assurance > 4 * cnrps.duree_de_service_minimale + critere_age_verifie = age >= cnrps.age_legal.civil.cadre_commun + return duree_de_service_minimale_accomplie * critere_age_verifie * (salaire_de_reference > 0) + +class cnrps_liquidation_date(Variable): + value_type = date + entity = Individu + definition_period = ETERNITY + label = 'Date de liquidation' + default_value = date(2250, 12, 31) + +class cnrps_majoration_pension(Variable): + value_type = int + entity = Individu + definition_period = MONTH + label = 'Majoration de pension' + + def formula(individu, period, parameters): + NotImplementedError + +class cnrps_pension(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension' + + def formula(individu, period): + pension_brute = individu('cnrps_pension_brute', period) + eligible = individu('cnrps_eligible', period) + try: + pension_minimale = individu('cnrps_pension_minimale', period) + except VariableNotFoundError: + pension_minimale = 0 + try: + pension_maximale = individu('cnrps_pension_maximale', period) + except (VariableNotFoundError, NotImplementedError): + return max_(pension_brute, pension_minimale) + return eligible * min_(pension_maximale, max_(pension_brute, pension_minimale)) + +class cnrps_pension_brute(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension brute' + + def formula(individu, period, parameters): + taux_de_liquidation = individu('cnrps_taux_de_liquidation', period) + salaire_de_reference = individu('cnrps_salaire_de_reference', period) + return (taux_de_liquidation * salaire_de_reference,) + +class cnrps_pension_maximale(Variable): + value_type = float + default_value = np.inf + entity = Individu + definition_period = YEAR + label = 'Pension maximale' + + def formula(individu, period, parameters): + NotImplementedError + +class cnrps_pension_minimale(Variable): + value_type = float + default_value = 0 + entity = Individu + definition_period = YEAR + label = 'Pension minimale' + + def formula(individu, period, parameters): + cnrps = parameters(period).retraite.cnrps + pension_minimale = cnrps.pension_minimale + duree_de_service_minimale = cnrps.duree_de_service_minimale + smig_annuel = 12 * parameters(period).marche_travail.smig_40h_mensuel + duree_assurance = individu('cnrps_duree_assurance', period) + return apply_thresholds(duree_assurance / 4, [pension_minimale.duree_service_allocation_vieillesse, duree_de_service_minimale], [0, pension_minimale.allocation_vieillesse * smig_annuel, pension_minimale.minimum_garanti * smig_annuel]) + +class cnrps_pension_servie(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension servie' + + def formula(individu, period, parameters): + annee_de_liquidation = individu('cnrps_liquidation_date', period).astype('datetime64[Y]').astype(int) + 1970 + if all(annee_de_liquidation > period.start.year): + return individu.empty_array() + last_year = period.last_year + pension_au_31_decembre_annee_precedente = individu('cnrps_pension_au_31_decembre', last_year) + revalorisation = parameters(period).cnrps.revalarisation_pension_servie + pension = individu('cnrps_pension_au_31_decembre', period) + return revalorise(pension_au_31_decembre_annee_precedente, pension, annee_de_liquidation, revalorisation, period) + +class cnrps_salaire_de_base(Variable): + value_type = float + entity = Individu + definition_period = MONTH + label = 'Salaire de base (salaire brut)' + set_input = set_input_divide_by_period + +class cnrps_salaire_de_reference(Variable): + value_type = float + entity = Individu + label = 'Salaires de référence du régime de la CNRPS' + definition_period = YEAR + + def formula(individu, period): + """3 dernières rémunérations ou les 2 plus élevées sur demande.""" + n = 40 + k = 2 + mean_over_largest = make_mean_over_consecutive_largest(k) + moyenne_2_salaires_plus_eleves = apply_along_axis(mean_over_largest, axis=0, arr=vstack([individu('cnrps_salaire_de_base', period=year, options=[ADD]) for year in range(period.start.year, period.start.year - n, -1)])) + p = 3 + moyenne_3_derniers_salaires = sum((individu('cnrps_salaire_de_base', period=year, options=[ADD]) for year in range(period.start.year, period.start.year - p, -1))) / p + salaire_refererence = where(individu('cnrps_salaire_de_reference_calcule_sur_demande', period), moyenne_2_salaires_plus_eleves, moyenne_3_derniers_salaires) + return salaire_refererence + +class cnrps_salaire_de_reference_calcule_sur_demande(Variable): + value_type = bool + entity = Individu + label = "Le salaire de référence du régime de la CNRPS est calculé à la demande de l'agent sur ses meilleures années" + definition_period = ETERNITY + +class cnrps_taux_de_liquidation(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Taux de liquidation de la pension' + + def formula(individu, period, parameters): + bareme_annuite = parameters(period).retraite.cnrps.bareme_annuite + duree_assurance = individu('cnrps_duree_assurance', period) + taux_annuite = bareme_annuite.calc(duree_assurance) + return taux_annuite \ No newline at end of file diff --git a/openfisca_tunisia_pension/variables/data.py b/openfisca_tunisia_pension/variables/data.py index 51a2ebc..0f78957 100644 --- a/openfisca_tunisia_pension/variables/data.py +++ b/openfisca_tunisia_pension/variables/data.py @@ -10,13 +10,6 @@ class age(Variable): definition_period = YEAR -class salaire(Variable): - value_type = float - entity = Individu - label = 'Salaires' - definition_period = YEAR - - class date_naissance(Variable): value_type = date default_value = date(1970, 1, 1) @@ -25,13 +18,6 @@ class date_naissance(Variable): definition_period = ETERNITY -class trimestres_valides(Variable): - value_type = int - entity = Individu - label = 'Nombre de trimestres validés' - definition_period = YEAR - - class TypesRegimeSecuriteSociale(Enum): __order__ = 'rsna rsa rsaa rtns rtte re rtfr raci salarie_cnrps pensionne_cnrps' # Needed to preserve the enum order in Python 2 diff --git a/openfisca_tunisia_pension/variables/helpers.py b/openfisca_tunisia_pension/variables/helpers.py index dcf14c2..e2a8f01 100644 --- a/openfisca_tunisia_pension/variables/helpers.py +++ b/openfisca_tunisia_pension/variables/helpers.py @@ -1,30 +1,57 @@ '''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 +def pension_generique(duree_assurance, sal_ref, taux_annuite_base, taux_annuite_supplementaire, duree_stage, + age_elig, periode_remplacement_base, plaf_taux_pension): + + bareme_annuite_en_trimestres = [ + { + 'threshold': 0, + 'annuity_rate': taux_annuite_base, + }, + { + 'threshold': periode_remplacement_base, + 'annuity_rate': taux_annuite_supplementaire, + }, + { + 'threshold': 40, + 'annuity_rate': 0, + }, + ] + + taux_pension_test = 0.0 + first = True + for bracket in bareme_annuite_en_trimestres: + if first: + lower_threshold = bracket['threshold'] + between_threshold_annuity_rate = bracket['annuity_rate'] + first = False + continue + + upper_threshold = bracket['threshold'] + + print(f'duree_assurance: {duree_assurance / 4}, lower_threshold: {lower_threshold}, upper_threshold: {upper_threshold}, taux_pension: {taux_pension_test}') + taux_pension_test += max( + 0, + min( + (duree_assurance / 4 - lower_threshold), + (upper_threshold - lower_threshold) + ) * between_threshold_annuity_rate ) - ) - 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 + lower_threshold = upper_threshold + between_threshold_annuity_rate = bracket['annuity_rate'] - if k <= len(vector): - return vector.sum() / len(vector) + # taux_pension = ( + # (duree_assurance < 4 * periode_remplacement_base) * (duree_assurance / 4) * taux_annuite_base + # + (duree_assurance >= 4 * periode_remplacement_base) * ( + # taux_annuite_base * periode_remplacement_base + # + (duree_assurance / 4 - periode_remplacement_base) * taux_annuite_supplementaire + # ) + # ) - z = -bottleneck.partition(-vector, kth = k) - return z.sum() / k + montant = min_(taux_pension_test, plaf_taux_pension) * sal_ref + return montant diff --git a/openfisca_tunisia_pension/variables/rsa.py b/openfisca_tunisia_pension/variables/rsa.py index df81f07..fd5051b 100644 --- a/openfisca_tunisia_pension/variables/rsa.py +++ b/openfisca_tunisia_pension/variables/rsa.py @@ -1,65 +1,170 @@ -import functools -from numpy import ( - apply_along_axis, - maximum as max_, - vstack, - ) - -from openfisca_core import periods +"""Abstract regimes definition.""" +import numpy as np from openfisca_core.model_api import * +from openfisca_core.errors.variable_not_found_error import VariableNotFoundError +from openfisca_tunisia_pension.entities import Individu +'Régime des salariés agricoles.' +from openfisca_core.model_api import * +from openfisca_core import periods from openfisca_tunisia_pension.entities import Individu +from openfisca_tunisia_pension.regimes.regime import AbstractRegimeEnAnnuites +from numpy import apply_along_axis, maximum as max_, vstack +from openfisca_tunisia_pension.tools import make_mean_over_largest +from openfisca_tunisia_pension.variables.helpers import pension_generique +class rsa_cotisation(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'cotisation retraite employeur' + + def formula(individu, period, parameters): + NotImplementedError -class salaire_reference_rsa(Variable): +class rsa_duree_assurance(Variable): + value_type = int + entity = Individu + definition_period = YEAR + label = "Durée d'assurance (trimestres validés)" + +class rsa_duree_assurance_annuelle(Variable): value_type = float entity = Individu - label = 'Salaires de référence du régime des salariés agricoles' definition_period = YEAR + label = "Durée d'assurance (en trimestres validés l'année considérée)" - 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 +class rsa_eligible(Variable): + value_type = bool + entity = Individu + label = "L'individu est éligible à une pension" + definition_period = YEAR - 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 + def formula(individu, period, parameters): + NotImplementedError + +class rsa_liquidation_date(Variable): + value_type = date + entity = Individu + definition_period = ETERNITY + label = 'Date de liquidation' + default_value = date(2250, 12, 31) +class rsa_majoration_pension(Variable): + value_type = int + entity = Individu + definition_period = MONTH + label = 'Majoration de pension' + + def formula(individu, period, parameters): + NotImplementedError -class pension_rsa(Variable): +class rsa_pension(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) + rsa = parameters(period).retraite.rsa taux_annuite_base = rsa.taux_annuite_base - taux_annuite_supplemetaire = rsa.taux_annuite_supplemetaire + taux_annuite_supplementaire = rsa.taux_annuite_supplementaire 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 + duree_stage_validee = duree_assurance > 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) - + salaire_reference = individu('rsa_salaire_reference', period) + montant = pension_generique(duree_assurance, sal_ref, taux_annuite_base, taux_annuite_supplementaire, duree_stage, age_elig, periode_remplacement_base, plaf_taux_pension) 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 + +class rsa_pension_brute(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension brute' + + def formula(individu, period, parameters): + taux_de_liquidation = individu('rsa_taux_de_liquidation', period) + salaire_de_reference = individu('rsa_salaire_de_reference', period) + return (taux_de_liquidation * salaire_de_reference,) + +class rsa_pension_maximale(Variable): + value_type = float + default_value = np.inf + entity = Individu + definition_period = YEAR + label = 'Pension maximale' + + def formula(individu, period, parameters): + NotImplementedError + +class rsa_pension_minimale(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension minimale' + + def formula(individu, period, parameters): + NotImplementedError + +class rsa_pension_servie(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension servie' + + def formula(individu, period, parameters): + annee_de_liquidation = individu('rsa_liquidation_date', period).astype('datetime64[Y]').astype(int) + 1970 + if all(annee_de_liquidation > period.start.year): + return individu.empty_array() + last_year = period.last_year + pension_au_31_decembre_annee_precedente = individu('rsa_pension_au_31_decembre', last_year) + revalorisation = parameters(period).rsa.revalarisation_pension_servie + pension = individu('rsa_pension_au_31_decembre', period) + return revalorise(pension_au_31_decembre_annee_precedente, pension, annee_de_liquidation, revalorisation, period) + +class rsa_salaire_de_base(Variable): + value_type = float + entity = Individu + definition_period = MONTH + label = 'Salaire de base (salaire brut)' + set_input = set_input_divide_by_period + +class rsa_salaire_de_reference(Variable): + value_type = float + entity = Individu + definition_period = ETERNITY + label = 'Salaire de référence' + +class rsa_salaire_reference(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): + base_declaration_rsa = 180 + base_liquidation_rsa = 300 + k = 3 + mean_over_largest = make_mean_over_largest(k) + 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 rsa_taux_de_liquidation(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Taux de liquidation de la pension' + + def formula(individu, period, parameters): + bareme_annuite = parameters(period).retraite.rsa.bareme_annuite + duree_assurance = individu('rsa_duree_assurance', period) + taux_annuite = bareme_annuite.calc(duree_assurance) + return taux_annuite \ No newline at end of file diff --git a/openfisca_tunisia_pension/variables/rsna.py b/openfisca_tunisia_pension/variables/rsna.py index 48c7b35..e67bf40 100644 --- a/openfisca_tunisia_pension/variables/rsna.py +++ b/openfisca_tunisia_pension/variables/rsna.py @@ -1,80 +1,173 @@ -import functools -from numpy import ( - apply_along_axis, - logical_not as not_, - maximum as max_, - vstack, - ) - +"""Abstract regimes definition.""" +import numpy as np +from openfisca_core.model_api import * +from openfisca_core.errors.variable_not_found_error import VariableNotFoundError +from openfisca_tunisia_pension.entities import Individu +'Régime des salariés non agricoles.' 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 +from openfisca_tunisia_pension.regimes.regime import AbstractRegimeEnAnnuites +from numpy import apply_along_axis, vstack +from openfisca_tunisia_pension.tools import make_mean_over_largest +class rsna_RSNATypesRaisonDepartAnticipe(Enum): + __order__ = 'non_concerne licenciement_economique usure_prematuree_organisme mere_3_enfants convenance_personnelle' + non_concerne = 'Non concerné' + licenciement_economique = 'Licenciement économique avec au minimum 60 mois de cotisations (20 trimestres)' + usure_prematuree_organisme = "Usure prématurée de l'organisme médicalement constatée avec au minimum 60 mois de cotisations (20 trimestres)" + mere_3_enfants = "Femme salariée, mère de 3 enfants en vie, justifiant d'au moins 180 mois de cotisations (60 trimestres)" + convenance_personnelle = 'Convenance personnelle, avec 360 mois de cotisations (120 trimestres)' -class salaire_reference_rsna(Variable): +class rsna_cotisation(Variable): value_type = float entity = Individu - label = 'Salaires de référence du régime des salariés non agricoles' + definition_period = YEAR + label = 'cotisation retraite employeur' + + def formula(individu, period, parameters): + NotImplementedError + +class rsna_duree_assurance(Variable): + value_type = int + entity = Individu + definition_period = YEAR + label = "Durée d'assurance (trimestres validés)" + +class rsna_duree_assurance_annuelle(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = "Durée d'assurance (en trimestres validés l'année considérée)" + +class rsna_eligible(Variable): + value_type = bool + entity = Individu + label = "L'individu est éligible à une pension CNRPS" definition_period = YEAR + def formula(individu, period, parameters): + duree_assurance = individu('rsna_duree_assurance', period=period) + salaire_de_reference = individu('rsna_salaire_de_reference', period=period) + age = individu('age', period=period) + rsna = parameters(period).retraite.rsna + duree_stage_accomplie = duree_assurance > 4 * rsna.stage_requis + critere_age_verifie = age >= rsna.age_legal + return duree_stage_accomplie * critere_age_verifie * (salaire_de_reference > 0) + +class rsna_liquidation_date(Variable): + value_type = date + entity = Individu + definition_period = ETERNITY + label = 'Date de liquidation' + default_value = date(2250, 12, 31) + +class rsna_majoration_pension(Variable): + value_type = int + entity = Individu + definition_period = MONTH + label = 'Majoration de pension' + + def formula(individu, period, parameters): + NotImplementedError + +class rsna_pension(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension' + 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 + pension_brute = individu('rsna_pension_brute', period) + eligible = individu('rsna_eligible', period) + try: + pension_minimale = individu('rsna_pension_minimale', period) + except VariableNotFoundError: + pension_minimale = 0 + try: + pension_maximale = individu('rsna_pension_maximale', period) + except (VariableNotFoundError, NotImplementedError): + return max_(pension_brute, pension_minimale) + return eligible * min_(pension_maximale, max_(pension_brute, pension_minimale)) +class rsna_pension_brute(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension brute' + + def formula(individu, period, parameters): + taux_de_liquidation = individu('rsna_taux_de_liquidation', period) + salaire_de_reference = individu('rsna_salaire_de_reference', period) + return (taux_de_liquidation * salaire_de_reference,) -class pension_rsna(Variable): +class rsna_pension_maximale(Variable): value_type = float + default_value = np.inf entity = Individu - label = 'Pension des affiliés au régime des salariés non agricoles' definition_period = YEAR + label = 'Pension maximale' 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) + NotImplementedError + +class rsna_pension_minimale(Variable): + value_type = float + default_value = 0 + entity = Individu + definition_period = YEAR + label = 'Pension minimale' + def formula(individu, period, parameters): 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 + pension_minimale = rsna.pension_minimale + smig_annuel = 12 * parameters(period).marche_travail.smig_40h_mensuel + duree_assurance = individu('rsna_duree_assurance', period) + return apply_thresholds(duree_assurance / 4, [rsna.stage_derog, rsna.stage_requis], [0, pension_minimale.inf * smig_annuel, pension_minimale.sup * smig_annuel]) + +class rsna_pension_servie(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Pension servie' + + def formula(individu, period, parameters): + annee_de_liquidation = individu('rsna_liquidation_date', period).astype('datetime64[Y]').astype(int) + 1970 + if all(annee_de_liquidation > period.start.year): + return individu.empty_array() + last_year = period.last_year + pension_au_31_decembre_annee_precedente = individu('rsna_pension_au_31_decembre', last_year) + revalorisation = parameters(period).rsna.revalarisation_pension_servie + pension = individu('rsna_pension_au_31_decembre', period) + return revalorise(pension_au_31_decembre_annee_precedente, pension, annee_de_liquidation, revalorisation, period) + +class rsna_salaire_de_base(Variable): + value_type = float + entity = Individu + definition_period = MONTH + label = 'Salaire de base (salaire brut)' + set_input = set_input_divide_by_period + +class rsna_salaire_de_reference(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): + k = 10 + mean_over_largest = make_mean_over_largest(k=k) + n = 40 + salaire_refererence = apply_along_axis(mean_over_largest, axis=0, arr=vstack([individu('rsna_salaire_de_base', period=year, options=[ADD]) for year in range(period.start.year, period.start.year - n, -1)])) + return salaire_refererence + +class rsna_taux_de_liquidation(Variable): + value_type = float + entity = Individu + definition_period = YEAR + label = 'Taux de liquidation de la pension' + + def formula(individu, period, parameters): + bareme_annuite = parameters(period).retraite.rsna.bareme_annuite + duree_assurance = individu('rsna_duree_assurance', period) + taux_annuite = bareme_annuite.calc(duree_assurance) + return taux_annuite \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 4448bf4..d05e1ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "OpenFisca-Tunisia-Pension" -version = "4.0.0" +version = "5.0.0" description = "OpenFisca Rules as Code model for Tunisia pensions." readme = "README.md" keywords = ["microsimulation", "tax", "benefit", "pension", "rac", "rules-as-code", "tunisia"] @@ -19,9 +19,9 @@ classifiers = [ ] requires-python = ">= 3.9" dependencies = [ - 'bottleneck >=1.4.2, <2.0.0', + "numba>=0.54,<1.0.0", 'numpy >=1.24.3, <2', - 'openfisca-core[web-api] >=41.5.0, <41.5.3', + 'openfisca-core[web-api] >=43.0.0, <44.0.0', 'scipy >= 0.12', ] @@ -68,6 +68,7 @@ ignore = ["E128","E251","F403","F405","E501","W503"] docstring-quotes = "single" inline-quotes = "single" multiline-quotes = "single" +exclude = "openfisca_tunisia_pension/variables/*.py" [tool.pep8] hang-closing = true diff --git a/tests/formulas/cnrps/pension.yaml b/tests/formulas/cnrps/pension.yaml new file mode 100644 index 0000000..f4ecddd --- /dev/null +++ b/tests/formulas/cnrps/pension.yaml @@ -0,0 +1,36 @@ +- name: "3 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-4 + input: + cnrps_duree_assurance: 3 * 4 + cnrps_salaire_de_reference: 1000 + output: + cnrps_pension: 0 + + +- name: "7 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 7 * 4 + cnrps_salaire_de_reference: 1000 + output: + cnrps_pension_minimale: 0.5 * 235.04 * 12 + + +- name: "12 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 12 * 4 + output: + cnrps_pension_minimale: 0.5 * 235.04 * 12 + + +- name: "17 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 17 * 4 + output: + cnrps_pension_minimale: 0.66666 * 235.04 * 12 diff --git a/tests/formulas/cnrps/pension_minimale.yaml b/tests/formulas/cnrps/pension_minimale.yaml new file mode 100644 index 0000000..7eb63e1 --- /dev/null +++ b/tests/formulas/cnrps/pension_minimale.yaml @@ -0,0 +1,34 @@ +- name: "3 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-4 + input: + cnrps_duree_assurance: 3 * 4 + output: + cnrps_pension_minimale: 0 + + +- name: "7 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 7 * 4 + output: + cnrps_pension_minimale: 0.5 * 235.04 * 12 + + +- name: "12 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 12 * 4 + output: + cnrps_pension_minimale: 0.5 * 235.04 * 12 + + +- name: "17 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 17 * 4 + output: + cnrps_pension_minimale: 0.66666 * 235.04 * 12 diff --git a/tests/formulas/cnrps/salaire_de_reference.yaml b/tests/formulas/cnrps/salaire_de_reference.yaml new file mode 100644 index 0000000..885347c --- /dev/null +++ b/tests/formulas/cnrps/salaire_de_reference.yaml @@ -0,0 +1,101 @@ +- name: "Fonctionnaires 12000 DT par an avec accélération en fin" + period: 2014 + absolute_error_margin: 0.5 + input: + age: 60 + cnrps_duree_assurance: 50 + cnrps_salaire_de_base: + 1975: 12000 + 1976: 12000 + 1977: 12000 + 1978: 12000 + 1979: 12000 + 1980: 12000 + 1981: 12000 + 1982: 12000 + 1983: 12000 + 1984: 12000 + 1985: 12000 + 1986: 12000 + 1987: 12000 + 1988: 12000 + 1989: 12000 + 1990: 12000 + 1991: 12000 + 1992: 12000 + 1993: 12000 + 1994: 12000 + 1995: 12000 + 1996: 12000 + 1997: 12000 + 1998: 12000 + 1999: 12000 + 2000: 12000 + 2001: 12000 + 2002: 12000 + 2003: 12000 + 2004: 12000 + 2005: 12000 + 2006: 12000 + 2007: 12000 + 2008: 12000 + 2009: 12000 + 2010: 12000 + 2011: 12000 + 2012: 12000 + 2013: 12500 + 2014: 13000 + output: + cnrps_salaire_de_reference: 12500 + + +- name: "Fonctionnaire 2 années à 20000 supérieures au reste de sa carrière" + period: 2014 + absolute_error_margin: 0.5 + input: + age: 60 + cnrps_duree_assurance: 50 + cnrps_salaire_de_reference_calcule_sur_demande: true + cnrps_salaire_de_base: + 1975: 12000 + 1976: 12000 + 1977: 12000 + 1978: 12000 + 1979: 12000 + 1980: 12000 + 1981: 12000 + 1982: 12000 + 1983: 12000 + 1984: 12000 + 1985: 12000 + 1986: 12000 + 1987: 12000 + 1988: 12000 + 1989: 12000 + 1990: 12000 + 1991: 12000 + 1992: 12000 + 1993: 12000 + 1994: 12000 + 1995: 12000 + 1996: 12000 + 1997: 12000 + 1998: 12000 + 1999: 20000 + 2000: 20000 + 2001: 20000 + 2002: 12000 + 2003: 12000 + 2004: 12000 + 2005: 12000 + 2006: 12000 + 2007: 12000 + 2008: 12000 + 2009: 12000 + 2010: 12000 + 2011: 12000 + 2012: 12000 + 2013: 15000 + 2014: 18000 + output: + cnrps_salaire_de_reference: 20000 diff --git a/tests/formulas/cnrps/taux_de_liquidation.yaml b/tests/formulas/cnrps/taux_de_liquidation.yaml new file mode 100644 index 0000000..4a10902 --- /dev/null +++ b/tests/formulas/cnrps/taux_de_liquidation.yaml @@ -0,0 +1,89 @@ +- name: "5 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 5 * 4 + output: + cnrps_taux_de_liquidation: .1 + +- name: "10 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 10 * 4 + output: + cnrps_taux_de_liquidation: .2 + +- name: "13 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 13 * 4 + output: + cnrps_taux_de_liquidation: .2 + .09 + +- name: "21 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 21 * 4 + output: + cnrps_taux_de_liquidation: .5 + .02 + +- name: "31 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 31 * 4 + output: + cnrps_taux_de_liquidation: .5 + .22 + +- name: "40 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 40 * 4 + output: + cnrps_taux_de_liquidation: .9 + +- name: "50 ans de trimetres CNRPS" + period: 2011 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 50 * 4 + output: + cnrps_taux_de_liquidation: .9 + +# Avant 1985 + +- name: "21 ans de trimetres CNRPS" + period: 1980 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 21 * 4 + output: + cnrps_taux_de_liquidation: .42 + +- name: "31 ans de trimetres CNRPS" + period: 1980 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 31 * 4 + output: + cnrps_taux_de_liquidation: .62 + +- name: "40 ans de trimetres CNRPS" + period: 1980 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 40 * 4 + output: + cnrps_taux_de_liquidation: .8 + +- name: "45 ans de trimetres CNRPS" + period: 1980 + absolute_error_margin: 1e-10 + input: + cnrps_duree_assurance: 45 * 4 + output: + cnrps_taux_de_liquidation: .8 diff --git a/tests/formulas/pension_rsna.yaml b/tests/formulas/rsna/pension.yaml similarity index 87% rename from tests/formulas/pension_rsna.yaml rename to tests/formulas/rsna/pension.yaml index f2fe4e4..3ade7ac 100644 --- a/tests/formulas/pension_rsna.yaml +++ b/tests/formulas/rsna/pension.yaml @@ -3,8 +3,8 @@ absolute_error_margin: 0.5 input: age: 60 - trimestres_valides: 50 - salaire: + rsna_duree_assurance: 50 + rsna_salaire_de_base: 1975: 12000 1976: 12000 1977: 12000 @@ -46,6 +46,5 @@ 2013: 12000 2014: 12000 output: - trimestres_valides: 50 - salaire_reference_rsna: 12000 - pension_rsna: 5400 + rsna_salaire_de_reference: 12000 + rsna_pension: 5400 diff --git a/tests/formulas/rsna/taux_de_liquidation.yaml b/tests/formulas/rsna/taux_de_liquidation.yaml new file mode 100644 index 0000000..ac772c4 --- /dev/null +++ b/tests/formulas/rsna/taux_de_liquidation.yaml @@ -0,0 +1,55 @@ +- name: "5 ans de trimetres CNSS" + period: 2011 + absolute_error_margin: 1e-10 + input: + rsna_duree_assurance: 5 * 4 + output: + rsna_taux_de_liquidation: .2 + +- name: "10 ans de trimetres CNSS RSNA" + period: 2011 + absolute_error_margin: 1e-10 + input: + rsna_duree_assurance: 10 * 4 + output: + rsna_taux_de_liquidation: .4 + +- name: "13 ans de trimetres CNSS RSNA" + period: 2011 + absolute_error_margin: 1e-10 + input: + rsna_duree_assurance: 13 * 4 + output: + rsna_taux_de_liquidation: .4 + .06 + +- name: "21 ans de trimetres CNSS RSNA" + period: 2011 + absolute_error_margin: 1e-10 + input: + rsna_duree_assurance: 21 * 4 + output: + rsna_taux_de_liquidation: .4 + .22 + +- name: "31 ans de trimetres CNSS RSNA" + period: 2011 + absolute_error_margin: 1e-10 + input: + rsna_duree_assurance: 31 * 4 + output: + rsna_taux_de_liquidation: .8 + +- name: "40 ans de trimetres CNSS RSNA" + period: 2011 + absolute_error_margin: 1e-10 + input: + rsna_duree_assurance: 40 * 4 + output: + rsna_taux_de_liquidation: .8 + +- name: "50 ans de trimetres CNSS RSNA" + period: 2011 + absolute_error_margin: 1e-10 + input: + rsna_duree_assurance: 50 * 4 + output: + rsna_taux_de_liquidation: .8 diff --git a/tests/formulas/salaire_reference_rsna.yaml b/tests/formulas/salaire_reference_rsna.yaml deleted file mode 100644 index 02a8ff7..0000000 --- a/tests/formulas/salaire_reference_rsna.yaml +++ /dev/null @@ -1,50 +0,0 @@ -- name: "Individu salarié 12000 DT par an toute sa carrière" - period: 2011 - absolute_error_margin: 0.5 - input: - age: 60 - trimestres_valides: 50 - salaire: - 1975: 12000 - 1976: 12000 - 1977: 12000 - 1978: 12000 - 1979: 12000 - 1980: 12000 - 1981: 12000 - 1982: 12000 - 1983: 12000 - 1984: 12000 - 1985: 12000 - 1986: 12000 - 1987: 12000 - 1988: 12000 - 1989: 12000 - 1990: 12000 - 1991: 12000 - 1992: 12000 - 1993: 12000 - 1994: 12000 - 1995: 12000 - 1996: 12000 - 1997: 12000 - 1998: 12000 - 1999: 12000 - 2000: 12000 - 2001: 12000 - 2002: 12000 - 2003: 12000 - 2004: 12000 - 2005: 12000 - 2006: 12000 - 2007: 12000 - 2008: 12000 - 2009: 12000 - 2010: 12000 - 2011: 12000 - 2012: 12000 - 2013: 12000 - 2014: 12000 - output: - trimestres_valides: 50 - salaire_reference_rsna: 12000 diff --git a/tests/test_tools.py b/tests/test_tools.py new file mode 100644 index 0000000..93e2c79 --- /dev/null +++ b/tests/test_tools.py @@ -0,0 +1,18 @@ +'''Tests of tools.''' + + +import numpy as np + + +from openfisca_tunisia_pension.tools import ( + mean_over_k_consecutive_largest, + ) + + +def test_mean_over_consecutive_largest(): + array = np.array([1] * 5 + [100] * 5 + [1000] * 5).astype(np.float32) + + assert mean_over_k_consecutive_largest(array, 1) == 1000 + assert mean_over_k_consecutive_largest(array, 3) == 1000 + assert mean_over_k_consecutive_largest(array, 5) == 1000 + assert mean_over_k_consecutive_largest(array, 6) == 850