Skip to content
Snippets Groups Projects
Select Git revision
  • 6f4d70c3d84f8d110019ac4a5aa52b8630027bdb
  • master default protected
  • doc-script-gen-off-tests
  • 366-signe-a-cote-du-droit-en-vigueur-sur-l-ui-pour-indiquer-que-la-reforme-a-eu-lieu-mais-qu-elle-n
  • revalo_retraites
  • 381-pb-affichage-labels-des-parametres-sur-plus-de-3-lignes
  • ajoute-duplicate-aide-logement
  • poc_castype_ia
  • parametres-editables-budget
  • ui-parametres
  • 355-les-dispositifs-prestations-sociales-du-graphique-se-cachent-montrent-en-meme-temps-2
  • 358-les-variables-dont-le-montant-est-nul-apparaissent-en-bleu-et-non-cliquables
  • 356-ajuster-la-largeur-sur-les-graphiques-budgetaires
  • incoherence_cas_type_0
  • fix-ui-suppression-tranches-baremes
  • ajout-agregat-cehr-version-plf
  • impact_carbone
  • xlsx
  • header_revamp
  • 270-concevoir-la-page-d-accueil-leximpact
  • 219-conversion-des-montants-min-et-max-de-l-axe-des-x-en-smic
  • 0.0.1177
  • 0.0.1176
  • 0.0.1175
  • 0.0.1174
  • 0.0.1173
  • 0.0.1172
  • 0.0.1171
  • 0.0.1170
  • 0.0.1169
  • 0.0.1168
  • 0.0.1167
  • 0.0.1166
  • 0.0.1165
  • 0.0.1164
  • 0.0.1163
  • 0.0.1162
  • 0.0.1161
  • 0.0.1160
  • 0.0.1159
  • 0.0.1158
41 results

variables.ts

