From ea24a47a3fdacc42b3c52fc951715627d709dc7d Mon Sep 17 00:00:00 2001 From: Johan Girod Date: Wed, 26 May 2021 16:21:46 +0200 Subject: [PATCH] =?UTF-8?q?Ajoute=20l'activit=C3=A9=20mixte=20aux=20simula?= =?UTF-8?q?teurs=20ind=C3=A9pendants?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Factorise la logique de la saisie des CA dans un nouveau composant --- .../règles/entreprise-établissement.yaml | 5 +- .../ChiffreAffairesActivitéMixte.tsx | 148 ++++++++++++++++++ .../pages/Simulateurs/AutoEntrepreneur.tsx | 136 +--------------- .../source/pages/Simulateurs/Indépendant.tsx | 16 +- .../configs/auto-entrepreneur.yaml | 4 +- 5 files changed, 167 insertions(+), 142 deletions(-) create mode 100644 mon-entreprise/source/components/ChiffreAffairesActivitéMixte.tsx diff --git a/modele-social/règles/entreprise-établissement.yaml b/modele-social/règles/entreprise-établissement.yaml index 582324cbe..77aad9492 100644 --- a/modele-social/règles/entreprise-établissement.yaml +++ b/modele-social/règles/entreprise-établissement.yaml @@ -833,18 +833,19 @@ entreprise . activité . mixte . proportions: - nom: service BIC variations: - si: activité = 'libérale' - alors: 0 + alors: 0% - sinon: 50% - nom: service BNC variations: - si: activité = 'libérale' alors: 2 / 3 - - sinon: 0 + - sinon: 0% - nom: vente restauration hébergement variations: - si: activité = 'libérale' alors: 1 / 3 - sinon: 50% + note: Il appartient à l'utilisateur de bien vérifier que la somme des trois pourcentages renseignés vaut 100%. entreprise . activité . libérale réglementée: diff --git a/mon-entreprise/source/components/ChiffreAffairesActivitéMixte.tsx b/mon-entreprise/source/components/ChiffreAffairesActivitéMixte.tsx new file mode 100644 index 000000000..6faa6dffb --- /dev/null +++ b/mon-entreprise/source/components/ChiffreAffairesActivitéMixte.tsx @@ -0,0 +1,148 @@ +import { batchUpdateSituation } from 'Actions/actions' +import { DottedName } from 'modele-social' +import { serializeEvaluation } from 'publicodes' +import { useCallback } from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { situationSelector } from 'Selectors/simulationSelectors' +import { Explicable } from './conversation/Explicable' +import { Condition } from './EngineValue' +import { SimulationGoal } from './SimulationGoals' +import { useEngine } from './utils/EngineContext' +import { Markdown } from './utils/markdown' + +const proportions = { + 'entreprise . activité . mixte . proportions . service BIC': + "entreprise . chiffre d'affaires . service BIC", + 'entreprise . activité . mixte . proportions . service BNC': + "entreprise . chiffre d'affaires . service BNC", + 'entreprise . activité . mixte . proportions . vente restauration hébergement': + "entreprise . chiffre d'affaires . vente restauration hébergement", +} as const + +export default function ChiffreAffairesActivitéMixte({ + dottedName, +}: { + dottedName: DottedName +}) { + const adjustProportions = useAdjustProportions(dottedName) + const dispatch = useDispatch() + const clearChiffreAffaireMixte = useCallback(() => { + dispatch( + batchUpdateSituation( + Object.values(proportions).reduce( + (acc, chiffreAffaires) => ({ ...acc, [chiffreAffaires]: undefined }), + {} + ) + ) + ) + }, [dispatch]) + return ( + <> + + + + +
  • +
      + {Object.values(proportions).map((chiffreAffaires) => ( + + ))} +
    +
  • +
    + + ) +} +export function useAdjustProportions(CADottedName: DottedName): () => void { + const engine = useEngine() + const dispatch = useDispatch() + + return useCallback(() => { + const nouveauCA = serializeEvaluation( + engine.evaluate({ + somme: Object.values(proportions) + .map((chiffreAffaire) => + serializeEvaluation(engine.evaluate(chiffreAffaire)) + ) + .filter(Boolean), + }) + ) + if (nouveauCA === '0€/an') { + return // Avoid division by 0 + } + const situation = Object.entries(proportions).reduce( + (acc, [proportionName, valueName]) => { + const value = serializeEvaluation( + engine.evaluate({ valeur: valueName, 'par défaut': '0€/an' }) + ) + const newProportion = serializeEvaluation( + engine.evaluate({ + valeur: `${value} / ${nouveauCA}`, + unité: '%', + }) + ) + + return { ...acc, [proportionName]: newProportion } + }, + { [CADottedName]: nouveauCA } + ) + dispatch(batchUpdateSituation(situation)) + }, [engine, dispatch]) +} + +function ActivitéMixte() { + const dispatch = useDispatch() + const situation = useSelector(situationSelector) + const rule = useEngine().getRule('entreprise . activité . mixte') + const defaultChecked = + useEngine().evaluate('entreprise . activité . mixte').nodeValue === true + + const onMixteChecked = useCallback( + (checked: boolean) => { + dispatch( + batchUpdateSituation( + Object.values(proportions).reduce( + (acc, dottedName) => ({ ...acc, [dottedName]: undefined }), + { 'entreprise . activité . mixte': checked ? 'oui' : 'non' } + ) + ) + ) + }, + [dispatch, situation] + ) + return ( +
  • + +
  • + ) +} diff --git a/mon-entreprise/source/pages/Simulateurs/AutoEntrepreneur.tsx b/mon-entreprise/source/pages/Simulateurs/AutoEntrepreneur.tsx index 97637e4c4..2b553f0f4 100644 --- a/mon-entreprise/source/pages/Simulateurs/AutoEntrepreneur.tsx +++ b/mon-entreprise/source/pages/Simulateurs/AutoEntrepreneur.tsx @@ -1,104 +1,22 @@ -import { batchUpdateSituation } from 'Actions/actions' -import { Explicable } from 'Components/conversation/Explicable' -import { Condition, WhenAlreadyDefined } from 'Components/EngineValue' +import ChiffreAffairesActivitéMixte from 'Components/ChiffreAffairesActivitéMixte' +import { WhenAlreadyDefined } from 'Components/EngineValue' import PeriodSwitch from 'Components/PeriodSwitch' import SimulateurWarning from 'Components/SimulateurWarning' import Simulation from 'Components/Simulation' import { SimulationGoal, SimulationGoals } from 'Components/SimulationGoals' import StackedBarChart from 'Components/StackedBarChart' import { ThemeColorsContext } from 'Components/utils/colors' -import { useEngine } from 'Components/utils/EngineContext' -import { Markdown } from 'Components/utils/markdown' -import { serializeEvaluation } from 'publicodes' -import { default as React, useCallback, useContext } from 'react' +import { default as React, useContext } from 'react' import { Trans, useTranslation } from 'react-i18next' -import { useDispatch, useSelector } from 'react-redux' -import { situationSelector } from 'Selectors/simulationSelectors' - -const proportions = { - 'entreprise . activité . mixte . proportions . service BIC': - "entreprise . chiffre d'affaires . service BIC", - 'entreprise . activité . mixte . proportions . service BNC': - "entreprise . chiffre d'affaires . service BNC", - 'entreprise . activité . mixte . proportions . vente restauration hébergement': - "entreprise . chiffre d'affaires . vente restauration hébergement", -} as const -function useAdjustProportions(): () => void { - const engine = useEngine() - const dispatch = useDispatch() - - return useCallback(() => { - const nouveauCA = serializeEvaluation( - engine.evaluate({ - somme: Object.values(proportions) - .map((chiffreAffaire) => - serializeEvaluation(engine.evaluate(chiffreAffaire)) - ) - .filter(Boolean), - }) - ) - if (nouveauCA === '0€/an') { - return // Avoid division by 0 - } - const situation = Object.entries(proportions).reduce( - (acc, [proportionName, valueName]) => { - const value = serializeEvaluation( - engine.evaluate({ valeur: valueName, 'par défaut': '0€/an' }) - ) - const newProportion = serializeEvaluation( - engine.evaluate({ - valeur: `${value} / ${nouveauCA}`, - unité: '%', - }) - ) - - return { ...acc, [proportionName]: newProportion } - }, - { "dirigeant . auto-entrepreneur . chiffre d'affaires": nouveauCA } - ) - dispatch(batchUpdateSituation(situation)) - }, [engine, dispatch]) -} export default function AutoEntrepreneur() { - const adjustProportions = useAdjustProportions() - const activitéMixte = - useEngine().evaluate('entreprise . activité . mixte').nodeValue === true - return ( <> }> - - - -
  • -
      - - - -
    -
  • -
    - + { - dispatch( - batchUpdateSituation( - Object.values(proportions).reduce( - (acc, dottedName) => ({ ...acc, [dottedName]: undefined }), - { 'entreprise . activité . mixte': checked ? 'oui' : 'non' } - ) - ) - ) - }, - [dispatch, situation] - ) - return ( -
  • - -
  • - ) -} - function Explanation() { const { t } = useTranslation() const { palettes } = useContext(ThemeColorsContext) diff --git a/mon-entreprise/source/pages/Simulateurs/Indépendant.tsx b/mon-entreprise/source/pages/Simulateurs/Indépendant.tsx index c7ef7e371..144edd79d 100644 --- a/mon-entreprise/source/pages/Simulateurs/Indépendant.tsx +++ b/mon-entreprise/source/pages/Simulateurs/Indépendant.tsx @@ -1,5 +1,6 @@ import { updateSituation } from 'Actions/actions' import Banner from 'Components/Banner' +import ChiffreAffairesActivitéMixte from 'Components/ChiffreAffairesActivitéMixte' import { Condition, WhenAlreadyDefined } from 'Components/EngineValue' import PeriodSwitch from 'Components/PeriodSwitch' import SimulateurWarning from 'Components/SimulateurWarning' @@ -78,11 +79,16 @@ function IndépendantSimulationGoals() { return ( - + + + + + +