diff --git a/source/components/simulationConfigs/indépendant.yaml b/source/components/simulationConfigs/indépendant.yaml
index 080879745..1478bf954 100644
--- a/source/components/simulationConfigs/indépendant.yaml
+++ b/source/components/simulationConfigs/indépendant.yaml
@@ -5,6 +5,7 @@ objectifs:
questions:
- entreprise . charges
- entreprise . catégorie d'activité
+ - entreprise . année d'activité
questions à l'affiche:
Charges: entreprise . charges
diff --git a/source/engine/mecanismViews/BarèmeContinu.js b/source/engine/mecanismViews/BarèmeContinu.js
index 4c6a0e885..c556faea7 100644
--- a/source/engine/mecanismViews/BarèmeContinu.js
+++ b/source/engine/mecanismViews/BarèmeContinu.js
@@ -5,7 +5,7 @@ import './Barème.css'
import { ShowValuesConsumer } from 'Components/rule/ShowValuesContext'
import withLanguage from 'Components/utils/withLanguage'
import { BarèmeAttributes } from './Barème'
-import { toPairs } from 'ramda'
+import { sortObjectByKeys } from 'Engine/mecanismViews/common'
let Comp = withLanguage(function Barème({ nodeValue, explanation }) {
return (
@@ -30,7 +30,7 @@ let Comp = withLanguage(function Barème({ nodeValue, explanation }) {
- {toPairs(explanation.points).map(([seuil, taux]) => (
+ {sortObjectByKeys(explanation.points).map(([seuil, taux]) => (
{seuil} |
{taux} |
@@ -46,6 +46,9 @@ let Comp = withLanguage(function Barème({ nodeValue, explanation }) {
{(100 * explanation.taux).toFixed(1)} %
)}
+
+ Ce barème ne retourne que le taux.
+
}
/>
diff --git a/source/engine/mecanismViews/common.js b/source/engine/mecanismViews/common.js
index ddebbeee1..64021f30b 100644
--- a/source/engine/mecanismViews/common.js
+++ b/source/engine/mecanismViews/common.js
@@ -1,7 +1,7 @@
import classNames from 'classnames'
import withLanguage from 'Components/utils/withLanguage'
import withSitePaths from 'Components/utils/withSitePaths'
-import { compose, contains } from 'ramda'
+import { sort, compose, contains, toPairs, pipe } from 'ramda'
import React, { Component } from 'react'
import { Trans } from 'react-i18next'
import { connect } from 'react-redux'
@@ -128,3 +128,9 @@ export function SimpleRuleLink({ rule: { dottedName, title, name } }) {
)
}
+
+export let sortObjectByKeys = pipe(
+ toPairs,
+ // we don't rely on the sorting of objects
+ sort(([k1], [k2]) => k1 - k2)
+)
diff --git a/source/engine/mecanisms.js b/source/engine/mecanisms.js
index dac39387b..750bd602e 100644
--- a/source/engine/mecanisms.js
+++ b/source/engine/mecanisms.js
@@ -671,6 +671,7 @@ export let mecanismProduct = (recurse, k, v) => {
evaluate = evaluateObject(objectShape, effect)
let jsx = (nodeValue, explanation) => (
+ // The rate and factor and threshold are given defaut neutral values. If there is nothing to explain, don't display them at all
{
{makeJsx(explanation.assiette)}
- {(explanation.taux.nodeValue != 1 ||
- explanation.taux.category == 'calcExpression') && (
+ {explanation.taux.explanation && (
taux:{' '}
@@ -692,8 +692,7 @@ export let mecanismProduct = (recurse, k, v) => {
{makeJsx(explanation.taux)}
)}
- {(explanation.facteur.nodeValue != 1 ||
- explanation.facteur.category == 'calcExpression') && (
+ {explanation.facteur.explanation && (
facteur:{' '}
@@ -701,7 +700,7 @@ export let mecanismProduct = (recurse, k, v) => {
{makeJsx(explanation.facteur)}
)}
- {explanation.plafond.nodeValue != Infinity && (
+ {explanation.plafond.explanation && (
plafond:{' '}
@@ -852,12 +851,14 @@ export let mecanismContinuousScale = (recurse, k, v) => {
// Outside of these 2 limits, it's a linear function a * x + b
let a = (y2 - y1) / (x2 - x1),
b = y1 - x1 * a,
- nodeValue = a * val(assiette) + b
+ nodeValue = a * val(assiette) + b,
+ taux = nodeValue / val(assiette)
return reduced({
- nodeValue,
+ nodeValue:
+ v['retourne seulement le taux'] === 'oui' ? taux : nodeValue,
additionalExplanation: {
seuil: val(assiette) / val(multiplicateur),
- taux: nodeValue / val(assiette)
+ taux
}
})
}
diff --git a/source/engine/treatVariable.js b/source/engine/treatVariable.js
index 48f841eb8..a5bcd59ae 100644
--- a/source/engine/treatVariable.js
+++ b/source/engine/treatVariable.js
@@ -1,9 +1,13 @@
-import React from 'react';
-import { Trans } from 'react-i18next';
-import { evaluateNode, makeJsx, rewriteNode } from './evaluation';
-import { Leaf, Node } from './mecanismViews/common';
-import { disambiguateRuleReference, findParentDependency, findRuleByDottedName } from './rules';
-import { getSituationValue } from './variables';
+import React from 'react'
+import { Trans } from 'react-i18next'
+import { evaluateNode, makeJsx, rewriteNode } from './evaluation'
+import { Leaf, Node } from './mecanismViews/common'
+import {
+ disambiguateRuleReference,
+ findParentDependency,
+ findRuleByDottedName
+} from './rules'
+import { getSituationValue } from './variables'
export let treatVariable = (rules, rule, filter) => parseResult => {
let evaluate = (cache, situation, parsedRules, node) => {
@@ -41,7 +45,7 @@ export let treatVariable = (rules, rule, filter) => parseResult => {
)
return cache[cacheName]
}
- const variableScore = variable.defaultValue ? 1 : 2;
+ const variableScore = variable.defaultValue ? 1 : 2
// SITUATION 1 : La variable est directement renseignée
if (situationValue != null) return cacheAndNode(situationValue, {})
@@ -135,10 +139,7 @@ export let treatVariableTransforms = (rules, rule) => parseResult => {
// Exceptions
if (!rule.période && !inlinePeriodTransform) {
- if (
- ruleToTransform.période == 'flexible' &&
- !cache.checkingParentDependencies.includes(rule.dottedName)
- )
+ if (ruleToTransform.période == 'flexible')
throw new Error(
`Attention, une variable sans période, ${
rule.dottedName
@@ -153,13 +154,12 @@ export let treatVariableTransforms = (rules, rule) => parseResult => {
if (!ruleToTransform.période) return filteredNode
let environmentPeriod = situation('période') || 'mois'
let callingPeriod =
- inlinePeriodTransform ||
- (rule.période === 'flexible' ? environmentPeriod : rule.période)
+ inlinePeriodTransform ||
+ (rule.période === 'flexible' ? environmentPeriod : rule.période)
let calledPeriod =
- ruleToTransform.période === 'flexible'
- ? environmentPeriod
- : ruleToTransform.période
-
+ ruleToTransform.période === 'flexible'
+ ? environmentPeriod
+ : ruleToTransform.période
let transformedNodeValue =
callingPeriod === 'mois' && calledPeriod === 'année'
diff --git a/source/règles/base.yaml b/source/règles/base.yaml
index 074a1b9f6..75a02a481 100644
--- a/source/règles/base.yaml
+++ b/source/règles/base.yaml
@@ -846,9 +846,8 @@
description: Le plafond de Sécurité sociale est le montant maximum des rémunérations à prendre en compte pour le calcul de certaines cotisations.
période: mois
formule: 3377
- note: Prévision basée sur le rapport `Les comptes de la sécurité sociale, résultats 2017, prévisions 2018 et 2019`
références:
- estimation pour 2019: https://lentreprise.lexpress.fr/rh-management/remuneration-salaire/plafond-de-la-securite-sociale-pass-40-526-euros-en-2019_2037358.html
+ 2019: https://www.urssaf.fr/portail/home/actualites/toute-lactualite-employeur/plafond-de-la-securite-social-1.html
arrêté: https://www.legifrance.gouv.fr/affichTexte.do?cidTexte=JORFTEXT000036171732
- espace: contrat salarié
@@ -2648,13 +2647,34 @@
période: flexible
par défaut: 0
format: euros
-
- espace: entreprise
nom: charges non déductibles
applicable si: autoentrepreneur
formule: charges
période: flexible
+- espace: indépendant
+ nom: réduction ACRE
+ applicable si: entreprise . année d'activité = 'première année'
+ période: flexible
+ formule:
+ multiplication:
+ assiette: cotisations - cotisations . retraite complémentaire
+ taux: taux ACRE
+
+- espace: indépendant
+ nom: taux ACRE
+ période: flexible
+ formule:
+ barème continu:
+ assiette: revenu net de cotisations
+ multiplicateur: plafond sécurité sociale temps plein
+ points:
+ 0: 100%
+ 0.75: 100%
+ 1: 0%
+ retourne seulement le taux: oui
+
- espace: indépendant
nom: revenu net de cotisations
titre: Revenu net en tant qu'indépendant
@@ -2662,7 +2682,7 @@
C'est le revenu professionel du travailleur indépendant.
- Attention, **notre calcul est fait au régime de croisière** : l'indépendant qui se lance paiera pendant ses 2 premières années un forfait relativement réduit de cotisations sociales. Il devra ensuite régulariser cette situation par rapport au revenu qu'il a vraiment touché.
+ Attention, **notre calcul est fait au régime de croisière** : l'indépendant qui se lance paiera pendant ses 2 premières années un forfait relativement réduit de cotisations sociales. Il devra ensuite régulariser cette situation par rapport au revenu qu'il a vraiment touché.
Il faut donc voir ce calcul comme *le montant qui devra de toute façon être payé* à court terme après 2 ans d'exercice.
formule:
@@ -2713,6 +2733,11 @@
par défaut: non
question: Activité à la sécurité sociale des indépendants ?
+- espace: indépendant
+ nom: cotisations à payer
+ période: flexible
+ formule: cotisations - réduction ACRE
+
- espace: indépendant
nom: cotisations
période: flexible
@@ -2732,7 +2757,7 @@
période: flexible
formule:
somme:
- - cotisations
+ - cotisations à payer
- formation professionnelle
- CSG et CRDS
diff --git a/test/mécanismes/barème-continu.yaml b/test/mécanismes/barème-continu.yaml
index b72126f90..965368a4f 100644
--- a/test/mécanismes/barème-continu.yaml
+++ b/test/mécanismes/barème-continu.yaml
@@ -38,3 +38,29 @@
valeur attendue: 63.5
+- nom: base deux
+ format: nombre
+ formule: 300
+
+- nom: assiette deux
+ format: nombre
+
+- test: Retour de taux, pas d'assiette
+ formule:
+ barème continu:
+ assiette: assiette deux
+ multiplicateur: base deux
+ points:
+ 0: 100%
+ 0.75: 100%
+ 1: 0%
+ retourne seulement le taux: oui
+ exemples:
+ - nom: Premier intervale
+ situation:
+ assiette deux: 10
+ valeur attendue: 0.026
+ - nom: Deuxième intervale
+ situation:
+ assiette deux: 120
+ valeur attendue: 3.792