Blame
  • Dorine Lambinet's avatar
    Dorine Lambinet authored
    Crée un nouvel import pour séparer les variables calculées des tests cases summaries des autres variables calculées
    6f4d70c3
    History
    variables.ts 18.85 KiB
    import variableSummaryByNameUnknown from "@leximpact/socio-fiscal-openfisca-json/variables_summaries.json"
    import type {
      Formula,
      Reference,
      Variable,
      VariableByName,
    } from "@openfisca/json-model"
    
    import type { CalculationName } from "$lib/calculations"
    import { reformChangesByName } from "$lib/reforms"
    
    export interface InstantFormulaAndReferences {
      formula?: Formula
      instant: string
      references: Reference[]
    }
    
    export type ValuesByCalculationNameByVariableName = {
      [variableName: string]: VariableValuesByCalculationName
    }
    
    export type VariableValueByCalculationName = Partial<{
      [calculationName in CalculationName]: VariableValue
    }>
    
    export type VariableValuesByCalculationName = Partial<{
      [calculationName in CalculationName]: VariableValues
    }>
    
    export type VariableValue = boolean | number | string
    
    export type VariableValues = boolean[] | number[] | string[]
    
    export const budgetEditableParametersNameByVariableName: {
      [variableName: string]: Set<string>
    } = {
      af: new Set([
        // Allocation familiale de base
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.nb_enfants_min_pour_allocation",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.age1",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.age2",
        "prestations_sociales.prestations_familiales.bmaf.bmaf",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.taux.enf2",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.taux.enf3",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.taux.nb_enf2",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.taux.nb_enf3",
        // Majoration pour âge
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.maj_age_deux_enfants.age1",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.maj_age_deux_enfants.age2",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.maj_age_deux_enfants.taux1",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.maj_age_deux_enfants.taux2",
        // Allocation forfaitaire
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.majoration_enfants.allocation_forfaitaire.age_minimum",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.majoration_enfants.allocation_forfaitaire.taux",
        // Complément dégressif
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cond_ress.majoration_plafond_par_enfant_supplementaire",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cond_ress.plafond_tranche_2_base",
      ]),
      af_base: new Set([
        // Allocation familiale de base
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.nb_enfants_min_pour_allocation",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.age1",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.age2",
        "prestations_sociales.prestations_familiales.bmaf.bmaf",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.taux.enf2",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.taux.enf3",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.taux.nb_enf2",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cm.taux.nb_enf3",
      ]),
      af_majoration: new Set([
        // Majoration pour âge
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.maj_age_deux_enfants.age1",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.maj_age_deux_enfants.age2",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.maj_age_deux_enfants.taux1",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.maj_age_deux_enfants.taux2",
      ]),
      af_allocation_forfaitaire: new Set([
        // Allocation familiale de base
        "prestations_sociales.prestations_familiales.bmaf.bmaf",
        // Allocation forfaitaire
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.majoration_enfants.allocation_forfaitaire.age_minimum",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_maj.majoration_enfants.allocation_forfaitaire.taux",
      ]),
      af_complement_degressif: new Set([
        // Complément dégressif
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cond_ress.majoration_plafond_par_enfant_supplementaire",
        "prestations_sociales.prestations_familiales.prestations_generales.af.af_cond_ress.plafond_tranche_2_base",
      ]),
      csg_deductible_retraite: new Set([
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.deductible.taux_median",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.deductible.taux_plein",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.deductible.taux_reduit",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.imposable.taux_median",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.imposable.taux_plein",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.imposable.taux_reduit",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_ir",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr1.demi_part_suppl_rfr1",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr1.seuil_rfr1",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr2.demi_part_suppl_rfr2",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr2.seuil_rfr2",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr3.demi_part_suppl_rfr3",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr3.seuil_rfr3",
        "prelevements_sociaux.pss.plafond_securite_sociale_mensuel",
      ]),
      csg_deductible_salaire: new Set([
        "prelevements_sociaux.contributions_sociales.csg.activite.deductible.abattement",
        "prelevements_sociaux.contributions_sociales.csg.activite.deductible.taux",
        "prelevements_sociaux.contributions_sociales.csg.activite.imposable.abattement",
        "prelevements_sociaux.contributions_sociales.csg.activite.imposable.taux",
        "prelevements_sociaux.pss.plafond_securite_sociale_mensuel",
      ]),
      csg_imposable_retraite: new Set([
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.deductible.taux_median",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.deductible.taux_plein",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.deductible.taux_reduit",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.imposable.taux_median",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.imposable.taux_plein",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.imposable.taux_reduit",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_ir",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr1.demi_part_suppl_rfr1",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr1.seuil_rfr1",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr2.demi_part_suppl_rfr2",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr2.seuil_rfr2",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr3.demi_part_suppl_rfr3",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr3.seuil_rfr3",
        "prelevements_sociaux.pss.plafond_securite_sociale_mensuel",
      ]),
      csg_imposable_salaire: new Set([
        "prelevements_sociaux.contributions_sociales.csg.activite.deductible.abattement",
        "prelevements_sociaux.contributions_sociales.csg.activite.deductible.taux",
        "prelevements_sociaux.contributions_sociales.csg.activite.imposable.abattement",
        "prelevements_sociaux.contributions_sociales.csg.activite.imposable.taux",
        "prelevements_sociaux.pss.plafond_securite_sociale_mensuel",
      ]),
      csg_retraite: new Set([
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.deductible.taux_median",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.deductible.taux_plein",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.deductible.taux_reduit",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.imposable.taux_median",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.imposable.taux_plein",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.pensions_retraite_invalidite.imposable.taux_reduit",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_ir",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr1.demi_part_suppl_rfr1",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr1.seuil_rfr1",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr2.demi_part_suppl_rfr2",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr2.seuil_rfr2",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr3.demi_part_suppl_rfr3",
        "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils.seuil_rfr3.seuil_rfr3",
        "prelevements_sociaux.pss.plafond_securite_sociale_mensuel",
      ]),
      csg_salaire: new Set([
        "prelevements_sociaux.contributions_sociales.csg.activite.deductible.abattement",
        "prelevements_sociaux.contributions_sociales.csg.activite.deductible.taux",
        "prelevements_sociaux.contributions_sociales.csg.activite.imposable.abattement",
        "prelevements_sociaux.contributions_sociales.csg.activite.imposable.taux",
        "prelevements_sociaux.pss.plafond_securite_sociale_mensuel",
      ]),
      irpp_economique: new Set([
        // Barème de l'impôt sur le revenu
        "impot_revenu.bareme_ir_depuis_1945.bareme",
        // Quotient familial - Règles générales
        "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.conj",
        "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.enf1",
        "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.enf2",
        "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.enf3_et_sup",
        // "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.inv1",
        // "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.inv2",
        // "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.not31b",
        // "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.not32",
        // "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.not41",
        // "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.not42",
        // "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.not6",
        // "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.isol",
        // "impot_revenu.calcul_impot_revenu.plaf_qf.quotient_familial.cdcd",
        // Quotient familial - Plafonds
        "impot_revenu.calcul_impot_revenu.plaf_qf.plafond_avantages_procures_par_demi_part.general",
        // Décote
        "impot_revenu.calcul_impot_revenu.plaf_qf.decote.seuil_celib",
        "impot_revenu.calcul_impot_revenu.plaf_qf.decote.seuil_couple",
        "impot_revenu.calcul_impot_revenu.plaf_qf.decote.taux",
      ]),
    }
    export const budgetEditableParametersName = new Set<string>()
    for (const parametersName of Object.values(
      budgetEditableParametersNameByVariableName,
    )) {
      for (const parameterName of parametersName) {
        budgetEditableParametersName.add(parameterName)
      }
    }
    
    export const budgetVariablesName = new Set([
      "csg_deductible_retraite",
      "csg_deductible_salaire",
      "csg_imposable_retraite",
      "csg_imposable_salaire",
      "csg_retraite",
      "csg_salaire",
      "irpp_economique",
      "af",
      "af_base",
      "af_majoration",
      "af_allocation_forfaitaire",
      "af_complement_degressif",
      "af_allocation_forfaitaire_complement_degressif",
    ])
    
    export const oilTypes = [
      "essence_sp95",
      "essence_sp95_e10",
      "essence_sp98",
      "essence_e85",
      "gazole_b7",
      "gazole_b10",
      "gpl_carburant",
    ]
    
    /// Name of variables that must be calculated to be displayed in
    /// test case summaries.
    export const summaryCalculatedVariablesName = [
      "assiette_csg_revenus_capital",
      "assiette_csg_plus_values",
      "niveau_de_vie",
      "plus_values_base_large",
      "rente_viagere_titre_onereux_net",
      "rsa",
    ].concat(
      oilTypes.reduce((names: string[], name: string) => {
        names.push(
          `depense_${name}_ttc`,
          `nombre_litres_${name}`,
          // `prix_${name}_hors_remise_ttc_sortie`,
          `prix_${name}_ttc`,
          `tva_sur_${name}`,
          `${name}_ticpe`,
        )
        return names
      }, []),
    )
    
    /// Autres variables à calculer
    export const otherCalculatedVariablesName = [
      "niveau_de_vie",
      "unites_consommation",
    ]
    
    export const variableSummaryByName =
      variableSummaryByNameUnknown as VariableByName
    
    export const variableSummaryByNameByReformName: {
      [name: string]: VariableByName
    } = Object.fromEntries(
      Object.entries(reformChangesByName).map(([reformName, reformChanges]) => [
        reformName,
        patchVariableSummaryByName(
          variableSummaryByName,
          reformChanges.variables_summaries,
        ),
      ]),
    )
    
    export function buildInstantFormulaAndReferencesArray(
      variable: Variable,
    ): InstantFormulaAndReferences[] {
      const instantFormulaAndReferencesByInstant: {
        [instant: string]: InstantFormulaAndReferences
      } = Object.fromEntries(
        Object.entries(variable.formulas ?? {}).map(([instant, formula]) => [
          instant,
          { formula, instant, references: [] },
        ]),
      )
      if (variable.reference !== undefined) {
        for (const [instant, references] of Object.entries(variable.reference)) {
          if (instantFormulaAndReferencesByInstant[instant] === undefined) {
            instantFormulaAndReferencesByInstant[instant] = {
              instant,
              references,
            }
          } else {
            instantFormulaAndReferencesByInstant[instant].references = references
          }
        }
      }
      return Object.entries(instantFormulaAndReferencesByInstant)
        .sort(([instant1], [instant2]) => instant2.localeCompare(instant1))
        .map(([, instantFormulaAndReferences]) => instantFormulaAndReferences)
    }
    
    export function getVariableParametersName(
      variable: Variable,
      date: string,
    ): string[] | undefined {
      if (variable.input || variable.formulas === undefined) {
        // Variable is an input variable => No parameter.
        return undefined
      }
      const dates = Object.keys(variable.formulas).reverse()
      let formula: Formula | undefined = undefined
      for (const bestDate of dates) {
        if (bestDate <= date) {
          formula = variable.formulas[bestDate]
          break
        }
      }
      if (formula == null) {
        // No candidate date less than or equal to date found.
        return undefined
      }
      return formula.parameters
    }
    
    export function* iterVariableInputVariables(
      variable: Variable,
      date: string,
      encounteredVariablesName: Set<string> = new Set(),
    ): Generator<Variable, void> {
      const name = variable.name
      if (encounteredVariablesName.has(name)) {
        return
      }
      encounteredVariablesName.add(name)
    
      if (variable.input) {
        // Variable has been customized to an input variable.
        yield variable
        return
      }
      const formulas = variable.formulas
      if (formulas === undefined) {
        // Variable is an input variable.
        yield variable
        return
      }
      const dates = Object.keys(formulas).reverse()
      let formula = undefined
      for (const bestDate of dates) {
        if (bestDate <= date) {
          formula = formulas[bestDate]
          break
        }
      }
      if (formula == null) {
        // No candidate date less than or equal to date found.
        return
      }
      const referredVariablesName = formula.variables
      if (referredVariablesName === undefined) {
        return
      }
      for (const referredVariableName of referredVariablesName) {
        const referredVariable = variableSummaryByName[referredVariableName]
        yield* iterVariableInputVariables(
          referredVariable,
          date,
          encounteredVariablesName,
        )
      }
    }
    
    export function* iterVariableParametersName(
      variable: Variable,
      date: string,
      encounteredParametersName: Set<string> = new Set(),
      encounteredVariablesName: Set<string> = new Set(),
    ): Generator<string, void> {
      const name = variable.name
      if (encounteredVariablesName.has(name)) {
        return
      }
      encounteredVariablesName.add(name)
    
      const formulas = variable.formulas
      if (formulas === undefined) {
        return
      }
      const dates = Object.keys(formulas).reverse()
      let formula = undefined
      for (const bestDate of dates) {
        if (bestDate <= date) {
          formula = formulas[bestDate]
          break
        }
      }
      if (formula == null) {
        // No candidate date less than or equal to date found.
        return
      }
    
      const referredVariablesName = formula.variables
      if (referredVariablesName !== undefined) {
        for (const referredVariableName of referredVariablesName) {
          const referredVariable = variableSummaryByName[referredVariableName]
          if (referredVariable === undefined) {
            console.warn(
              `iterVariableParametersName: Undefined variable ${referredVariableName}`,
            )
            continue
          }
          yield* iterVariableParametersName(
            referredVariable,
            date,
            encounteredParametersName,
            encounteredVariablesName,
          )
        }
      }
    
      const referredParametersName = formula.parameters
      if (referredParametersName !== undefined) {
        for (const referredParameterName of referredParametersName) {
          if (encounteredParametersName.has(referredParameterName)) {
            continue
          }
          encounteredParametersName.add(referredParameterName)
          yield referredParameterName
        }
      }
    }
    
    function patchVariableSummaryByName(
      variableSummaryByName: VariableByName,
      patch: { [name: string]: Variable | null },
    ): VariableByName {
      if (Object.keys(patch).length === 0) {
        return variableSummaryByName
      }
      const patchedVariableSummaryByName = { ...variableSummaryByName }
      for (const [name, variableSummaryPatch] of Object.entries(patch)) {
        if (variableSummaryPatch === null) {
          // This case should not occur, because a reform should always
          // have all the variables of the original tax-benefit system.
          delete patchedVariableSummaryByName[name]
        } else {
          patchedVariableSummaryByName[name] = variableSummaryPatch
        }
      }
      return patchedVariableSummaryByName
    }