Skip to content
Snippets Groups Projects
Commit 741475f5 authored by Emmanuel Raviart's avatar Emmanuel Raviart
Browse files

Add a sample decomposition to try to use OpenFisca Web API.

Using this API is more complicated than expected for a waterfall.
parent 2dcb6b4e
Branches
Tags
No related merge requests found
interface Decomposition {
code: string
short_name: string
children?: Decomposition[]
}
export const decomposition: Decomposition = {
code: "revenu_disponible",
short_name: "Revenu disponible",
children: [
{
code: "revenus_nets_du_travail",
short_name: "Revenus nets",
children: [
{
code: "salaire_net",
short_name: "Salaire net",
children: [
{
code: "salaire_imposable",
short_name: "Salaire imposable",
children: [
{
code: "salaire_de_base",
short_name: "Salaire brut",
children: [
{
code: "salaire_super_brut_hors_allegements",
short_name: "Salaire super brut HA",
children: [
{
code: "salaire_super_brut",
short_name: "Salaire super brut",
children: [
{
code: "cout_du_travail",
short_name: "Coût du travail",
},
{
code: "credit_impot_competitivite_emploi",
short_name: "CICE",
},
{
code: "aide_premier_salarie",
short_name: "Aide premier salarié",
},
{
code: "aide_embauche_pme",
short_name: "Aide PME",
},
{ code: "tehr", short_name: "Taxe exceptionnelle" },
],
},
{ code: "allegement_fillon", short_name: "Fillon" },
],
},
{
code: "cotisations_employeur",
short_name: "Cotisations employeur",
},
],
},
{
code: "cotisations_salariales",
short_name: "Cotisations salariales",
},
{
code: "csg_deductible_salaire",
short_name: "CSG déductible",
},
],
},
{ code: "csg_imposable_salaire", short_name: "CSG imposable" },
{ code: "crds_salaire", short_name: "CRDS" },
],
},
],
},
{
code: "prestations_sociales",
short_name: "Prestations sociales",
children: [
{
code: "minima_sociaux",
short_name: "Minima sociaux",
children: [
{ code: "rsa", short_name: "RSA" },
{ code: "ppa", short_name: "PPA" },
],
},
],
},
{ code: "ppe", short_name: "PPE" },
{
code: "impots_directs",
short_name: "Impôts directs",
children: [{ code: "irpp", short_name: "Impôt sur le revenu" }],
},
],
}
export function* walkDecomposition(
decomposition: Decomposition,
): Generator<Decomposition, void, unknown> {
yield decomposition
for (const child of decomposition.children ?? []) {
yield* walkDecomposition(child)
}
}
<script context="module" lang="ts">
export async function load({ page, fetch, session, context }) {
const url = "https://fr.openfisca.org/api/latest/calculate"
import { decomposition, walkDecomposition } from "$lib/decomposition"
// See https://github.com/cbenz/openfisca-interactive/blob/master/waterfall.ipynb
const year = 2017
const variablesDecomposition = Object.fromEntries(
[...walkDecomposition(decomposition)]
.filter(
(node) =>
![
"aide_embauche_pme",
"aide_premier_salarie",
"allegement_fillon",
"cotisations_employeur",
"cotisations_salariales",
"cout_du_travail",
"crds_salaire",
"credit_impot_competitivite_emploi",
"csg_deductible_salaire",
"csg_imposable_salaire",
"irpp",
"minima_sociaux",
"ppa",
"ppe",
"prestations_sociales",
"revenus_nets_du_travail",
"rsa",
"salaire_de_base",
"salaire_imposable",
"salaire_net",
"salaire_super_brut",
"salaire_super_brut_hors_allegements",
"tehr",
].includes(node.code),
)
.map((node) => [node.code, { [year]: null }]),
)
const situation = {
individus: {
Claude: {
salaire_de_base: {
"2017": 20000,
[year]: 20000,
},
},
Dominique: {
salaire_de_base: {
"2017": 30000,
[year]: 30000,
},
},
Camille: {},
......@@ -20,12 +54,7 @@
personne_de_reference: ["Claude"],
conjoint: ["Dominique"],
enfants: ["Camille"],
revenu_disponible: {
"2017": null,
},
impots_directs: {
"2017": null,
},
...variablesDecomposition,
},
},
familles: {
......@@ -41,6 +70,9 @@
},
},
}
export async function load({ page, fetch, session, context }) {
const url = "https://fr.openfisca.org/api/latest/calculate"
const res = await fetch(url, {
body: JSON.stringify(situation, null, 2),
headers: {
......@@ -49,17 +81,23 @@
method: "POST",
})
if (res.ok) {
if (!res.ok) {
console.error(
`Erreur ${res.status} while POSTing ${url}\n${JSON.stringify(
situation,
null,
2,
)}\n\n${await res.text()}`,
)
return {
props: {
simulation: await res.json(),
},
status: res.status,
error: new Error(`Could not load ${url}`),
}
}
return {
status: res.status,
error: new Error(`Could not load ${url}`),
props: {
simulation: await res.json(),
},
}
}
</script>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment