Select Git revision
variables.ts
Dorine Lambinet authored
Crée un nouvel import pour séparer les variables calculées des tests cases summaries des autres variables calculées
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
}