+
+ {/* Passing location down to prevent update blocking */}
-
-
-
- {redirects}
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ {redirects}
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
- {!inIframe() &&
}
+
+
+
+ {!inIframe() && }
-
+
)
}
diff --git a/source/sites/mon-entreprise.fr/layout/Footer/Footer.css b/source/sites/mon-entreprise.fr/layout/Footer/Footer.css
index 560f8ba5d..ad7ed3f2b 100644
--- a/source/sites/mon-entreprise.fr/layout/Footer/Footer.css
+++ b/source/sites/mon-entreprise.fr/layout/Footer/Footer.css
@@ -36,7 +36,7 @@
text-transform: uppercase;
font-size: 85%;
color: var(--darkColor);
- font-weight: 600;
+ font-weight: 500;
}
.footer__registerField {
display: flex;
diff --git a/source/sites/mon-entreprise.fr/layout/Footer/Footer.tsx b/source/sites/mon-entreprise.fr/layout/Footer/Footer.tsx
index c53a676b5..c90d90447 100644
--- a/source/sites/mon-entreprise.fr/layout/Footer/Footer.tsx
+++ b/source/sites/mon-entreprise.fr/layout/Footer/Footer.tsx
@@ -1,6 +1,6 @@
import PageFeedback from 'Components/Feedback/PageFeedback'
import LegalNotice from 'Components/LegalNotice'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import { lensPath, view } from 'ramda'
import React, { useContext } from 'react'
import emoji from 'react-easy-emoji'
diff --git a/source/sites/mon-entreprise.fr/layout/Header.tsx b/source/sites/mon-entreprise.fr/layout/Header.tsx
index bd0d9e51d..fac62a808 100644
--- a/source/sites/mon-entreprise.fr/layout/Header.tsx
+++ b/source/sites/mon-entreprise.fr/layout/Header.tsx
@@ -1,4 +1,4 @@
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import logoEnSvg from 'Images/logo-mycompany.svg'
import logoSvg from 'Images/logo.svg'
import marianneSvg from 'Images/marianne.svg'
diff --git a/source/sites/mon-entreprise.fr/layout/NewsBanner.tsx b/source/sites/mon-entreprise.fr/layout/NewsBanner.tsx
index ba1c47ac9..30216bbb9 100644
--- a/source/sites/mon-entreprise.fr/layout/NewsBanner.tsx
+++ b/source/sites/mon-entreprise.fr/layout/NewsBanner.tsx
@@ -1,5 +1,5 @@
import { useLocalStorage, writeStorage } from '@rehooks/local-storage'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import emoji from 'react-easy-emoji'
import { useTranslation } from 'react-i18next'
diff --git a/source/sites/mon-entreprise.fr/middlewares/trackSimulatorActions.ts b/source/sites/mon-entreprise.fr/middlewares/trackSimulatorActions.ts
index 1b620ce6d..b5837350f 100644
--- a/source/sites/mon-entreprise.fr/middlewares/trackSimulatorActions.ts
+++ b/source/sites/mon-entreprise.fr/middlewares/trackSimulatorActions.ts
@@ -1,4 +1,7 @@
-import { situationSelector } from 'Selectors/simulationSelectors'
+import {
+ currentQuestionSelector,
+ situationSelector
+} from 'Selectors/analyseSelectors'
import Tracker from 'Tracker'
export default (tracker: Tracker) => {
@@ -14,15 +17,14 @@ export default (tracker: Tracker) => {
situationSelector(newState)[action.step]
])
- // TODO : add tracking in UI instead ?
- // if (!currentQuestionSelector(newState)) {
- // tracker.push([
- // 'trackEvent',
- // 'Simulator',
- // 'simulation completed',
- // 'after ' + newState.simulation.foldedSteps.length + ' questions'
- // ])
- // }
+ if (!currentQuestionSelector(newState)) {
+ tracker.push([
+ 'trackEvent',
+ 'Simulator',
+ 'simulation completed',
+ 'after ' + newState.simulation.foldedSteps.length + ' questions'
+ ])
+ }
}
if (action.type === 'SET_ACTIVE_TARGET_INPUT') {
@@ -36,14 +38,14 @@ export default (tracker: Tracker) => {
if (
action.type === 'UPDATE_SITUATION' ||
- action.type === 'UPDATE_TARGET_UNIT'
+ action.type === 'UPDATE_DEFAULT_UNIT'
) {
tracker.push([
'trackEvent',
'Simulator',
'update situation',
- ...(action.type === 'UPDATE_TARGET_UNIT'
- ? ['unité', action.targetUnit]
+ ...(action.type === 'UPDATE_DEFAULT_UNIT'
+ ? ['unité', action.defaultUnit]
: [action.fieldName, action.value])
])
}
diff --git a/source/sites/mon-entreprise.fr/pages/Coronavirus.tsx b/source/sites/mon-entreprise.fr/pages/Coronavirus.tsx
index d98a25e3a..028aa59d2 100644
--- a/source/sites/mon-entreprise.fr/pages/Coronavirus.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Coronavirus.tsx
@@ -5,19 +5,19 @@ import chomagePartielConfig from 'Components/simulationConfigs/chômage-partiel.
import Warning from 'Components/ui/WarningBlock'
import { ThemeColorsContext } from 'Components/utils/colors'
import { IsEmbeddedContext } from 'Components/utils/embeddedContext'
-import { useEvaluation } from 'Components/utils/EngineContext'
import { Markdown } from 'Components/utils/markdown'
import { ScrollToTop } from 'Components/utils/Scroll'
import { formatValue } from 'Engine/format'
-import { EvaluatedRule } from 'Engine/types'
+import { getRuleFromAnalysis } from 'Engine/ruleUtils'
import React, { useContext, useEffect, useState } from 'react'
import { Helmet } from 'react-helmet'
import { Trans, useTranslation } from 'react-i18next'
-import { useDispatch } from 'react-redux'
+import { useDispatch, useSelector } from 'react-redux'
import { useLocation } from 'react-router'
+import { EvaluatedRule } from 'Rules'
+import { analysisWithDefaultsSelector } from 'Selectors/analyseSelectors'
import styled from 'styled-components'
import Animate from 'Ui/animate'
-import { DottedName } from 'Rules'
declare global {
interface Window {
@@ -108,22 +108,25 @@ export default function ChômagePartiel() {
}
function ExplanationSection() {
+ const analysis = useSelector(analysisWithDefaultsSelector)
const {
i18n: { language },
t
} = useTranslation()
+ const { palettes } = useContext(ThemeColorsContext)
+ const getRule = getRuleFromAnalysis(analysis)
- const net = useEvaluation('contrat salarié . rémunération . net')
- const netHabituel = useEvaluation('chômage partiel . revenu net habituel')
- const totalEntreprise = useEvaluation('contrat salarié . prix du travail')
- const totalEntrepriseHabituel = useEvaluation(
+ const net = getRule('contrat salarié . rémunération . net')
+ const netHabituel = getRule('chômage partiel . revenu net habituel')
+ const totalEntreprise = getRule('contrat salarié . prix du travail')
+ const totalEntrepriseHabituel = getRule(
'chômage partiel . coût employeur habituel'
)
if (
- typeof net?.nodeValue !== 'number' ||
- typeof netHabituel?.nodeValue !== 'number' ||
- typeof totalEntreprise?.nodeValue !== 'number' ||
- typeof totalEntrepriseHabituel?.nodeValue !== 'number'
+ !net?.nodeValue ||
+ !netHabituel?.nodeValue ||
+ totalEntreprise?.nodeValue == null ||
+ !totalEntrepriseHabituel?.nodeValue
) {
return null
}
@@ -150,19 +153,17 @@ function ExplanationSection() {
{
...net,
additionalText: language === 'fr' && (
-
+ <>
Soit{' '}
{formatValue({
- nodeValue:
- (net.nodeValue / netHabituel.nodeValue) * 100,
+ value: (net.nodeValue / netHabituel.nodeValue) * 100,
unit: '%',
- language: 'fr',
- precision: 0
+ maximumFractionDigits: 0
})}
{' '}
du revenu net
-
+ >
)
}
],
@@ -172,21 +173,20 @@ function ExplanationSection() {
{
...totalEntreprise,
additionalText: language === 'fr' && (
-
+ <>
Soit{' '}
{formatValue({
- nodeValue:
+ value:
(totalEntreprise.nodeValue /
totalEntrepriseHabituel.nodeValue) *
100,
unit: '%',
- language: 'fr',
- precision: 0
+ maximumFractionDigits: 0
})}
{' '}
du coût habituel
-
+ >
)
}
]
@@ -203,7 +203,7 @@ type ComparaisonTableProps = {
}
type Line = Array<
- EvaluatedRule
& {
+ EvaluatedRule & {
additionalText?: React.ReactNode
}
>
@@ -278,15 +278,15 @@ function ComparaisonTable({ rows: [head, ...body] }: ComparaisonTableProps) {
)
}
-function ValueWithLink(rule: EvaluatedRule) {
+function ValueWithLink(rule: EvaluatedRule) {
const { language } = useTranslation().i18n
return (
{formatValue({
- nodeValue: rule.nodeValue as number,
+ value: rule.nodeValue as number,
language,
unit: '€',
- precision: 0
+ maximumFractionDigits: 0
})}
)
diff --git a/source/sites/mon-entreprise.fr/pages/Créer/AfterRegistration.tsx b/source/sites/mon-entreprise.fr/pages/Créer/AfterRegistration.tsx
index e817573ba..bd867e016 100644
--- a/source/sites/mon-entreprise.fr/pages/Créer/AfterRegistration.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Créer/AfterRegistration.tsx
@@ -1,5 +1,5 @@
import { ScrollToTop } from 'Components/utils/Scroll'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
diff --git a/source/sites/mon-entreprise.fr/pages/Créer/CreationChecklist.tsx b/source/sites/mon-entreprise.fr/pages/Créer/CreationChecklist.tsx
index 4d069e57e..e17b61ebb 100644
--- a/source/sites/mon-entreprise.fr/pages/Créer/CreationChecklist.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Créer/CreationChecklist.tsx
@@ -4,7 +4,7 @@ import {
} from 'Actions/companyCreationChecklistActions'
import { goToCompanyStatusChoice } from 'Actions/companyStatusActions'
import Scroll from 'Components/utils/Scroll'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import emoji from 'react-easy-emoji'
import { Helmet } from 'react-helmet'
diff --git a/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/PickLegalStatus.tsx b/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/PickLegalStatus.tsx
index 9b055e452..930a2ef31 100644
--- a/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/PickLegalStatus.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/PickLegalStatus.tsx
@@ -1,4 +1,4 @@
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import { filter } from 'ramda'
import React, { useContext } from 'react'
import { Helmet } from 'react-helmet'
diff --git a/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/PreviousAnswers.tsx b/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/PreviousAnswers.tsx
index eab706712..7a88e4356 100644
--- a/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/PreviousAnswers.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/PreviousAnswers.tsx
@@ -1,4 +1,4 @@
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import { isNil } from 'ramda'
import React, { useContext } from 'react'
import { Trans } from 'react-i18next'
diff --git a/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/index.tsx b/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/index.tsx
index ee0cee966..d0812a4d7 100644
--- a/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/index.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Créer/GuideStatut/index.tsx
@@ -1,5 +1,5 @@
import { resetCompanyStatusChoice } from 'Actions/companyStatusActions'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import { toPairs } from 'ramda'
import React, { useContext, useEffect } from 'react'
import { Trans } from 'react-i18next'
diff --git a/source/sites/mon-entreprise.fr/pages/Créer/Home.tsx b/source/sites/mon-entreprise.fr/pages/Créer/Home.tsx
index 78728d224..5bccca196 100644
--- a/source/sites/mon-entreprise.fr/pages/Créer/Home.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Créer/Home.tsx
@@ -1,4 +1,4 @@
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import { Helmet } from 'react-helmet'
import { Trans, useTranslation } from 'react-i18next'
diff --git a/source/sites/mon-entreprise.fr/pages/Créer/index.tsx b/source/sites/mon-entreprise.fr/pages/Créer/index.tsx
index acfd2c859..cfea9bba9 100644
--- a/source/sites/mon-entreprise.fr/pages/Créer/index.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Créer/index.tsx
@@ -1,5 +1,5 @@
import { ScrollToTop } from 'Components/utils/Scroll'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import { Route, Switch } from 'react-router'
import { useLocation } from 'react-router-dom'
diff --git a/source/sites/mon-entreprise.fr/pages/Dev/Sitemap.tsx b/source/sites/mon-entreprise.fr/pages/Dev/Sitemap.tsx
index 273a30d64..ff73eaccd 100644
--- a/source/sites/mon-entreprise.fr/pages/Dev/Sitemap.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Dev/Sitemap.tsx
@@ -1,4 +1,4 @@
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import { generateSiteMap, SitePathsType } from '../../sitePaths'
diff --git a/source/sites/mon-entreprise.fr/pages/Documentation.tsx b/source/sites/mon-entreprise.fr/pages/Documentation.tsx
deleted file mode 100644
index 1e6d34cb7..000000000
--- a/source/sites/mon-entreprise.fr/pages/Documentation.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import Documentation from 'Components/Documentation'
-import { EngineContext } from 'Components/utils/EngineContext'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
-import React, { useContext } from 'react'
-import { useLocation } from 'react-router'
-
-export default function SiteDocumentation() {
- const engine = useContext(EngineContext)
- const sitePaths = useContext(SitePathsContext)
- const useDefaultValues =
- (useLocation().state as { useDefaultValues?: boolean })?.useDefaultValues ??
- false
- return (
-
- )
-}
diff --git a/source/components/Documentation/RulesList.css b/source/sites/mon-entreprise.fr/pages/Documentation/RulesList.css
similarity index 100%
rename from source/components/Documentation/RulesList.css
rename to source/sites/mon-entreprise.fr/pages/Documentation/RulesList.css
diff --git a/source/components/Documentation/RulesList.tsx b/source/sites/mon-entreprise.fr/pages/Documentation/RulesList.tsx
similarity index 70%
rename from source/components/Documentation/RulesList.tsx
rename to source/sites/mon-entreprise.fr/pages/Documentation/RulesList.tsx
index 1000aa410..4368b3a84 100644
--- a/source/components/Documentation/RulesList.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Documentation/RulesList.tsx
@@ -1,12 +1,12 @@
import SearchBar from 'Components/SearchBar'
-import React, { useContext } from 'react'
+import React from 'react'
import { Trans } from 'react-i18next'
import { useSelector } from 'react-redux'
+import { parsedRulesSelector } from 'Selectors/analyseSelectors'
import './RulesList.css'
-import { EngineContext } from 'Components/utils/EngineContext'
export default function RulesList() {
- const rules = useContext(EngineContext).getParsedRules()
+ const rules = useSelector(parsedRulesSelector)
return (
diff --git a/source/sites/mon-entreprise.fr/pages/Documentation/index.tsx b/source/sites/mon-entreprise.fr/pages/Documentation/index.tsx
new file mode 100644
index 000000000..234a6984a
--- /dev/null
+++ b/source/sites/mon-entreprise.fr/pages/Documentation/index.tsx
@@ -0,0 +1,18 @@
+import RulePage from 'Components/RulePage'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
+import React, { useContext } from 'react'
+import { Route, Switch } from 'react-router'
+import RulesList from './RulesList'
+
+export default function Documentation() {
+ const sitePaths = useContext(SitePathsContext)
+ return (
+
+
+
+
+ )
+}
diff --git a/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/Result.tsx b/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/Result.tsx
index bf16db536..1d1bf5ac1 100644
--- a/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/Result.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/Result.tsx
@@ -1,20 +1,22 @@
import RuleLink from 'Components/RuleLink'
-import { useEvaluation } from 'Components/utils/EngineContext'
import { formatValue } from 'Engine/format'
import React from 'react'
import emoji from 'react-easy-emoji'
import { Trans } from 'react-i18next'
import Skeleton from 'react-loading-skeleton'
import ReactToPrint from 'react-to-print'
+import { DottedName, EvaluatedRule } from 'Rules'
import Animate from 'Ui/animate'
+import { useRule } from '../../Simulateurs/ArtisteAuteur'
import simulationConfig from './config.yaml'
-import { DottedName } from 'Rules'
type ResultsProp = {
componentRef?: any
}
export function Results({ componentRef }: ResultsProp) {
- const results = useEvaluation(simulationConfig.objectifs as Array)
+ const results: EvaluatedRule[] = simulationConfig.objectifs.map(
+ (dottedName: DottedName) => useRule(dottedName)
+ )
const onGoingComputation = !results.filter(node => node.nodeValue != null)
.length
return (
@@ -49,10 +51,10 @@ export function Results({ componentRef }: ResultsProp) {
{r.nodeValue != null ? (
formatValue({
- nodeValue: r.nodeValue || 0,
+ value: r.nodeValue || 0,
language: 'fr',
unit: '€',
- precision: 0
+ maximumFractionDigits: 0
})
) : (
diff --git a/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/Récapitulatif.tsx b/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/Récapitulatif.tsx
new file mode 100644
index 000000000..c9c50975d
--- /dev/null
+++ b/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/Récapitulatif.tsx
@@ -0,0 +1,120 @@
+import CompanyDetails from 'Components/CompanyDetails'
+import { formatValue } from 'Engine/format'
+import React, { useRef } from 'react'
+import { Trans } from 'react-i18next'
+import { useSelector } from 'react-redux'
+import { RootState } from 'Reducers/rootReducer'
+import { DottedName } from 'Rules'
+import { situationSelector } from 'Selectors/analyseSelectors'
+import { Results } from './Result'
+
+export function AideDéclarationIndépendantsRécapitulatif() {
+ const situation = useSelector(situationSelector)
+ const siren = useSelector(
+ (state: RootState) => state.inFranceApp.existingCompany?.siren
+ )
+ const componentRef = useRef(null)
+
+ return (
+
+
+ Aide à la déclaration de revenus au titre de l'année 2019
+
+
+
+ Ce document atteste de votre bonne foi concernant votre déclaration
+ selon les éléments transmis.
+
+
+
+ Récapitulatif
+
+
+
+
+ {siren &&
}
+
+
+
+
+
+ {!situation[
+ "situation personnelle . domiciliation fiscale à l'étranger"
+ ] && (
+ <>
+
+
+
+
+
+ >
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+type SimpleFieldProps = {
+ dottedName: DottedName
+ unit?: string
+}
+function SimpleField({ dottedName, unit }: SimpleFieldProps) {
+ const situation = useSelector(situationSelector)
+ const rules = useSelector((state: RootState) => state.rules)
+ const value = situation[dottedName]
+ return value && (value === 'oui' || unit === '€') ? (
+
+ {rules[dottedName]?.question}
+
+
+
+ {value !== null && unit === '€' ? (
+ formatValue({
+ value: value || 0,
+ language: 'fr',
+ unit: unit,
+ maximumFractionDigits: 0
+ })
+ ) : (
+ <>{value}>
+ )}
+
+
+
+ ) : null
+}
diff --git a/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/index.tsx b/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/index.tsx
index 975a9a864..9307ca50c 100644
--- a/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/index.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Gérer/AideDéclarationIndépendant/index.tsx
@@ -3,29 +3,27 @@ import Aide from 'Components/conversation/Aide'
import Explicable from 'Components/conversation/Explicable'
import 'Components/TargetSelection.css'
import Warning from 'Components/ui/WarningBlock'
-import { useEvaluation, EngineContext } from 'Components/utils/EngineContext'
import { ScrollToTop } from 'Components/utils/Scroll'
import useDisplayOnIntersecting from 'Components/utils/useDisplayOnIntersecting'
import RuleInput from 'Engine/RuleInput'
import { ParsedRule } from 'Engine/types'
-import React, {
- useCallback,
- useEffect,
- useRef,
- useState,
- useContext
-} from 'react'
+import React, { useCallback, useEffect, useRef, useState } from 'react'
import { Trans } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
import { RootState } from 'Reducers/rootReducer'
import { DottedName } from 'Rules'
-import { situationSelector } from 'Selectors/simulationSelectors'
+import {
+ nextStepsSelector,
+ parsedRulesSelector,
+ ruleAnalysisSelector,
+ situationSelector
+} from 'Selectors/analyseSelectors'
import styled from 'styled-components'
import Animate from 'Ui/animate'
+import { useRule } from '../../Simulateurs/ArtisteAuteur'
import { CompanySection } from '../Home'
import simulationConfig from './config.yaml'
import { Results } from './Result'
-import { useNextQuestions } from 'Components/utils/useNextQuestion'
const lauchComputationWhenResultsInViewport = () => {
const dottedName = 'dirigeant . rémunération totale'
@@ -57,8 +55,7 @@ const lauchComputationWhenResultsInViewport = () => {
export default function AideDéclarationIndépendant() {
const dispatch = useDispatch()
- const rules = useContext(EngineContext).getParsedRules()
-
+ const rules = useSelector(parsedRulesSelector)
const company = useSelector(
(state: RootState) => state.inFranceApp.existingCompany
)
@@ -217,9 +214,9 @@ function SubSection({
dottedName: sectionDottedName,
hideTitle = false
}: SubSectionProp) {
- const parsedRules = useContext(EngineContext).getParsedRules()
- const ruleTitle = parsedRules[sectionDottedName]?.title
- const nextSteps = useNextQuestions()
+ const parsedRules = useSelector(parsedRulesSelector)
+ const ruleTitle = useRule(sectionDottedName)?.title
+ const nextSteps = useSelector(nextStepsSelector)
const situation = useSelector(situationSelector)
const title = hideTitle ? null : ruleTitle
const subQuestions = Object.values(parsedRules).filter(
@@ -246,8 +243,10 @@ type SimpleFieldProps = {
}
function SimpleField({ dottedName, question, summary }: SimpleFieldProps) {
const dispatch = useDispatch()
- const evaluatedRule = useEvaluation(dottedName)
- const rules = useContext(EngineContext).getParsedRules()
+ const evaluatedRule = useSelector((state: RootState) => {
+ return ruleAnalysisSelector(state, { dottedName })
+ })
+ const rules = useSelector(parsedRulesSelector)
const value = useSelector(situationSelector)[dottedName]
const [currentValue, setCurrentValue] = useState(value)
const dispatchValue = useCallback(
diff --git a/source/sites/mon-entreprise.fr/pages/Gérer/Home.tsx b/source/sites/mon-entreprise.fr/pages/Gérer/Home.tsx
index 07deec910..bcbfe9f6c 100644
--- a/source/sites/mon-entreprise.fr/pages/Gérer/Home.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Gérer/Home.tsx
@@ -7,7 +7,7 @@ import CompanyDetails from 'Components/CompanyDetails'
import FindCompany from 'Components/FindCompany'
import Overlay from 'Components/Overlay'
import { ScrollToTop } from 'Components/utils/Scroll'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext, useEffect, useRef, useState } from 'react'
import emoji from 'react-easy-emoji'
import { Helmet } from 'react-helmet'
diff --git a/source/sites/mon-entreprise.fr/pages/Gérer/SchemeSelection.tsx b/source/sites/mon-entreprise.fr/pages/Gérer/SchemeSelection.tsx
index 10a9883a9..d84fc7c3f 100644
--- a/source/sites/mon-entreprise.fr/pages/Gérer/SchemeSelection.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Gérer/SchemeSelection.tsx
@@ -1,4 +1,4 @@
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import emoji from 'react-easy-emoji'
import { Helmet } from 'react-helmet'
diff --git a/source/sites/mon-entreprise.fr/pages/Gérer/index.tsx b/source/sites/mon-entreprise.fr/pages/Gérer/index.tsx
index 0d9996ca2..260b6dd40 100644
--- a/source/sites/mon-entreprise.fr/pages/Gérer/index.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Gérer/index.tsx
@@ -1,10 +1,11 @@
import { ScrollToTop } from 'Components/utils/Scroll'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import { Trans } from 'react-i18next'
import { Route, Switch } from 'react-router'
import { NavLink, useLocation } from 'react-router-dom'
import AideDéclarationIndépendant from './AideDéclarationIndépendant/index'
+import { AideDéclarationIndépendantsRécapitulatif } from './AideDéclarationIndépendant/Récapitulatif'
import Embaucher from './Embaucher'
import Home from './Home'
import SécuritéSociale from './SécuritéSociale'
@@ -15,14 +16,28 @@ export default function Gérer() {
return (
<>
-
- ← Retour à mon activité
-
+
+ {location.pathname ===
+ '/gérer/aide-declaration-independants/récapitulatif' ? (
+
+ ← Retour à ma déclaration
+
+ ) : (
+
+ ← Retour à mon activité
+
+ )}
+
+
>
)
diff --git a/source/sites/mon-entreprise.fr/pages/Iframes/SimulateurEmbauche.tsx b/source/sites/mon-entreprise.fr/pages/Iframes/SimulateurEmbauche.tsx
index 3886b56ab..500b1f171 100644
--- a/source/sites/mon-entreprise.fr/pages/Iframes/SimulateurEmbauche.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Iframes/SimulateurEmbauche.tsx
@@ -1,4 +1,4 @@
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import { Helmet } from 'react-helmet'
import { SalarySimulation } from '../Simulateurs/Salarié'
diff --git a/source/sites/mon-entreprise.fr/pages/Landing/Landing.tsx b/source/sites/mon-entreprise.fr/pages/Landing/Landing.tsx
index 947ee94b7..1dbb0bc7b 100644
--- a/source/sites/mon-entreprise.fr/pages/Landing/Landing.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Landing/Landing.tsx
@@ -1,4 +1,4 @@
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import logoSvg from 'Images/logo.svg'
import React, { useContext } from 'react'
import emoji from 'react-easy-emoji'
diff --git a/source/sites/mon-entreprise.fr/pages/Nouveautés/Nouveautés.tsx b/source/sites/mon-entreprise.fr/pages/Nouveautés/Nouveautés.tsx
index 6ac90d094..d4921701b 100644
--- a/source/sites/mon-entreprise.fr/pages/Nouveautés/Nouveautés.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Nouveautés/Nouveautés.tsx
@@ -1,7 +1,7 @@
import MoreInfosOnUs from 'Components/MoreInfosOnUs'
import { MarkdownWithAnchorLinks } from 'Components/utils/markdown'
import { ScrollToTop } from 'Components/utils/Scroll'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext, useEffect } from 'react'
import emoji from 'react-easy-emoji'
import { Redirect, useHistory, useRouteMatch } from 'react-router'
diff --git a/source/sites/mon-entreprise.fr/pages/Simulateurs/ArtisteAuteur.tsx b/source/sites/mon-entreprise.fr/pages/Simulateurs/ArtisteAuteur.tsx
index c936b2a45..ed6559fc3 100644
--- a/source/sites/mon-entreprise.fr/pages/Simulateurs/ArtisteAuteur.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Simulateurs/ArtisteAuteur.tsx
@@ -1,21 +1,33 @@
import { setSimulationConfig, updateSituation } from 'Actions/actions'
import { DistributionBranch } from 'Components/Distribution'
-import { Condition } from 'Components/EngineValue'
+import RuleLink from 'Components/RuleLink'
import SimulateurWarning from 'Components/SimulateurWarning'
import config from 'Components/simulationConfigs/artiste-auteur.yaml'
import 'Components/TargetSelection.css'
import { IsEmbeddedContext } from 'Components/utils/embeddedContext'
-import { EngineContext, useEvaluation } from 'Components/utils/EngineContext'
-import Value from 'Components/EngineValue'
+import { formatValue } from 'Engine/format'
import RuleInput from 'Engine/RuleInput'
+import { getRuleFromAnalysis } from 'Engine/ruleUtils'
import React, { createContext, useContext, useEffect, useState } from 'react'
-import { Trans } from 'react-i18next'
+import { Trans, useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
+import { RootState } from 'Reducers/rootReducer'
import { DottedName } from 'Rules'
-import { situationSelector } from 'Selectors/simulationSelectors'
+import {
+ analysisWithDefaultsSelector,
+ parsedRulesSelector,
+ ruleAnalysisSelector,
+ situationSelector
+} from 'Selectors/analyseSelectors'
import styled from 'styled-components'
import Animate from 'Ui/animate'
+export function useRule(dottedName: DottedName) {
+ const analysis = useSelector(analysisWithDefaultsSelector)
+ const getRule = getRuleFromAnalysis(analysis)
+ return getRule(dottedName)
+}
+
const InitialRenderContext = createContext(false)
function useInitialRender() {
const [initialRender, setInitialRender] = useState(true)
@@ -65,12 +77,16 @@ type SimpleFieldProps = {
}
function SimpleField({ dottedName }: SimpleFieldProps) {
+ const rule = useSelector(parsedRulesSelector)[dottedName]
const dispatch = useDispatch()
- const rule = useEvaluation(dottedName)
+ const analysis = useSelector((state: RootState) => {
+ return ruleAnalysisSelector(state, { dottedName })
+ })
const initialRender = useContext(InitialRenderContext)
- const parsedRules = useContext(EngineContext).getParsedRules()
- const value = useSelector(situationSelector)[dottedName] ?? rule['par défaut']
- if (rule.isApplicable === false || rule.isApplicable === null) {
+ const parsedRules = useSelector(parsedRulesSelector)
+ const value = useSelector(situationSelector)[dottedName]
+
+ if (!analysis.isApplicable) {
return null
}
@@ -131,7 +147,10 @@ const ResultLabel = styled.div`
function CotisationsResult() {
const [display, setDisplay] = useState(false)
+ const { i18n } = useTranslation()
const situation = useSelector(situationSelector)
+ const cotisationRule = useRule('artiste-auteur . cotisations')
+ const value = cotisationRule.nodeValue
if (Object.keys(situation).length && !display) {
setDisplay(true)
@@ -147,15 +166,16 @@ function CotisationsResult() {
Montant des cotisations
-
+
+ {formatValue({
+ value: cotisationRule.nodeValue,
+ language: i18n.language,
+ unit: '€',
+ maximumFractionDigits: 0
+ })}
+
-
-
-
+ {cotisationRule.nodeValue ? : null}
)
}
@@ -180,10 +200,9 @@ const branches = [
] as const
function RepartitionCotisations() {
- const engine = useContext(EngineContext)
const cotisations = branches.map(branch => ({
...branch,
- value: engine.evaluate(branch.dottedName).nodeValue as number
+ value: useRule(branch.dottedName).nodeValue as number
}))
const maximum = Math.max(...cotisations.map(x => x.value))
const total = cotisations.map(x => x.value).reduce((a = 0, b) => a + b)
diff --git a/source/sites/mon-entreprise.fr/pages/Simulateurs/AutoEntrepreneur.tsx b/source/sites/mon-entreprise.fr/pages/Simulateurs/AutoEntrepreneur.tsx
index a9e76da9b..96d705564 100644
--- a/source/sites/mon-entreprise.fr/pages/Simulateurs/AutoEntrepreneur.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Simulateurs/AutoEntrepreneur.tsx
@@ -5,12 +5,13 @@ import autoEntrepreneurConfig from 'Components/simulationConfigs/auto-entreprene
import StackedBarChart from 'Components/StackedBarChart'
import { ThemeColorsContext } from 'Components/utils/colors'
import { IsEmbeddedContext } from 'Components/utils/embeddedContext'
-import { EngineContext } from 'Components/utils/EngineContext'
+import { getRuleFromAnalysis } from 'Engine/ruleUtils'
import { default as React, useContext } from 'react'
import { Helmet } from 'react-helmet'
import { Trans, useTranslation } from 'react-i18next'
-import { useDispatch } from 'react-redux'
+import { useDispatch, useSelector } from 'react-redux'
import { useLocation } from 'react-router'
+import { analysisWithDefaultsSelector } from 'Selectors/analyseSelectors'
export default function AutoEntrepreneur() {
const dispatch = useDispatch()
@@ -53,11 +54,12 @@ export default function AutoEntrepreneur() {
}
function ExplanationSection() {
- const engine = useContext(EngineContext)
+ const analysis = useSelector(analysisWithDefaultsSelector)
+ const getRule = getRuleFromAnalysis(analysis)
const { t } = useTranslation()
const { palettes } = useContext(ThemeColorsContext)
- const impôt = engine.evaluate('impôt')
+ const impôt = getRule('impôt')
return (
@@ -66,9 +68,7 @@ function ExplanationSection() {
{
const dispatch = useDispatch()
const location = useLocation<{ fromGérer?: boolean }>()
- const sitePaths = useContext(SitePathsContext)
dispatch(setSimulationConfig(salariéConfig, location.state?.fromGérer))
+ const sitePaths = useContext(SitePathsContext)
return (
<>
diff --git a/source/sites/mon-entreprise.fr/pages/integration/Options.tsx b/source/sites/mon-entreprise.fr/pages/integration/Options.tsx
index a9f55561e..8a0f886f8 100644
--- a/source/sites/mon-entreprise.fr/pages/integration/Options.tsx
+++ b/source/sites/mon-entreprise.fr/pages/integration/Options.tsx
@@ -1,4 +1,4 @@
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import emoji from 'react-easy-emoji'
import { Trans } from 'react-i18next'
diff --git a/source/sites/mon-entreprise.fr/pages/integration/index.tsx b/source/sites/mon-entreprise.fr/pages/integration/index.tsx
index 19030abca..26d6bde0e 100644
--- a/source/sites/mon-entreprise.fr/pages/integration/index.tsx
+++ b/source/sites/mon-entreprise.fr/pages/integration/index.tsx
@@ -1,5 +1,5 @@
import { ScrollToTop } from 'Components/utils/Scroll'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import { Trans } from 'react-i18next'
import { Route, Switch, useLocation } from 'react-router'
diff --git a/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/Activité.tsx b/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/Activité.tsx
index c02c9c6e9..a959ceea4 100644
--- a/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/Activité.tsx
+++ b/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/Activité.tsx
@@ -1,7 +1,7 @@
import { Markdown } from 'Components/utils/markdown'
import { ScrollToTop } from 'Components/utils/Scroll'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
-import Value from 'Components/EngineValue'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
+import Value from 'Components/Value'
import React, { useContext } from 'react'
import emoji from 'react-easy-emoji'
import { Trans, useTranslation } from 'react-i18next'
@@ -14,7 +14,6 @@ import ExceptionsExonération from './ExceptionsExonération'
import NextButton from './NextButton'
import { estExonéréeSelector } from './selectors'
import { StoreContext } from './StoreContext'
-import { formatValue } from 'Engine/format'
export default function Activité({
match: {
@@ -111,12 +110,9 @@ export default function Activité({
defaultChecked={seuilRevenus === 'AUCUN'}
/>{' '}
inférieurs à{' '}
- {formatValue({
- nodeValue: activité['seuil déclaration'],
- precision: 0,
- language,
- unit: '€'
- })}
+
+ {activité['seuil déclaration']}
+
)}
@@ -129,12 +125,9 @@ export default function Activité({
defaultChecked={seuilRevenus === 'IMPOSITION'}
/>{' '}
inférieurs à{' '}
- {formatValue({
- nodeValue: activité['seuil pro'],
- precision: 0,
- language,
- unit: '€'
- })}
+
+ {activité['seuil pro']}
+
{activité['seuil régime général'] && (
@@ -149,12 +142,9 @@ export default function Activité({
}
/>{' '}
supérieurs à{' '}
- {formatValue({
- nodeValue: activité['seuil pro'],
- precision: 0,
- language,
- unit: '€'
- })}
+
+ {activité['seuil pro']}
+
)}
@@ -170,13 +160,9 @@ export default function Activité({
}
/>{' '}
supérieurs à{' '}
- {formatValue({
- nodeValue:
- activité['seuil régime général'] || activité['seuil pro'],
- precision: 0,
- language,
- unit: '€'
- })}
+
+ {activité['seuil régime général'] || activité['seuil pro']}
+
diff --git a/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/ActivitésSelection.tsx b/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/ActivitésSelection.tsx
index 619187011..a1fbe8810 100644
--- a/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/ActivitésSelection.tsx
+++ b/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/ActivitésSelection.tsx
@@ -1,6 +1,6 @@
import classnames from 'classnames'
import { ScrollToTop } from 'Components/utils/Scroll'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import { intersection } from 'ramda'
import React, { useCallback, useContext } from 'react'
import emoji from 'react-easy-emoji'
diff --git a/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/NextButton.tsx b/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/NextButton.tsx
index 06d3df4ea..8061a2d9a 100644
--- a/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/NextButton.tsx
+++ b/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/NextButton.tsx
@@ -1,5 +1,5 @@
import classnames from 'classnames'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import { Trans } from 'react-i18next'
import { Link } from 'react-router-dom'
diff --git a/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/VotreSituation.tsx b/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/VotreSituation.tsx
index 8b97f6101..3476fff1b 100644
--- a/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/VotreSituation.tsx
+++ b/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/VotreSituation.tsx
@@ -1,5 +1,5 @@
import { ScrollToTop } from 'Components/utils/Scroll'
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import { Helmet } from 'react-helmet'
import { Trans, useTranslation } from 'react-i18next'
diff --git a/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/index.tsx b/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/index.tsx
index d06e3398b..6b9570bed 100644
--- a/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/index.tsx
+++ b/source/sites/mon-entreprise.fr/pages/ÉconomieCollaborative/index.tsx
@@ -1,4 +1,4 @@
-import { SitePathsContext } from 'Components/utils/SitePathsContext'
+import { SitePathsContext } from 'Components/utils/withSitePaths'
import React, { useContext } from 'react'
import { Trans } from 'react-i18next'
import { Route, Switch } from 'react-router'
diff --git a/source/sites/mon-entreprise.fr/sitePaths.ts b/source/sites/mon-entreprise.fr/sitePaths.ts
index 346ff3e28..04129e035 100644
--- a/source/sites/mon-entreprise.fr/sitePaths.ts
+++ b/source/sites/mon-entreprise.fr/sitePaths.ts
@@ -93,6 +93,10 @@ export const constructLocalizedSitePath = (language: string) => {
index: t(
'path.gérer.déclaration-indépendant.index',
'/aide-declaration-independants'
+ ),
+ récapitulatif: t(
+ 'path.gérer.déclaration-indépendant.récapitulatif',
+ '/récapitulatif'
)
}
},
diff --git a/source/sites/publi.codes/Studio.tsx b/source/sites/publi.codes/Studio.tsx
index eead76968..86fe3bd5c 100644
--- a/source/sites/publi.codes/Studio.tsx
+++ b/source/sites/publi.codes/Studio.tsx
@@ -1,13 +1,12 @@
// import { ControlledEditor } from '@monaco-editor/react'
-import Engine from 'Engine'
import { formatValue } from 'Engine/format'
+import Engine from 'Engine/react'
import { safeLoad } from 'js-yaml'
import { last } from 'ramda'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import emoji from 'react-easy-emoji'
import MonacoEditor from 'react-monaco-editor'
import { useLocation } from 'react-router'
-import { DottedName } from 'Rules'
import styled from 'styled-components'
const EXAMPLE_CODE = `
@@ -84,6 +83,7 @@ export default function Studio() {
setEditorValue(newValue ?? '')}
options={{
@@ -96,15 +96,9 @@ export default function Studio() {
flex: 1;
`}
>
-
- {/* TODO: prévoir de changer la signature de EngineProvider */}
-
-
-
+
+
+
)
@@ -112,23 +106,32 @@ export default function Studio() {
type ResultsProps = {
targets: string[]
- rules: string
onClickShare: React.MouseEventHandler
}
-export const Results = ({ targets, onClickShare, rules }: ResultsProps) => {
+export const Results = ({ targets, onClickShare }: ResultsProps) => {
const [rule, setCurrentTarget] = useState()
const currentTarget = rule ?? (last(targets) as string)
- const engine = useMemo(() => new Engine(rules), [rules])
+ const error = Engine.useError()
// EN ATTENDANT d'AVOIR une meilleure gestion d'erreur, on va mocker
// console.warn
const warnings: string[] = []
const originalWarn = console.warn
console.warn = warning => warnings.push(warning)
- const evaluation = engine.evaluate(currentTarget)
+ const analysis = Engine.useEvaluation(currentTarget)
console.warn = originalWarn
- return (
+ return error !== null ? (
+
+ {nl2br(error)}
+
+ ) : (
<>
{
{nl2br(warning)}
))}
- {evaluation ? (
+ {analysis ? (
Résultats
- {evaluation.isApplicable === false ? (
+ {analysis.isApplicable === false ? (
<>{emoji('❌')} Cette règle n'est pas applicable>
) : (
<>
- {formatValue({
- ...evaluation,
- language: 'fr'
- })}
+
- {'temporalValue' in evaluation &&
- evaluation.temporalValue &&
- evaluation.temporalValue
- .filter(({ value }) => value !== false)
- .map(({ start: du, end: au, value }) => (
-
-
- Du {du} au {au} :{' '}
-
-
- {formatValue({
- nodeValue: value,
- unit: evaluation.unit,
- language: 'fr'
- })}
-
{' '}
-
-
- ))}
+ {analysis.temporalValue
+ ?.filter(({ value }) => value !== false)
+ .map(({ start: du, end: au, value }) => (
+
+
+ Du {du} au {au} :{' '}
+
+ {formatValue({ value, unit: analysis.unit })}
{' '}
+
+
+ ))}
>
)}
@@ -240,41 +232,13 @@ const Layout = styled.div`
flex-grow: 1;
display: flex;
height: 100%;
- > :first-child {
- width: 55% !important;
- }
@media (max-width: 960px) {
flex-direction: column;
padding: 20px;
- > :first-child {
- width: 100% !important;
+ section {
+ width: 100%;
}
}
`
-
-class ErrorBoundary extends React.Component {
- state: { error: false | string } = { error: false }
-
- static getDerivedStateFromError(error) {
- console.error(error)
- return { error: error.message }
- }
- render() {
- if (this.state.error) {
- return (
-
- {nl2br(this.state.error)}
-
- )
- }
- return this.props.children
- }
-}
diff --git a/test/contrôles.test.js b/test/contrôles.test.js
index 48dcdd6a2..803b112a7 100644
--- a/test/contrôles.test.js
+++ b/test/contrôles.test.js
@@ -51,7 +51,7 @@ describe('controls', function() {
})
it('Should allow imbricated conditions', function() {
- const engine = new Engine(rawRules)
+ const engine = new Engine({ rules: rawRules })
let controls = engine.setSituation({ brut: 2000000 }).controls()
expect(
controls.find(
diff --git a/test/conversation.test.js b/test/conversation.test.js
index 8363d04eb..b92344a78 100644
--- a/test/conversation.test.js
+++ b/test/conversation.test.js
@@ -1,25 +1,102 @@
import { expect } from 'chai'
-import { getNextQuestions } from '../source/components/utils/useNextQuestion'
-import Engine from 'Engine'
+import { assocPath, merge } from 'ramda'
+import reducers from 'Reducers/rootReducer'
+import rules from 'Rules'
+import salariéConfig from '../source/components/simulationConfigs/salarié.yaml'
+import {
+ currentQuestionSelector,
+ nextStepsSelector
+} from '../source/selectors/analyseSelectors'
+let baseState = {
+ simulation: { defaultUnit: '€/an', situation: {}, foldedSteps: [] }
+}
describe('conversation', function() {
it('should start with the first missing variable', function() {
- const missingVariables = new Engine({
+ let rules = {
+ // TODO - this won't work without the indirection, figure out why
+ 'top . startHere': { formule: { somme: ['a', 'b'] } },
+ 'top . a': { formule: 'aa' },
+ 'top . b': { formule: 'bb' },
+ 'top . aa': { question: '?', titre: 'a', unité: '€' },
+ 'top . bb': { question: '?', titre: 'b', unité: '€' }
+ },
+ state = merge(baseState, {
+ rules,
+ simulation: {
+ defaultUnit: '€/an',
+ config: { objectifs: ['top . startHere'] },
+ foldedSteps: []
+ }
+ }),
+ currentQuestion = currentQuestionSelector(state)
+
+ expect(currentQuestion).to.equal('top . aa')
+ })
+ it('should deal with double unfold', function() {
+ let rules = {
// TODO - this won't work without the indirection, figure out why
- 'top . startHere': { formule: { somme: ['a', 'b'] } },
+ 'top . startHere': {
+ formule: { somme: ['a', 'b', 'c'] }
+ },
'top . a': { formule: 'aa' },
'top . b': { formule: 'bb' },
+ 'top . c': { formule: 'cc' },
'top . aa': { question: '?', titre: 'a', unité: '€' },
- 'top . bb': { question: '?', titre: 'b', unité: '€' }
- }).evaluate('top . startHere').missingVariables
- expect(getNextQuestions([missingVariables])[0]).to.equal('top . aa')
+ 'top . bb': { question: '?', titre: 'b', unité: '€' },
+ 'top . cc': { question: '?', titre: 'c', unité: '€' }
+ }
+
+ let step1 = merge(baseState, {
+ rules,
+ simulation: {
+ defaultUnit: '€/an',
+ config: { objectifs: ['top . startHere'] },
+ foldedSteps: []
+ }
+ })
+ let step2 = reducers(
+ assocPath(['simulation', 'situation'], { 'top . aa': '1' }, step1),
+ {
+ type: 'STEP_ACTION',
+ name: 'fold',
+ step: 'top . aa'
+ }
+ )
+
+ let step3 = reducers(
+ assocPath(
+ ['simulation', 'situation'],
+ { 'top . aa': '1', 'top . bb': '1' },
+ step2
+ ),
+ {
+ type: 'STEP_ACTION',
+ name: 'fold',
+ step: 'top . bb'
+ }
+ )
+ let step4 = reducers(step3, {
+ type: 'STEP_ACTION',
+ name: 'unfold',
+ step: 'top . aa'
+ })
+ let lastStep = reducers(step4, {
+ type: 'STEP_ACTION',
+ name: 'unfold',
+ step: 'top . bb'
+ })
+
+ expect(currentQuestionSelector(lastStep)).to.equal('top . bb')
+ expect(lastStep.simulation).to.have.property('foldedSteps')
+ expect(lastStep.simulation.foldedSteps).to.have.lengthOf(0)
})
+
it('should first ask for questions without defaults, then those with defaults', function() {
- const engine = new Engine({
+ let rules = {
net: { formule: 'brut - cotisation' },
brut: {
- question: 'Quel est le salaire brut ?',
- unité: '€/an'
+ question: 'Quel est le salaire brut ?'
},
cotisation: {
formule: {
@@ -45,24 +122,47 @@ describe('conversation', function() {
question: 'Est-ce un cadre ?',
'par défaut': 'non'
}
+ }
+
+ let step1 = merge(baseState, {
+ rules,
+ simulation: {
+ defaultUnit: '€/an',
+ config: { objectifs: ['net'] },
+ foldedSteps: []
+ }
})
+ expect(currentQuestionSelector(step1)).to.equal('brut')
- expect(
- getNextQuestions([engine.evaluate('net').missingVariables])[0]
- ).to.equal('brut')
+ let step2 = reducers(
+ assocPath(['simulation', 'situation', 'brut'], '2300', step1),
+ {
+ type: 'STEP_ACTION',
+ name: 'fold',
+ step: 'brut'
+ }
+ )
- engine.setSituation({
- brut: 2300
- })
-
- expect(
- getNextQuestions([engine.evaluate('net').missingVariables])[0]
- ).to.equal(undefined)
-
- expect(
- getNextQuestions([
- engine.evaluate('net', { useDefaultValues: false }).missingVariables
- ])[0]
- ).to.equal('cadre')
+ expect(step2.simulation).to.have.property('foldedSteps')
+ expect(step2.simulation.foldedSteps).to.have.lengthOf(1)
+ expect(step2.simulation.foldedSteps[0]).to.equal('brut')
+ expect(currentQuestionSelector(step2)).to.equal('cadre')
+ })
+})
+describe('real conversation', function() {
+ it('should not have more than X questions', function(done) {
+ let state = merge(baseState, {
+ rules,
+ simulation: {
+ defaultUnit: '€/an',
+ config: salariéConfig,
+ foldedSteps: []
+ }
+ }),
+ nextSteps = nextStepsSelector(state)
+
+ expect(nextSteps.length).to.be.below(30) // If this breaks, that's good news
+ expect(nextSteps.length).to.be.above(10)
+ done()
})
})
diff --git a/test/ficheDePaieSelector.test.js b/test/ficheDePaieSelector.test.js
new file mode 100644
index 000000000..abd718d7d
--- /dev/null
+++ b/test/ficheDePaieSelector.test.js
@@ -0,0 +1,70 @@
+import { expect } from 'chai'
+import salariéConfig from 'Components/simulationConfigs/salarié.yaml'
+import { getRuleFromAnalysis } from 'Engine/ruleUtils'
+import rules from 'Rules'
+import { analysisWithDefaultsSelector } from 'Selectors/analyseSelectors'
+import {
+ analysisToCotisationsSelector,
+ COTISATION_BRANCHE_ORDER
+} from 'Selectors/ficheDePaieSelectors'
+
+let state = {
+ rules,
+ simulation: {
+ defaultUnit: '€/mois',
+ config: salariéConfig,
+ situation: {
+ 'contrat salarié . rémunération . brut de base': '2300',
+ 'entreprise . effectif': '50'
+ },
+ foldedSteps: []
+ }
+}
+
+let cotisations = null,
+ analysis
+
+describe('pay slip selector', function() {
+ beforeEach(() => {
+ cotisations = analysisToCotisationsSelector(state)
+ analysis = analysisWithDefaultsSelector(state)
+
+ expect(cotisations).not.to.eq(null)
+ })
+ it('should have cotisations grouped by branches in the proper ordering', function() {
+ let branches = cotisations.map(([branche]) => branche)
+ expect(branches).to.eql(COTISATION_BRANCHE_ORDER)
+ })
+
+ it('should collect all cotisations in a branche', function() {
+ let cotisationsSanté = (cotisations.find(([branche]) =>
+ branche.includes('santé')
+ ) || [])[1].map(cotisation => cotisation.name)
+ expect(cotisationsSanté).to.have.lengthOf(2)
+ expect(cotisationsSanté).to.include('maladie')
+ expect(cotisationsSanté).to.include('complémentaire santé')
+ })
+
+ it('should sum all cotisations', function() {
+ let pat = getRuleFromAnalysis(analysis)(
+ 'contrat salarié . cotisations . patronales'
+ ),
+ sal = getRuleFromAnalysis(analysis)(
+ 'contrat salarié . cotisations . salariales'
+ )
+ expect(pat.nodeValue).to.be.closeTo(808.9, 5)
+ expect(sal.nodeValue).to.be.closeTo(498, 5)
+ })
+
+ it('should have value for "salarié" and "employeur" for a cotisation', function() {
+ let cotisationATMP = (cotisations.find(([branche]) =>
+ branche.includes('accidents du travail et maladies professionnelles')
+ ) || [])[1][0]
+ expect(cotisationATMP.montant.partSalariale).to.be.closeTo(0, 0.1)
+ let defaultATMPRate = 2.22 / 100
+ expect(cotisationATMP.montant.partPatronale).to.be.closeTo(
+ 2300 * defaultATMPRate,
+ 1
+ )
+ })
+})
diff --git a/test/missingVariables.test.js b/test/generateQuestions.test.js
similarity index 82%
rename from test/missingVariables.test.js
rename to test/generateQuestions.test.js
index 70f0e356d..789aa99d2 100644
--- a/test/missingVariables.test.js
+++ b/test/generateQuestions.test.js
@@ -1,7 +1,7 @@
import { expect } from 'chai'
import Engine from 'Engine'
import rules from 'Rules'
-import { getNextSteps } from '../source/components/utils/useNextQuestion'
+import { getNextSteps } from '../source/engine/generateQuestions'
describe('Missing variables', function() {
it('should identify missing variables', function() {
@@ -19,7 +19,8 @@ describe('Missing variables', function() {
'sum . evt . ko': {}
}
const result = Object.keys(
- new Engine(rawRules).evaluate('sum . startHere').missingVariables
+ new Engine({ rules: rawRules }).evaluate('sum . startHere')
+ .missingVariables
)
expect(result).to.include('sum . evt . ko')
@@ -37,7 +38,8 @@ describe('Missing variables', function() {
'sum . evt . nyet': {}
}
const result = Object.keys(
- new Engine(rawRules).evaluate('sum . startHere').missingVariables
+ new Engine({ rules: rawRules }).evaluate('sum . startHere')
+ .missingVariables
)
expect(result).to.include('sum . evt . nyet')
@@ -54,7 +56,8 @@ describe('Missing variables', function() {
'sum . trois': {}
}
const result = Object.keys(
- new Engine(rawRules).evaluate('sum . startHere').missingVariables
+ new Engine({ rules: rawRules }).evaluate('sum . startHere')
+ .missingVariables
)
expect(result).to.be.empty
@@ -72,7 +75,8 @@ describe('Missing variables', function() {
'sum . trois': {}
}
const result = Object.keys(
- new Engine(rawRules).evaluate('sum . startHere').missingVariables
+ new Engine({ rules: rawRules }).evaluate('sum . startHere')
+ .missingVariables
)
expect(result).to.be.empty
@@ -87,7 +91,8 @@ describe('Missing variables', function() {
}
}
const result = Object.keys(
- new Engine(rawRules).evaluate('top . startHere').missingVariables
+ new Engine({ rules: rawRules }).evaluate('top . startHere')
+ .missingVariables
)
expect(result).to.include('top . trois')
@@ -103,7 +108,8 @@ describe('Missing variables', function() {
}
}
const result = Object.keys(
- new Engine(rawRules).evaluate('top . startHere').missingVariables
+ new Engine({ rules: rawRules }).evaluate('top . startHere')
+ .missingVariables
)
expect(result).to.be.empty
@@ -119,8 +125,8 @@ describe('Missing variables', function() {
}
}
const result = Object.keys(
- new Engine(rawRules)
- .setSituation({ 'top . trois': "'ko'" })
+ new Engine({ rules: rawRules })
+ .setSituation({ 'top . trois': 'ko' })
.evaluate('top . startHere').missingVariables
)
@@ -171,7 +177,8 @@ describe('Missing variables', function() {
'top . quatre': {}
}
const result = Object.keys(
- new Engine(rawRules).evaluate('top . startHere').missingVariables
+ new Engine({ rules: rawRules }).evaluate('top . startHere')
+ .missingVariables
)
expect(result).to.include('top . dix')
@@ -197,7 +204,7 @@ describe('nextSteps', function() {
}
const result = Object.keys(
- new Engine(rawRules).evaluate('top . sum').missingVariables
+ new Engine({ rules: rawRules }).evaluate('top . sum').missingVariables
)
expect(result).to.have.lengthOf(1)
@@ -216,7 +223,7 @@ describe('nextSteps', function() {
}
const result = Object.keys(
- new Engine(rawRules).evaluate('top . sum').missingVariables
+ new Engine({ rules: rawRules }).evaluate('top . sum').missingVariables
)
expect(result).to.have.lengthOf(1)
@@ -239,7 +246,7 @@ describe('nextSteps', function() {
'top . sum . evt . ko': {}
}
const result = Object.keys(
- new Engine(rawRules).evaluate('top . sum').missingVariables
+ new Engine({ rules: rawRules }).evaluate('top . sum').missingVariables
)
expect(result).to.eql(['top . sum . evt'])
@@ -247,15 +254,13 @@ describe('nextSteps', function() {
it('should ask "motif CDD" if "CDD" applies', function() {
const result = Object.keys(
- new Engine(rules)
+ new Engine({ rules, useDefaultValues: false })
.setSituation({
'contrat salarié': 'oui',
'contrat salarié . CDD': 'oui',
'contrat salarié . rémunération . brut de base': '2300'
})
- .evaluate('contrat salarié . rémunération . net', {
- useDefaultValues: false
- }).missingVariables
+ .evaluate('contrat salarié . rémunération . net').missingVariables
)
expect(result).to.include('contrat salarié . CDD . motif')
@@ -264,19 +269,19 @@ describe('nextSteps', function() {
describe('getNextSteps', function() {
it('should give priority to questions that advance most targets', function() {
- let missingVariablesByTarget = [
- {
+ let missingVariablesByTarget = {
+ chargé: {
effectif: 34.01,
cadre: 30
},
- {
+ net: {
cadre: 10.1
},
- {
+ aides: {
effectif: 32.0,
cadre: 10
}
- ]
+ }
let result = getNextSteps(missingVariablesByTarget)
@@ -284,17 +289,17 @@ describe('getNextSteps', function() {
})
it('should give priority to questions by total weight when advancing the same target count', function() {
- let missingVariablesByTarget = [
- {
+ let missingVariablesByTarget = {
+ chargé: {
effectif: 24.01,
cadre: 30
},
- {
+ net: {
effectif: 24.01,
cadre: 10.1
},
- {}
- ]
+ aides: {}
+ }
let result = getNextSteps(missingVariablesByTarget)
diff --git a/test/inversion.test.js b/test/inversion.test.js
index bb6cb3438..97f851bda 100644
--- a/test/inversion.test.js
+++ b/test/inversion.test.js
@@ -14,7 +14,7 @@ describe('inversions', () => {
brut:
unité: €
`
- const result = new Engine(rules)
+ const result = new Engine({ rules })
.setSituation({ brut: 2300 })
.evaluate('net')
@@ -36,7 +36,7 @@ describe('inversions', () => {
avec:
- net
`
- const result = new Engine(rules)
+ const result = new Engine({ rules })
.setSituation({ net: 2000 })
.evaluate('brut')
@@ -58,7 +58,9 @@ describe('inversions', () => {
avec:
- net
`
- const result = new Engine(rules).setSituation({ net: 0 }).evaluate('brut')
+ const result = new Engine({ rules })
+ .setSituation({ net: 0 })
+ .evaluate('brut')
expect(result.nodeValue).to.be.closeTo(0, 0.0001)
})
@@ -84,10 +86,10 @@ describe('inversions', () => {
- net
cadre:
assiette:
- formule: 67€ + brut
+ formule: 67 + brut
`
- const result = new Engine(rules).evaluate('brut')
+ const result = new Engine({ rules }).evaluate('brut')
expect(result.nodeValue).to.be.null
expect(Object.keys(result.missingVariables)).to.include('brut')
@@ -125,7 +127,7 @@ describe('inversions', () => {
taxe:
formule:
produit:
- assiette: 1200 €
+ assiette: 1200
variations:
- si: cadre
alors:
@@ -133,7 +135,7 @@ describe('inversions', () => {
- sinon:
taux: 70%
`
- const result = new Engine(rules)
+ const result = new Engine({ rules })
.setSituation({ net: 2000 })
.evaluate('brut')
expect(result.nodeValue).to.be.null
@@ -174,7 +176,7 @@ describe('inversions', () => {
formule: 67 + brut
`
- const result = new Engine(rules)
+ const result = new Engine({ rules })
.setSituation({ net: 2000, cadre: 'oui' })
.evaluate('total')
expect(result.nodeValue).to.be.closeTo(3750, 1)
@@ -212,7 +214,7 @@ describe('inversions', () => {
- net
- total
`
- const result = new Engine(rules)
+ const result = new Engine({ rules })
.setSituation({ net: 2000 })
.evaluate('total')
expect(result.nodeValue).to.be.closeTo(3750, 1)
diff --git a/test/library.test.js b/test/library.test.js
index 67e150b76..6e09894ad 100644
--- a/test/library.test.js
+++ b/test/library.test.js
@@ -7,7 +7,7 @@ import sasuRules from './rules/sasu.yaml'
describe('library', function() {
it('should evaluate one target with no input data', function() {
let target = 'contrat salarié . rémunération . net'
- let engine = new Engine(rules)
+ let engine = new Engine({ rules })
engine.setSituation({
'contrat salarié . rémunération . brut de base': 2300
})
@@ -23,20 +23,20 @@ ya:
yi:
formule: yo + 2
`
- let engine = new Engine(rules)
+ let engine = new Engine({ rules })
expect(engine.evaluate('ya').nodeValue).to.equal(201)
expect(engine.evaluate('yi').nodeValue).to.equal(202)
})
- it.skip('should let the user add rules to an existing rule base', function() {
- let extraRules = `
+ it.skip('should let the user add rules to the default ones', function() {
+ let rules = `
yo:
formule: 1
ya:
formule: contrat salarié . rémunération . net + yo
`
- let engine = new Engine(rules, extraRules)
+ let engine = new Engine({ extra: rules })
engine.setSituation({
'contrat salarié . rémunération . brut de base': 2300
})
@@ -47,7 +47,7 @@ ya:
'should let the user extend the rules constellation in a serious manner',
function() {
let CA = 550 * 16
- let engine = new Engine(rules, sasuRules)
+ let engine = new Engine({ extra: sasuRules })
engine.setSituation({
'chiffre affaires': CA
})
@@ -64,10 +64,10 @@ ya:
'contrat salarié . rémunération . net après impôt': salaireNetAprèsImpôt,
'chiffre affaires': CA
})
- let [revenuDisponible, dividendes] = [
+ let [revenuDisponible, dividendes] = engine.evaluate([
'contrat salarié . rémunération . net après impôt',
'dividendes . net'
- ].map(name => engine.evaluate(name))
+ ])
expect(revenuDisponible.nodeValue).to.be.closeTo(2324, 1)
expect(dividendes.nodeValue).to.be.closeTo(2507, 1)
@@ -110,7 +110,7 @@ impôt sur le revenu à payer:
plafond: 1177
`
- let engine = new Engine(rules)
+ let engine = new Engine({ rules })
engine.setSituation({
'revenu imposable': '48000'
})
@@ -119,10 +119,10 @@ impôt sur le revenu à payer:
})
it('should let the user define a rule base on a completely different subject', function() {
- let engine = new Engine(co2)
+ let engine = new Engine({ rules: co2 })
engine.setSituation({
'nombre de douches': 30,
- 'chauffage . type': "'gaz'",
+ 'chauffage . type': 'gaz',
'durée de la douche': 10
})
let value = engine.evaluate('douche . impact')
diff --git a/test/mecanisms.test.js b/test/mecanisms.test.js
index 7001cd85e..d7137097a 100644
--- a/test/mecanisms.test.js
+++ b/test/mecanisms.test.js
@@ -8,21 +8,20 @@
import { expect } from 'chai'
import Engine from 'Engine'
import { parseUnit } from '../source/engine/units'
-import { coerceArray } from '../source/utils'
import testSuites from './load-mecanism-tests'
testSuites.forEach(([suiteName, suite]) => {
- const engine = new Engine(suite)
+ const engine = new Engine({ rules: suite, useDefaultValues: false })
describe(`Mécanisme ${suiteName}`, () => {
Object.entries(suite)
.filter(([, rule]) => rule?.exemples)
.forEach(([name, test]) => {
const { exemples, 'unité attendue': unit } = test
- coerceArray(exemples).forEach(
+ exemples.forEach(
(
{
nom: testName,
situation,
- 'unité par défaut': defaultUnit,
+ 'unités par défaut': defaultUnits,
'valeur attendue': valeur,
'variables manquantes': expectedMissing
},
@@ -38,10 +37,8 @@ testSuites.forEach(([suiteName, suite]) => {
() => {
const result = engine
.setSituation(situation ?? {})
- .evaluate(name, {
- unit: defaultUnit,
- useDefaultValues: false
- })
+ .setDefaultUnits(defaultUnits)
+ .evaluate(name)
if (typeof valeur === 'number') {
expect(result.nodeValue).to.be.closeTo(valeur, 0.001)
} else if (valeur !== undefined) {
diff --git a/test/mécanismes/allègement.yaml b/test/mécanismes/allègement.yaml
index 8831e12ce..490bb11ea 100644
--- a/test/mécanismes/allègement.yaml
+++ b/test/mécanismes/allègement.yaml
@@ -96,7 +96,7 @@ montant abattu avec plafond numérique:
montant: 100000
valeur attendue: 88000 # 85000 s'il n'y avait pas de plafond à la somme abattue
-montant franchisé décote abattu:
+montant franchisé, décote, abattu:
unité: €
formule:
allègement:
diff --git a/test/mécanismes/applicable.yaml b/test/mécanismes/applicable.yaml
index d85620ed8..4697071a0 100644
--- a/test/mécanismes/applicable.yaml
+++ b/test/mécanismes/applicable.yaml
@@ -1,4 +1,12 @@
statut cadre:
+ formule:
+ variations:
+ - si: 3 > 2
+ alors: oui
+ - sinon: choix du statut cadre
+
+choix du statut cadre:
+ par défaut: non
prévoyance obligatoire cadre:
applicable si: statut cadre
@@ -14,4 +22,4 @@ prévoyance obligatoire cadre:
- nom: Non Applicabilité
situation:
statut cadre: non
- valeur attendue: false
+ valeur attendue: 0
diff --git a/test/mécanismes/conversion-unité.yaml b/test/mécanismes/conversion-unité.yaml
index 31b2efed5..1c9bcdf83 100644
--- a/test/mécanismes/conversion-unité.yaml
+++ b/test/mécanismes/conversion-unité.yaml
@@ -18,11 +18,11 @@ Conversion de reference 2:
- situation:
douches par mois: 30
valeur attendue: 360
- - nom: unités par défaut prioritaire devant unité de variable
+ - nom: Unité de variable prioritaire devant les unités par défaut
situation:
douches par mois: 30
- unité par défaut: douche/mois
- valeur attendue: 30
+ unités par défaut: [douche/mois]
+ valeur attendue: 360
Conversion de variable:
formule: 1.5 kCo2/douche * douches par mois
@@ -34,7 +34,7 @@ Conversion de variable:
- nom: Unité cible de simulation
situation:
douches par mois: 20
- unité par défaut: kCo2/an
+ unités par défaut: [kCo2/an]
unité attendue: kCo2/an
valeur attendue: 360
@@ -102,7 +102,7 @@ Conversion de mécanisme 2:
- situation:
assiette annuelle: 36000
valeur attendue: 131.25
- unité par défaut: €/mois
+ unités par défaut: [€/mois]
Conversion dans une expression:
unité: €/an
@@ -132,7 +132,7 @@ Conversion dans une somme compliquée:
exemples:
- situation:
assiette annuelle: 20000
- unité par défaut: €/mois
+ unités par défaut: [€/mois]
valeur attendue: 130
maladie:
@@ -166,11 +166,11 @@ Conversion dans un allègement:
assiette: 1000€/an
abattement: 10€/mois
exemples:
- unité par défaut: €/an
- valeur attendue: 880
+ - unités par défaut: [€/an]
+ valeur attendue: 880
Conversion dans avec un abattement en %:
- unité: €/an
+ unité par défaut: €/an
formule:
allègement:
assiette: 1000€/an
@@ -196,10 +196,10 @@ Conversion avec plusieurs échelons:
- prévoyance cadre
- 35€/mois
exemples:
- unité par défaut: €/an
- situation:
- assiette mensuelle: 1100
- valeur attendue: 600
+ - unités par défaut: [€/an]
+ situation:
+ assiette mensuelle: 1100
+ valeur attendue: 600
Conversion de situation:
formule:
@@ -207,7 +207,25 @@ Conversion de situation:
- retraite
- mutuelle
exemples:
- unité par défaut: €/an
- situation:
- retraite: 4000
- valeur attendue: 4360
+ - unités par défaut: [€/an]
+ situation:
+ retraite: 4000
+ valeur attendue: 4360
+
+rémunération brute:
+ unité par défaut: €/mois
+
+Conversion de situation avec unité:
+ unité: €/an
+ formule:
+ produit:
+ assiette: rémunération brute
+ taux: 10%
+ exemples:
+ - situation:
+ rémunération brute: 1000
+ valeur attendue: 1200
+ - unités par défaut: [k€/an]
+ situation:
+ rémunération brute: 12
+ valeur attendue: 1200
diff --git a/test/mécanismes/date.yaml b/test/mécanismes/date.yaml
index beef4a793..8b7710aa8 100644
--- a/test/mécanismes/date.yaml
+++ b/test/mécanismes/date.yaml
@@ -34,4 +34,4 @@ Applicable si:
valeur attendue: 10
- situation:
date de création: 09/02/2019
- valeur attendue: false
+ valeur attendue: 0
diff --git a/test/mécanismes/expressions.yaml b/test/mécanismes/expressions.yaml
index 90612b300..586462bd1 100644
--- a/test/mécanismes/expressions.yaml
+++ b/test/mécanismes/expressions.yaml
@@ -172,8 +172,7 @@ négation:
pourcentage:
formule: 38.1%
exemples:
- - valeur attendue: 38.1
- unité attendue: '%'
+ - valeur attendue: 0.381
#- test: variable modifiée temporellement
multiplication et pourcentage:
@@ -214,10 +213,10 @@ test de possibilités:
formule: catégorie d'activité = 'artisanale'
exemples:
- situation:
- catégorie d'activité: "'artisanale'"
+ catégorie d'activité: artisanale
valeur attendue: true
- situation:
- catégorie d'activité: "'commerciale'"
+ catégorie d'activité: commerciale
valeur attendue: false
revenu:
@@ -268,24 +267,6 @@ variables négatives dans expression:
- situation:
salaire de base: 3000
valeur attendue: -300
-
-expression dans situation:
- formule: 10% * salaire de base
- exemples:
- - situation:
- salaire de base: 12 * 100
- unité attendue: $
- valeur attendue: 120
-
-salaire:
- unité: €/mois
-expression dans situation 2:
- formule: 10% * salaire
- exemples:
- - situation:
- salaire: 48k€/an
- unité attendue: €/mois
- valeur attendue: 400
# TODO
# expression sur plusieurs lignes:
# formule: >
diff --git a/test/mécanismes/le-maximum-de.yaml b/test/mécanismes/le-maximum-de.yaml
index 2a287044e..09fe34574 100644
--- a/test/mécanismes/le-maximum-de.yaml
+++ b/test/mécanismes/le-maximum-de.yaml
@@ -9,7 +9,9 @@ Maximum:
taux: 9%
exemples:
- - valeur attendue: 1
+ - nom:
+ situation:
+ valeur attendue: 1
a:
applicable si: non
diff --git a/test/mécanismes/question-conditionelle.yaml b/test/mécanismes/question-conditionelle.yaml
index 6dc0596ec..fbc3ec391 100644
--- a/test/mécanismes/question-conditionelle.yaml
+++ b/test/mécanismes/question-conditionelle.yaml
@@ -3,7 +3,7 @@ enfants:
nombre enfants:
applicable si: enfants
question: Combien d'enfants avez vous ?
- par défaut: 4 enfants
+ par défaut: 4
famille nombreuse:
titre: question conditionnelle
diff --git a/test/mécanismes/remplace.yaml b/test/mécanismes/remplace.yaml
index 16a405534..b1fe273c0 100644
--- a/test/mécanismes/remplace.yaml
+++ b/test/mécanismes/remplace.yaml
@@ -177,7 +177,7 @@ x . y:
remplace: z
formule: 20
-remplacement non applicable car branche desactivée:
+remplacement non applicable (branche desactivée):
formule: z
exemples:
- valeur attendue: 1
diff --git a/test/mécanismes/régularisation.yaml b/test/mécanismes/régularisation.yaml
index 0114a26ed..3b47d7679 100644
--- a/test/mécanismes/régularisation.yaml
+++ b/test/mécanismes/régularisation.yaml
@@ -88,9 +88,4 @@ régularisation . test variations 1:
régularisation . test variations 2:
formule: cotisation spéciale | du 01/02/2020 | au 29/02/2020
exemples:
- - valeur attendue: 0
-
-régularisation . test variations 3:
- formule: cotisation spéciale | du 01/03/2020 | au 31/03/2020
- exemples:
- - valeur attendue: 1380
+ - valeur attendue: 660
diff --git a/test/mécanismes/toutes-ces-conditions.yaml b/test/mécanismes/toutes-ces-conditions.yaml
index ae07b7682..7ec5510e1 100644
--- a/test/mécanismes/toutes-ces-conditions.yaml
+++ b/test/mécanismes/toutes-ces-conditions.yaml
@@ -21,7 +21,7 @@ remboursement dépot de garantie:
situation:
dégradation mineure: oui
dégradation majeure: oui
- valeur attendue: false
+ valeur attendue: 0
variables manquantes: []
- nom: C
situation:
diff --git a/test/mécanismes/une-de-ces-conditions.yaml b/test/mécanismes/une-de-ces-conditions.yaml
index af37bb257..e651c38d0 100644
--- a/test/mécanismes/une-de-ces-conditions.yaml
+++ b/test/mécanismes/une-de-ces-conditions.yaml
@@ -14,7 +14,7 @@ remboursement dépot de garantie:
- nom: Est vraie -> non applicable -> 0
situation:
dégradation mineure: oui
- valeur attendue: false
+ valeur attendue: 0
variables manquantes: []
- nom: Est fausse -> en attente de l'autre
situation:
diff --git a/test/mécanismes/variable-temporelle.yaml b/test/mécanismes/variable-temporelle.yaml
index e8519bf34..0c8d201ec 100644
--- a/test/mécanismes/variable-temporelle.yaml
+++ b/test/mécanismes/variable-temporelle.yaml
@@ -85,7 +85,7 @@ variable temporelle numérique . test addition:
valeur attendue: 30
prix avec variations:
- formule: prix - (prix * 50% | du 01/01/2020 | au 31/01/2020)
+ formule: prix * (50% | du 01/01/2020 | au 31/01/2020)
début:
fin:
variable temporelle numérique . expression . multiplication:
@@ -96,17 +96,14 @@ variable temporelle numérique . expression . multiplication:
début: 01/01/2020
fin: 31/01/2020
valeur attendue: 10
- unité attendue: €/mois
- situation:
début: 01/01/2020
fin: 29/02/2020
valeur attendue: 20
- unité attendue: €/mois
- situation:
début: 01/02/2020
fin: 31/03/2020
valeur attendue: 30
- unité attendue: €/mois
taux associé:
formule:
@@ -115,7 +112,7 @@ taux associé:
alors: 10%/mois
- si: prix avec variations < 20 €/mois
alors: 60%/mois
- # Cette formule peut paraître bizarre, mais lorsque le prix est non
+ # Cette formule peut paraître bizarre, mais lorsque multiplication est non
# applicable, c'est bien le sinon qui s'applique
- sinon: 5%/mois
variable temporelle numérique . variation:
diff --git a/test/mécanismes/variations.yaml b/test/mécanismes/variations.yaml
index 289e69206..930cb8c38 100644
--- a/test/mécanismes/variations.yaml
+++ b/test/mécanismes/variations.yaml
@@ -80,10 +80,10 @@ variations avec cas défaut calculé:
variables manquantes: []
effectif:
- unité: ''
+ unité: _
effectif plafond:
- unité: ''
+ unité: _
plusieurs variations et un cas défaut:
formule:
@@ -100,7 +100,7 @@ plusieurs variations et un cas défaut:
- nom: 1er cas
situation:
effectif: 300
- valeur attendue: 5
+ valeur attendue: 0.05
- nom: 2ème cas, non résolu
situation:
effectif: 40
@@ -111,7 +111,7 @@ plusieurs variations et un cas défaut:
situation:
effectif: 20
effectif plafond: 60
- valeur attendue: 1
+ valeur attendue: 0.01
variations au sein d'un mécanisme:
formule:
diff --git a/test/real-rules.test.js b/test/real-rules.test.js
index fdb0460f9..b1b2717dd 100644
--- a/test/real-rules.test.js
+++ b/test/real-rules.test.js
@@ -6,7 +6,7 @@ import rules from 'Rules'
// les variables dans les tests peuvent être exprimées relativement à l'espace de nom de la règle,
// comme dans sa formule
let parsedRules = parseRules(rules)
-const engine = new Engine(parsedRules)
+const engine = new Engine({ rules: parsedRules })
let runExamples = (examples, rule) =>
examples.map(ex => {
const expected = ex['valeur attendue']
@@ -19,9 +19,10 @@ let runExamples = (examples, rule) =>
)
const evaluation = engine
.setSituation(situation)
- .evaluate(rule.dottedName, {
- unit: ex['unités par défaut']?.[0] ?? rule['unité par défaut']
- })
+ .setDefaultUnits(
+ ex['unités par défaut'] ?? [rule['unité par défaut'] ?? '€/mois']
+ )
+ .evaluate(rule.dottedName)
const ok =
evaluation.nodeValue === expected
? true
diff --git a/test/regressions/__snapshots__/simulations.jest.js.snap b/test/regressions/__snapshots__/simulations.jest.js.snap
index 6db17c2e5..dcb3975c5 100644
--- a/test/regressions/__snapshots__/simulations.jest.js.snap
+++ b/test/regressions/__snapshots__/simulations.jest.js.snap
@@ -1,453 +1,453 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`calculate simulations-artiste-auteur: bnc 1`] = `"[1230]"`;
+exports[`calculate simulations-artiste-auteur: bnc 1`] = `"[1230]"`;
-exports[`calculate simulations-artiste-auteur: bnc 2`] = `"[1863]"`;
+exports[`calculate simulations-artiste-auteur: bnc 2`] = `"[1863]"`;
-exports[`calculate simulations-artiste-auteur: bnc 3`] = `"[931]"`;
+exports[`calculate simulations-artiste-auteur: bnc 3`] = `"[932]"`;
-exports[`calculate simulations-artiste-auteur: salarié 1`] = `"[160]"`;
+exports[`calculate simulations-artiste-auteur: salarié 1`] = `"[160]"`;
-exports[`calculate simulations-artiste-auteur: salarié 2`] = `"[1603]"`;
+exports[`calculate simulations-artiste-auteur: salarié 2`] = `"[1603]"`;
-exports[`calculate simulations-artiste-auteur: salarié 3`] = `"[12410]"`;
+exports[`calculate simulations-artiste-auteur: salarié 3`] = `"[12410]"`;
-exports[`calculate simulations-auto-entrepreneur: ACRE 1`] = `"[21394,116,20000,0,20000]"`;
+exports[`calculate simulations-auto-entrepreneur: ACRE 1`] = `"[21394,1394,20000,0,20000]"`;
-exports[`calculate simulations-auto-entrepreneur: ACRE 2`] = `"[31029,86,30000,0,30000]"`;
+exports[`calculate simulations-auto-entrepreneur: ACRE 2`] = `"[31029,1029,30000,0,30000]"`;
-exports[`calculate simulations-auto-entrepreneur: ACRE 3`] = `"[44304,359,40000,0,40000]"`;
+exports[`calculate simulations-auto-entrepreneur: ACRE 3`] = `"[44304,4304,40000,0,40000]"`;
-exports[`calculate simulations-auto-entrepreneur: aides 1`] = `"[5348,29,5000,0,5000]"`;
+exports[`calculate simulations-auto-entrepreneur: aides 1`] = `"[5348,348,5000,0,5000]"`;
-exports[`calculate simulations-auto-entrepreneur: aides 2`] = `"[53485,290,50000,93,49907]"`;
+exports[`calculate simulations-auto-entrepreneur: aides 2`] = `"[53485,3485,50000,93,49907]"`;
-exports[`calculate simulations-auto-entrepreneur: impôt sur le revenu 1`] = `"[32092,591,25000,706,24294]"`;
+exports[`calculate simulations-auto-entrepreneur: impôt sur le revenu 1`] = `"[32092,7092,25000,706,24294]"`;
-exports[`calculate simulations-auto-entrepreneur: échelle de revenus 1`] = `"[574,6,500,0,500]"`;
+exports[`calculate simulations-auto-entrepreneur: échelle de revenus 1`] = `"[574,74,500,0,500]"`;
-exports[`calculate simulations-auto-entrepreneur: échelle de revenus 2`] = `"[1148,12,1000,0,1000]"`;
+exports[`calculate simulations-auto-entrepreneur: échelle de revenus 2`] = `"[1148,148,1000,0,1000]"`;
-exports[`calculate simulations-auto-entrepreneur: échelle de revenus 3`] = `"[2297,25,2000,0,2000]"`;
+exports[`calculate simulations-auto-entrepreneur: échelle de revenus 3`] = `"[2297,297,2000,0,2000]"`;
-exports[`calculate simulations-auto-entrepreneur: échelle de revenus 4`] = `"[5742,62,5000,0,5000]"`;
+exports[`calculate simulations-auto-entrepreneur: échelle de revenus 4`] = `"[5742,742,5000,0,5000]"`;
-exports[`calculate simulations-auto-entrepreneur: échelle de revenus 5`] = `"[11483,124,10000,0,10000]"`;
+exports[`calculate simulations-auto-entrepreneur: échelle de revenus 5`] = `"[11483,1483,10000,0,10000]"`;
-exports[`calculate simulations-auto-entrepreneur: échelle de revenus 6`] = `"[22966,247,20000,0,20000]"`;
+exports[`calculate simulations-auto-entrepreneur: échelle de revenus 6`] = `"[22966,2966,20000,0,20000]"`;
-exports[`calculate simulations-auto-entrepreneur: échelle de revenus 7`] = `"[57415,618,50000,275,49725]"`;
+exports[`calculate simulations-auto-entrepreneur: échelle de revenus 7`] = `"[57415,7415,50000,275,49725]"`;
-exports[`calculate simulations-auto-entrepreneur: échelle de revenus 8`] = `"[80381,865,70000,1340,68660]"`;
+exports[`calculate simulations-auto-entrepreneur: échelle de revenus 8`] = `"[80381,10381,70000,1340,68660]"`;
-exports[`calculate simulations-auto-entrepreneur: échelle de revenus 9`] = `"[114830,1236,100000,4008,95992]"`;
+exports[`calculate simulations-auto-entrepreneur: échelle de revenus 9`] = `"[114830,14830,100000,4008,95992]"`;
-exports[`calculate simulations-auto-entrepreneur: échelle de revenus 10`] = `"[1148303,12359,1000000,131979,868021]"`;
+exports[`calculate simulations-auto-entrepreneur: échelle de revenus 10`] = `"[1148303,148303,1000000,131979,868021]"`;
-exports[`calculate simulations-indépendant: acre 1`] = `"[73024,23024,50000,51980,8052,41948,0,73024]"`;
+exports[`calculate simulations-indépendant: acre 1`] = `"[73024,23024,50000,51980,8052,41948,null,73024]"`;
-exports[`calculate simulations-indépendant: activité 1`] = `"[28923,8923,20000,20783,604,19396,0,28923]"`;
+exports[`calculate simulations-indépendant: activité 1`] = `"[28923,8923,20000,20783,604,19396,null,28923]"`;
-exports[`calculate simulations-indépendant: activité 2`] = `"[29101,9101,20000,20787,604,19396,0,29101]"`;
+exports[`calculate simulations-indépendant: activité 2`] = `"[29101,9101,20000,20787,604,19396,null,29101]"`;
-exports[`calculate simulations-indépendant: cotisations minimales 1`] = `"[1373,1273,100,134,0,100,0,1373]"`;
+exports[`calculate simulations-indépendant: cotisations minimales 1`] = `"[1373,1273,100,134,0,100,null,1373]"`;
-exports[`calculate simulations-indépendant: cotisations minimales 2`] = `"[245,145,100,104,0,100,0,245]"`;
+exports[`calculate simulations-indépendant: cotisations minimales 2`] = `"[245,145,100,104,0,100,null,245]"`;
-exports[`calculate simulations-indépendant: impôt sur le revenu 1`] = `"[29085,9085,20000,20787,603,19397,0,29085]"`;
+exports[`calculate simulations-indépendant: impôt sur le revenu 1`] = `"[29085,9085,20000,20787,603,19397,null,29085]"`;
-exports[`calculate simulations-indépendant: impôt sur le revenu 2`] = `"[73024,23024,50000,51980,8213,41787,0,73024]"`;
+exports[`calculate simulations-indépendant: impôt sur le revenu 2`] = `"[73024,23024,50000,51980,8213,41787,null,73024]"`;
-exports[`calculate simulations-indépendant: impôt sur le revenu 3`] = `"[29085,9085,20000,20787,2079,17921,0,29085]"`;
+exports[`calculate simulations-indépendant: impôt sur le revenu 3`] = `"[29085,9085,20000,20787,2079,17921,null,29085]"`;
-exports[`calculate simulations-indépendant: inversions 1`] = `"[2000,1384,616,667,0,616,0,2000]"`;
+exports[`calculate simulations-indépendant: inversions 1`] = `"[2000,1384,616,667,0,616,null,2000]"`;
-exports[`calculate simulations-indépendant: inversions 2`] = `"[50000,16003,33997,35352,3563,30434,0,50000]"`;
+exports[`calculate simulations-indépendant: inversions 2`] = `"[50000,16003,33997,35352,3563,30434,null,50000]"`;
-exports[`calculate simulations-indépendant: inversions 3`] = `"[14596,4596,10000,10394,0,10000,0,14596]"`;
+exports[`calculate simulations-indépendant: inversions 3`] = `"[14596,4596,10000,10394,0,10000,null,14596]"`;
-exports[`calculate simulations-indépendant: inversions 4`] = `"[88547,27360,61187,63588,11187,50000,0,88547]"`;
+exports[`calculate simulations-indépendant: inversions 4`] = `"[88547,27360,61187,63588,11187,50000,null,88547]"`;
-exports[`calculate simulations-indépendant: inversions 5`] = `"[14596,4596,10000,10394,0,10000,1000,15596]"`;
+exports[`calculate simulations-indépendant: inversions 5`] = `"[14596,4596,10000,10394,0,10000,null,15596]"`;
-exports[`calculate simulations-indépendant: inversions 6`] = `"[19000,5928,13072,13585,0,13072,1000,20000]"`;
+exports[`calculate simulations-indépendant: inversions 6`] = `"[19000,5928,13072,13585,0,13072,1000,20000]"`;
-exports[`calculate simulations-indépendant: inversions 7`] = `"[18000,5626,12374,12860,0,12374,2000,20000]"`;
+exports[`calculate simulations-indépendant: inversions 7`] = `"[18000,5626,12374,12860,0,12374,2000,20000]"`;
-exports[`calculate simulations-indépendant: échelle de revenus 1`] = `"[1859,1359,500,548,0,500,0,1859]"`;
+exports[`calculate simulations-indépendant: échelle de revenus 1`] = `"[1859,1359,500,548,0,500,null,1859]"`;
-exports[`calculate simulations-indépendant: échelle de revenus 2`] = `"[2467,1467,1000,1064,0,1000,0,2467]"`;
+exports[`calculate simulations-indépendant: échelle de revenus 2`] = `"[2467,1467,1000,1064,0,1000,null,2467]"`;
-exports[`calculate simulations-indépendant: échelle de revenus 3`] = `"[3075,1575,1500,1581,0,1500,0,3075]"`;
+exports[`calculate simulations-indépendant: échelle de revenus 3`] = `"[3075,1575,1500,1581,0,1500,null,3075]"`;
-exports[`calculate simulations-indépendant: échelle de revenus 4`] = `"[3682,1682,2000,2097,0,2000,0,3682]"`;
+exports[`calculate simulations-indépendant: échelle de revenus 4`] = `"[3682,1682,2000,2097,0,2000,null,3682]"`;
-exports[`calculate simulations-indépendant: échelle de revenus 5`] = `"[7427,2427,5000,5199,0,5000,0,7427]"`;
+exports[`calculate simulations-indépendant: échelle de revenus 5`] = `"[7427,2427,5000,5199,0,5000,null,7427]"`;
-exports[`calculate simulations-indépendant: échelle de revenus 6`] = `"[14596,4596,10000,10394,0,10000,0,14596]"`;
+exports[`calculate simulations-indépendant: échelle de revenus 6`] = `"[14596,4596,10000,10394,0,10000,null,14596]"`;
-exports[`calculate simulations-indépendant: échelle de revenus 7`] = `"[139594,39594,100000,103788,24245,75755,0,139594]"`;
+exports[`calculate simulations-indépendant: échelle de revenus 7`] = `"[139594,39594,100000,103788,24245,75755,null,139594]"`;
-exports[`calculate simulations-indépendant: échelle de revenus 8`] = `"[1239955,239955,1000000,1033666,467505,532495,0,1239955]"`;
+exports[`calculate simulations-indépendant: échelle de revenus 8`] = `"[1239955,239955,1000000,1033666,467505,532495,null,1239955]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): ACRE 1`] = `"[605,0,0,7184,4,13]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - ACRE 1`] = `"[7257,7257,7184,4,13,16]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): ACRE 2`] = `"[1247,0,0,14544,4,26]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - ACRE 2`] = `"[14963,14963,14544,4,26,32]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): ACRE 3`] = `"[1889,0,0,21905,4,40]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - ACRE 3`] = `"[21575,22669,21905,4,40,48]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): Contrats Madelin 1`] = `"[1389,0,0,16178,4,29]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - Contrats Madelin 1`] = `"[16490,16673,16178,4,29,35]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): Contrats Madelin 2`] = `"[1389,0,0,16178,4,29]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - Contrats Madelin 2`] = `"[16490,16673,16178,4,29,35]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): Contrats Madelin 3`] = `"[1389,0,0,16178,4,29]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - Contrats Madelin 3`] = `"[16490,16673,16178,4,29,35]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): Contrats Madelin 4`] = `"[915,0,0,10742,4,19]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - Contrats Madelin 4`] = `"[10982,10982,10742,4,19,23]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): Contrats Madelin 5`] = `"[14469,0,0,154362,4,46]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - Contrats Madelin 5`] = `"[118288,173630,154362,4,46,203]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): Contrats Madelin 6`] = `"[915,0,0,10742,4,19]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - Contrats Madelin 6`] = `"[10982,10982,10742,4,19,23]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): activités 1`] = `"[915,0,0,10742,4,19]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - activités 1`] = `"[10982,10982,10742,4,19,23]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): activités 2`] = `"[915,0,0,10742,4,19]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - activités 2`] = `"[10982,10982,10742,4,19,23]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): activités 3`] = `"[915,0,0,10742,4,19]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - activités 3`] = `"[10982,10982,10742,4,19,23]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): activités 4`] = `"[915,0,0,10742,4,19]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - activités 4`] = `"[10982,10982,10742,4,19,23]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): activités 5`] = `"[915,0,0,10742,4,19]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - activités 5`] = `"[10982,10982,10742,4,19,23]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): avec charges 1`] = `"[441,0,0,5306,4,10]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - avec charges 1`] = `"[5291,5291,5306,4,10,12]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): avec charges 2`] = `"[915,0,0,10742,4,19]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - avec charges 2`] = `"[10982,10982,10742,4,19,23]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 1`] = `"[0,0,0,0,0,0]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 1`] = `"[-2313,-2313,2488,0,0,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 2`] = `"[14,0,0,139,0,1]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 2`] = `"[169,169,139,0,1,1]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 3`] = `"[62,0,0,323,0,2]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 3`] = `"[738,738,323,0,2,2]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 4`] = `"[204,0,0,2588,2,5]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 4`] = `"[2446,2446,2588,2,5,6]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 5`] = `"[441,0,0,5306,4,10]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 5`] = `"[5291,5291,5306,4,10,12]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 6`] = `"[915,0,0,10742,4,19]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 6`] = `"[10982,10982,10742,4,19,23]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 7`] = `"[2338,0,0,27050,4,46]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 7`] = `"[25971,28055,27050,4,46,59]"`;
-exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 8`] = `"[4751,0,0,52684,4,46]"`;
+exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 8`] = `"[46812,57017,52684,4,46,119]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): ACRE 1`] = `"[0,0,779,2046,2,0]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - ACRE 1`] = `"[9349,9349,2046,2,0,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): ACRE 2`] = `"[0,0,1558,4093,3,8]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - ACRE 2`] = `"[18697,18697,4093,3,8,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): ACRE 3`] = `"[0,0,2337,6139,4,12]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - ACRE 3`] = `"[28046,28046,6139,4,12,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): Contrats Madelin 1`] = `"[0,0,2070,8186,4,16]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - Contrats Madelin 1`] = `"[24834,24834,8186,4,16,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): Contrats Madelin 2`] = `"[0,0,2070,8186,4,16]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - Contrats Madelin 2`] = `"[24834,24834,8186,4,16,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): Contrats Madelin 3`] = `"[0,0,2070,8186,4,16]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - Contrats Madelin 3`] = `"[24834,24834,8186,4,16,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): Contrats Madelin 4`] = `"[0,0,1441,4298,4,8]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - Contrats Madelin 4`] = `"[17288,17288,4298,4,8,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): Contrats Madelin 5`] = `"[0,0,21610,39357,4,56]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - Contrats Madelin 5`] = `"[235917,259318,39357,4,56,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): Contrats Madelin 6`] = `"[0,0,1446,4195,3,8]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - Contrats Madelin 6`] = `"[17352,17352,4195,3,8,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): activités 1`] = `"[0,0,1298,6600,4,18]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - activités 1`] = `"[15580,15580,6600,4,18,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): activités 2`] = `"[0,0,1297,0,4,0]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - activités 2`] = `"[15560,15560,0,4,0,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): activités 3`] = `"[0,0,1445,4093,3,8]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - activités 3`] = `"[17336,17336,4093,3,8,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): activités 4`] = `"[0,0,1451,4093,3,8]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - activités 4`] = `"[17417,17417,4093,3,8,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): activités 5`] = `"[0,0,1451,4093,3,8]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - activités 5`] = `"[17417,17417,4093,3,8,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): avec charges 1`] = `"[0,0,704,2456,3,0]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - avec charges 1`] = `"[8450,8450,2456,3,0,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): avec charges 2`] = `"[0,0,1290,7163,4,14]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - avec charges 2`] = `"[15480,15480,7163,4,14,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): échelle de rémunération 1`] = `"[0,0,7,6,0,0]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 1`] = `"[87,87,6,0,0,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): échelle de rémunération 2`] = `"[0,0,73,60,0,0]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 2`] = `"[871,871,60,0,0,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): échelle de rémunération 3`] = `"[0,0,145,119,0,0]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 3`] = `"[1742,1742,119,0,0,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): échelle de rémunération 4`] = `"[0,0,363,1023,1,0]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 4`] = `"[4354,4354,1023,1,0,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): échelle de rémunération 5`] = `"[0,0,726,2046,2,0]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 5`] = `"[8709,8709,2046,2,0,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): échelle de rémunération 6`] = `"[0,0,1451,4093,3,8]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 6`] = `"[17417,17417,4093,3,8,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): échelle de rémunération 7`] = `"[0,0,3629,10232,4,20]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 7`] = `"[43543,43543,10232,4,20,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (auto-entrepreneur): échelle de rémunération 8`] = `"[0,0,7257,20465,4,40]"`;
+exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 8`] = `"[84367,87085,20465,4,40,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): ACRE 1`] = `"[0,8215,0,6018,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - ACRE 1`] = `"[8215,8215,6018,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): ACRE 2`] = `"[0,16527,0,12103,4,24]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - ACRE 2`] = `"[16442,16527,12103,4,24,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): ACRE 3`] = `"[0,21570,0,15799,4,31]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - ACRE 3`] = `"[20731,21570,15799,4,31,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): Contrats Madelin 1`] = `"[0,20567,0,15183,4,30]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - Contrats Madelin 1`] = `"[19279,20567,15183,4,30,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): Contrats Madelin 2`] = `"[0,20264,0,15648,4,30]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - Contrats Madelin 2`] = `"[18737,20264,15648,4,30,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): Contrats Madelin 3`] = `"[0,20620,0,15102,4,29]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - Contrats Madelin 3`] = `"[19779,20620,15102,4,29,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): Contrats Madelin 4`] = `"[0,13769,0,10084,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - Contrats Madelin 4`] = `"[13769,13769,10084,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): Contrats Madelin 5`] = `"[0,226878,0,57937,4,56]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - Contrats Madelin 5`] = `"[144184,226878,57937,4,56,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): Contrats Madelin 6`] = `"[0,13769,0,10084,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - Contrats Madelin 6`] = `"[13769,13769,10084,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): activités 1`] = `"[0,13886,0,10166,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - activités 1`] = `"[13886,13886,10166,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): activités 2`] = `"[0,14645,0,0,4,0]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - activités 2`] = `"[14645,14645,0,4,0,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): activités 3`] = `"[0,13758,0,10075,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - activités 3`] = `"[13758,13758,10075,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): activités 4`] = `"[0,13769,0,10084,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - activités 4`] = `"[13769,13769,10084,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): activités 5`] = `"[0,13769,0,10084,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - activités 5`] = `"[13769,13769,10084,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): avec charges 1`] = `"[0,6795,0,4977,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - avec charges 1`] = `"[6795,6795,4977,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): avec charges 2`] = `"[0,13769,0,10084,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - avec charges 2`] = `"[13769,13769,10084,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): échelle de rémunération 1`] = `"[0,-1044,0,0,3,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 1`] = `"[-1044,-1044,0,3,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): échelle de rémunération 2`] = `"[0,-225,0,0,3,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 2`] = `"[-225,-225,0,3,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): échelle de rémunération 3`] = `"[0,616,0,470,3,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 3`] = `"[616,616,470,3,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): échelle de rémunération 4`] = `"[0,3084,0,2267,3,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 4`] = `"[3084,3084,2267,3,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): échelle de rémunération 5`] = `"[0,6795,0,4977,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 5`] = `"[6795,6795,4977,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): échelle de rémunération 6`] = `"[0,13769,0,10084,4,21]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 6`] = `"[13769,13769,10084,4,21,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): échelle de rémunération 7`] = `"[0,33997,0,24912,4,48]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 7`] = `"[30434,33997,24912,4,48,0]"`;
-exports[`calculate simulations-rémunération-dirigeant (indépendant): échelle de rémunération 8`] = `"[0,69895,0,36431,4,56]"`;
+exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 8`] = `"[56273,69895,36431,4,56,0]"`;
-exports[`calculate simulations-salarié: JEI 1`] = `"[3440,0,3000,2353,2187]"`;
+exports[`calculate simulations-salarié: JEI 1`] = `"[3440,0,0,3000,2353,2187]"`;
-exports[`calculate simulations-salarié: JEI 2`] = `"[26635,0,20000,15969,10681]"`;
+exports[`calculate simulations-salarié: JEI 2`] = `"[26635,0,0,20000,15969,10681]"`;
-exports[`calculate simulations-salarié: JEI 3`] = `"[4517,0,4000,3141,2741]"`;
+exports[`calculate simulations-salarié: JEI 3`] = `"[4517,0,0,4000,3141,2741]"`;
-exports[`calculate simulations-salarié: activité partielle 1`] = `"[27,0,1560,1197,1197]"`;
+exports[`calculate simulations-salarié: activité partielle 1`] = `"[27,1218,0,1560,1197,1197]"`;
-exports[`calculate simulations-salarié: activité partielle 2`] = `"[27,0,4000,2594,2365]"`;
+exports[`calculate simulations-salarié: activité partielle 2`] = `"[27,2800,0,4000,2594,2365]"`;
-exports[`calculate simulations-salarié: activité partielle 3`] = `"[778,0,8000,5209,4253]"`;
+exports[`calculate simulations-salarié: activité partielle 3`] = `"[778,4849,0,8000,5209,4253]"`;
-exports[`calculate simulations-salarié: activité partielle 4`] = `"[852,0,4000,2704,2444]"`;
+exports[`calculate simulations-salarié: activité partielle 4`] = `"[852,2240,0,4000,2704,2444]"`;
-exports[`calculate simulations-salarié: activité partielle 5`] = `"[2483,0,4000,2870,2562]"`;
+exports[`calculate simulations-salarié: activité partielle 5`] = `"[2483,1400,0,4000,2870,2562]"`;
-exports[`calculate simulations-salarié: activité partielle 6`] = `"[27,3750,3000,1940,1848]"`;
+exports[`calculate simulations-salarié: activité partielle 6`] = `"[27,2100,3750,3000,1940,1848]"`;
-exports[`calculate simulations-salarié: activité partielle 7`] = `"[27,0,4000,2594,2497]"`;
+exports[`calculate simulations-salarié: activité partielle 7`] = `"[27,2800,0,4000,2594,2497]"`;
-exports[`calculate simulations-salarié: activité partielle 8`] = `"[227,0,2000,1578,1547]"`;
+exports[`calculate simulations-salarié: activité partielle 8`] = `"[227,1400,0,2000,1578,1547]"`;
-exports[`calculate simulations-salarié: activité partielle 9`] = `"[1156,0,2000,1540,1510]"`;
+exports[`calculate simulations-salarié: activité partielle 9`] = `"[1156,700,0,2000,1540,1510]"`;
-exports[`calculate simulations-salarié: activité partielle 10`] = `"[327,0,6000,4182,3511]"`;
+exports[`calculate simulations-salarié: activité partielle 10`] = `"[327,4200,0,6000,4182,3511]"`;
-exports[`calculate simulations-salarié: aides 1`] = `"[2302,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: aides 1`] = `"[2302,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: aides 2`] = `"[12823,0,10000,8911,7667]"`;
+exports[`calculate simulations-salarié: aides 2`] = `"[12823,0,0,10000,8911,7667]"`;
-exports[`calculate simulations-salarié: aides 3`] = `"[2062,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: aides 3`] = `"[2062,417,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: aides 4`] = `"[2292,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: aides 4`] = `"[2292,208,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: apprentissage 1`] = `"[1552,0,1500,1448,1448]"`;
+exports[`calculate simulations-salarié: apprentissage 1`] = `"[1552,0,0,1500,1448,1448]"`;
-exports[`calculate simulations-salarié: apprentissage 2`] = `"[1385,0,1500,1448,1448]"`;
+exports[`calculate simulations-salarié: apprentissage 2`] = `"[1385,167,0,1500,1448,1448]"`;
-exports[`calculate simulations-salarié: assimilé salarié 1`] = `"[7015,0,5000,3943,3318]"`;
+exports[`calculate simulations-salarié: assimilé salarié 1`] = `"[7015,0,0,5000,3943,3318]"`;
-exports[`calculate simulations-salarié: assimilé salarié 2`] = `"[1583,0,1500,1163,1163]"`;
+exports[`calculate simulations-salarié: assimilé salarié 2`] = `"[1583,0,0,1500,1163,1163]"`;
-exports[`calculate simulations-salarié: assimilé salarié 3`] = `"[3685,0,3000,2348,2172]"`;
+exports[`calculate simulations-salarié: assimilé salarié 3`] = `"[3685,0,0,3000,2348,2172]"`;
-exports[`calculate simulations-salarié: atmp 1`] = `"[2534,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: atmp 1`] = `"[2534,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: avantages 1`] = `"[2667,0,2000,1540,1492]"`;
+exports[`calculate simulations-salarié: avantages 1`] = `"[2667,0,0,2000,1540,1492]"`;
-exports[`calculate simulations-salarié: avantages 2`] = `"[2677,0,2000,1539,1490]"`;
+exports[`calculate simulations-salarié: avantages 2`] = `"[2677,0,0,2000,1539,1490]"`;
-exports[`calculate simulations-salarié: avantages 3`] = `"[2587,0,2000,1549,1506]"`;
+exports[`calculate simulations-salarié: avantages 3`] = `"[2587,0,0,2000,1549,1506]"`;
-exports[`calculate simulations-salarié: cadre 1`] = `"[4122,0,3000,2348,2171]"`;
+exports[`calculate simulations-salarié: cadre 1`] = `"[4122,0,0,3000,2348,2171]"`;
-exports[`calculate simulations-salarié: cdd 1`] = `"[2509,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: cdd 1`] = `"[2509,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: cdd 2`] = `"[2591,0,2000,1599,1557]"`;
+exports[`calculate simulations-salarié: cdd 2`] = `"[2591,0,0,2000,1599,1557]"`;
-exports[`calculate simulations-salarié: cdd 3`] = `"[3394,0,2400,1967,1883]"`;
+exports[`calculate simulations-salarié: cdd 3`] = `"[3394,0,0,2400,1967,1883]"`;
-exports[`calculate simulations-salarié: effectif 1`] = `"[2479,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: effectif 1`] = `"[2479,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: effectif 2`] = `"[2525,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: effectif 2`] = `"[2525,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: effectif 3`] = `"[2539,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: effectif 3`] = `"[2539,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: effectif 4`] = `"[2539,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: effectif 4`] = `"[2539,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: frais pro - DFS 1`] = `"[2242,0,2000,1630,1630]"`;
+exports[`calculate simulations-salarié: frais pro - DFS 1`] = `"[2242,0,0,2000,1630,1630]"`;
-exports[`calculate simulations-salarié: frais pro - DFS 2`] = `"[2335,0,2000,1584,1544]"`;
+exports[`calculate simulations-salarié: frais pro - DFS 2`] = `"[2335,0,0,2000,1584,1544]"`;
-exports[`calculate simulations-salarié: frais pro - DFS 3`] = `"[2265,0,2000,1606,1563]"`;
+exports[`calculate simulations-salarié: frais pro - DFS 3`] = `"[2265,0,0,2000,1606,1563]"`;
-exports[`calculate simulations-salarié: frais pro - DFS 4`] = `"[2243,0,2000,1613,1569]"`;
+exports[`calculate simulations-salarié: frais pro - DFS 4`] = `"[2243,0,0,2000,1613,1569]"`;
-exports[`calculate simulations-salarié: frais pro - DFS 5`] = `"[2437,0,2000,1590,1590]"`;
+exports[`calculate simulations-salarié: frais pro - DFS 5`] = `"[2437,0,0,2000,1590,1590]"`;
-exports[`calculate simulations-salarié: frais pro - DFS 6`] = `"[1767,0,1700,1364,1364]"`;
+exports[`calculate simulations-salarié: frais pro - DFS 6`] = `"[1767,0,0,1700,1364,1364]"`;
-exports[`calculate simulations-salarié: frais pro - DFS 7`] = `"[3287,0,2600,2125,2097]"`;
+exports[`calculate simulations-salarié: frais pro - DFS 7`] = `"[3287,0,0,2600,2125,2097]"`;
-exports[`calculate simulations-salarié: frais pro - IKV 1`] = `"[4367,0,3200,2530,2320]"`;
+exports[`calculate simulations-salarié: frais pro - IKV 1`] = `"[4367,0,0,3200,2530,2320]"`;
-exports[`calculate simulations-salarié: frais pro - IKV 2`] = `"[4346,0,3200,2511,2302]"`;
+exports[`calculate simulations-salarié: frais pro - IKV 2`] = `"[4346,0,0,3200,2511,2302]"`;
-exports[`calculate simulations-salarié: frais pro - IKV 3`] = `"[2774,0,2157,1685,1630]"`;
+exports[`calculate simulations-salarié: frais pro - IKV 3`] = `"[2774,0,0,2157,1685,1630]"`;
-exports[`calculate simulations-salarié: frais pro - titres restaurant 1`] = `"[2519,0,2000,1521,1484]"`;
+exports[`calculate simulations-salarié: frais pro - titres restaurant 1`] = `"[2519,0,0,2000,1521,1484]"`;
-exports[`calculate simulations-salarié: frais pro - titres restaurant 2`] = `"[4307,0,3000,2134,1949]"`;
+exports[`calculate simulations-salarié: frais pro - titres restaurant 2`] = `"[4307,0,0,3000,2134,1949]"`;
-exports[`calculate simulations-salarié: frais pro - titres restaurant 3`] = `"[2562,0,2000,1493,1456]"`;
+exports[`calculate simulations-salarié: frais pro - titres restaurant 3`] = `"[2562,0,0,2000,1493,1456]"`;
-exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 1`] = `"[2583,0,2000,1636,1599]"`;
+exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 1`] = `"[2583,0,0,2000,1636,1599]"`;
-exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 2`] = `"[3105,0,2000,2009,1965]"`;
+exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 2`] = `"[3105,0,0,2000,2009,1965]"`;
-exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 3`] = `"[2654,0,2000,1636,1599]"`;
+exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 3`] = `"[2654,0,0,2000,1636,1599]"`;
-exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 4`] = `"[2565,0,2000,1627,1590]"`;
+exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 4`] = `"[2565,0,0,2000,1627,1590]"`;
-exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 5`] = `"[3025,0,2000,1970,1932]"`;
+exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 5`] = `"[3025,0,0,2000,1970,1932]"`;
-exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 6`] = `"[3041,0,2000,1978,1939]"`;
+exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 6`] = `"[3041,0,0,2000,1978,1939]"`;
-exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 7`] = `"[3336,2446,2000,1919,1889]"`;
+exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 7`] = `"[3336,0,2446,2000,1919,1889]"`;
-exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 8`] = `"[3286,2286,2000,1889,1859]"`;
+exports[`calculate simulations-salarié: heures supplémentaires et complémentaires 8`] = `"[3286,0,2286,2000,1889,1859]"`;
-exports[`calculate simulations-salarié: impôt sur le revenu 1`] = `"[4076,0,3000,2353,2168]"`;
+exports[`calculate simulations-salarié: impôt sur le revenu 1`] = `"[4076,0,0,3000,2353,2168]"`;
-exports[`calculate simulations-salarié: impôt sur le revenu 2`] = `"[41834,0,30000,24227,14588]"`;
+exports[`calculate simulations-salarié: impôt sur le revenu 2`] = `"[41834,0,0,30000,24227,14588]"`;
-exports[`calculate simulations-salarié: impôt sur le revenu 3`] = `"[4111,0,3000,2353,2172]"`;
+exports[`calculate simulations-salarié: impôt sur le revenu 3`] = `"[4111,0,0,3000,2353,2172]"`;
-exports[`calculate simulations-salarié: impôt sur le revenu 4`] = `"[3896,0,3000,2353,2252]"`;
+exports[`calculate simulations-salarié: impôt sur le revenu 4`] = `"[3896,0,0,3000,2353,2252]"`;
-exports[`calculate simulations-salarié: impôt sur le revenu 5`] = `"[41834,0,30000,24227,14588]"`;
+exports[`calculate simulations-salarié: impôt sur le revenu 5`] = `"[41834,0,0,30000,24227,14588]"`;
-exports[`calculate simulations-salarié: impôt sur le revenu 6`] = `"[4076,0,3000,2626,2481]"`;
+exports[`calculate simulations-salarié: impôt sur le revenu 6`] = `"[4076,0,0,3000,2626,2481]"`;
-exports[`calculate simulations-salarié: impôt sur le revenu 7`] = `"[41834,0,30000,26966,16204]"`;
+exports[`calculate simulations-salarié: impôt sur le revenu 7`] = `"[41834,0,0,30000,26966,16204]"`;
-exports[`calculate simulations-salarié: impôt sur le revenu 8`] = `"[4076,0,3000,2353,2107]"`;
+exports[`calculate simulations-salarié: impôt sur le revenu 8`] = `"[4076,0,0,3000,2353,2107]"`;
-exports[`calculate simulations-salarié: inversions 1`] = `"[2000,0,1746,1360,1353]"`;
+exports[`calculate simulations-salarié: inversions 1`] = `"[2000,0,0,1746,1360,1353]"`;
-exports[`calculate simulations-salarié: inversions 2`] = `"[3474,0,2554,2000,1898]"`;
+exports[`calculate simulations-salarié: inversions 2`] = `"[3474,0,0,2554,2000,1898]"`;
-exports[`calculate simulations-salarié: inversions 3`] = `"[3679,0,2706,2120,2000]"`;
+exports[`calculate simulations-salarié: inversions 3`] = `"[3679,0,0,2706,2120,2000]"`;
-exports[`calculate simulations-salarié: lodeom 1`] = `"[1592,0,1521,1182,1182]"`;
+exports[`calculate simulations-salarié: lodeom 1`] = `"[1592,0,0,1521,1182,1182]"`;
-exports[`calculate simulations-salarié: lodeom 2`] = `"[2085,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: lodeom 2`] = `"[2085,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: lodeom 3`] = `"[3896,0,3000,2353,2187]"`;
+exports[`calculate simulations-salarié: lodeom 3`] = `"[3896,0,0,3000,2353,2187]"`;
-exports[`calculate simulations-salarié: lodeom 4`] = `"[5674,0,4000,3146,2759]"`;
+exports[`calculate simulations-salarié: lodeom 4`] = `"[5674,0,0,4000,3146,2759]"`;
-exports[`calculate simulations-salarié: lodeom 5`] = `"[7889,0,5500,4349,3625]"`;
+exports[`calculate simulations-salarié: lodeom 5`] = `"[7889,0,0,5500,4349,3625]"`;
-exports[`calculate simulations-salarié: lodeom compétitivité renforcée 1`] = `"[1592,0,1521,1182,1182]"`;
+exports[`calculate simulations-salarié: lodeom compétitivité renforcée 1`] = `"[1592,0,0,1521,1182,1182]"`;
-exports[`calculate simulations-salarié: lodeom compétitivité renforcée 2`] = `"[2085,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: lodeom compétitivité renforcée 2`] = `"[2085,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: lodeom compétitivité renforcée 3`] = `"[3444,0,3000,2353,2187]"`;
+exports[`calculate simulations-salarié: lodeom compétitivité renforcée 3`] = `"[3444,0,0,3000,2353,2187]"`;
-exports[`calculate simulations-salarié: lodeom compétitivité renforcée 4`] = `"[5588,0,4000,3146,2759]"`;
+exports[`calculate simulations-salarié: lodeom compétitivité renforcée 4`] = `"[5588,0,0,4000,3146,2759]"`;
-exports[`calculate simulations-salarié: lodeom compétitivité renforcée 5`] = `"[7889,0,5500,4349,3625]"`;
+exports[`calculate simulations-salarié: lodeom compétitivité renforcée 5`] = `"[7889,0,0,5500,4349,3625]"`;
-exports[`calculate simulations-salarié: lodeom innovation et croissance 1`] = `"[1592,0,1521,1182,1182]"`;
+exports[`calculate simulations-salarié: lodeom innovation et croissance 1`] = `"[1592,0,0,1521,1182,1182]"`;
-exports[`calculate simulations-salarié: lodeom innovation et croissance 2`] = `"[2085,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: lodeom innovation et croissance 2`] = `"[2085,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: lodeom innovation et croissance 3`] = `"[3235,0,3000,2353,2187]"`;
+exports[`calculate simulations-salarié: lodeom innovation et croissance 3`] = `"[3235,0,0,3000,2353,2187]"`;
-exports[`calculate simulations-salarié: lodeom innovation et croissance 4`] = `"[4915,0,4000,3146,2759]"`;
+exports[`calculate simulations-salarié: lodeom innovation et croissance 4`] = `"[4915,0,0,4000,3146,2759]"`;
-exports[`calculate simulations-salarié: lodeom innovation et croissance 5`] = `"[7889,0,5500,4349,3625]"`;
+exports[`calculate simulations-salarié: lodeom innovation et croissance 5`] = `"[7889,0,0,5500,4349,3625]"`;
-exports[`calculate simulations-salarié: stage 1`] = `"[507,0,500,500,500]"`;
+exports[`calculate simulations-salarié: stage 1`] = `"[507,0,0,500,500,500]"`;
-exports[`calculate simulations-salarié: stage 2`] = `"[2490,0,2000,1750,1750]"`;
+exports[`calculate simulations-salarié: stage 2`] = `"[2490,0,0,2000,1750,1750]"`;
-exports[`calculate simulations-salarié: taux spécifiques retraite complémentaire 1`] = `"[1606,0,1521,1195,1195]"`;
+exports[`calculate simulations-salarié: taux spécifiques retraite complémentaire 1`] = `"[1606,0,0,1521,1195,1195]"`;
-exports[`calculate simulations-salarié: taux spécifiques retraite complémentaire 2`] = `"[3423,0,2500,1979,1880]"`;
+exports[`calculate simulations-salarié: taux spécifiques retraite complémentaire 2`] = `"[3423,0,0,2500,1979,1880]"`;
-exports[`calculate simulations-salarié: taux spécifiques retraite complémentaire 3`] = `"[1592,0,1521,1170,1170]"`;
+exports[`calculate simulations-salarié: taux spécifiques retraite complémentaire 3`] = `"[1592,0,0,1521,1170,1170]"`;
-exports[`calculate simulations-salarié: taux spécifiques retraite complémentaire 4`] = `"[3382,0,2500,1938,1844]"`;
+exports[`calculate simulations-salarié: taux spécifiques retraite complémentaire 4`] = `"[3382,0,0,2500,1938,1844]"`;
-exports[`calculate simulations-salarié: temps partiel 1`] = `"[2592,2188,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: temps partiel 1`] = `"[2592,0,2188,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: temps partiel 2`] = `"[2533,2500,1857,1448,1428]"`;
+exports[`calculate simulations-salarié: temps partiel 2`] = `"[2533,0,2500,1857,1448,1428]"`;
-exports[`calculate simulations-salarié: temps partiel 3`] = `"[1159,1750,1000,770,770]"`;
+exports[`calculate simulations-salarié: temps partiel 3`] = `"[1159,0,1750,1000,770,770]"`;
-exports[`calculate simulations-salarié: treizième mois 1`] = `"[3390,0,2300,1950,1856]"`;
+exports[`calculate simulations-salarié: treizième mois 1`] = `"[3390,0,0,2300,1950,1856]"`;
-exports[`calculate simulations-salarié: treizième mois 2`] = `"[3800,2965,2300,2186,2073]"`;
+exports[`calculate simulations-salarié: treizième mois 2`] = `"[3800,0,2965,2300,2186,2073]"`;
-exports[`calculate simulations-salarié: treizième mois 3`] = `"[3044,0,2300,1799,1726]"`;
+exports[`calculate simulations-salarié: treizième mois 3`] = `"[3044,0,0,2300,1799,1726]"`;
-exports[`calculate simulations-salarié: échelle de salaires 1`] = `"[130,0,100,57,57]"`;
+exports[`calculate simulations-salarié: échelle de salaires 1`] = `"[130,0,0,100,57,57]"`;
-exports[`calculate simulations-salarié: échelle de salaires 2`] = `"[284,0,250,176,176]"`;
+exports[`calculate simulations-salarié: échelle de salaires 2`] = `"[284,0,0,250,176,176]"`;
-exports[`calculate simulations-salarié: échelle de salaires 3`] = `"[541,0,500,374,374]"`;
+exports[`calculate simulations-salarié: échelle de salaires 3`] = `"[541,0,0,500,374,374]"`;
-exports[`calculate simulations-salarié: échelle de salaires 4`] = `"[799,0,750,572,572]"`;
+exports[`calculate simulations-salarié: échelle de salaires 4`] = `"[799,0,0,750,572,572]"`;
-exports[`calculate simulations-salarié: échelle de salaires 5`] = `"[1056,0,1000,770,770]"`;
+exports[`calculate simulations-salarié: échelle de salaires 5`] = `"[1056,0,0,1000,770,770]"`;
-exports[`calculate simulations-salarié: échelle de salaires 6`] = `"[1313,0,1250,968,968]"`;
+exports[`calculate simulations-salarié: échelle de salaires 6`] = `"[1313,0,0,1250,968,968]"`;
-exports[`calculate simulations-salarié: échelle de salaires 7`] = `"[1571,0,1500,1165,1165]"`;
+exports[`calculate simulations-salarié: échelle de salaires 7`] = `"[1571,0,0,1500,1165,1165]"`;
-exports[`calculate simulations-salarié: échelle de salaires 8`] = `"[2479,0,2000,1561,1524]"`;
+exports[`calculate simulations-salarié: échelle de salaires 8`] = `"[2479,0,0,2000,1561,1524]"`;
-exports[`calculate simulations-salarié: échelle de salaires 9`] = `"[3401,0,2500,1957,1861]"`;
+exports[`calculate simulations-salarié: échelle de salaires 9`] = `"[3401,0,0,2500,1957,1861]"`;
-exports[`calculate simulations-salarié: échelle de salaires 10`] = `"[4076,0,3000,2353,2187]"`;
+exports[`calculate simulations-salarié: échelle de salaires 10`] = `"[4076,0,0,3000,2353,2187]"`;
-exports[`calculate simulations-salarié: échelle de salaires 11`] = `"[5674,0,4000,3146,2759]"`;
+exports[`calculate simulations-salarié: échelle de salaires 11`] = `"[5674,0,0,4000,3146,2759]"`;
-exports[`calculate simulations-salarié: échelle de salaires 12`] = `"[7085,0,5000,3948,3336]"`;
+exports[`calculate simulations-salarié: échelle de salaires 12`] = `"[7085,0,0,5000,3948,3336]"`;
-exports[`calculate simulations-salarié: échelle de salaires 13`] = `"[14319,0,10000,7958,6080]"`;
+exports[`calculate simulations-salarié: échelle de salaires 13`] = `"[14319,0,0,10000,7958,6080]"`;
-exports[`calculate simulations-salarié: échelle de salaires 14`] = `"[28345,0,20000,15969,10681]"`;
+exports[`calculate simulations-salarié: échelle de salaires 14`] = `"[28345,0,0,20000,15969,10681]"`;
-exports[`calculate simulations-salarié: échelle de salaires 15`] = `"[128575,0,100000,87157,46271]"`;
+exports[`calculate simulations-salarié: échelle de salaires 15`] = `"[128575,0,0,100000,87157,46271]"`;
-exports[`calculate simulations-salarié: échelle de salaires 16`] = `"[1243819,0,1000000,896257,446123]"`;
+exports[`calculate simulations-salarié: échelle de salaires 16`] = `"[1243819,0,0,1000000,896257,446123]"`;
diff --git a/test/regressions/simulations-artiste-auteur.yaml b/test/regressions/simulations-artiste-auteur.yaml
index 3e5123d3d..3778c90f2 100644
--- a/test/regressions/simulations-artiste-auteur.yaml
+++ b/test/regressions/simulations-artiste-auteur.yaml
@@ -1,12 +1,12 @@
salarié:
- - artiste-auteur . revenus . traitements et salaires: 1000 €/an
- - artiste-auteur . revenus . traitements et salaires: 10000 €/an
- - artiste-auteur . revenus . traitements et salaires: 100000 €/an
+ - artiste-auteur . revenus . traitements et salaires: 1000
+ - artiste-auteur . revenus . traitements et salaires: 10000
+ - artiste-auteur . revenus . traitements et salaires: 100000
bnc:
- - artiste-auteur . revenus . BNC . recettes: 10000 €/an
- - artiste-auteur . revenus . BNC . recettes: 10000 €/an
+ - artiste-auteur . revenus . BNC . recettes: 10000
+ - artiste-auteur . revenus . BNC . recettes: 10000
artiste-auteur . revenus . BNC . micro-bnc: non
- - artiste-auteur . revenus . BNC . recettes: 10000 €/an
+ - artiste-auteur . revenus . BNC . recettes: 10000
artiste-auteur . revenus . BNC . micro-bnc: non
- artiste-auteur . revenus . BNC . frais réels: 5000 €/an
+ artiste-auteur . revenus . BNC . frais réels: 5000
diff --git a/test/regressions/simulations-auto-entrepreneur.yaml b/test/regressions/simulations-auto-entrepreneur.yaml
index 742bc6753..1a7e4d24a 100644
--- a/test/regressions/simulations-auto-entrepreneur.yaml
+++ b/test/regressions/simulations-auto-entrepreneur.yaml
@@ -1,33 +1,33 @@
échelle de revenus:
- - dirigeant . auto-entrepreneur . net de cotisations: 500 €/an
- - dirigeant . auto-entrepreneur . net de cotisations: 1000 €/an
- - dirigeant . auto-entrepreneur . net de cotisations: 2000 €/an
- - dirigeant . auto-entrepreneur . net de cotisations: 5000 €/an
- - dirigeant . auto-entrepreneur . net de cotisations: 10000 €/an
- - dirigeant . auto-entrepreneur . net de cotisations: 20000 €/an
- - dirigeant . auto-entrepreneur . net de cotisations: 50000 €/an
- - dirigeant . auto-entrepreneur . net de cotisations: 70000 €/an
- - dirigeant . auto-entrepreneur . net de cotisations: 100000 €/an
- - dirigeant . auto-entrepreneur . net de cotisations: 1000000 €/an
+ - dirigeant . auto-entrepreneur . net de cotisations: 500
+ - dirigeant . auto-entrepreneur . net de cotisations: 1000
+ - dirigeant . auto-entrepreneur . net de cotisations: 2000
+ - dirigeant . auto-entrepreneur . net de cotisations: 5000
+ - dirigeant . auto-entrepreneur . net de cotisations: 10000
+ - dirigeant . auto-entrepreneur . net de cotisations: 20000
+ - dirigeant . auto-entrepreneur . net de cotisations: 50000
+ - dirigeant . auto-entrepreneur . net de cotisations: 70000
+ - dirigeant . auto-entrepreneur . net de cotisations: 100000
+ - dirigeant . auto-entrepreneur . net de cotisations: 1000000
aides:
- - dirigeant . auto-entrepreneur . net de cotisations: 5000 €/an
+ - dirigeant . auto-entrepreneur . net de cotisations: 5000
entreprise . ACRE: oui
- - dirigeant . auto-entrepreneur . net de cotisations: 50000 €/an
+ - dirigeant . auto-entrepreneur . net de cotisations: 50000
entreprise . ACRE: oui
impôt sur le revenu:
- - dirigeant . auto-entrepreneur . net de cotisations: 25000 €/an
- entreprise . catégorie d'activité: "'libérale'"
+ - dirigeant . auto-entrepreneur . net de cotisations: 25000
+ entreprise . catégorie d'activité: 'libérale'
dirigeant . auto-entrepreneur . impôt . versement libératoire: oui
ACRE:
- - dirigeant . auto-entrepreneur . net de cotisations: 20000 €/an
+ - dirigeant . auto-entrepreneur . net de cotisations: 20000
entreprise . date de création: 01/01/2020
entreprise . ACRE: oui
- - dirigeant . auto-entrepreneur . net de cotisations: 30000 €/an
+ - dirigeant . auto-entrepreneur . net de cotisations: 30000
entreprise . date de création: 01/06/2019
entreprise . ACRE: oui
- - dirigeant . auto-entrepreneur . net de cotisations: 40000 €/an
+ - dirigeant . auto-entrepreneur . net de cotisations: 40000
entreprise . date de création: 01/06/2018
entreprise . ACRE: oui
diff --git a/test/regressions/simulations-indépendant.yaml b/test/regressions/simulations-indépendant.yaml
index d94241bfe..56c77f8d1 100644
--- a/test/regressions/simulations-indépendant.yaml
+++ b/test/regressions/simulations-indépendant.yaml
@@ -1,45 +1,45 @@
échelle de revenus:
- - dirigeant . indépendant . revenu net de cotisations: 500 €/an
- - dirigeant . indépendant . revenu net de cotisations: 1000 €/an
- - dirigeant . indépendant . revenu net de cotisations: 1500 €/an
- - dirigeant . indépendant . revenu net de cotisations: 2000 €/an
- - dirigeant . indépendant . revenu net de cotisations: 5000 €/an
- - dirigeant . indépendant . revenu net de cotisations: 10000 €/an
- - dirigeant . indépendant . revenu net de cotisations: 100000 €/an
- - dirigeant . indépendant . revenu net de cotisations: 1000000 €/an
+ - dirigeant . indépendant . revenu net de cotisations: 500
+ - dirigeant . indépendant . revenu net de cotisations: 1000
+ - dirigeant . indépendant . revenu net de cotisations: 1500
+ - dirigeant . indépendant . revenu net de cotisations: 2000
+ - dirigeant . indépendant . revenu net de cotisations: 5000
+ - dirigeant . indépendant . revenu net de cotisations: 10000
+ - dirigeant . indépendant . revenu net de cotisations: 100000
+ - dirigeant . indépendant . revenu net de cotisations: 1000000
inversions:
- - dirigeant . rémunération totale: 2000 €/an
- - dirigeant . rémunération totale: 50000 €/an
- - revenu net après impôt: 10000 €/an
- - revenu net après impôt: 50000 €/an
- - revenu net après impôt: 10000 €/an
- entreprise . charges: 1000 €/an
- - entreprise . chiffre d'affaires minimum: 20000 €/an
- entreprise . charges: 1000 €/an
- - entreprise . chiffre d'affaires minimum: 20000 €/an
- entreprise . charges: 2000 €/an
+ - dirigeant . rémunération totale: 2000
+ - dirigeant . rémunération totale: 50000
+ - revenu net après impôt: 10000
+ - revenu net après impôt: 50000
+ - revenu net après impôt: 10000
+ entreprise . charges: 1000
+ - entreprise . chiffre d'affaires minimum: 20000
+ entreprise . charges: 1000
+ - entreprise . chiffre d'affaires minimum: 20000
+ entreprise . charges: 2000
cotisations minimales:
- - dirigeant . indépendant . revenu net de cotisations: 100 €/an
- - dirigeant . indépendant . revenu net de cotisations: 100 €/an
+ - dirigeant . indépendant . revenu net de cotisations: 100
+ - dirigeant . indépendant . revenu net de cotisations: 100
situation personnelle . RSA: oui
activité:
- - dirigeant . indépendant . revenu net de cotisations: 20000 €/an
- entreprise . catégorie d'activité: "'libérale'"
- - dirigeant . indépendant . revenu net de cotisations: 20000 €/an
- entreprise . catégorie d'activité: "'artisanale'"
+ - dirigeant . indépendant . revenu net de cotisations: 20000
+ entreprise . catégorie d'activité: libérale
+ - dirigeant . indépendant . revenu net de cotisations: 20000
+ entreprise . catégorie d'activité: artisanale
acre:
- - dirigeant . indépendant . revenu net de cotisations: 50000 €/an
+ - dirigeant . indépendant . revenu net de cotisations: 50000
entreprise . ACRE: true
impôt sur le revenu:
- - dirigeant . indépendant . revenu net de cotisations: 20000 €/an
- impôt . méthode de calcul: "'taux neutre'"
- - dirigeant . indépendant . revenu net de cotisations: 50000 €/an
- impôt . méthode de calcul: "'taux neutre'"
- - dirigeant . indépendant . revenu net de cotisations: 20000 €/an
- impôt . méthode de calcul: "'taux personnalisé'"
+ - dirigeant . indépendant . revenu net de cotisations: 20000
+ impôt . méthode de calcul: taux neutre
+ - dirigeant . indépendant . revenu net de cotisations: 50000
+ impôt . méthode de calcul: taux neutre
+ - dirigeant . indépendant . revenu net de cotisations: 20000
+ impôt . méthode de calcul: taux personnalisé
impôt . taux personnalisé: 10
diff --git a/test/regressions/simulations-rémunération-dirigeant.yaml b/test/regressions/simulations-rémunération-dirigeant.yaml
index 104f87467..9ca07d898 100644
--- a/test/regressions/simulations-rémunération-dirigeant.yaml
+++ b/test/regressions/simulations-rémunération-dirigeant.yaml
@@ -1,74 +1,74 @@
échelle de rémunération:
- - dirigeant . rémunération totale: 100 €/an
- - dirigeant . rémunération totale: 1000 €/an
- - dirigeant . rémunération totale: 2000 €/an
- - dirigeant . rémunération totale: 5000 €/an
- - dirigeant . rémunération totale: 10000 €/an
- - dirigeant . rémunération totale: 20000 €/an
- - dirigeant . rémunération totale: 50000 €/an
- - dirigeant . rémunération totale: 100000 €/an
+ - dirigeant . rémunération totale: 100
+ - dirigeant . rémunération totale: 1000
+ - dirigeant . rémunération totale: 2000
+ - dirigeant . rémunération totale: 5000
+ - dirigeant . rémunération totale: 10000
+ - dirigeant . rémunération totale: 20000
+ - dirigeant . rémunération totale: 50000
+ - dirigeant . rémunération totale: 100000
avec charges:
- - dirigeant . rémunération totale: 10000 €/an
+ - dirigeant . rémunération totale: 10000
entreprise . charges: 2000
- - dirigeant . rémunération totale: 20000 €/an
+ - dirigeant . rémunération totale: 20000
entreprise . charges: 15000
ACRE:
- - dirigeant . rémunération totale: 10000 €/an
+ - dirigeant . rémunération totale: 10000
entreprise . date de création: 01/01/2020
entreprise . ACRE: oui
- - dirigeant . rémunération totale: 20000 €/an
+ - dirigeant . rémunération totale: 20000
entreprise . date de création: 01/01/2020
entreprise . ACRE: oui
- - dirigeant . rémunération totale: 30000 €/an
+ - dirigeant . rémunération totale: 30000
entreprise . date de création: 01/06/2020
entreprise . ACRE: oui
activités:
- - dirigeant . rémunération totale: 20000 €/an
- entreprise . catégorie d'activité: "'libérale'"
- - dirigeant . rémunération totale: 20000 €/an
- entreprise . catégorie d'activité: "'libérale'"
+ - dirigeant . rémunération totale: 20000
+ entreprise . catégorie d'activité: libérale
+ - dirigeant . rémunération totale: 20000
+ entreprise . catégorie d'activité: libérale
entreprise . catégorie d'activité . libérale règlementée: oui
- - dirigeant . rémunération totale: 20000 €/an
- entreprise . catégorie d'activité: "'artisanale'"
- - dirigeant . rémunération totale: 20000 €/an
- entreprise . catégorie d'activité: "'commerciale ou industrielle'"
- entreprise . catégorie d'activité . service ou vente: "'vente'"
- - dirigeant . rémunération totale: 20000 €/an
- entreprise . catégorie d'activité: "'commerciale ou industrielle'"
- entreprise . catégorie d'activité . service ou vente: "'service'"
+ - dirigeant . rémunération totale: 20000
+ entreprise . catégorie d'activité: artisanale
+ - dirigeant . rémunération totale: 20000
+ entreprise . catégorie d'activité: commerciale ou industrielle
+ entreprise . catégorie d'activité . service ou vente: vente
+ - dirigeant . rémunération totale: 20000
+ entreprise . catégorie d'activité: commerciale ou industrielle
+ entreprise . catégorie d'activité . service ou vente: service
entreprise . catégorie d'activité . restauration ou hébergement: oui
Contrats Madelin:
# Cas retraite: la cotisation Madelin est inferieure au plafond => le revenu net de
# cotisations (résultat comptable) n'est pas affecté car l'assiette des
# cotisations ne change pas:
- - dirigeant . rémunération totale: 30000 €/an
+ - dirigeant . rémunération totale: 30000
entreprise . charges: 10000
dirigeant . indépendant . contrats madelin . mutuelle . montant: 4000 # plafond: 10% PSS donc environ 4100
# Cas retraite: la cotisation Madelin est supérieure au plafond => le revenu net de
# cotisations est affecté car l'assiette des cotisations est plus élevée
- - dirigeant . rémunération totale: 30000 €/an
+ - dirigeant . rémunération totale: 30000
entreprise . charges: 10000
dirigeant . indépendant . contrats madelin . mutuelle . montant: 5000 # plafond: 10% PSS donc environ 4100
# Cas mutuelle
- - dirigeant . rémunération totale: 30000 €/an
+ - dirigeant . rémunération totale: 30000
entreprise . charges: 10000
dirigeant . indépendant . contrats madelin . mutuelle . montant: 1000
# Cas global madelin faible
- - dirigeant . rémunération totale: 20000 €/an
+ - dirigeant . rémunération totale: 20000
entreprise . charges: 1000
dirigeant . indépendant . contrats madelin . mutuelle . montant: 200
dirigeant . indépendant . contrats madelin . retraite . montant: 300
# Cas global madelin grand (plafonds calculés différemment)
- - dirigeant . rémunération totale: 300000 €/an
+ - dirigeant . rémunération totale: 300000
entreprise . charges: 15000
dirigeant . indépendant . contrats madelin . mutuelle . montant: 1500
dirigeant . indépendant . contrats madelin . retraite . montant: 5000
# Cas charges plus faibles que total madelin
- - dirigeant . rémunération totale: 20000 €/an
+ - dirigeant . rémunération totale: 20000
entreprise . charges: 500
dirigeant . indépendant . contrats madelin . mutuelle . montant: 300
dirigeant . indépendant . contrats madelin . retraite . montant: 300
diff --git a/test/regressions/simulations-salarié.yaml b/test/regressions/simulations-salarié.yaml
index b0639cd9d..52edf30e6 100644
--- a/test/regressions/simulations-salarié.yaml
+++ b/test/regressions/simulations-salarié.yaml
@@ -1,316 +1,316 @@
échelle de salaires:
- - contrat salarié . rémunération . brut de base: 100 €/mois
- - contrat salarié . rémunération . brut de base: 250 €/mois
- - contrat salarié . rémunération . brut de base: 500 €/mois
- - contrat salarié . rémunération . brut de base: 750 €/mois
- - contrat salarié . rémunération . brut de base: 1000 €/mois
- - contrat salarié . rémunération . brut de base: 1250 €/mois
- - contrat salarié . rémunération . brut de base: 1500 €/mois
- - contrat salarié . rémunération . brut de base: 2000 €/mois
- - contrat salarié . rémunération . brut de base: 2500 €/mois
- - contrat salarié . rémunération . brut de base: 3000 €/mois
- - contrat salarié . rémunération . brut de base: 4000 €/mois
- - contrat salarié . rémunération . brut de base: 5000 €/mois
- - contrat salarié . rémunération . brut de base: 10000 €/mois
- - contrat salarié . rémunération . brut de base: 20000 €/mois
- - contrat salarié . rémunération . brut de base: 100000 €/mois
- - contrat salarié . rémunération . brut de base: 1000000 €/mois
+ - contrat salarié . rémunération . brut de base: 100
+ - contrat salarié . rémunération . brut de base: 250
+ - contrat salarié . rémunération . brut de base: 500
+ - contrat salarié . rémunération . brut de base: 750
+ - contrat salarié . rémunération . brut de base: 1000
+ - contrat salarié . rémunération . brut de base: 1250
+ - contrat salarié . rémunération . brut de base: 1500
+ - contrat salarié . rémunération . brut de base: 2000
+ - contrat salarié . rémunération . brut de base: 2500
+ - contrat salarié . rémunération . brut de base: 3000
+ - contrat salarié . rémunération . brut de base: 4000
+ - contrat salarié . rémunération . brut de base: 5000
+ - contrat salarié . rémunération . brut de base: 10000
+ - contrat salarié . rémunération . brut de base: 20000
+ - contrat salarié . rémunération . brut de base: 100000
+ - contrat salarié . rémunération . brut de base: 1000000
effectif:
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
entreprise . effectif: 10
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
entreprise . effectif: 20
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
entreprise . effectif: 50
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
entreprise . effectif: 100
inversions:
- - contrat salarié . prix du travail: 2000 €/mois
- - contrat salarié . rémunération . net: 2000 €/mois
- - contrat salarié . rémunération . net après impôt: 2000 €/mois
+ - contrat salarié . prix du travail: 2000
+ - contrat salarié . rémunération . net: 2000
+ - contrat salarié . rémunération . net après impôt: 2000
stage:
- - contrat salarié: "'stage'"
- contrat salarié . rémunération . brut de base: 500 €/mois
- - contrat salarié: "'stage'"
- contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié: stage
+ contrat salarié . rémunération . brut de base: 500
+ - contrat salarié: stage
+ contrat salarié . rémunération . brut de base: 2000
apprentissage:
- - contrat salarié: "'apprentissage'"
- contrat salarié . rémunération . brut de base: 1500 €/mois
- - contrat salarié: "'apprentissage'"
- contrat salarié . rémunération . brut de base: 1500 €/mois
- contrat salarié . apprentissage . diplôme préparé: "'niveau bac ou moins'"
- contrat salarié . apprentissage . ancienneté: "'moins de deux ans'"
+ - contrat salarié: apprentissage
+ contrat salarié . rémunération . brut de base: 1500
+ - contrat salarié: apprentissage
+ contrat salarié . rémunération . brut de base: 1500
+ contrat salarié . apprentissage . diplôme préparé: niveau bac ou moins
+ contrat salarié . apprentissage . ancienneté: moins de deux ans
cadre:
- - contrat salarié . rémunération . brut de base: 3000 €/mois
+ - contrat salarié . rémunération . brut de base: 3000
contrat salarié . statut cadre: oui
cdd:
- - contrat salarié: "'CDD'"
- contrat salarié . rémunération . brut de base: 2000 €/mois
- - contrat salarié: "'CDD'"
- contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié: CDD
+ contrat salarié . rémunération . brut de base: 2000
+ - contrat salarié: CDD
+ contrat salarié . rémunération . brut de base: 2000
contrat salarié . CDD . durée contrat: 6
contrat salarié . CDD . congés non pris: 3
- - contrat salarié: "'CDD'"
- contrat salarié . rémunération . brut de base: 2400 €/mois
+ - contrat salarié: CDD
+ contrat salarié . rémunération . brut de base: 2400
contrat salarié . CDD . durée contrat: 10
contrat salarié . temps de travail . heures supplémentaires: 5
contrat salarié . indemnité kilométrique vélo: oui
contrat salarié . avantages en nature . montant: 200
atmp:
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . ATMP . taux collectif ATMP: 5
assimilé salarié:
- - dirigeant: "'assimilé salarié'"
- contrat salarié . rémunération . brut de base: 5000 €/mois
- - dirigeant: "'assimilé salarié'"
- contrat salarié . rémunération . brut de base: 1500 €/mois
+ - dirigeant: assimilé salarié
+ contrat salarié . rémunération . brut de base: 5000
+ - dirigeant: assimilé salarié
+ contrat salarié . rémunération . brut de base: 1500
entreprise . ACRE: oui
- - dirigeant: "'assimilé salarié'"
- contrat salarié . rémunération . brut de base: 3000 €/mois
+ - dirigeant: assimilé salarié
+ contrat salarié . rémunération . brut de base: 3000
entreprise . ACRE: oui
aides:
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . statut JEI: oui
- - contrat salarié . rémunération . brut de base: 10000 €/mois
+ - contrat salarié . rémunération . brut de base: 10000
contrat salarié . régime des impatriés: oui
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . aides employeur . emploi franc . éligible: oui
- - contrat salarié: "'CDD'"
- contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié: CDD
+ contrat salarié . rémunération . brut de base: 2000
contrat salarié . CDD . durée contrat: 6
contrat salarié . aides employeur . emploi franc . éligible: oui
temps partiel:
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . temps partiel: oui
- - contrat salarié . rémunération . brut de base . équivalent temps plein: 2500€/mois
+ - contrat salarié . rémunération . brut de base . équivalent temps plein: 2500
contrat salarié . temps de travail . temps partiel: oui
contrat salarié . temps de travail . temps partiel . heures par semaine: 26
- - contrat salarié . rémunération . brut de base: 1000 €/mois
+ - contrat salarié . rémunération . brut de base: 1000
contrat salarié . temps de travail . temps partiel: oui
contrat salarié . temps de travail . temps partiel . heures par semaine: 20
treizième mois:
- - contrat salarié . rémunération . brut de base: 2300 €/mois
+ - contrat salarié . rémunération . brut de base: 2300
contrat salarié . rémunération . primes . fin d'année . treizième mois: oui
- - contrat salarié . rémunération . brut de base: 2300 €/mois
+ - contrat salarié . rémunération . brut de base: 2300
contrat salarié . rémunération . primes . activité . base: 200
contrat salarié . rémunération . primes . fin d'année . treizième mois: oui
contrat salarié . temps de travail . temps partiel: oui
contrat salarié . temps de travail . temps partiel . heures par semaine: 26
contrat salarié . temps de travail . heures complémentaires: 5
- - contrat salarié . rémunération . brut de base: 2300 €/mois
+ - contrat salarié . rémunération . brut de base: 2300
contrat salarié . rémunération . primes . fin d'année . prime de fin d'année en mois: 2
impôt sur le revenu:
- - contrat salarié . rémunération . brut de base: 3000 €/mois
- impôt . méthode de calcul: "'taux neutre'"
- - contrat salarié . rémunération . brut de base: 30000 €/mois
- impôt . méthode de calcul: "'taux neutre'"
- - contrat salarié: "'CDD'"
- contrat salarié . rémunération . brut de base: 3000 €/mois
+ - contrat salarié . rémunération . brut de base: 3000
+ impôt . méthode de calcul: taux neutre
+ - contrat salarié . rémunération . brut de base: 30000
+ impôt . méthode de calcul: taux neutre
+ - contrat salarié: CDD
+ contrat salarié . rémunération . brut de base: 3000
contrat salarié . CDD . durée contrat: 2
- impôt . méthode de calcul: "'taux neutre'"
- - contrat salarié . rémunération . brut de base: 3000 €/mois
- impôt . méthode de calcul: "'taux neutre'"
- établissement . localisation . département: "'Guadeloupe'"
- - contrat salarié . rémunération . brut de base: 30000 €/mois
- impôt . méthode de calcul: "'taux neutre'"
- établissement . localisation . département: "'Guadeloupe'"
- - contrat salarié . rémunération . brut de base: 3000 €/mois
- impôt . méthode de calcul: "'taux neutre'"
- établissement . localisation . département: "'Mayotte'"
- - contrat salarié . rémunération . brut de base: 30000 €/mois
- impôt . méthode de calcul: "'taux neutre'"
- établissement . localisation . département: "'Mayotte'"
- - contrat salarié . rémunération . brut de base: 3000 €/mois
- impôt . méthode de calcul: "'taux personnalisé'"
+ impôt . méthode de calcul: taux neutre
+ - contrat salarié . rémunération . brut de base: 3000
+ impôt . méthode de calcul: taux neutre
+ établissement . localisation . département: Guadeloupe
+ - contrat salarié . rémunération . brut de base: 30000
+ impôt . méthode de calcul: taux neutre
+ établissement . localisation . département: Guadeloupe
+ - contrat salarié . rémunération . brut de base: 3000
+ impôt . méthode de calcul: taux neutre
+ établissement . localisation . département: Mayotte
+ - contrat salarié . rémunération . brut de base: 30000
+ impôt . méthode de calcul: taux neutre
+ établissement . localisation . département: Mayotte
+ - contrat salarié . rémunération . brut de base: 3000
+ impôt . méthode de calcul: taux personnalisé
impôt . taux personnalisé: 10
heures supplémentaires et complémentaires:
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 5
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 30
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 5
entreprise . effectif: 100
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 5
- contrat salarié . convention collective: "'HCR'"
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ contrat salarié . convention collective: 'HCR'
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 30
- contrat salarié . convention collective: "'HCR'"
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ contrat salarié . convention collective: 'HCR'
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 30
- contrat salarié . convention collective: "'compta'"
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ contrat salarié . convention collective: 'compta'
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . temps partiel: oui
contrat salarié . temps de travail . temps partiel . heures par semaine: 24
contrat salarié . temps de travail . heures complémentaires: 20
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . temps partiel: oui
contrat salarié . temps de travail . temps partiel . heures par semaine: 26
contrat salarié . temps de travail . heures complémentaires: 20
avantages:
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . rémunération . avantages en nature: oui
contrat salarié . rémunération . avantages en nature . montant: 100
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . rémunération . avantages en nature: oui
contrat salarié . rémunération . avantages en nature . autres: oui
contrat salarié . rémunération . avantages en nature . autres . montant: 100
contrat salarié . rémunération . avantages en nature . ntic . coût appareils: 400
contrat salarié . rémunération . avantages en nature . ntic . abonnements: 20
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . rémunération . avantages en nature: oui
contrat salarié . rémunération . avantages en nature . nourriture: oui
contrat salarié . rémunération . avantages en nature . nourriture . repas par mois: 10
JEI:
- - contrat salarié . rémunération . brut de base: 3000 €/mois
+ - contrat salarié . rémunération . brut de base: 3000
contrat salarié . statut JEI: oui
- - contrat salarié . rémunération . brut de base: 20000 €/mois
+ - contrat salarié . rémunération . brut de base: 20000
contrat salarié . statut JEI: oui
- - contrat salarié . rémunération . brut de base: 4000 €/mois
- dirigeant: "'assimilé salarié'"
+ - contrat salarié . rémunération . brut de base: 4000
+ dirigeant: 'assimilé salarié'
contrat salarié . statut JEI: oui
frais pro - titres restaurant:
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . frais professionnels . titres-restaurant: oui
contrat salarié . frais professionnels . titres-restaurant . titres-restaurant par mois: 10
- - contrat salarié . rémunération . brut de base: 3000 €/mois
+ - contrat salarié . rémunération . brut de base: 3000
contrat salarié . frais professionnels . titres-restaurant: oui
contrat salarié . frais professionnels . titres-restaurant . titres-restaurant par mois: 20
contrat salarié . frais professionnels . titres-restaurant . montant unitaire: 20
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . frais professionnels . titres-restaurant: oui
contrat salarié . frais professionnels . titres-restaurant . taux participation employeur: 55
frais pro - IKV:
- - contrat salarié . rémunération . brut de base: 3200 €/mois
+ - contrat salarié . rémunération . brut de base: 3200
contrat salarié . frais professionnels . indemnité kilométrique vélo: oui
- - contrat salarié . rémunération . brut de base: 3200 €/mois
+ - contrat salarié . rémunération . brut de base: 3200
contrat salarié . frais professionnels . indemnité kilométrique vélo . distance mensuelle: 200
- - contrat salarié . rémunération . net après impôt: 1630 €/mois
+ - contrat salarié . rémunération . net après impôt: 1630
contrat salarié . frais professionnels . indemnité kilométrique vélo . distance mensuelle: 30
frais pro - DFS:
- - contrat salarié . rémunération . brut de base: 2000 €/mois
- contrat salarié . profession spécifique: "'journaliste'"
- - contrat salarié . rémunération . brut de base: 2000 €/mois
- contrat salarié . profession spécifique: "'ouvrier du bâtiment'"
- - contrat salarié . rémunération . brut de base: 2000 €/mois
- contrat salarié . profession spécifique: "'artiste musicien'"
- - contrat salarié . rémunération . brut de base: 2000 €/mois
- contrat salarié . profession spécifique: "'pilote de ligne ou personnel navigant'"
- - contrat salarié . rémunération . brut de base: 2000 €/mois
- contrat salarié . profession spécifique: "'journaliste'"
+ - contrat salarié . rémunération . brut de base: 2000
+ contrat salarié . profession spécifique: journaliste
+ - contrat salarié . rémunération . brut de base: 2000
+ contrat salarié . profession spécifique: ouvrier du bâtiment
+ - contrat salarié . rémunération . brut de base: 2000
+ contrat salarié . profession spécifique: artiste musicien
+ - contrat salarié . rémunération . brut de base: 2000
+ contrat salarié . profession spécifique: pilote de ligne ou personnel navigant
+ - contrat salarié . rémunération . brut de base: 2000
+ contrat salarié . profession spécifique: journaliste
contrat salarié . déduction forfaitaire spécifique . application: non
# Test des taux réduits journalistes et abattement fiscal
- - contrat salarié . rémunération . brut de base: 1700 €/mois
- contrat salarié . profession spécifique: "'journaliste'"
- - contrat salarié . rémunération . brut de base: 2600 €/mois
- contrat salarié . profession spécifique: "'journaliste'"
+ - contrat salarié . rémunération . brut de base: 1700
+ contrat salarié . profession spécifique: journaliste
+ - contrat salarié . rémunération . brut de base: 2600
+ contrat salarié . profession spécifique: journaliste
activité partielle:
- - contrat salarié . rémunération . brut de base: 1560 €/mois
+ - contrat salarié . rémunération . brut de base: 1560
contrat salarié . activité partielle: oui
- - contrat salarié . rémunération . brut de base: 4000 €/mois
+ - contrat salarié . rémunération . brut de base: 4000
contrat salarié . activité partielle: oui
- - contrat salarié . rémunération . brut de base: 8000 €/mois
+ - contrat salarié . rémunération . brut de base: 8000
contrat salarié . activité partielle: oui
- - contrat salarié . rémunération . brut de base: 4000 €/mois
+ - contrat salarié . rémunération . brut de base: 4000
contrat salarié . activité partielle: oui
contrat salarié . activité partielle . heures travaillées: 30.33331
- - contrat salarié . rémunération . brut de base: 4000 €/mois
+ - contrat salarié . rémunération . brut de base: 4000
contrat salarié . activité partielle: oui
contrat salarié . activité partielle . heures travaillées: 75.833275
- - contrat salarié . rémunération . brut de base: 3000 €/mois
+ - contrat salarié . rémunération . brut de base: 3000
contrat salarié . activité partielle: oui
contrat salarié . temps de travail . temps partiel: oui
contrat salarié . temps de travail . temps partiel . heures par semaine: 28
- - contrat salarié . rémunération . brut de base: 4000 €/mois
+ - contrat salarié . rémunération . brut de base: 4000
contrat salarié . activité partielle: oui
- contrat salarié . profession spécifique: "'journaliste'"
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ contrat salarié . profession spécifique: journaliste
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . activité partielle: oui
contrat salarié . activité partielle . convention syntec: oui
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . activité partielle . heures travaillées: 75.833275
contrat salarié . activité partielle: oui
contrat salarié . activité partielle . convention syntec: oui
- - contrat salarié . rémunération . brut de base: 6000 €/mois
+ - contrat salarié . rémunération . brut de base: 6000
contrat salarié . activité partielle: oui
contrat salarié . activité partielle . convention syntec: oui
lodeom:
- - contrat salarié . rémunération . brut de base: 1521.22 €/mois
+ - contrat salarié . rémunération . brut de base: 1521.22
contrat salarié . lodeom . zone un: oui
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . lodeom . zone un: oui
- - contrat salarié . rémunération . brut de base: 3000 €/mois
+ - contrat salarié . rémunération . brut de base: 3000
contrat salarié . lodeom . zone un: oui
- - contrat salarié . rémunération . brut de base: 4000 €/mois
+ - contrat salarié . rémunération . brut de base: 4000
contrat salarié . lodeom . zone un: oui
- - contrat salarié . rémunération . brut de base: 5500 €/mois
+ - contrat salarié . rémunération . brut de base: 5500
contrat salarié . lodeom . zone un: oui
lodeom compétitivité renforcée:
- - contrat salarié . rémunération . brut de base: 1521.22 €/mois
+ - contrat salarié . rémunération . brut de base: 1521.22
contrat salarié . lodeom . zone un: oui
contrat salarié . lodeom . éligible barème compétitivité renforcée: oui
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . lodeom . zone un: oui
contrat salarié . lodeom . éligible barème compétitivité renforcée: oui
- - contrat salarié . rémunération . brut de base: 3000 €/mois
+ - contrat salarié . rémunération . brut de base: 3000
contrat salarié . lodeom . zone un: oui
contrat salarié . lodeom . éligible barème compétitivité renforcée: oui
- - contrat salarié . rémunération . brut de base: 4000 €/mois
+ - contrat salarié . rémunération . brut de base: 4000
contrat salarié . lodeom . zone un: oui
contrat salarié . lodeom . éligible barème compétitivité renforcée: oui
- - contrat salarié . rémunération . brut de base: 5500 €/mois
+ - contrat salarié . rémunération . brut de base: 5500
contrat salarié . lodeom . zone un: oui
contrat salarié . lodeom . éligible barème compétitivité renforcée: oui
lodeom innovation et croissance:
- - contrat salarié . rémunération . brut de base: 1521.22 €/mois
+ - contrat salarié . rémunération . brut de base: 1521.22
contrat salarié . lodeom . zone un: oui
contrat salarié . lodeom . éligible barème innovation et croissance: oui
- - contrat salarié . rémunération . brut de base: 2000 €/mois
+ - contrat salarié . rémunération . brut de base: 2000
contrat salarié . lodeom . zone un: oui
contrat salarié . lodeom . éligible barème innovation et croissance: oui
- - contrat salarié . rémunération . brut de base: 3000 €/mois
+ - contrat salarié . rémunération . brut de base: 3000
contrat salarié . lodeom . zone un: oui
contrat salarié . lodeom . éligible barème innovation et croissance: oui
- - contrat salarié . rémunération . brut de base: 4000 €/mois
+ - contrat salarié . rémunération . brut de base: 4000
contrat salarié . lodeom . zone un: oui
contrat salarié . lodeom . éligible barème innovation et croissance: oui
- - contrat salarié . rémunération . brut de base: 5500 €/mois
+ - contrat salarié . rémunération . brut de base: 5500
contrat salarié . lodeom . zone un: oui
contrat salarié . lodeom . éligible barème innovation et croissance: oui
taux spécifiques retraite complémentaire:
- - contrat salarié . rémunération . brut de base: 1521.22 €/mois
+ - contrat salarié . rémunération . brut de base: 1521.22
contrat salarié . retraite complémentaire . taux employeur tranche 1: 5.59
contrat salarié . retraite complémentaire . taux salarié tranche 1: 2.28
- - contrat salarié . rémunération . brut de base: 2500 €/mois
+ - contrat salarié . rémunération . brut de base: 2500
contrat salarié . retraite complémentaire . taux employeur tranche 1: 5.59
contrat salarié . retraite complémentaire . taux salarié tranche 1: 2.28
- - contrat salarié . rémunération . brut de base: 1521.22 €/mois
+ - contrat salarié . rémunération . brut de base: 1521.22
contrat salarié . retraite complémentaire . taux employeur tranche 1: 3.94
contrat salarié . retraite complémentaire . taux salarié tranche 1: 3.93
- - contrat salarié . rémunération . brut de base: 2500 €/mois
+ - contrat salarié . rémunération . brut de base: 2500
contrat salarié . retraite complémentaire . taux employeur tranche 1: 3.94
contrat salarié . retraite complémentaire . taux salarié tranche 1: 3.93
diff --git a/test/regressions/simulations.jest.js b/test/regressions/simulations.jest.js
index 7dbb82f73..638c47f0e 100644
--- a/test/regressions/simulations.jest.js
+++ b/test/regressions/simulations.jest.js
@@ -20,16 +20,25 @@ import remunerationDirigeantSituations from './simulations-rémunération-dirige
import employeeSituations from './simulations-salarié.yaml'
const roundResult = arr => arr.map(x => Math.round(x))
-const engine = new Engine(rules)
-const runSimulations = (situations, targets, baseSituation = {}) =>
+const engine = new Engine({ rules })
+const runSimulations = (
+ situations,
+ targets,
+ baseSituation = {},
+ defaultUnits,
+ namePrefix = ''
+) =>
Object.entries(situations).map(([name, situations]) =>
situations.forEach(situation => {
engine.setSituation({ ...baseSituation, ...situation })
- const res = targets.map(target => engine.evaluate(target).nodeValue)
+ engine.setDefaultUnits(defaultUnits)
+ const res = engine.evaluate(targets).map(node => node.nodeValue)
// Stringify is not required, but allows the result to be displayed in a single
// line in the snapshot, which considerably reduce the number of lines of this snapshot
// and improve its readability.
- expect(JSON.stringify(roundResult(res))).toMatchSnapshot(name)
+ expect(JSON.stringify(roundResult(res))).toMatchSnapshot(
+ namePrefix + ' ' + name
+ )
})
)
@@ -37,7 +46,8 @@ it('calculate simulations-salarié', () => {
runSimulations(
employeeSituations,
employeeConfig.objectifs,
- employeeConfig.situation
+ employeeConfig.situation,
+ ['€/mois']
)
})
@@ -46,57 +56,38 @@ it('calculate simulations-indépendant', () => {
(acc, cur) => [...acc, ...cur.objectifs],
[]
)
- runSimulations(independentSituations, targets, independantConfig.situation)
+ runSimulations(independentSituations, targets, independantConfig.situation, [
+ '€/an'
+ ])
})
it('calculate simulations-auto-entrepreneur', () => {
runSimulations(
autoEntrepreneurSituations,
autoentrepreneurConfig.objectifs,
- autoentrepreneurConfig.situation
+ autoentrepreneurConfig.situation,
+ ['€/an']
)
})
-it('calculate simulations-rémunération-dirigeant (assimilé salarié)', () => {
- runSimulations(
- remunerationDirigeantSituations,
- remunerationDirigeantConfig.objectifs,
- {
- ...remunerationDirigeantConfig.situation,
- dirigeant: "'assimilé salarié'"
- },
- 'assimilé salarié'
- )
-})
-
-it('calculate simulations-rémunération-dirigeant (auto-entrepreneur)', () => {
- runSimulations(
- remunerationDirigeantSituations,
- remunerationDirigeantConfig.objectifs,
- {
- ...remunerationDirigeantConfig.situation,
- dirigeant: "'auto-entrepreneur'"
- },
- 'auto-entrepreneur'
- )
-})
-
-it('calculate simulations-rémunération-dirigeant (indépendant)', () => {
- runSimulations(
- remunerationDirigeantSituations,
- remunerationDirigeantConfig.objectifs,
- {
- ...remunerationDirigeantConfig.situation,
- dirigeant: "'indépendant'"
- },
- 'indépendant'
- )
+it('calculate simulations-rémunération-dirigeant', () => {
+ const baseSituation = remunerationDirigeantConfig.situation
+ remunerationDirigeantConfig.branches.forEach(({ nom, situation }) => {
+ runSimulations(
+ remunerationDirigeantSituations,
+ remunerationDirigeantConfig.objectifs,
+ { ...baseSituation, ...situation },
+ ['€/an'],
+ `${nom} - `
+ )
+ })
})
it('calculate simulations-artiste-auteur', () => {
runSimulations(
artisteAuteurSituations,
artisteAuteurConfig.objectifs,
- artisteAuteurConfig.situation
+ artisteAuteurConfig.situation,
+ ['€/an']
)
})
diff --git a/test/rules/co2.yaml b/test/rules/co2.yaml
index 5a4e93422..b0da5e3e4 100644
--- a/test/rules/co2.yaml
+++ b/test/rules/co2.yaml
@@ -8,7 +8,8 @@ douche . impact:
douche . nombre:
question: Combien prenez-vous de douches ?
- par défaut: 30 douches
+ unité: douche
+ par défaut: 30
suggestions:
Une par jour: 30
@@ -53,7 +54,7 @@ chauffage . type:
- gaz
- fioul
- électricité
- par défaut: "'gaz'"
+ par défaut: gaz
chauffage . type . gaz:
icônes: 🔵
@@ -101,7 +102,8 @@ chauffage . impact par litre:
douche . durée de la douche:
question: Combien de temps dure votre douche en général ?
- par défaut: 5 min
+ unité: min
+ par défaut: 5
suggestions:
expresse: 5
moyenne: 10
diff --git a/test/rules/sasu.yaml b/test/rules/sasu.yaml
index 86bb8ecce..55de08d28 100644
--- a/test/rules/sasu.yaml
+++ b/test/rules/sasu.yaml
@@ -3,13 +3,16 @@
# dans la base centrale
chiffre affaires:
- par défaut: 0 €/mois
+ unité par défaut: €/mois
+ par défaut: 0
charges:
- par défaut: 0 €/mois
+ unité: €/mois
+ par défaut: 0
répartition salaire sur dividendes:
- par défaut: 50%
+ par défaut: 50
+ unité: '%'
impôt sur les sociétés:
formule:
diff --git a/test/tree.test.js b/test/tree.test.js
new file mode 100644
index 000000000..b81c9fd3a
--- /dev/null
+++ b/test/tree.test.js
@@ -0,0 +1,439 @@
+import * as R from 'ramda'
+import { expect } from 'chai'
+import daggy from 'daggy'
+import { Maybe as M } from 'ramda-fantasy'
+import { StateT, Writer } from 'akh'
+
+describe('simplified tree walks', function() {
+ // Notre domaine peut se simplifier à une liste d'équations à trous:
+ // a: 45
+ // b: a + c
+ // d: a + 4
+ // e: b + d
+ // Disons que je veux connaitre "e", alors il va me manquer "c"
+ // Si je connais "c", alors je peux calculer "e"
+ // Et mon ambition est aussi de pouvoir visualiser le calcul en HTML
+ // Donc j'ai une structure plate que je transforme en arbre (ce n'est pas
+ // le focus de la présente exploration), je veux pouvoir demander des choses
+ // diverses à cet arbre: l'évaluer, repérer les trous, le transformer en HTML
+
+ // Plus tard je vais avoir des trucs plus sophistiqués, par exemple:
+ // b: a + (bleu: b, vert: c)
+ // qui est équivalent à:
+ // b: b-bleu + b-vert
+ // b-bleu: a + b
+ // b-vert: a + c
+ // Le but du jeu est de pouvoir le représenter de façon compacte, mais
+ // d'avoir un arbre simple à manipuler
+
+ // Pour intégrer dans le simulateur, il faut remplir les exigences
+ // suivantes:
+ // X décorer l'arbre avec une valeur à chaque noeud
+ // X réaliser le calcul de façon efficiente (1 fois par variable)
+ // - savoir "court-circuiter" le calcul de variables manquantes dans les conditionnelles
+ // - avoir un moyen de gérer les composantes et filtrage
+
+ // Ce qu'on décrit est un framework de programmation déclarative: on stipule des
+ // définitions (salaire net = brut - cotisations) mais on les donne sans ordre
+ // impératif, on laisse au moteur le soin de calculer les dépendances
+
+ // Chaque élément de notre base de règles est une définition:
+
+ const Def = daggy.taggedSum('Def', {
+ Assign: ['name', 'expr']
+ })
+ const { Assign } = Def
+
+ // Par contre, à l'exécution, il faut bien calculer des "effets de bord"
+ // pour rester performant: chaque évaluation d'une définition doit mettre
+ // à jour le 'dictionnaire' des valeurs connues, puis le mettre à disposition
+ // de la suite du calcul - on verra comment au Chapitre 3
+
+ // La partie droite d'une définition est une expression:
+
+ const Expr = daggy.taggedSum('Expr', {
+ Num: ['x'],
+ Add: ['x', 'y'],
+ Var: ['name']
+ // NotIf: ['condition','formule'],
+ // OnlyIf: ['condition','formule'],
+ // AnyOf: ['conditions'],
+ // AllOf: ['conditions'],
+ })
+ const { Num, Add, Var } = Expr
+
+ // Chapitre 1...
+
+ // Le type Expr est la traduction en JS du type suivant en Haskell,
+ // "naivement récursif":
+ // data Expr = Num Int | Var String | Add Expr Expr
+
+ // Il se trouve qu'on peut gagner beaucoup en introduisant une petite
+ // complexité: on va exprimer la récursion avec un niveau d'indirection,
+ // la première étape étant de rendre le type polymorphique sur ce qui
+ // est récursif:
+
+ // data ExprF r = Num Int | Var String | Add r r
+
+ // Par exemple, une addition de deux additions c'est de type ExprF (ExprF r),
+ // et si je veux décrire des imbrications plus poussées d'additions dans
+ // des additions il me faudra un ExprF (ExprF (ExprF r)) et ainsi de
+ // suite: on a "déroulé" la récursion dans le type d'origine.
+
+ // On peut alors retrouver le type d'origine en introduisant un
+ // "constructeur de point fixe de type", appelé Fx, et en introduisant
+ // ce qu'on appelle un "functor type" (c'est le suffixe F)
+
+ // data Expr = Fx ExprF
+
+ // Le point fixe de f est une solution à l'équation x = f x - on
+ // peut l'appliquer à des fonctions récursives, voir par exemple:
+ // https://www.vex.net/~trebla/haskell/fix.xhtml
+
+ // En JS ça ne marche pas parce que JS est strict et non lazy...
+
+ // Quand au point fixe d'un type, c'est le point fixe de son
+ // constructeur: une solution à l'équation T = Fx T
+
+ // En JS c'est juste une fonction qui emballe et une qui déballe:
+
+ const Fx = daggy.tagged('Fx', ['x'])
+ Fx.prototype.project = function() {
+ return this.x
+ }
+ const unFix = fx => fx.project()
+
+ // Les helpers suivants rendent moins pénible la construction de valeurs
+ // notamment pour les tests
+
+ let num = x => Fx(Num(x))
+ let add = (x, y) => Fx(Add(x, y))
+ let ref = name => Fx(Var(name))
+
+ // Une application de la théorie des catégories permet de dériver
+ // la fonction "fold" suivante, qui généralise aux structures récursives
+ // la notion de "reduction" (comme pour les listes), on l'appelle aussi
+ // un catamorphisme
+
+ // fold :: Functor f => (f a -> a) -> Fix f -> a
+ const fold = R.curry((algebra, x) =>
+ R.compose(algebra, R.map(fold(algebra)), unFix)(x)
+ )
+
+ // Cf. https://www.schoolofhaskell.com/user/bartosz/understanding-algebras
+
+ // Dans ce contexte, un "algebre" est une fonction qui nous dit comment calculer
+ // la réduction pour un noeud à partir des valeurs calculées pour les noeuds fils
+
+ // Cette fonction fournit la traversée
+ Expr.prototype.map = function(f) {
+ return this.cata({
+ Num: x => this, // fixed
+ Add: (x, y) => Add(f(x), f(y)),
+ Var: name => this
+ })
+ }
+
+ // Celle-ci l'évaluation
+ const evaluator = state => a => {
+ return a.cata({
+ Num: x => M.Just(x),
+ Add: (x, y) => R.lift(R.add)(x, y),
+ Var: name => M.toMaybe(state[name]) // Doesn't typecheck
+ })
+ }
+
+ let evaluate = (expr, state = {}) =>
+ fold(evaluator(state), expr).getOrElse(null) // for convenience
+
+ // Voici donc l'évaluation d'un arbre...
+
+ it('should provide a protocol for evaluation', function() {
+ let tree = num(45),
+ result = evaluate(tree)
+ expect(result).to.equal(45)
+ })
+
+ it('should evaluate expressions', function() {
+ let tree = add(num(45), num(25)),
+ result = evaluate(tree)
+ expect(result).to.equal(70)
+ })
+
+ it('should evaluate nested expressions', function() {
+ let tree = add(num(45), add(num(15), num(10))),
+ result = evaluate(tree)
+ expect(result).to.equal(70)
+ })
+
+ // Problème: on évalue l'arbre tout entier d'un seul coup; mais
+ // peut-on aussi "décorer" l'arbre pendant sa traversée avec les
+ // valeurs intermédiaires ? On verra que oui, au Chapitre 2; en
+ // attendant on voudrait aussi savoir quelles sont les variables
+ // manquantes...
+
+ const collector = state => a => {
+ return a.cata({
+ Num: x => [],
+ Add: (x, y) => R.concat(x, y),
+ Var: name => (state[name] ? [] : [name])
+ })
+ }
+
+ let missing = (expr, state = {}) => fold(collector(state), expr)
+
+ it('should evaluate expressions involving variables', function() {
+ let tree = add(num(45), ref('a')),
+ result = evaluate(tree, { a: 25 })
+ expect(result).to.equal(70)
+ })
+
+ it('should evaluate expressions involving missing variables', function() {
+ let tree = add(num(45), ref('b')),
+ result = evaluate(tree, { a: 25 })
+ expect(result).to.equal(null)
+ })
+
+ it('should provide a protocol for missing variables', function() {
+ let tree = ref('a'),
+ result = missing(tree)
+ expect(result).to.deep.equal(['a'])
+ })
+
+ it('should locate missing variables in expressions', function() {
+ let tree = add(num(45), ref('a')),
+ result = missing(tree)
+ expect(result).to.deep.equal(['a'])
+ })
+
+ it('should locate missing variables in nested expressions', function() {
+ let tree = add(add(num(35), ref('a')), num(25)),
+ result = missing(tree)
+ expect(result).to.deep.equal(['a'])
+ })
+
+ it('should locate missing variables in nested expressions', function() {
+ let tree = add(add(num(35), ref('a')), num(25)),
+ result = missing(tree, { a: 25 })
+ expect(result).to.deep.equal([])
+ })
+
+ // Chapitre 2...
+
+ // Pour annoter l'arbre avec les valeurs intermédiaires on utilise un
+ // type "Cofree Comonad": ce sont des paires (fst,snd) dont la première
+ // valeur est un noeud de l'arbre et la seconde l'annotation; on a un
+ // constructeur ann et une fonction de lecture
+
+ // Cf https://github.com/willtim/recursion-schemes/
+ // or http://www.timphilipwilliams.com/slides/HaskellAtBarclays.pdf
+
+ const AnnF = daggy.tagged('AnnF', ['fr', 'a'])
+ let ann = ({ fst, snd }) => Fx(AnnF(fst, snd))
+ let nodeValue = annf => {
+ let { fr, a } = unFix(annf)
+ return a
+ }
+
+ // fork est l'opérateur "&&&" de Haskell: (f &&& g) x = Pair(f(x),g(x))
+ let fork = (f, g) => x => ({ fst: f(x), snd: g(x) })
+
+ // synthesize combine l'application d'un algèbre fourni f et de l'annotation
+ let synthesize = f => {
+ let algebra = f =>
+ R.compose(ann, fork(R.identity, R.compose(f, R.map(nodeValue))))
+ return fold(algebra(f))
+ }
+
+ let annotate = (state, tree) => synthesize(evaluator(state))(tree)
+
+ it('should annotate tree with evaluation results', function() {
+ let tree = add(num(45), add(num(15), num(10))),
+ result = nodeValue(annotate({}, tree)).getOrElse(null)
+ expect(result).to.equal(70)
+ })
+
+ // Chapitre 3
+
+ // On sait evaluer des expressions, il faut aussi être capable de
+ // gérer les règles définissant les variables appelées dans ces
+ // expressions; voyons ce que ça donne avec un algèbre plus simple:
+
+ let calculate = R.curry((rules, name) => {
+ let find = (rules, name) =>
+ R.find(x => R.prop('name', x) == name, rules).expr,
+ expr = find(rules, name)
+ return fold(evaluator2(calculate(rules)), expr)
+ })
+
+ const evaluator2 = calculate => a => {
+ return a.cata({
+ Num: x => x,
+ Add: (x, y) => x + y,
+ Var: name => calculate(name)
+ })
+ }
+
+ it('should resolve variable dependencies', function() {
+ let rule1 = Assign('a', add(ref('b'), ref('b'))),
+ rule2 = Assign('b', num(15)),
+ rules = [rule1, rule2],
+ result = calculate(rules, 'a')
+ expect(result).to.equal(30)
+ })
+
+ // Utilisons un Writer (un idiome fonctionnel pour par exemple écrire des logs)
+ // pour examiner le calcul de plus près.
+
+ const Str = daggy.tagged('Str', ['s'])
+ Str.zero = Str('')
+ Str.prototype.zero = Str.zero
+ Str.prototype.concat = function(b) {
+ return Str(this.s + b.s)
+ }
+
+ let trace = R.curry((rules, name) => {
+ let find = (rules, name) =>
+ R.find(x => R.prop('name', x) == name, rules).expr,
+ expr = find(rules, name)
+ return fold(tracer(trace(rules)), expr)
+ })
+
+ const tracer = recurse => a => {
+ let log = (x, s) => Writer.tell(Str(s)).map(_ => x)
+ return a.cata({
+ Num: x => log(x, x + ','),
+ Add: (x, y) => x.chain(xx => y.chain(yy => log(xx + yy, '+,'))),
+ Var: name => recurse(name).chain(x => log(x, name + ','))
+ })
+ }
+
+ // On voit qu'on a calculé la valeur de b 2 fois! Ce n'est pas utile,
+ // puisque cette valeur ne changera pas au cours du calcul; et comme on
+ // répète le calcul autant de fois qu'il y a de références à une variable
+ // donnée, si l'arbre est un tant soit peu complexe les performances seront
+ // très mauvaises.
+
+ it('should trace the shape of the computation', function() {
+ let rule1 = Assign('a', add(ref('b'), ref('b'))),
+ rule2 = Assign('b', num(15)),
+ rules = [rule1, rule2],
+ result = trace(rules, 'a').run(Str.zero)
+ expect(result.value).to.equal(30)
+ expect(result.output.s).to.equal('15,b,15,b,+,')
+ })
+
+ // Pour corriger ce problème on va avoir besoin de formuler une version
+ // "monadique" du catamorphisme, c'est-à-dire qu'on va pouvoir l'associer
+ // à un contexte (ou monade) dans lequel tout le calcul va se dérouler,
+ // et qui va pouvoir accumuler des informations au fur et à mesure, par
+ // exemple un cache des variables déjà calculées.
+
+ // On a déjà vu un exemple de monade, c'était Writer: voyons comment on
+ // reformule le catamorphisme pour qu'il se déroule dans la monade Writer.
+ // L'implémentation de cataM est inspirée de
+ // https://github.com/DrBoolean/excursion/
+ // D'abord on ajoute de la plomberie:
+
+ const cataM = (of, algM) => m =>
+ m
+ .project()
+ .traverse(of, x => x.cataM(of, algM))
+ .chain(algM)
+
+ const traverse = function(of, f) {
+ return this.cata({
+ Num: x => of(this),
+ Add: (x, y) => f(x).chain(xx => f(y).chain(yy => of(Add(xx, yy)))),
+ Var: name => of(this)
+ })
+ }
+ Expr.prototype.traverse = traverse
+ Fx.prototype.cataM = function(of, alg) {
+ return cataM(of, alg)(this)
+ }
+
+ // Maintenant que c'est fait on voit qu'on a simplifié l'expression du
+ // catamorphisme: on n'a plus à expliciter l'enchaînement (sauf pour la
+ // récursion de plus haut niveau dans les variables)
+
+ let trace2 = R.curry((rules, name) => {
+ let find = (rules, name) =>
+ R.find(x => R.prop('name', x) == name, rules).expr,
+ expr = find(rules, name)
+ return cataM(Writer.of, tracer2(trace2(rules)))(expr)
+ })
+
+ const tracer2 = recurse => a => {
+ let log = (x, s) => Writer.tell(Str(s)).map(_ => x)
+ return a.cata({
+ Num: x => log(x, x + ','),
+ Add: (x, y) => log(x + y, '+,'),
+ Var: name => recurse(name).chain(x => log(x, name + ','))
+ })
+ }
+
+ it('should trace the shape of the computation, showing two passes through b', function() {
+ let rule1 = Assign('a', add(ref('b'), ref('c'))),
+ rule2 = Assign('b', num(15)),
+ rule3 = Assign('c', num(10)),
+ rules = [rule1, rule2, rule3],
+ result = trace2(rules, 'a').run(Str.zero)
+ expect(result.value).to.equal(25)
+ expect(result.output.s).to.equal('15,b,10,c,+,')
+ })
+
+ // On a la possibilité "d'encapsuler" une monade dans une autre:
+ // on va se doter d'un State, une monade qui permet de stocker un
+ // état et de le modifier en le propageant dans tout le calcul, et
+ // conserver Writer à l'intérieur (on utilise la variante StateT,
+ // le T veut dire "transformation de monade")
+
+ // On peut aller plus loin et mémoiser le catamorphisme:
+ // https://idontgetoutmuch.wordpress.com/2011/05/15/monadic-caching-folds/
+ // ça ne semble pas nécessaire ici puisque tout se passe au niveau de
+ // la récursion sur "Var"
+
+ const S = StateT(Writer)
+ const log = (x, s) => S.lift(S.inner.tell(Str(s)).map(_ => x))
+
+ let trace3 = R.curry((rules, name) => {
+ let find = (rules, name) =>
+ R.find(x => R.prop('name', x) == name, rules).expr,
+ expr = find(rules, name)
+ return cataM(S.of, tracer3(trace3(rules)))(expr)
+ })
+
+ const memoize = f => name => {
+ let cache = result =>
+ result.chain(x =>
+ result
+ .modify(state => R.assoc(name, run(result), state))
+ .chain(z => S.of(x))
+ )
+
+ return S.get.chain(state => {
+ let cached = state[name]
+ return cached ? S.of(cached.value.value) : cache(f(name))
+ })
+ }
+
+ const tracer3 = recurse => a => {
+ return a.cata({
+ Num: x => log(x, x + ','),
+ Add: (x, y) => log(x + y, '+,'),
+ Var: memoize(name => recurse(name).chain(x => log(x, name + ',')))
+ })
+ }
+
+ const run = (c, state) => Writer.run(StateT.run(c, state), Str.zero)
+
+ it('should trace the shape of the computation, showing one pass through b', function() {
+ let rule1 = Assign('a', add(ref('b'), ref('b'))),
+ rule2 = Assign('b', num(15)),
+ rules = [rule1, rule2],
+ result = run(trace3(rules, 'a'), {})
+ expect(result.value.value).to.equal(30)
+ expect(result.output.s).to.equal('15,b,+,')
+ })
+})
diff --git a/test/trees.md b/test/trees.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/test/variables.test.js b/test/variables.test.js
index 6ea35c146..3d1477f72 100644
--- a/test/variables.test.js
+++ b/test/variables.test.js
@@ -10,6 +10,22 @@ describe('getSituationValue', function() {
expect(getSituationValue(situationGate, 'salaire', rule)).to.equal('2300')
})
+ it("should interpret rules without a formula as boolean-valued, with 'oui' for true", function() {
+ let rule = {},
+ state = { condition: 'oui' },
+ situationGate = name => state[name]
+
+ expect(getSituationValue(situationGate, 'condition', rule)).to.be.true
+ })
+
+ it("should interpret rules without a formula as boolean-valued, with 'non' meaning false", function() {
+ let rule = {},
+ state = { condition: 'non' },
+ situationGate = name => state[name]
+
+ expect(getSituationValue(situationGate, 'condition', rule)).to.be.false
+ })
+
it("should interpret rules with 'one of these', with 'oui' for true", function() {
let rule = { formule: { 'une possibilité': ['noir', 'blanc'] } },
state = { condition: 'oui' },