Skip to content

Commit

Permalink
Corrige l'exoneration de la CSG et CRDS pour les non residents (#2104)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nodraak committed May 23, 2023
1 parent 66af4a6 commit 2eee0cf
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 3 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## 147.1.1 [#2106](https://github.com/openfisca/openfisca-france/pull/2106)

* Évolution du système socio-fiscal
* Périodes concernées : après 2019
* Zones impactées :
* `openfisca_france/model/caracteristiques_socio_demographiques/demographie.py`
* `openfisca_france/model/prelevements_obligatoires/prelevements_sociaux/contributions_sociales/`
* `openfisca_france/model/prestations/minima_sociaux/rsa.py`
* `tests/`
* Détails :
* Après 2019, les non résidents sont exonérés de la CSG et CRDS.
* Les non résidents ne sont pas éligibles au RSA.
* Création de la variable `resident_eee_hors_france` pour gérer ce cas.

## 147.0.1 [#2102](https://github.com/openfisca/openfisca-france/pull/2102)

* Amélioration technique.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,11 +364,20 @@ def formula(individu, period, parameters):
return sum([nationalite == str.encode(etat_membre) for etat_membre in parameters(period).geopolitique.eee]) # TOOPTIMIZE: string encoding into bytes array should be done at load time


class resident_eee_hors_france(Variable):
value_type = bool
default_value = False
entity = Individu
label = "Individu résident dans un pays membre de l'Espace Économique Européen (EEE), hors France. Voir aussi 'resident_ue'."
definition_period = YEAR
set_input = set_input_dispatch_by_period


class resident_ue(Variable):
value_type = bool
default_value = True
entity = Individu
label = "Individu résidant dans pays membre de l'Union européenne (UE)."
label = "Individu résidant dans pays membre de l'Union européenne (UE). Voir aussi 'resident_eee_hors_france'."
definition_period = MONTH
set_input = set_input_dispatch_by_period

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging

from openfisca_france.model.base import *
from openfisca_france.model.prelevements_obligatoires.prelevements_sociaux.contributions_sociales.base import montant_csg_crds
from openfisca_france.model.prelevements_obligatoires.prelevements_sociaux.contributions_sociales.base import montant_csg_crds, est_exonere_csg_crds


log = logging.getLogger(__name__)
Expand Down Expand Up @@ -106,6 +106,9 @@ class csg_deductible_salaire(Variable):
set_input = set_input_divide_by_period

def formula(individu, period, parameters):
if est_exonere_csg_crds(individu, period.this_year):
return 0

assiette_csg_abattue = individu('assiette_csg_abattue', period)
assiette_csg_non_abattue = individu('assiette_csg_non_abattue', period)
plafond_securite_sociale = individu('plafond_securite_sociale', period)
Expand All @@ -129,6 +132,9 @@ class csg_imposable_salaire(Variable):
set_input = set_input_divide_by_period

def formula(individu, period, parameters):
if est_exonere_csg_crds(individu, period.this_year):
return 0

assiette_csg_abattue = individu('assiette_csg_abattue', period)
assiette_csg_non_abattue = individu('assiette_csg_non_abattue', period)
plafond_securite_sociale = individu('plafond_securite_sociale', period)
Expand All @@ -153,6 +159,9 @@ class crds_salaire(Variable):
set_input = set_input_divide_by_period

def formula(individu, period, parameters):
if est_exonere_csg_crds(individu, period.this_year):
return 0

assiette_csg_abattue = individu('assiette_csg_abattue', period)
assiette_csg_non_abattue = individu('assiette_csg_non_abattue', period)
plafond_securite_sociale = individu('plafond_securite_sociale', period)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from openfisca_core import periods


def montant_csg_crds(base_avec_abattement = None, base_sans_abattement = None, indicatrice_taux_plein = None,
Expand All @@ -18,3 +19,18 @@ def montant_csg_crds(base_avec_abattement = None, base_sans_abattement = None, i
return -law_node.taux * base
else:
return - (law_node.taux_plein * indicatrice_taux_plein + law_node.taux_reduit * indicatrice_taux_reduit) * base


def est_exonere_csg_crds(individu_or_members, period):
'''
Depuis le 1er janvier 2019, les personnes affiliées à un régime obligatoire
de sécurité sociale autre que français au sein d'un pays de l'EEE (Union
européenne, Islande, Norvège, Liechtenstein) ou de la Suisse sont exonérées
de CSG et de CRDS.
Ces revenus demeurent soumis à un prélèvement de solidarité au taux de 7,5%.
Reference: https://www.impots.gouv.fr/international-particulier/questions/je-suis-non-resident-suis-je-redevable-des-contributions
'''
return (
(periods.period('2019-01-01').start <= period.start)
and individu_or_members('resident_eee_hors_france', period)
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
from openfisca_france.model.base import *
from openfisca_france.model.prelevements_obligatoires.prelevements_sociaux.contributions_sociales.base import est_exonere_csg_crds

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -330,6 +331,9 @@ def formula(foyer_fiscal, period, parameters):
Attention : Pour les années avant 2013, cette formule n'est pas entièrement correcte car le taux de la CSG n'était pas unique (distinction revenus du patrimoine et revenus de placement)
et il y a aussi un problème pour les années postérieures à 2017/2018
'''
if est_exonere_csg_crds(foyer_fiscal.members, period):
return 0

assiette_csg_revenus_capital = foyer_fiscal('assiette_csg_revenus_capital', period)
csg = parameters(period).taxation_capital.prelevements_sociaux.csg

Expand All @@ -346,6 +350,9 @@ class crds_revenus_capital(Variable):
definition_period = YEAR

def formula(foyer_fiscal, period, parameters):
if est_exonere_csg_crds(foyer_fiscal.members, period):
return 0

assiette_csg_revenus_capital = foyer_fiscal('assiette_csg_revenus_capital', period)
P = parameters(period).taxation_capital.prelevements_sociaux

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
from openfisca_france.model.base import *
from openfisca_france.model.prelevements_obligatoires.prelevements_sociaux.contributions_sociales.base import est_exonere_csg_crds

log = logging.getLogger(__name__)

Expand All @@ -11,6 +12,9 @@ class csg(Variable):
definition_period = YEAR

def formula(individu, period):
if est_exonere_csg_crds(individu, period):
return 0

csg_imposable_salaire = individu('csg_imposable_salaire', period, options = [ADD])
csg_deductible_salaire = individu('csg_deductible_salaire', period, options = [ADD])
csg_imposable_chomage = individu('csg_imposable_chomage', period, options = [ADD])
Expand Down Expand Up @@ -49,6 +53,9 @@ class crds(Variable):
definition_period = YEAR

def formula(individu, period):
if est_exonere_csg_crds(individu, period):
return 0

# CRDS sur revenus individuels
crds_salaire = individu('crds_salaire', period, options = [ADD])
crds_retraite = individu('crds_retraite', period, options = [ADD])
Expand All @@ -75,6 +82,9 @@ class crds_hors_prestations(Variable):
definition_period = YEAR

def formula(individu, period):
if est_exonere_csg_crds(individu, period):
return 0

# CRDS sur revenus individuels
crds_salaire = individu('crds_salaire', period, options = [ADD])
crds_retraite = individu('crds_retraite', period, options = [ADD])
Expand Down
4 changes: 4 additions & 0 deletions openfisca_france/model/prestations/minima_sociaux/rsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,10 @@ class rsa_eligibilite(Variable):
set_input = set_input_dispatch_by_period

def formula(famille, period, parameters):
# les non residents ne sont pas eligibles au RSA
if famille.members('resident_eee_hors_france', period.this_year):
return 0

rsa_nb_enfants = famille('rsa_nb_enfants', period)
rsa_eligibilite_tns = famille('rsa_eligibilite_tns', period)
condition_nationalite_i = famille.members('rsa_condition_nationalite', period)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

setup(
name = 'OpenFisca-France',
version = '147.0.1',
version = '147.1.1',
author = 'OpenFisca Team',
author_email = '[email protected]',
classifiers = [
Expand Down
57 changes: 57 additions & 0 deletions tests/capital/non_residents_exoneration_csg_crds.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Before 2019, everybody pay

- name: pre_2019_residents_non_exoneres
description: Avant 2019, les résidents ne sont pas exonérés
period: 2018
absolute_error_margin: 1
input:
f4ba: 1000
# resident_eee_hors_france: False
output:
csg_revenus_capital: -99
crds_revenus_capital: -5
prelevements_sociaux_revenus_capital_hors_csg_crds: -68
revenus_nets_du_capital: 828

- name: pre_2019_non_residents_non_exoneres
description: Avant 2019, les non résidents ne sont pas exonérés
period: 2018
absolute_error_margin: 1
input:
f4ba: 1000
resident_eee_hors_france: True
output:
csg_revenus_capital: -99
crds_revenus_capital: -5
prelevements_sociaux_revenus_capital_hors_csg_crds: -68
revenus_nets_du_capital: 828

# After 2019, only residents in France pay

- name: post_2019_residents_non_exoneres
description: A partir de 2019, les résidents ne sont pas exonérés
period: 2019
absolute_error_margin: 1
input:
f4ba: 1000
# resident_eee_hors_france: False
output:
csg_revenus_capital: -92
crds_revenus_capital: -5
prelevements_sociaux_revenus_capital_hors_csg_crds: -75
revenus_nets_du_capital: 828
revenu_disponible: 6837 # due to RSA

- name: post_2019_non_residents_exoneres
description: A partir de 2019, les non résidents sont exonérés
period: 2019
absolute_error_margin: 1
input:
f4ba: 1000
resident_eee_hors_france: True
output:
csg_revenus_capital: 0
crds_revenus_capital: 0
prelevements_sociaux_revenus_capital_hors_csg_crds: -75
revenus_nets_du_capital: 925
revenu_disponible: 925

0 comments on commit 2eee0cf

Please sign in to comment.