From 61b428059a1856e236d4c1ccc65a16a7dc9e5c98 Mon Sep 17 00:00:00 2001 From: Maxime Quandalle Date: Wed, 27 Jan 2021 18:19:51 +0100 Subject: [PATCH] WIP --- modele-social/règles/entreprise-établissement.yaml | 7 +++++-- .../source/components/conversation/Question.tsx | 12 +++++++----- .../source/components/conversation/RuleInput.tsx | 12 +++++++----- .../source/pages/Simulateurs/ISSimulation.tsx | 13 +++++++++++++ publicodes/core/source/mecanisms/barème.ts | 7 +++---- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/modele-social/règles/entreprise-établissement.yaml b/modele-social/règles/entreprise-établissement.yaml index 3927a9fba..023e6b75f 100644 --- a/modele-social/règles/entreprise-établissement.yaml +++ b/modele-social/règles/entreprise-établissement.yaml @@ -173,6 +173,7 @@ entreprise . exercice . durée maximale: entreprise . impôt sur les sociétés: unité: €/an formule: + plafond: plafond taux réduit 1 barème: assiette: bénéfice multiplicateur: prorata temporis @@ -211,7 +212,7 @@ entreprise . impôt sur les sociétés: - taux: 28% plafond: plafond taux réduit 2 - taux: 33.3333% - arrondi: oui + # arrondi: oui références: Fiche impots.gouv.fr: https://www.impots.gouv.fr/portail/international-professionnel/impot-sur-les-societes Fiche service-public.fr: https://www.service-public.fr/professionnels-entreprises/vosdroits/F23575 @@ -225,7 +226,9 @@ entreprise . impôt sur les sociétés . plafond taux réduit 2: valeur: 500000 €/an entreprise . impôt sur les sociétés . éligible taux réduit: - formule: + type: booléen + question: Êtes-vous éligible aux taux réduits ? + par défaut: toutes ces conditions: - chiffre d'affaires <= 7630 k€/an * prorata temporis - nom: capital détenu au moins à 75 pourcents par des personnes physiques diff --git a/mon-entreprise/source/components/conversation/Question.tsx b/mon-entreprise/source/components/conversation/Question.tsx index 6bf608a86..c82ce462f 100644 --- a/mon-entreprise/source/components/conversation/Question.tsx +++ b/mon-entreprise/source/components/conversation/Question.tsx @@ -6,7 +6,7 @@ import { useCallback, useEffect, useState } from 'react' import emoji from 'react-easy-emoji' import { Trans } from 'react-i18next' import { Explicable } from './Explicable' -import { binaryQuestion, InputCommonProps, RuleInputProps } from './RuleInput' +import { InputCommonProps, RuleInputProps } from './RuleInput' /* Ceci est une saisie de type "radio" : l'utilisateur choisit une réponse dans une liste, ou une liste de listes. Les données @choices sont un arbre de type: @@ -31,7 +31,7 @@ export type Choice = RuleNode & { type QuestionProps = InputCommonProps & { onSubmit: (source: string) => void - choices: Choice | typeof binaryQuestion + choices: Choice | Array<{ value: string | null; label: string }> } export default function Question({ @@ -68,7 +68,9 @@ export default function Question({ } }, [currentSelection]) - const renderBinaryQuestion = (choices: typeof binaryQuestion) => { + const renderBinaryQuestion = ( + choices: Array<{ value: string | null; label: string }> + ) => { return choices.map(({ value, label }) => ( ( ) type RadioLabelContentProps = { - value: string + value: string | null label: string name: string currentSelection?: null | string icônes?: string onChange: RuleInputProps['onChange'] - onSubmit: (src: string, value: string) => void + onSubmit: (src: string, value: string | null) => void } function RadioLabelContent({ diff --git a/mon-entreprise/source/components/conversation/RuleInput.tsx b/mon-entreprise/source/components/conversation/RuleInput.tsx index e20909084..73db8f335 100644 --- a/mon-entreprise/source/components/conversation/RuleInput.tsx +++ b/mon-entreprise/source/components/conversation/RuleInput.tsx @@ -43,11 +43,6 @@ export type InputCommonProps = Pick< required: boolean } -export const binaryQuestion = [ - { value: 'oui', label: 'Oui' }, - { value: 'non', label: 'Non' }, -] as const - // This function takes the unknown rule and finds which React component should // be displayed to get a user input through successive if statements // That's not great, but we won't invest more time until we have more diverse @@ -118,6 +113,10 @@ export default function RuleInput({ (rule.rawNode.type === 'booléen' || rule.rawNode.type == undefined) && typeof evaluation.nodeValue !== 'number' ) { + // TODO : super hacky, we need to find a way to read the missing variables + // of the 'par défaut' expression + const defaultValueIsAnswerable = + typeof rule.rawNode?.['par défaut'] === 'object' return useSwitch ? ( ({ choices={[ { value: 'oui', label: 'Oui' }, { value: 'non', label: 'Non' }, + ...(defaultValueIsAnswerable + ? [{ value: null, label: 'Je ne sais pas' }] + : []), ]} onSubmit={onSubmit} /> diff --git a/mon-entreprise/source/pages/Simulateurs/ISSimulation.tsx b/mon-entreprise/source/pages/Simulateurs/ISSimulation.tsx index 1e30728b2..f5ff1167f 100644 --- a/mon-entreprise/source/pages/Simulateurs/ISSimulation.tsx +++ b/mon-entreprise/source/pages/Simulateurs/ISSimulation.tsx @@ -1,4 +1,5 @@ import { updateSituation } from 'Actions/actions' +import Conversation from 'Components/conversation/Conversation' import RuleInput from 'Components/conversation/RuleInput' import Value from 'Components/EngineValue' import Notifications from 'Components/Notifications' @@ -6,6 +7,7 @@ import { SimulationGoal, SimulationGoals } from 'Components/SimulationGoals' import Animate from 'Components/ui/animate' import Warning from 'Components/ui/WarningBlock' import { ThemeColorsContext } from 'Components/utils/colors' +import { useEngine } from 'Components/utils/EngineContext' import useSimulationConfig from 'Components/utils/useSimulationConfig' import { useContext } from 'react' import emoji from 'react-easy-emoji' @@ -18,7 +20,11 @@ export default function ISSimulation() { useSimulationConfig({ color, 'unité par défaut': '€/an', + objectifs: ['entreprise . impôt sur les sociétés'], situation: {}, + questions: { + liste: ['entreprise . impôt sur les sociétés . éligible taux réduit'], + }, }) return ( @@ -37,6 +43,7 @@ export default function ISSimulation() { + ) @@ -85,6 +92,12 @@ function ExerciceDate() { function Explanations() { const situation = useSelector(situationSelector) + const engine = useEngine() + console.log( + engine.evaluate( + 'entreprise . impôt sur les sociétés . plafond taux réduit 1' + ) + ) const showResult = situation['entreprise . bénéfice'] if (!showResult) { return null diff --git a/publicodes/core/source/mecanisms/barème.ts b/publicodes/core/source/mecanisms/barème.ts index ac35ee4ec..864084964 100644 --- a/publicodes/core/source/mecanisms/barème.ts +++ b/publicodes/core/source/mecanisms/barème.ts @@ -39,7 +39,7 @@ export default function parseBarème(v, context): BarèmeNode { } } -function evaluateBarème(tranches, assiette, evaluate, cache) { +function evaluateBarème(tranches, assiette, evaluate) { return tranches.map((tranche) => { if (tranche.isAfterActive) { return { ...tranche, nodeValue: 0 } @@ -69,7 +69,7 @@ function evaluateBarème(tranches, assiette, evaluate, cache) { (Math.min(assiette.nodeValue, tranche.plafondValue) - tranche.plancherValue) * convertUnit(taux.unit, parseUnit(''), taux.nodeValue as number), - missingVariables: mergeAllMissing([taux, tranche]), + missingVariables: mergeAllMissing([assiette, taux, tranche]), } }) } @@ -88,8 +88,7 @@ const evaluate: EvaluationFunction<'barème'> = function (node) { liftTemporalNode(multiplicateur as any) ) const temporalTranches = liftTemporal2( - (tranches, assiette) => - evaluateBarème(tranches, assiette, evaluate, this.cache), + (tranches, assiette) => evaluateBarème(tranches, assiette, evaluate), temporalTranchesPlafond, liftTemporalNode(assiette as any) )