diff --git a/CHANGELOG.md b/CHANGELOG.md
index a5471a3b87b0a32ebc65f4521dc5d3e2db466c75..beb2b2528fda222700ad2049ccb0690d262dbbeb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,33 @@
# Changelog
+## 4.1.0 [!36](https://git.leximpact.dev/leximpact/simulateur-dotations-communes/openfisca-france-dotations-locales/-/merge_requests/36)
+
+* Évolution du système socio-fiscal.
+* Périodes concernées : toutes.
+* Zones impactées :
+ - `/parameters/dotation_communes_nouvelles/amorcage/montant_attribution.yaml`
+ - `/parameters/dotation_communes_nouvelles/amorcage/plafond_age_commune.yaml`
+ - `/parameters/dotation_communes_nouvelles/amorcage/seuil_age_commune.yaml`
+ - `/parameters/dotation_communes_nouvelles/eligibilite/plafond_nombre_habitants.yaml`
+ - `/parameters/dotation_globale_fonctionnement/communes/taux_evolution.yaml`
+ - `/variables/base.py`
+ - `/variables/dotation_communes_nouvelles.py`
+ - `/variables/dotation_globale_fonctionnement.py`
+ - `/variables/dotation_nationale_perequation.py`
+ - `/variables/dotation_solidarite_rurale.py`
+ - `/variables/dotation_solidarite_urbaine.py`
+ - `/variables/population.py`
+ - `/variables/zone_de_montagne.py`
+* Détails :
+ - Pour 2024, ajoute le calcul `dotation_communes_nouvelles` par le calcul de ses deux parts
+ * Ajoute `dotation_communes_nouvelles_eligible_part_amorcage` et `dotation_communes_nouvelles_part_amorcage`
+ * Ajoute `dotation_communes_nouvelles_eligible_part_garantie` et `dotation_communes_nouvelles_part_garantie`
+ - Ajoute `date_creation_commune`, `commune_nouvelle`, `age_commune` et calcule `population_insee_initiale`
+ - Ajoute des éléments de la DGF pour calculer la part garantie de la dotation en faveur des communes nouvelles (DCN)
+ * Initie le calcul de `dotation_globale_fonctionnement_communes`
+ * Ajoute `dotation_nationale_perequation`, `dgf_reference_communes_spontanee` et `dotation_globale_fonctionnement_reference_communes` sans formule
+ - Ajoute `taux_proratisation_population_commune_nouvelle` et `taux_evolution_dgf` afin de couvrir tous les concepts de la note DGCL DCN 2024
+
# 4.0.0 [!37](https://git.leximpact.dev/leximpact/simulateur-dotations-communes/openfisca-france-dotations-locales/-/merge_requests/37)
* Évolution du système socio-fiscal non rétro-compatible.
diff --git a/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/amorcage/montant_attribution.yaml b/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/amorcage/montant_attribution.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..baf0d886b3610f754c60ade738d8d4595cd451b0
--- /dev/null
+++ b/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/amorcage/montant_attribution.yaml
@@ -0,0 +1,19 @@
+description: Montant annuel de l'attribution par habitant de la part amorçage \
+ de la dotation en faveur des communes nouvelles
+documentation: |
+ À partir de 2024 et au cours des trois premières années suivant leur création,
+ les communes nouvelles éligibles à la dotation en faveur des communes nouvelles
+ bénéficient d'une attribution au titre de la part d'amorçage.
+ Le montant de l'attribution revenant à chaque commune est calculé chaque année
+ pour tenir compte de l'évolution de la population.
+
+values:
+ 2024-01-01:
+ value: 15
+
+metadata:
+ reference:
+ 2024-01-01:
+ href: https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/
+ title: "Article L. 2113-22-1 du Code général des collectivités territoriales (CGCT)"
+ unit: currency
diff --git a/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/amorcage/plafond_age_commune.yaml b/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/amorcage/plafond_age_commune.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d54237daadf7ea1e41f7dfdb7f106d5427d52a28
--- /dev/null
+++ b/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/amorcage/plafond_age_commune.yaml
@@ -0,0 +1,13 @@
+description: Nombre maximal d'années de la commune à compter de l'année suivant sa création \
+ pour l'attribution de la part amorçage de la dotation en faveur des communes nouvelles
+
+values:
+ 2024-01-01:
+ value: 3
+
+metadata:
+ reference:
+ 2024-01-01:
+ href: https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/
+ title: "Article L. 2113-22-1 du Code général des collectivités territoriales (CGCT)"
+ # unit: year
diff --git a/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/amorcage/seuil_age_commune.yaml b/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/amorcage/seuil_age_commune.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f4e53fbf0e8499ff770a927ba9722cead851663b
--- /dev/null
+++ b/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/amorcage/seuil_age_commune.yaml
@@ -0,0 +1,14 @@
+description: Nombre minimal d'années de la commune pour l'attribution \
+ de la part amorçage de la dotation en faveur des communes nouvelles
+
+values:
+ 2024-01-01:
+ # 1 an d'âge de commune = année suivant l'année de création de la commune
+ value: 1
+
+metadata:
+ reference:
+ 2024-01-01:
+ href: https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/
+ title: "Article L. 2113-22-1 du Code général des collectivités territoriales (CGCT)"
+ # unit: year
diff --git a/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/eligibilite/plafond_nombre_habitants.yaml b/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/eligibilite/plafond_nombre_habitants.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7604935d30131cf1e09e941ce74f131db8495beb
--- /dev/null
+++ b/openfisca_france_dotations_locales/parameters/dotation_communes_nouvelles/eligibilite/plafond_nombre_habitants.yaml
@@ -0,0 +1,13 @@
+description: Nombre maximal d'habitants de la commune nouvelle l'année suivant sa création \
+ pour l'attribution de la dotation en faveur des communes nouvelles
+
+values:
+ 2024-01-01:
+ value: 150000
+
+metadata:
+ reference:
+ 2024-01-01:
+ href: https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/
+ title: "Article L. 2113-22-1 du Code général des collectivités territoriales (CGCT)"
+ # unit: people
diff --git a/openfisca_france_dotations_locales/parameters/dotation_globale_fonctionnement/communes/taux_evolution.yaml b/openfisca_france_dotations_locales/parameters/dotation_globale_fonctionnement/communes/taux_evolution.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ead4a837e42ed672317a2c3479849e35c4ccb784
--- /dev/null
+++ b/openfisca_france_dotations_locales/parameters/dotation_globale_fonctionnement/communes/taux_evolution.yaml
@@ -0,0 +1,29 @@
+description: Taux d'évolution de la DGF du bloc communal
+
+values:
+ 2021-01-01:
+ value: 1.000200361
+ 2022-01-01:
+ value: 0.999756401
+ 2023-01-01:
+ value: 1.017307774
+ 2024-01-01:
+ value: 1.017137699
+
+metadata:
+ 2021-01-01:
+ href: http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=262
+ title: Note technique relative aux modalités de répartition de la dotation en faveur des \
+ communes nouvelles au titre de I'exercice 2024
+ 2022-01-01:
+ href: http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=262
+ title: Note technique relative aux modalités de répartition de la dotation en faveur des \
+ communes nouvelles au titre de I'exercice 2024
+ 2023-01-01:
+ href: http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=262
+ title: Note technique relative aux modalités de répartition de la dotation en faveur des \
+ communes nouvelles au titre de I'exercice 2024
+ 2024-01-01:
+ href: http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=262
+ title: Note technique relative aux modalités de répartition de la dotation en faveur des \
+ communes nouvelles au titre de I'exercice 2024
diff --git a/openfisca_france_dotations_locales/variables/base.py b/openfisca_france_dotations_locales/variables/base.py
index 3a46014bf39e513125ffb69ebba391e2feefff10..c33c6b2878137916dad797f68a331635d0903893 100644
--- a/openfisca_france_dotations_locales/variables/base.py
+++ b/openfisca_france_dotations_locales/variables/base.py
@@ -1,10 +1,13 @@
-import numpy as np
+from numpy import divide, errstate, where
-
-from openfisca_core.model_api import MONTH, set_input_dispatch_by_period, Variable
+from openfisca_core.model_api import ETERNITY, MONTH, YEAR, date, set_input_dispatch_by_period, Variable
from openfisca_france_dotations_locales.entities import Commune
+# L'année où le temps commence :) Par exemple, utile aux conversions datetime / int.
+ANNEE_DATETIME_EPOCH = 1970 # = time.gmtime(0).tm_year
+
+
class nom(Variable):
value_type = str
entity = Commune
@@ -23,6 +26,50 @@ class code_insee(Variable):
set_input = set_input_dispatch_by_period
+class date_creation_commune(Variable):
+ value_type = date
+ entity = Commune
+ definition_period = ETERNITY
+ default_value = date(1, 1, 1)
+ label = "Date de création de la commune"
+ # Référence à partir de 2024 et de l'apparition de la dotation communes nouvelles : Article R.2113-24 CGCT
+ reference = "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000049484404/2024-04-29/"
+
+
+class commune_nouvelle(Variable):
+ value_type = bool
+ entity = Commune
+ definition_period = YEAR
+ label = "Est une commune nouvellement créée"
+ # Référence à partir de 2024 et de l'apparition de la dotation communes nouvelles : Article R.2113-24 CGCT
+ reference = "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000049484404/2024-04-29/"
+
+ def formula(commune, period):
+ date_creation_commune = commune("date_creation_commune", period)
+
+ annee_precedente = period.last_year.start.year
+ annee_creation_commune = date_creation_commune.astype('datetime64[Y]').astype(int) + ANNEE_DATETIME_EPOCH
+
+ return annee_creation_commune == annee_precedente
+
+
+class age_commune(Variable):
+ value_type = int
+ entity = Commune
+ definition_period = YEAR
+ default_value = -9999
+ label = "Âge en années de la commune"
+ documentation = '''
+ Âge calculé relativement au premier jour de l'an.
+ Le jour et le mois de création de la commune sont ignorés.
+ '''
+
+ def formula(commune, period):
+ date_creation_commune = commune("date_creation_commune", period)
+ annee_creation_commune = date_creation_commune.astype('datetime64[Y]').astype(int) + ANNEE_DATETIME_EPOCH
+ return period.start.year - annee_creation_commune
+
+
def safe_divide(a, b, value_if_error=0):
- with np.errstate(divide='ignore', invalid='ignore'):
- return np.where(b != 0, np.divide(a, b), value_if_error)
+ with errstate(divide='ignore', invalid='ignore'):
+ return where(b != 0, divide(a, b), value_if_error)
diff --git a/openfisca_france_dotations_locales/variables/dotation_communes_nouvelles.py b/openfisca_france_dotations_locales/variables/dotation_communes_nouvelles.py
new file mode 100644
index 0000000000000000000000000000000000000000..d64922ad3c241f87bb9076d8322e65d907c1df22
--- /dev/null
+++ b/openfisca_france_dotations_locales/variables/dotation_communes_nouvelles.py
@@ -0,0 +1,126 @@
+from openfisca_core.model_api import Variable, max_, YEAR
+from openfisca_france_dotations_locales.entities import Commune
+
+
+class dotation_communes_nouvelles(Variable):
+ value_type = float
+ entity = Commune
+ definition_period = YEAR
+ label = "Montant total de la dotation en faveur des communes nouvelles"
+ reference = [
+ # Article 134 de la loi n° 2023-1322 du 29 décembre 2023 de finances pour 2024
+ "https://www.legifrance.gouv.fr/loda/article_lc/LEGIARTI000048769531/2023-12-31/",
+ # Article L. 2113-22-1 du Code général des collectivités territoriales (CGCT)
+ "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/",
+ # Note DGCL 2024
+ "http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=262"
+ ]
+
+ documentation = '''
+ La dotation en faveur des communes nouvelles est instituée par la LF pour 2024.
+ Elle vient remplacer le pacte de stabilité pour les communes nouvelles
+ dont le montant était financé sur l'enveloppe allouée à la dotation globale de fonctionnement (DGF).
+ '''
+
+ def formula_2024(commune, period):
+ dotation_communes_nouvelles_part_amorcage = commune('dotation_communes_nouvelles_part_amorcage', period)
+ dotation_communes_nouvelles_part_garantie = commune('dotation_communes_nouvelles_part_garantie', period)
+ return dotation_communes_nouvelles_part_amorcage + dotation_communes_nouvelles_part_garantie
+
+
+class dotation_communes_nouvelles_eligible_part_amorcage(Variable):
+ value_type = bool
+ entity = Commune
+ definition_period = YEAR
+ label = "Éligibilité à la part amorçage de la dotation en faveur des communes nouvelles"
+ reference = "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/"
+
+ def formula_2024(commune, period, parameters):
+ # condition communes dans les _3_ premières années suivant leurs créations
+ age_commune = commune("age_commune", period)
+ age_eligible = (
+ (age_commune >= parameters(period).dotation_communes_nouvelles.amorcage.seuil_age_commune)
+ * (age_commune <= parameters(period).dotation_communes_nouvelles.amorcage.plafond_age_commune)
+ )
+
+ # condition population insee initiale <= _150000_ habitants
+ # où la population insee initiale est la population insee l'année suivant la création de chaque commune
+ population_insee_initiale = commune("population_insee_initiale", period)
+ population_insee_eligible = (
+ (population_insee_initiale >= 0) # plus précisément, différente de NB_HABITANT_NEUTRALISE = -9999
+ * (population_insee_initiale <= parameters(period).dotation_communes_nouvelles.eligibilite.plafond_nombre_habitants)
+ )
+
+ return age_eligible * population_insee_eligible
+
+
+class dotation_communes_nouvelles_part_amorcage(Variable):
+ value_type = float
+ entity = Commune
+ definition_period = YEAR
+ label = "Montant total de la part amorçage de la dotation en faveur des communes nouvelles"
+ # Article L. 2113-22-1 du Code général des collectivités territoriales (CGCT)
+ reference = "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/"
+ documentation = '''
+ La part amorçage est destinée à aides les communes nouvelles à faire face,
+ dans les premières années suivant leur création, aux coûts inhérents à la fusion.
+ En 2024, si l'éligibilité est évaluée au regard de la population INSEE,
+ le montant considère la population DGF telle que définie au 2ème alinéa de l’article L. 2334-2 du CGCT.
+ '''
+
+ def formula_2024(commune, period, parameters):
+ dotation_communes_nouvelles_eligible_part_amorcage = commune("dotation_communes_nouvelles_eligible_part_amorcage", period)
+
+ population_dgf = commune("population_dgf", period)
+ montant_attribution_par_habitant = parameters(period).dotation_communes_nouvelles.amorcage.montant_attribution
+ montant_part_amorcage_commune = montant_attribution_par_habitant * population_dgf
+
+ return dotation_communes_nouvelles_eligible_part_amorcage * montant_part_amorcage_commune
+
+
+class dotation_communes_nouvelles_eligible_part_garantie(Variable):
+ value_type = float
+ entity = Commune
+ definition_period = YEAR
+ label = "Éligibilité à la part garantie de la dotation en faveur des communes nouvelles"
+ # Article L. 2113-22-1 du Code général des collectivités territoriales (CGCT)
+ reference = "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/"
+
+ def formula_2024(commune, period, parameters):
+ # condition population insee initiale <= _150000_ habitants
+ # où la population insee initiale est la population insee l'année suivant la création de chaque commune
+ population_insee_initiale = commune("population_insee_initiale", period)
+ population_insee_eligible = (
+ (population_insee_initiale >= 0) # plus précisément, différente de NB_HABITANT_NEUTRALISE = -9999
+ * (population_insee_initiale <= parameters(period).dotation_communes_nouvelles.eligibilite.plafond_nombre_habitants)
+ )
+
+ return population_insee_eligible
+
+
+class dotation_communes_nouvelles_part_garantie(Variable):
+ value_type = float
+ entity = Commune
+ definition_period = YEAR
+ label = "Montant total de la part garantie de la dotation en faveur des communes nouvelles"
+ # Article L. 2113-22-1 du Code général des collectivités territoriales (CGCT)
+ reference = "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/"
+ documentation = '''
+ La part garantie compense de manière pérenne toute perte de DGF
+ de la commune nouvelle suite à sa fusion.
+ '''
+
+ def formula_2024(commune, period):
+ dotation_communes_nouvelles_eligible_part_garantie = commune("dotation_communes_nouvelles_eligible_part_garantie", period)
+
+ # Part de garantie 2024 = DGF de référence finale 2024 - DGF 2024
+ # si la différence est positive.
+ dotation_globale_fonctionnement_reference_communes = commune("dotation_globale_fonctionnement_reference_communes", period)
+ dotation_globale_fonctionnement_communes = commune("dotation_globale_fonctionnement_communes", period)
+ return (
+ dotation_communes_nouvelles_eligible_part_garantie
+ * max_(
+ 0,
+ (dotation_globale_fonctionnement_reference_communes - dotation_globale_fonctionnement_communes)
+ )
+ )
diff --git a/openfisca_france_dotations_locales/variables/dotation_globale_fonctionnement.py b/openfisca_france_dotations_locales/variables/dotation_globale_fonctionnement.py
new file mode 100644
index 0000000000000000000000000000000000000000..7f0d7953cbd818ba8ff8543cab883f2dc58ae788
--- /dev/null
+++ b/openfisca_france_dotations_locales/variables/dotation_globale_fonctionnement.py
@@ -0,0 +1,128 @@
+from openfisca_core.model_api import Variable, YEAR
+from openfisca_france_dotations_locales.entities import Commune
+
+
+class dotation_globale_fonctionnement_communes(Variable):
+ value_type = float
+ entity = Commune
+ definition_period = YEAR
+ label = "Montant total de la dotation globale de fonctionnement des communes (DGF des communes)"
+ # Article L2334-1 du Code général des collectivités locales
+ reference = "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850193/2023-12-31/"
+
+ def formula(commune, period):
+ # On ne s'intéresse ici qu'aux portions communales. Néanmoins, pour la vue d'ensemble :
+ # DGF des communes et EPCI
+ # = dotation forfaitaire
+ # + dotation forfaitaire des groupements touristiques (TODO variable)
+ # + dotation d'aménagement
+ dotation_forfaitaire = commune("dotation_forfaitaire", period)
+
+ # dotation d'aménagement
+ # = dotations de péréquation des communes
+ # + DGF des EPCI (TODO variable)
+
+ # dotations de péréquation des communes
+ # = DSU
+ # + DSR
+ # + DNP (TODO formule)
+ dotation_solidarite_rurale = commune("dotation_solidarite_rurale", period)
+ dsu_montant = commune("dsu_montant", period)
+ dotation_nationale_perequation = commune("dotation_nationale_perequation", period)
+ dotations_perequation_communes = dotation_solidarite_rurale + dsu_montant + dotation_nationale_perequation
+
+ return dotation_forfaitaire + dotations_perequation_communes
+
+
+class taux_proratisation_population_commune_nouvelle(Variable):
+ value_type = float
+ entity = Commune
+ definition_period = YEAR
+ label = "Taux de proratisation par population applicable à une commune nouvelle"
+ reference = "http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=262"
+ documentation = '''
+ Si la commune nouvelle est défusionnée, la DGF de référence de la commune nouvelle
+ est proratisée en fonction de sa population telle qu'indiquée dans l‘arrêté préfectoral
+ établissant la modification des limites territoriales de la commune.
+
+ Taux de proratisation applicable à la CN :
+ = population de la nouvelle commune conservant le statut de commune nouvelle
+ / population de la commune nouvelle avant la modification de ses limites territoriales
+ '''
+
+
+class taux_evolution_dgf(Variable):
+ value_type = float
+ entity = Commune # et groupements de communes ?!
+ definition_period = YEAR
+ label = "Taux d'évolution de la DGF"
+ reference = "http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=262"
+ documentation = '''
+ La DGF de référence finale de la commune nouvelle est calculée en multipliant
+ chaque année la DGF de référence spontanée par le taux d’évolution de la DGF des communes
+ et des groupements mentionnée au premier alinéa de l'article L. 2334-1 du CGCT.
+
+ Taux d'évolution N =
+ DGF des communes et des groupements N
+ / DGF des communes et des groupements N — 1
+
+ Où DGF des communes et des groupements = somme des montants attribués au titre
+ de la DGF des communes et des groupements mentionnée au premier alinéa
+ de l'article L. 2334-1 CGCT.
+ '''
+
+
+class dgf_reference_communes_spontanee(Variable):
+ value_type = float
+ entity = Commune
+ definition_period = YEAR
+ label = "Montant spontané de la dotation globale de fonctionnement de référence des communes (DGF de référence des communes)"
+ # Article L2113-22-1, III du Code général des collectivités territoriales
+ # dans le calcul de la part garantie de la dotation en faveur des communes nouvelles
+ reference = [
+ "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/",
+ "http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=262"
+ ]
+ documentation = '''
+ Au regard de la part garantie de la dotation en faveur des communes nouvelles débutant en 2024,
+ la DGF de référence varie en fonction de la date de création de la commune nouvelle.
+
+ Pour les communes nouvelles créées avant le 2 janvier 2023, c'est le montant de la DGF
+ perçu par la commune nouvelle lors de sa dernière année d‘éligibilité au pacte de stabilité :
+ * DGF 2020 pour les communes nouvelles créées entre le 2 janvier 2017 et le 1er janvier 2018.
+ * DGF 2021 pour les communes nouvelles créées entre le 2 janvier 2018 et le 1er janvier 2019.
+ * DGF 2023 pour les autres communes.
+
+ Pour les communes nouvelles créées à compter du 2 janvier 2023,
+ c'est la somme des DGF perçues par les communes l’année précédant la fusion.
+
+ Si la commune nouvelle est une commune nouvelle rurale au sens de l’article L. 2334-22-2 du CGCT,
+ alors il sera soustrait à sa DGF de référence les éventuelles sommes perçues en 2023
+ au titre d'une garantie de sortie de la dotation de solidarité rurale.
+
+ Si la commune nouvelle est défusionnée, la DGF de référence de la commune nouvelle
+ est proratisée en fonction de sa population telle qu'indiquée dans l‘arrêté préfectoral
+ établissant la modification des limites territoriales de la commune.
+ '''
+ # formula ? :
+ # https://git.leximpact.dev/leximpact/simulateur-dotations-communes/openfisca-france-dotations-locales/-/issues/16
+
+
+class dotation_globale_fonctionnement_reference_communes(Variable):
+ value_type = float
+ entity = Commune
+ definition_period = YEAR
+ label = "Montant final de la dotation globale de fonctionnement de référence des communes (DGF de référence des communes)"
+ # Article L2113-22-1, III du Code général des collectivités territoriales
+ # dans le calcul de la part garantie de la dotation en faveur des communes nouvelles
+ reference = [
+ "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048850000/2023-12-31/",
+ "http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=262"
+ ]
+ documentation = '''
+ La DGF de référence finale de la commune nouvelle est calculée en multipliant
+ chaque année la DGF de référence spontanée par le taux d’évolution de la DGF
+ des communes et des groupements mentionnée au premier alinéa de l'article L. 2334-1 du CGCT.
+ '''
+ # formula ? :
+ # https://git.leximpact.dev/leximpact/simulateur-dotations-communes/openfisca-france-dotations-locales/-/issues/17
diff --git a/openfisca_france_dotations_locales/variables/dotation_nationale_perequation.py b/openfisca_france_dotations_locales/variables/dotation_nationale_perequation.py
new file mode 100644
index 0000000000000000000000000000000000000000..611c5f6dd041df1df3cfa8d1de262cb2a58ef0ad
--- /dev/null
+++ b/openfisca_france_dotations_locales/variables/dotation_nationale_perequation.py
@@ -0,0 +1,11 @@
+from openfisca_core.model_api import Variable, YEAR
+from openfisca_france_dotations_locales.entities import Commune
+
+
+class dotation_nationale_perequation(Variable):
+ value_type = float
+ entity = Commune
+ definition_period = YEAR
+ label = "Dotation nationale de péréquation (DNP)"
+ # Article L2334-14-1 du Code général des collectivités locales
+ reference = "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000048849540/2023-12-31/"
diff --git a/openfisca_france_dotations_locales/variables/dotation_solidarite_rurale.py b/openfisca_france_dotations_locales/variables/dotation_solidarite_rurale.py
index 36c2a567972594e95c9bba01854848f79ab4d0b1..ef883824fcee628e1d52a4a1058658f5ab712218 100644
--- a/openfisca_france_dotations_locales/variables/dotation_solidarite_rurale.py
+++ b/openfisca_france_dotations_locales/variables/dotation_solidarite_rurale.py
@@ -1,5 +1,5 @@
-from openfisca_core.model_api import *
-from openfisca_france_dotations_locales.entities import *
+from openfisca_core.model_api import Variable, YEAR
+from openfisca_france_dotations_locales.entities import Commune
class dotation_solidarite_rurale(Variable):
@@ -7,7 +7,11 @@ class dotation_solidarite_rurale(Variable):
entity = Commune
definition_period = YEAR
label = "Dotation de solidarité rurale (DSR)"
- reference = "http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=94"
+ reference = [
+ # Articles L2334-20 à L2334-23 du Code général des collectivités territoriales
+ "https://www.legifrance.gouv.fr/codes/section_lc/LEGITEXT000006070633/LEGISCTA000006197650/2020-01-01/",
+ "http://www.dotations-dgcl.interieur.gouv.fr/consultation/documentAffichage.php?id=94"
+ ]
def formula(commune, period, parameters):
dsr_fraction_cible = commune("dsr_fraction_cible", period)
diff --git a/openfisca_france_dotations_locales/variables/dotation_solidarite_urbaine.py b/openfisca_france_dotations_locales/variables/dotation_solidarite_urbaine.py
index beffb3d68d1cd9010713120a357e43e0841f1406..05de1605cb266d4f1a02d9933b879f8a9cf66d4d 100644
--- a/openfisca_france_dotations_locales/variables/dotation_solidarite_urbaine.py
+++ b/openfisca_france_dotations_locales/variables/dotation_solidarite_urbaine.py
@@ -1,5 +1,5 @@
-from openfisca_core.model_api import *
-from openfisca_france_dotations_locales.entities import *
+from openfisca_core.model_api import Variable, min_, max_, YEAR
+from openfisca_france_dotations_locales.entities import Commune, Etat
import numpy as np
from openfisca_france_dotations_locales.variables.base import safe_divide
@@ -464,7 +464,8 @@ class dsu_montant(Variable):
definition_period = YEAR
label = "Montant total versé au titre de la DSU:\
Montant total versé au titre de la DSU : garanties + montant spontané + augmentation"
- reference = "https://www.legifrance.gouv.fr/affichCode.do?idSectionTA=LEGISCTA000006197674&cidTexte=LEGITEXT000006070633"
+ # Articles L2334-15 à L2334-18-4 du Code général des collectivités territoriales
+ reference = "https://www.legifrance.gouv.fr/codes/id/LEGISCTA000006197674/2020-01-01/"
def formula(commune, period, parameters):
dsu_montant_eligible = commune('dsu_montant_eligible', period)
diff --git a/openfisca_france_dotations_locales/variables/population.py b/openfisca_france_dotations_locales/variables/population.py
index 0fa77d35358efefde0767f3d8b99d837c3587863..fc9cf8c2cd28586d88052c5284c38a930e3dcb66 100644
--- a/openfisca_france_dotations_locales/variables/population.py
+++ b/openfisca_france_dotations_locales/variables/population.py
@@ -1,5 +1,8 @@
-from openfisca_core.model_api import *
+from numpy import full, where, max as numpy_max, unique
+
+from openfisca_core.model_api import Variable, min_, YEAR
from openfisca_france_dotations_locales.entities import *
+from openfisca_france_dotations_locales.variables.base import ANNEE_DATETIME_EPOCH
class strate_demographique(Variable):
@@ -37,7 +40,63 @@ class strate_demographique(Variable):
class population_insee(Variable):
value_type = int
entity = Commune
+ label = "Population de la commune au sens de l'INSEE"
definition_period = YEAR
+ default_value = -9999
+ reference = "https://www.insee.fr/fr/metadonnees/definition/c1751"
+
+
+class population_insee_initiale(Variable):
+ value_type = int
+ entity = Commune
+ label = "Population au sens de l'INSEE à la création de la commune"
+ definition_period = YEAR
+ default_value = -9999
+ # Article R2113-24 du Code général des collectivités locales
+ reference = "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000049484404/2024-04-29/"
+ documentation = '''
+ En 2024, la population initiale est la population INSEE l'année suivant la création de la commune.
+ C'est par exemple la population de référence pour évaluer l'éligibilité à la part amorçage
+ de la dotation en faveur des communes nouvelles.
+ '''
+
+ def formula(commune, period):
+ NB_HABITANT_NEUTRALISE = -9999
+ date_creation_commune = commune("date_creation_commune", period)
+ annee_suivante_creation_commune = date_creation_commune.astype('datetime64[Y]').astype(int) + ANNEE_DATETIME_EPOCH + 1
+
+ # la population est accessible année par année
+ # les communes ont des dates de création très variables
+ # on identifie donc les dates de création des communes (de toute la France) sans doublon
+ # pour récupérer la population connue pour chaque commune l'année suivant sa création
+ bilan_annees_suivant_creation_communes = unique(annee_suivante_creation_commune)
+
+ # on crée un array/matrice avec :
+ # - nb de lignes : nb d'années de création (sans doublon)
+ # - nb de colonnes : nb de communes
+ # - valeur par défaut : NB_HABITANT_NEUTRALISE
+ nombre_communes = date_creation_commune.size
+ matrice_population_insee_initiale = full((bilan_annees_suivant_creation_communes.size, nombre_communes), NB_HABITANT_NEUTRALISE)
+
+ # boucle : pour chaque année de création, on recherche :
+ # - la population de chaque commune (population_insee_annee)
+ # - si l'année correspond à la date de création d'une ou plusieurs communes (filtre_annee_initiale)
+ # on remplit la matrice population_insee_initiale grâce à l'information obtenue avec ces deux arrays
+ for index, annee in enumerate(bilan_annees_suivant_creation_communes):
+ # pour une 'annee' donnée = une année suivant la création d'une commune ou plus
+ population_insee_annee = commune("population_insee", str(annee))
+
+ # on constitue une colonne où pour chaque commune
+ # si 'annee' est l'année suivant sa création, on a la population insee officielle
+ filtre_annee_initiale = annee_suivante_creation_commune == annee
+
+ # on ajoute les informations à la matrice avec un np.where :
+ # - si l'année correspond à l'année initiale, on ajoute la population de l'année initiale
+ # - sinon, valeur par défaut -9999
+ matrice_population_insee_initiale[index] = where(filtre_annee_initiale, population_insee_annee, NB_HABITANT_NEUTRALISE)
+
+ population_insee_initiale = numpy_max(matrice_population_insee_initiale, axis=0)
+ return population_insee_initiale
class population_dgf(Variable):
diff --git a/openfisca_france_dotations_locales/variables/zone_de_montagne.py b/openfisca_france_dotations_locales/variables/zone_de_montagne.py
index cc9306b5098f885c59937299a5a8a718ac73d332..a48b67b1aa7f33a5a205d9ebdba4bba3626c3e17 100644
--- a/openfisca_france_dotations_locales/variables/zone_de_montagne.py
+++ b/openfisca_france_dotations_locales/variables/zone_de_montagne.py
@@ -1,11 +1,10 @@
-from openfisca_core.model_api import *
-from openfisca_france_dotations_locales.entities import *
+from openfisca_core.model_api import Variable, YEAR
+from openfisca_france_dotations_locales.entities import Commune
class zone_de_montagne(Variable):
value_type = bool
entity = Commune
definition_period = YEAR
- label = "Commune de montagne:\
-Commune située en zone de montagne"
+ label = "Commune de montagne: Commune située en zone de montagne"
reference = "https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000036433094&cidTexte=LEGITEXT000006070633"
diff --git a/setup.py b/setup.py
index 2b203096a5b2d0c302a5845a20e5f3543164a6e3..8d2af4a8a8bf996d3544251b0280649ce7dd18dd 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
setup(
name = "OpenFisca-France-Dotations-Locales",
- version = "4.0.0",
+ version = "4.1.0",
author = "LexImpact Team",
author_email = "leximpact@an.fr",
classifiers=[
diff --git a/tests/population/population_insee.yaml b/tests/population/population_insee.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5b362620f4694bcdbe506665f922aac989c033ab
--- /dev/null
+++ b/tests/population/population_insee.yaml
@@ -0,0 +1,11 @@
+- name: Récupération de la population INSEE initiale
+ period: 2024
+ input:
+ date_creation_commune: ['1999-01-01', '2021-07-01', '2022-01-01']
+ population_insee:
+ # 2000 = 1999+1 : populations INSEE inconnues
+ 2021: [49, 89, 219] # année même de la création ; doit être ignoré
+ 2022: [50, 90, 220]
+ 2023: [50, 100, 200] # la population a baissé pour la 3ème commune
+ output:
+ population_insee_initiale: [-9999, 90, 200]
diff --git a/tests/test_base_communes_nouvelles.yaml b/tests/test_base_communes_nouvelles.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5e696a551c316ad4256d5ab1be1ead5fe7da81bf
--- /dev/null
+++ b/tests/test_base_communes_nouvelles.yaml
@@ -0,0 +1,7 @@
+- name: Est commune nouvelle créée l'année dernière
+ period: 2024
+ input:
+ date_creation_commune: ["2024-01-01", "2023-01-01", "2022-01-01"]
+ output:
+ commune_nouvelle: [False, True, False]
+ age_commune: [0, 1, 2]
diff --git a/tests/test_dotation_communes_nouvelles.yaml b/tests/test_dotation_communes_nouvelles.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..37f820f8b8362449f988601bdeb56919c7ea1bfd
--- /dev/null
+++ b/tests/test_dotation_communes_nouvelles.yaml
@@ -0,0 +1,40 @@
+- name: Éligibilité par l'âge à la part amorçage de la dotation communes nouvelles (DCN)
+ period: 2024
+ input:
+ date_creation_commune: ["2024-01-01", "2023-01-01", "2022-01-01", "2021-01-01", "2020-01-01"]
+ population_insee: # toutes éligibles car < _150000_ habitants
+ 2020: [24, 23, 22, 21, 20]
+ 2021: [24, 23, 22, 21, 20]
+ 2022: [24, 23, 22, 21, 20]
+ 2023: [24, 23, 22, 21, 20]
+ 2024: [24, 23, 22, 21, 20]
+ 2025: [-9999, -9999, -9999, -9999, -9999]
+ output:
+ commune_nouvelle: [False, True, False, False, False]
+ age_commune: [0, 1, 2, 3, 4]
+ dotation_communes_nouvelles_eligible_part_amorcage: [False, True, True, True, False]
+
+- name: Éligibilité par la population suivant l'année de création à la part amorçage de la DCN
+ period: 2024
+ input:
+ date_creation_commune: ["2024-01-01", "2023-01-01", "2022-01-01", "2021-01-01", "2021-06-01", "2020-01-01"]
+ population_insee:
+ # ! limitation : pour une simulation, on a le même nombre de communes pour toutes les années
+ 2020: [24, 23, 22, 21, -9999, 19] # pour la dernière commune, 2020 est l'année de sa création même ; population à ignorer au profit de l'année suivante
+ 2021: [24, 23, 22, 21, -9999, 20] # pour l'avant dernière commune, l'année de sa création on ne connaît pas la population parce que la commune s'appelait autrement
+ 2022: [24, 23, 22, 21, 150_001, 20] # l'avant dernière commune sort de l'éligibilité l'année suivant sa création
+ 2023: [24, 23, 22, 21, 150_000, 20]
+ 2024: [24, 23, 22, 21, 2100, 20]
+ 2025: [-9999, -9999, -9999, -9999, -9999, -9999]
+ output:
+ commune_nouvelle: [False, True, False, False, False, False]
+ age_commune: [0, 1, 2, 3, 3, 4]
+ dotation_communes_nouvelles_eligible_part_amorcage: [False, True, True, True, False, False]
+
+- name: Montant de la part amorçage de la dotation communes nouvelles
+ period: 2024
+ input:
+ dotation_communes_nouvelles_eligible_part_amorcage: [True, True, True, False]
+ population_dgf: [0, 10, 100, 1000]
+ output:
+ dotation_communes_nouvelles_part_amorcage: [0, 150, 1500, 0]