From 74310bd06d1b40b7c38814b85d676daaec74e77a Mon Sep 17 00:00:00 2001
From: Mael
Date: Thu, 11 Jul 2019 13:53:02 +0200
Subject: [PATCH 01/32] :art: Changement de style des valeurs dans la /doc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
L'idée est de les extraire visuellement du reste, et de ne plus utiliser
les parenthèses qui ne sont pas faites pour convoyer ce sens
---
source/engine/mecanismViews/common.js | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/source/engine/mecanismViews/common.js b/source/engine/mecanismViews/common.js
index b8b5a517c..fb0ebbded 100644
--- a/source/engine/mecanismViews/common.js
+++ b/source/engine/mecanismViews/common.js
@@ -23,7 +23,18 @@ export let NodeValuePointer = ({ data, unit }) => (
+ })}
+ css={`
+ background: white;
+ border-bottom: 0 !important;
+ padding: 0 0.2rem;
+ text-decoration: none !important;
+ margin: 0 0.3rem;
+ font-size: 80%;
+ box-shadow: 2px 2px 4px 1px #d9d9d9, 0 0 0 1px #d9d9d9;
+ line-height: 1.6em;
+ border-radius: 0.2rem;
+ `}>
)
@@ -114,11 +125,9 @@ export const Leaf = compose(
}>
{rule.title || capitalise0(name)} {filter}
- {!isNil(value) && (
-
- )}
+ {!isNil(value) && }
)}
From d2a0904c994709917a683ca71cf0588ddccd68a8 Mon Sep 17 00:00:00 2001
From: Mael
Date: Thu, 11 Jul 2019 13:56:24 +0200
Subject: [PATCH 02/32] =?UTF-8?q?:art:=20D=C3=A9placement=20et=20simplific?=
=?UTF-8?q?ation=20des=20r=C3=A9sultats=20des=20m=C3=A9canismes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/components/rule/Algorithm.css | 7 +------
source/engine/mecanismViews/common.js | 10 ++++++++--
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/source/components/rule/Algorithm.css b/source/components/rule/Algorithm.css
index 2933d4a45..de8d70715 100644
--- a/source/components/rule/Algorithm.css
+++ b/source/components/rule/Algorithm.css
@@ -166,13 +166,8 @@
.mecanism-result {
position: absolute;
display: none;
- bottom: 0;
+ top: -4px;
right: 0;
- border-top: 1px solid;
- border-left: 1px solid;
- border-top-left-radius: 0.3rem;
- border-color: inherit;
- padding: 0.1rem 0.6rem;
}
#rule-rules.showValues .mecanism-result {
display: initial;
diff --git a/source/engine/mecanismViews/common.js b/source/engine/mecanismViews/common.js
index fb0ebbded..d951424b3 100644
--- a/source/engine/mecanismViews/common.js
+++ b/source/engine/mecanismViews/common.js
@@ -29,7 +29,6 @@ export let NodeValuePointer = ({ data, unit }) => (
border-bottom: 0 !important;
padding: 0 0.2rem;
text-decoration: none !important;
- margin: 0 0.3rem;
font-size: 80%;
box-shadow: 2px 2px 4px 1px #d9d9d9, 0 0 0 1px #d9d9d9;
line-height: 1.6em;
@@ -127,7 +126,14 @@ export const Leaf = compose(
{rule.title || capitalise0(name)} {filter}
- {!isNil(value) && }
+ {!isNil(value) && (
+
+
+
+ )}
)}
From 956a8662feeb7d6619bbb5c7eacc4e8f7b3bcb48 Mon Sep 17 00:00:00 2001
From: Mael
Date: Thu, 11 Jul 2019 14:07:29 +0200
Subject: [PATCH 03/32] :fire: Un seul numberFormatter
---
source/components/Value.js | 5 ++++-
source/engine/mecanismViews/Barème.js | 26 +++++++++++++++-----------
source/engine/mecanismViews/common.js | 6 ------
3 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/source/components/Value.js b/source/components/Value.js
index 67d02aa38..8831c6258 100644
--- a/source/components/Value.js
+++ b/source/components/Value.js
@@ -8,7 +8,10 @@ const NumberFormat = memoizeWith(
Intl.NumberFormat
)
-let numberFormatter = (style, numFractionDigits = 2) => (value, language) =>
+export let numberFormatter = (style, numFractionDigits = 2) => (
+ value,
+ language
+) =>
NumberFormat(language, {
style,
currency: 'EUR',
diff --git a/source/engine/mecanismViews/Barème.js b/source/engine/mecanismViews/Barème.js
index dd781f2bc..dcb9a90cf 100644
--- a/source/engine/mecanismViews/Barème.js
+++ b/source/engine/mecanismViews/Barème.js
@@ -7,7 +7,8 @@ import React from 'react'
import { Trans } from 'react-i18next'
import { makeJsx } from '../evaluation'
import './Barème.css'
-import { formatNumber, Node, NodeValuePointer } from './common'
+import { Node, NodeValuePointer } from './common'
+import { numberFormatter } from 'Components/Value'
export let BarèmeAttributes = ({ explanation, lazyEval = identity }) => (
<>
@@ -96,12 +97,13 @@ let Component = withLanguage(function Barème({
Taux final :{' '}
- {formatNumber(
- (nodeValue /
- lazyEval(explanation['assiette']).nodeValue) *
- 100,
- language
- )}{' '}
+
%
>
)}
@@ -113,6 +115,8 @@ let Component = withLanguage(function Barème({
)
})
+let number = numberFormatter(undefined, 0)
+
let Tranche = ({
tranche: {
'en-dessous de': maxOnly,
@@ -132,16 +136,16 @@ let Tranche = ({
{maxOnly ? (
<>
- En-dessous de {formatNumber(maxOnly, language)}
+ En-dessous de {number(maxOnly, language)}
>
) : minOnly ? (
<>
- Au-dessus de {formatNumber(minOnly, language)}
+ Au-dessus de {number(minOnly, language)}
>
) : (
<>
- De {formatNumber(min, language)} à {' '}
- {formatNumber(max, language)}
+ De {number(min, language)} à {' '}
+ {number(max, language)}
>
)}
diff --git a/source/engine/mecanismViews/common.js b/source/engine/mecanismViews/common.js
index d951424b3..11853fbd7 100644
--- a/source/engine/mecanismViews/common.js
+++ b/source/engine/mecanismViews/common.js
@@ -13,12 +13,6 @@ import mecanismColours from './colours'
import classnames from 'classnames'
import Value from 'Components/Value'
-//TODO remove this one, it should reside in 'Value.js'
-export let formatNumber = (data, language) =>
- !isNaN(data)
- ? Intl.NumberFormat(language, { maximumFractionDigits: 4 }).format(data)
- : data
-
export let NodeValuePointer = ({ data, unit }) => (
Date: Thu, 11 Jul 2019 16:29:05 +0200
Subject: [PATCH 04/32] =?UTF-8?q?Impl=C3=A9mentation=20plus=20g=C3=A9n?=
=?UTF-8?q?=C3=A9rique=20des=20unit=C3=A9s?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/components/rule/Rule.js | 1 +
source/engine/mecanisms.js | 11 ++++++++--
source/engine/parse.js | 6 +----
source/engine/units.js | 40 ++++++++++++++++++++++------------
source/règles/base.yaml | 1 -
test/units.test.js | 6 ++---
6 files changed, 40 insertions(+), 25 deletions(-)
diff --git a/source/components/rule/Rule.js b/source/components/rule/Rule.js
index 573c6af19..f8f5d5b28 100644
--- a/source/components/rule/Rule.js
+++ b/source/components/rule/Rule.js
@@ -63,6 +63,7 @@ export default compose(
namespaceRules = findRuleByNamespace(flatRules, dottedName)
let displayedRule = analysedExample || analysedRule
+
return (
<>
{this.state.viewSource ? (
diff --git a/source/engine/mecanisms.js b/source/engine/mecanisms.js
index b514a3537..05f99932c 100644
--- a/source/engine/mecanisms.js
+++ b/source/engine/mecanisms.js
@@ -58,6 +58,7 @@ import Variations from './mecanismViews/Variations'
import { disambiguateRuleReference, findRuleByDottedName } from './rules'
import { anyNull, val } from './traverse-common-functions'
import uniroot from './uniroot'
+import { inferUnit } from 'Engine/units'
/* @devariate = true => This function will produce variations of a same mecanism (e.g. product) that share some common properties */
export let mecanismVariations = (recurse, k, v, devariate) => {
@@ -502,7 +503,8 @@ export let mecanismSum = (recurse, k, v) => {
explanation,
category: 'mecanism',
name: 'somme',
- type: 'numeric'
+ type: 'numeric',
+ unit: inferUnit('+', explanation.map(r => r.unit))
}
}
@@ -608,7 +610,12 @@ export let mecanismProduct = (recurse, k, v) => {
explanation,
category: 'mecanism',
name: 'multiplication',
- type: 'numeric'
+ type: 'numeric',
+ unit: inferUnit('*', [
+ explanation.assiette,
+ explanation.taux,
+ explanation.facteur
+ ])
}
}
diff --git a/source/engine/parse.js b/source/engine/parse.js
index 92ed57c24..3ac304185 100644
--- a/source/engine/parse.js
+++ b/source/engine/parse.js
@@ -202,11 +202,7 @@ let mecanismOperation = (k, operatorFunction, symbol) => (recurse, k, v) => {
let explanation = v.explanation.map(recurse)
- let unit = inferUnit(
- k,
- explanation[0].unit || undefined,
- explanation[1].unit || undefined
- )
+ let unit = inferUnit(k, [explanation[0].unit, explanation[1].unit])
let jsx = (nodeValue, explanation) => (
{
let [a, b = ''] = string.split('/'),
@@ -9,7 +9,7 @@ export let parseUnit = string => {
return result
}
-export let serialiseUnit = ({ numerators, denominators }) => {
+export let serialiseUnit = ({ numerators = [], denominators = [] }) => {
let n = !isEmpty(numerators)
let d = !isEmpty(denominators)
return !n && !d
@@ -22,19 +22,31 @@ export let serialiseUnit = ({ numerators, denominators }) => {
}
let noUnit = { numerators: [], denominators: [] }
-export let inferUnit = (operator, unit1 = noUnit, unit2 = noUnit) =>
- operator === '*'
- ? simplify({
- numerators: [...unit1.numerators, ...unit2.numerators],
- denominators: [...unit1.denominators, ...unit2.denominators]
- })
- : operator === '/'
- ? inferUnit('*', unit1, {
- numerators: unit2.denominators,
- denominators: unit2.numerators
- })
- : null
+export let inferUnit = (operator, rawUnits) => {
+ let units = rawUnits.map(u => u || noUnit)
+ if (operator === '*')
+ return simplify({
+ numerators: unnest(units.map(u => u.numerators)),
+ denominators: unnest(units.map(u => u.denominators))
+ })
+ if (operator === '/') {
+ if (units.length !== 2)
+ throw new Error('Infer units of a division with units.length !== 2)')
+ return inferUnit('*', [
+ units[0],
+ {
+ numerators: units[1].denominators,
+ denominators: units[1].numerators
+ }
+ ])
+ }
+ if (operator === '-' || operator === '+') {
+ return rawUnits.find(u => u)
+ }
+
+ return null
+}
export let removeOnce = element => list => {
let index = list.indexOf(element)
if (index > -1) return remove(index, 1)(list)
diff --git a/source/règles/base.yaml b/source/règles/base.yaml
index 830fa1282..e285e1969 100644
--- a/source/règles/base.yaml
+++ b/source/règles/base.yaml
@@ -990,7 +990,6 @@
- espace: contrat salarié
nom: indemnités salarié
période: flexible
- unité: €
formule:
somme:
- CDD . indemnités salarié CDD
diff --git a/test/units.test.js b/test/units.test.js
index 506c13f7b..2f73b954e 100644
--- a/test/units.test.js
+++ b/test/units.test.js
@@ -19,7 +19,7 @@ describe('Units', () => {
it('should work with simple use case *', () => {
let unit1 = { numerators: ['m'], denominators: ['s'] }
let unit2 = { numerators: ['s'], denominators: [] }
- let unit = inferUnit('*', unit1, unit2)
+ let unit = inferUnit('*', [unit1, unit2])
expect(unit).to.deep.equal({
numerators: ['m'],
@@ -29,7 +29,7 @@ describe('Units', () => {
it('should work with simple use case / ', () => {
let unit1 = { numerators: ['m'], denominators: ['s'] }
let unit2 = { numerators: ['m'], denominators: [] }
- let unit = inferUnit('/', unit1, unit2)
+ let unit = inferUnit('/', [unit1, unit2])
expect(unit).to.deep.equal({
numerators: [],
@@ -39,7 +39,7 @@ describe('Units', () => {
it('should work with advanced use case /', () => {
let unit1 = { numerators: ['a', 'b', 'a', 'z'], denominators: ['c'] }
let unit2 = { numerators: ['a', 'e', 'f'], denominators: ['z', 'c'] }
- let unit = inferUnit('/', unit1, unit2)
+ let unit = inferUnit('/', [unit1, unit2])
expect(unit).to.deep.equal({
numerators: ['b', 'a', 'z', 'z'],
From 342605e86bf7e9870f0a54f5624b8179b015187c Mon Sep 17 00:00:00 2001
From: Mael
Date: Thu, 11 Jul 2019 17:07:34 +0200
Subject: [PATCH 05/32] =?UTF-8?q?Unit=C3=A9s=20:=20pourcentage=20et=20mult?=
=?UTF-8?q?iplication?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/components/Value.js | 11 +++++------
source/components/rule/Rule.js | 2 ++
source/engine/grammarFunctions.js | 2 ++
source/engine/mecanisms.js | 11 ++++++-----
source/engine/parse.js | 1 +
source/engine/units.js | 22 ++++++++++++++--------
6 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/source/components/Value.js b/source/components/Value.js
index 8831c6258..431a48805 100644
--- a/source/components/Value.js
+++ b/source/components/Value.js
@@ -8,10 +8,7 @@ const NumberFormat = memoizeWith(
Intl.NumberFormat
)
-export let numberFormatter = (style, numFractionDigits = 2) => (
- value,
- language
-) =>
+export let numberFormatter = (style, numFractionDigits) => (value, language) =>
NumberFormat(language, {
style,
currency: 'EUR',
@@ -37,7 +34,7 @@ export default withLanguage(
nodeValue: value,
unit,
nilValueSymbol,
- numFractionDigits,
+ numFractionDigits = 2,
children,
negative,
language,
@@ -66,8 +63,10 @@ export default withLanguage(
nodeValue.nom
) : valueType === 'boolean' ? (
booleanTranslations[language][nodeValue]
- ) : unit === '€' ? (
+ ) : unitText === '€' ? (
numberFormatter('currency', numFractionDigits)(nodeValue, language)
+ ) : unitText === '%' ? (
+ numberFormatter('percent')(nodeValue)
) : (
<>
{numberFormatter('decimal', numFractionDigits)(nodeValue)}
diff --git a/source/components/rule/Rule.js b/source/components/rule/Rule.js
index f8f5d5b28..f6b7624e4 100644
--- a/source/components/rule/Rule.js
+++ b/source/components/rule/Rule.js
@@ -64,6 +64,8 @@ export default compose(
let displayedRule = analysedExample || analysedRule
+ console.log(displayedRule)
+
return (
<>
{this.state.viewSource ? (
diff --git a/source/engine/grammarFunctions.js b/source/engine/grammarFunctions.js
index 6f4b0c4ff..5f1c44e58 100644
--- a/source/engine/grammarFunctions.js
+++ b/source/engine/grammarFunctions.js
@@ -1,5 +1,6 @@
/* Those are postprocessor functions for the Nearley grammar.ne.
The advantage of putting them here is to get prettier's JS formatting, since Nealrey doesn't support it https://github.com/kach/nearley/issues/310 */
+import { parseUnit } from 'Engine/units'
export let operation = operationType => ([A, , operator, , B]) => ({
[operator]: {
@@ -41,6 +42,7 @@ export let percentage = d => ({
constant: {
rawNode: d,
type: 'percentage',
+ unit: parseUnit('%'),
nodeValue:
parseFloat(d[0].join('') + (d[1] ? d[1][0] + d[1][1].join('') : '')) / 100
}
diff --git a/source/engine/mecanisms.js b/source/engine/mecanisms.js
index 05f99932c..c7c006fe4 100644
--- a/source/engine/mecanisms.js
+++ b/source/engine/mecanisms.js
@@ -611,11 +611,12 @@ export let mecanismProduct = (recurse, k, v) => {
category: 'mecanism',
name: 'multiplication',
type: 'numeric',
- unit: inferUnit('*', [
- explanation.assiette,
- explanation.taux,
- explanation.facteur
- ])
+ unit: inferUnit(
+ '*',
+ [explanation.assiette, explanation.taux, explanation.facteur].map(
+ el => el.unit
+ )
+ )
}
}
diff --git a/source/engine/parse.js b/source/engine/parse.js
index 3ac304185..5dca8e9f2 100644
--- a/source/engine/parse.js
+++ b/source/engine/parse.js
@@ -171,6 +171,7 @@ export let parseObject = (rules, rule, parsedRules) => rawNode => {
constant: () => ({
type: v.type,
nodeValue: v.nodeValue,
+ unit: v.unit,
// eslint-disable-next-line
jsx: () => {v.rawNode}
})
diff --git a/source/engine/units.js b/source/engine/units.js
index d61c90162..5c7ce6e29 100644
--- a/source/engine/units.js
+++ b/source/engine/units.js
@@ -9,16 +9,22 @@ export let parseUnit = string => {
return result
}
-export let serialiseUnit = ({ numerators = [], denominators = [] }) => {
+export let serialiseUnit = rawUnit => {
+ let unit = simplify(rawUnit),
+ { numerators = [], denominators = [] } = unit
let n = !isEmpty(numerators)
let d = !isEmpty(denominators)
- return !n && !d
- ? ''
- : n && !d
- ? numerators.join('')
- : !n && d
- ? `/${denominators.join('')}`
- : `${numerators.join('')} / ${denominators.join('')}`
+ let string =
+ !n && !d
+ ? ''
+ : n && !d
+ ? numerators.join('')
+ : !n && d
+ ? `/${denominators.join('')}`
+ : `${numerators.join('')} / ${denominators.join('')}`
+
+ if (string.length > 1) return string.replace(/%/g, '')
+ return string
}
let noUnit = { numerators: [], denominators: [] }
From 1adce3e514c952a92a296ef6fe85387309b1906f Mon Sep 17 00:00:00 2001
From: Mael
Date: Thu, 11 Jul 2019 17:28:43 +0200
Subject: [PATCH 06/32] :gear: On abandonne NegatedVariable
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
C'est illisible dans l'explication, je n'arrive pas à faire mieux que '≠
oui'
---
source/engine/grammar.ne | 3 ---
source/engine/parse.js | 5 ----
source/engine/parseReference.js | 37 -----------------------------
source/règles/base.yaml | 18 +++++++-------
source/règles/externalized.yaml | 4 ++--
test/inversion.test.js | 2 +-
test/mecanisms.test.js | 7 +++++-
test/mécanismes/expressions.yaml | 2 +-
test/mécanismes/multiplication.yaml | 1 +
test/mécanismes/variations.yaml | 4 ++--
10 files changed, 22 insertions(+), 61 deletions(-)
diff --git a/source/engine/grammar.ne b/source/engine/grammar.ne
index e17a9a5d7..04c85cbe9 100644
--- a/source/engine/grammar.ne
+++ b/source/engine/grammar.ne
@@ -32,11 +32,8 @@ Comparable -> ( AdditionSubstraction | NonNumericTerminal) {% ([[e]]) => e %}
NonNumericTerminal ->
Boolean {% id %}
| String {% id %}
- | NegatedVariable {% id %}
-NegatedVariable -> "≠" _ Variable {% ([,,{variable}]) => ({'≠': {explanation: variable} }) %}
-
FilteredVariable -> Variable _ Filter {% filteredVariable %}
Filter -> "[" VariableFragment "]" {% ([,filter]) => filter %}
diff --git a/source/engine/parse.js b/source/engine/parse.js
index 5dca8e9f2..daba3a3fa 100644
--- a/source/engine/parse.js
+++ b/source/engine/parse.js
@@ -47,7 +47,6 @@ import {
} from './mecanisms'
import { Node } from './mecanismViews/common'
import {
- parseNegatedReference,
parseReference,
parseReferenceTransforms
} from './parseReference'
@@ -152,10 +151,6 @@ export let parseObject = (rules, rule, parsedRules) => rawNode => {
variations: mecanismVariations,
synchronisation: mecanismSynchronisation,
...operationDispatch,
- '≠': () =>
- parseNegatedReference(
- parseReference(rules, rule, parsedRules)(v.explanation)
- ),
filter: () =>
parseReferenceTransforms(rules, rule, parsedRules)({
filter: v.filter,
diff --git a/source/engine/parseReference.js b/source/engine/parseReference.js
index 18c40b710..dc25ef334 100644
--- a/source/engine/parseReference.js
+++ b/source/engine/parseReference.js
@@ -217,40 +217,3 @@ export let parseReferenceTransforms = (
evaluate: evaluateTransforms(node.evaluate)
}
}
-
-export let parseNegatedReference = variable => {
- let evaluate = (cache, situation, parsedRules, node) => {
- let explanation = evaluateNode(
- cache,
- situation,
- parsedRules,
- node.explanation
- ),
- nodeValue = explanation.nodeValue == null ? null : !explanation.nodeValue,
- missingVariables = explanation.missingVariables
-
- return rewriteNode(node, nodeValue, explanation, missingVariables)
- }
-
- let jsx = (nodeValue, explanation) => (
-
- Non {' '}
- {makeJsx(explanation)}
-
- }
- />
- )
-
- return {
- evaluate,
- jsx,
- category: 'mecanism',
- name: 'négation',
- type: 'boolean',
- explanation: variable
- }
-}
diff --git a/source/règles/base.yaml b/source/règles/base.yaml
index e285e1969..fff14d37e 100644
--- a/source/règles/base.yaml
+++ b/source/règles/base.yaml
@@ -753,7 +753,7 @@
- si:
toutes ces conditions:
- brut de base [mensuel] < SMIC [mensuel]
- - ≠ assimilé salarié
+ - assimilé salarié != oui
niveau: avertissement
message: |
Le salaire saisi est inférieur au SMIC.
@@ -2038,8 +2038,8 @@
- si:
toutes ces conditions:
- cotisations . assiette < plafond de réduction
- - ≠ statut JEI
- - ≠ assimilé salarié
+ - statut JEI != oui
+ - assimilé salarié != oui
alors: 3.45%
- sinon: 5.25%
références:
@@ -2403,8 +2403,8 @@
- si:
toutes ces conditions:
- cotisations . assiette < plafond de réduction employeur
- - ≠ statut JEI
- - ≠ assimilé salarié
+ - statut JEI != oui
+ - assimilé salarié != oui
alors: 7%
- sinon: 13%
- attributs:
@@ -3327,7 +3327,7 @@
formule:
toutes ces conditions:
- entreprise . catégorie d'activité . libérale règlementée
- - ≠ rattachée à la CIPAV
+ - rattachée à la CIPAV != oui
note: D'autres conditions d'exclusions existent, il faudra les compléter, mais la question de la catégorie d'activité doit avant être complétée.
- nom: indépendant
@@ -3372,7 +3372,7 @@
formule:
une de ces conditions:
- toutes ces conditions:
- - ≠ contrat salarié
+ - contrat salarié != oui
- entreprise . catégorie d'activité . libérale règlementée
- toutes ces conditions:
- entreprise . année d'activité
@@ -3547,7 +3547,7 @@
titre: assiette retraite de base
formule:
variations:
- - si: ≠ situation personnelle . RSA
+ - si: situation personnelle . RSA != oui
alors:
le maximum de:
- 11.5% * plafond sécurité sociale temps plein
@@ -3619,7 +3619,7 @@
titre: assiette invalidité et décès
formule:
variations:
- - si: ≠ situation personnelle . RSA
+ - si: situation personnelle . RSA != oui
alors:
le maximum de:
- 11.5% * plafond sécurité sociale temps plein
diff --git a/source/règles/externalized.yaml b/source/règles/externalized.yaml
index a13052597..e41e2e203 100644
--- a/source/règles/externalized.yaml
+++ b/source/règles/externalized.yaml
@@ -580,7 +580,7 @@ contrat salarié . salaire . brut de base:
- si:
toutes ces conditions:
- 'brut de base [mensuel] < SMIC [mensuel]'
- - ≠ assimilé salarié
+ - assimilé salarié != oui
niveau: avertissement
message: |
The wage entered is lower than the minimum wage.
@@ -599,7 +599,7 @@ contrat salarié . salaire . brut de base:
- si:
toutes ces conditions:
- 'brut de base [mensuel] < SMIC [mensuel]'
- - ≠ assimilé salarié
+ - assimilé salarié != oui
niveau: avertissement
message: |
Le salaire saisi est inférieur au SMIC.
diff --git a/test/inversion.test.js b/test/inversion.test.js
index 68bdac6c4..603f1353c 100644
--- a/test/inversion.test.js
+++ b/test/inversion.test.js
@@ -145,7 +145,7 @@ describe('inversions', () => {
- si: cadre
alors:
taux: 80%
- - si: ≠ cadre
+ - si: cadre != oui
alors:
taux: 70%
diff --git a/test/mecanisms.test.js b/test/mecanisms.test.js
index c4a6a3089..d4f7b366c 100644
--- a/test/mecanisms.test.js
+++ b/test/mecanisms.test.js
@@ -11,11 +11,12 @@ import { collectMissingVariables } from '../source/engine/generateQuestions'
import testSuites from './load-mecanism-tests'
import * as R from 'ramda'
import { isNumeric } from '../source/utils'
+import { serialiseUnit } from 'Engine/units'
describe('Mécanismes', () =>
testSuites.map(([suiteName, suite]) =>
suite.map(
- ({ exemples, test }) =>
+ ({ exemples, test, 'unité attendue': unit }) =>
exemples &&
describe(`Suite ${suiteName}, test : ${test ||
'Nom de test (propriété "test") manquant dans la variable contenant ces "exemples"'}`, () =>
@@ -51,6 +52,10 @@ describe('Mécanismes', () =>
if (expectedMissing) {
expect(missing).to.eql(expectedMissing)
}
+
+ if (unit) {
+ expect(serialiseUnit(target.unit)).to.eql(unit)
+ }
})
))
)
diff --git a/test/mécanismes/expressions.yaml b/test/mécanismes/expressions.yaml
index 36c6d4bc1..cabd3204e 100644
--- a/test/mécanismes/expressions.yaml
+++ b/test/mécanismes/expressions.yaml
@@ -133,7 +133,7 @@
- valeur attendue: true
- test: négation
- formule: ≠ CDD . poursuivi en CDI
+ formule: CDD . poursuivi en CDI != oui
exemples:
- situation:
CDD . poursuivi en CDI: oui
diff --git a/test/mécanismes/multiplication.yaml b/test/mécanismes/multiplication.yaml
index a3fe67ed4..65a57dc62 100644
--- a/test/mécanismes/multiplication.yaml
+++ b/test/mécanismes/multiplication.yaml
@@ -6,6 +6,7 @@
multiplication:
assiette: mon assiette
taux: 3%
+ unité attendue: €
exemples:
- nom: entier
diff --git a/test/mécanismes/variations.yaml b/test/mécanismes/variations.yaml
index d8b362ce7..566d800e8 100644
--- a/test/mécanismes/variations.yaml
+++ b/test/mécanismes/variations.yaml
@@ -21,7 +21,7 @@
variations:
- si: statut cadre
alors: 2300
- - si: ≠ statut cadre
+ - si: statut cadre != oui
alors: 2100
exemples:
@@ -143,7 +143,7 @@
- si: statut cadre
alors:
taux: 8%
- - si: ≠ statut cadre
+ - si: statut cadre != oui
alors:
taux: 5%
From 0d0fcabe1bdf1a7e54922e9a74d2a3d1a7562d19 Mon Sep 17 00:00:00 2001
From: Mael
Date: Thu, 11 Jul 2019 18:12:34 +0200
Subject: [PATCH 07/32] =?UTF-8?q?Tests=20des=20unit=C3=A9s=20dans=20les=20?=
=?UTF-8?q?tests=20de=20m=C3=A9canismes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
test/mécanismes/barème.yaml | 1 +
test/mécanismes/expressions.yaml | 28 ++++++++++++++++++++++++++++
test/mécanismes/multiplication.yaml | 5 +++--
3 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/test/mécanismes/barème.yaml b/test/mécanismes/barème.yaml
index 25915ed39..e9f589cee 100644
--- a/test/mécanismes/barème.yaml
+++ b/test/mécanismes/barème.yaml
@@ -18,6 +18,7 @@
- au-dessus de: 3
taux: 1%
+
exemples:
- nom: 'petite assiette'
situation:
diff --git a/test/mécanismes/expressions.yaml b/test/mécanismes/expressions.yaml
index cabd3204e..626794b83 100644
--- a/test/mécanismes/expressions.yaml
+++ b/test/mécanismes/expressions.yaml
@@ -29,10 +29,13 @@
- valeur attendue: 29
- nom: salaire de base
+ unité: $
+
- nom: contrat . salaire de base
- test: multiplication
formule: salaire de base * 3
+ unité attendue: $
exemples:
- situation:
salaire de base: 1000
@@ -46,9 +49,11 @@
valeur attendue: 3000
- nom: taux
+ unité: '%'
- test: soustraction
formule: 1 - taux
+ unité attendue: '%'
exemples:
- situation:
taux: 0.89
@@ -56,6 +61,7 @@
- test: addition
formule: salaire de base + 2000
+ unité attendue: $
exemples:
- situation:
salaire de base: 3000
@@ -78,6 +84,27 @@
salaire de base: 3000
valeur attendue: 1000
+- test: division deux
+ formule: 2000 / salaire de base
+ unité attendue: /$
+ exemples:
+ - situation:
+ salaire de base: 3000
+ valeur attendue: 0.66667
+
+- nom: nombre de personnes
+ unité: personne
+
+- test: division trois
+ formule: salaire de base / nombre de personnes
+ unité attendue: $ / personne
+ exemples:
+ - situation:
+ salaire de base: 3000
+ nombre de personnes: 10
+ valeur attendue: 300
+
+
- test: comparaison stricte
formule: salaire de base < 3001
exemples:
@@ -150,6 +177,7 @@
- test: multiplication et pourcentage
formule: 38.1% * salaire de base
+ unité attendue: $
exemples:
- situation:
salaire de base: 1000
diff --git a/test/mécanismes/multiplication.yaml b/test/mécanismes/multiplication.yaml
index 65a57dc62..0e21faa6f 100644
--- a/test/mécanismes/multiplication.yaml
+++ b/test/mécanismes/multiplication.yaml
@@ -7,7 +7,6 @@
assiette: mon assiette
taux: 3%
unité attendue: €
-
exemples:
- nom: entier
situation:
@@ -52,9 +51,10 @@
valeur attendue: 1.5
- nom: mon facteur
- unité: _
+ unité: patates
- test: Multiplication à facteur
+ unité attendue: patates
formule:
multiplication:
assiette: 100
@@ -76,6 +76,7 @@
plafond: mon plafond
taux: 0.5%
+ unité attendue: €patates
exemples:
- nom:
situation:
From 6606bb4f34ba7db0b5827fc4825cf26afb31d2a5 Mon Sep 17 00:00:00 2001
From: Mael
Date: Thu, 11 Jul 2019 18:25:08 +0200
Subject: [PATCH 08/32] =?UTF-8?q?Unit=C3=A9s=20des=20bar=C3=A8mes=20et=20c?=
=?UTF-8?q?omposantes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/components/Value.js | 1 +
source/engine/mecanisms.js | 56 ------------------
source/engine/mecanisms/barème-continu.js | 63 ++++++++++++++++++++
source/engine/mecanisms/barème-linéaire.js | 68 ++++++++++++++++++++++
source/engine/mecanisms/barème.js | 4 +-
source/engine/mecanisms/utils.js | 4 +-
source/engine/parse.js | 13 ++---
source/engine/units.js | 1 +
test/mecanisms.test.js | 1 +
test/mécanismes/barème-continu.yaml | 12 ++--
test/mécanismes/barème-linéaire.yaml | 2 +
test/mécanismes/barème.yaml | 9 ++-
test/mécanismes/composantes.yaml | 7 ++-
13 files changed, 166 insertions(+), 75 deletions(-)
create mode 100644 source/engine/mecanisms/barème-continu.js
create mode 100644 source/engine/mecanisms/barème-linéaire.js
diff --git a/source/components/Value.js b/source/components/Value.js
index 431a48805..6942ef0e5 100644
--- a/source/components/Value.js
+++ b/source/components/Value.js
@@ -77,6 +77,7 @@ export default withLanguage(
return nodeValue == undefined ? null : (
+ unit: {unitText}
{negative ? '-' : ''}
{formattedValue}
diff --git a/source/engine/mecanisms.js b/source/engine/mecanisms.js
index c7c006fe4..aa4441fa9 100644
--- a/source/engine/mecanisms.js
+++ b/source/engine/mecanisms.js
@@ -620,62 +620,6 @@ export let mecanismProduct = (recurse, k, v) => {
}
}
-/* on réécrit en une syntaxe plus bas niveau mais plus régulière les tranches :
- `en-dessous de: 1`
- devient
- ```
- de: 0
- à: 1
- ```
- */
-
-export let mecanismLinearScale = (recurse, k, v) => {
- if (v.composantes) {
- //mécanisme de composantes. Voir known-mecanisms.md/composantes
- return decompose(recurse, k, v)
- }
- if (v.variations) {
- return mecanismVariations(recurse, k, v, true)
- }
- let tranches = desugarScale(recurse)(v['tranches']),
- objectShape = {
- assiette: false,
- multiplicateur: defaultNode(1)
- }
-
- let effect = ({ assiette, multiplicateur, tranches }) => {
- if (val(assiette) === null) return null
-
- let roundedAssiette = Math.round(val(assiette))
-
- let matchedTranche = tranches.find(
- ({ de: min, à: max }) =>
- roundedAssiette >= val(multiplicateur) * min &&
- roundedAssiette <= max * val(multiplicateur)
- )
-
- if (!matchedTranche) return 0
- if (matchedTranche.taux)
- return matchedTranche.taux.nodeValue * val(assiette)
- return matchedTranche.montant
- }
-
- let explanation = {
- ...parseObject(recurse, objectShape, v),
- tranches
- },
- evaluate = evaluateObject(objectShape, effect)
-
- return {
- evaluate,
- jsx: Barème('linéaire'),
- explanation,
- category: 'mecanism',
- name: 'barème linéaire',
- barème: 'en taux',
- type: 'numeric'
- }
-}
export let mecanismContinuousScale = (recurse, k, v) => {
let objectShape = {
diff --git a/source/engine/mecanisms/barème-continu.js b/source/engine/mecanisms/barème-continu.js
new file mode 100644
index 000000000..4f9546d2a
--- /dev/null
+++ b/source/engine/mecanisms/barème-continu.js
@@ -0,0 +1,63 @@
+import { defaultNode, evaluateObject } from 'Engine/evaluation'
+import BarèmeContinu from 'Engine/mecanismViews/BarèmeContinu'
+import { val, anyNull } from 'Engine/traverse-common-functions'
+import { parseUnit } from 'Engine/units'
+import { parseObject } from 'Engine/evaluation'
+import { reduce, toPairs, sort, aperture, pipe, reduced, last } from 'ramda'
+
+export default (recurse, k, v) => {
+ let objectShape = {
+ assiette: false,
+ multiplicateur: defaultNode(1)
+ }
+
+ let returnRate = v['retourne seulement le taux'] === 'oui'
+ let effect = ({ assiette, multiplicateur, points }) => {
+ if (anyNull([assiette, multiplicateur])) return null
+ //We'll build a linear function given the two constraints that must be respected
+ let result = pipe(
+ toPairs,
+ // we don't rely on the sorting of objects
+ sort(([k1], [k2]) => k1 - k2),
+ points => [...points, [Infinity, last(points)[1]]],
+ aperture(2),
+ reduce((_, [[lowerLimit, lowerRate], [upperLimit, upperRate]]) => {
+ let x1 = val(multiplicateur) * lowerLimit,
+ x2 = val(multiplicateur) * upperLimit,
+ y1 = val(assiette) * val(recurse(lowerRate)),
+ y2 = val(assiette) * val(recurse(upperRate))
+ if (val(assiette) > x1 && val(assiette) <= x2) {
+ // 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,
+ taux = nodeValue / val(assiette)
+ return reduced({
+ nodeValue: returnRate ? taux : nodeValue,
+ additionalExplanation: {
+ seuil: val(assiette) / val(multiplicateur),
+ taux
+ }
+ })
+ }
+ }, 0)
+ )(points)
+
+ return result
+ }
+ let explanation = {
+ ...parseObject(recurse, objectShape, v),
+ points: v.points,
+ returnRate
+ },
+ evaluate = evaluateObject(objectShape, effect)
+ return {
+ evaluate,
+ jsx: BarèmeContinu,
+ explanation,
+ category: 'mecanism',
+ name: 'barème continu',
+ type: 'numeric',
+ unit: returnRate ? parseUnit('%') : explanation.assiette.unit
+ }
+}
diff --git a/source/engine/mecanisms/barème-linéaire.js b/source/engine/mecanisms/barème-linéaire.js
new file mode 100644
index 000000000..41e7437aa
--- /dev/null
+++ b/source/engine/mecanisms/barème-linéaire.js
@@ -0,0 +1,68 @@
+import { defaultNode, evaluateObject } from 'Engine/evaluation'
+import Barème from 'Engine/mecanismViews/Barème'
+import { mecanismVariations } from 'Engine/mecanisms'
+import { decompose } from 'Engine/mecanisms/utils'
+import { val } from 'Engine/traverse-common-functions'
+import { inferUnit, parseUnit } from 'Engine/units'
+import { parseObject } from 'Engine/evaluation'
+import { desugarScale } from './barème'
+/* on réécrit en une syntaxe plus bas niveau mais plus régulière les tranches :
+ `en-dessous de: 1`
+ devient
+ ```
+ de: 0
+ à: 1
+ ```
+ */
+
+export default (recurse, k, v) => {
+ if (v.composantes) {
+ //mécanisme de composantes. Voir known-mecanisms.md/composantes
+ return decompose(recurse, k, v)
+ }
+ if (v.variations) {
+ return mecanismVariations(recurse, k, v, true)
+ }
+ let tranches = desugarScale(recurse)(v['tranches']),
+ objectShape = {
+ assiette: false,
+ multiplicateur: defaultNode(1)
+ }
+
+ let effect = ({ assiette, multiplicateur, tranches }) => {
+ if (val(assiette) === null) return null
+
+ let roundedAssiette = Math.round(val(assiette))
+
+ let matchedTranche = tranches.find(
+ ({ de: min, à: max }) =>
+ roundedAssiette >= val(multiplicateur) * min &&
+ roundedAssiette <= max * val(multiplicateur)
+ )
+
+ if (!matchedTranche) return 0
+ if (matchedTranche.taux)
+ return matchedTranche.taux.nodeValue * val(assiette)
+ return matchedTranche.montant
+ }
+
+ let explanation = {
+ ...parseObject(recurse, objectShape, v),
+ tranches
+ },
+ evaluate = evaluateObject(objectShape, effect)
+
+ console.log('explanation', explanation)
+
+ return {
+ evaluate,
+ jsx: Barème('linéaire'),
+ explanation,
+ category: 'mecanism',
+ name: 'barème linéaire',
+ barème: 'en taux',
+ type: 'numeric',
+
+ unit: explanation.assiette.unit
+ }
+}
diff --git a/source/engine/mecanisms/barème.js b/source/engine/mecanisms/barème.js
index a7b7c6754..270389a70 100644
--- a/source/engine/mecanisms/barème.js
+++ b/source/engine/mecanisms/barème.js
@@ -4,6 +4,7 @@ import { decompose } from 'Engine/mecanisms/utils'
import Barème from 'Engine/mecanismViews/Barème'
import { val } from 'Engine/traverse-common-functions'
import { evolve, has, pluck, sum } from 'ramda'
+import { inferUnit, parseUnit } from 'Engine/units'
export let desugarScale = recurse => tranches =>
tranches
@@ -85,6 +86,7 @@ export default (recurse, k, v) => {
jsx: Barème('marginal'),
category: 'mecanism',
name: 'barème',
- barème: 'marginal'
+ barème: 'marginal',
+ unit: inferUnit('*', [explanation.assiette.unit, parseUnit('%')])
}
}
diff --git a/source/engine/mecanisms/utils.js b/source/engine/mecanisms/utils.js
index 88362872a..cf986ee25 100644
--- a/source/engine/mecanisms/utils.js
+++ b/source/engine/mecanisms/utils.js
@@ -1,6 +1,7 @@
import Composantes from 'Engine/mecanismViews/Composantes'
import { add, dissoc, objOf } from 'ramda'
import { evaluateArrayWithFilter } from 'Engine/evaluation'
+import { inferUnit } from 'Engine/units'
export let decompose = (recurse, k, v) => {
let subProps = dissoc('composantes')(v),
@@ -28,7 +29,8 @@ export let decompose = (recurse, k, v) => {
evaluate: evaluateArrayWithFilter(filter, add, 0),
category: 'mecanism',
name: 'composantes',
- type: 'numeric'
+ type: 'numeric',
+ unit: inferUnit('+', explanation.map(e => e.unit))
}
}
diff --git a/source/engine/parse.js b/source/engine/parse.js
index daba3a3fa..7eebe2488 100644
--- a/source/engine/parse.js
+++ b/source/engine/parse.js
@@ -3,6 +3,8 @@
// TODO import them automatically
// TODO convert the legacy functions to new files
import barème from 'Engine/mecanisms/barème.js'
+import barèmeContinu from 'Engine/mecanisms/barème-continu.js'
+import barèmeLinéaire from 'Engine/mecanisms/barème-linéaire.js'
import { Parser } from 'nearley'
import {
add,
@@ -30,10 +32,8 @@ import Grammar from './grammar.ne'
import {
mecanismAllOf,
mecanismComplement,
- mecanismContinuousScale,
mecanismError,
mecanismInversion,
- mecanismLinearScale,
mecanismMax,
mecanismMin,
mecanismNumericalSwitch,
@@ -46,10 +46,7 @@ import {
mecanismOnePossibility
} from './mecanisms'
import { Node } from './mecanismViews/common'
-import {
- parseReference,
- parseReferenceTransforms
-} from './parseReference'
+import { parseReferenceTransforms } from './parseReference'
import { inferUnit } from 'Engine/units'
export let parse = (rules, rule, parsedRules) => rawNode => {
@@ -140,8 +137,8 @@ export let parseObject = (rules, rule, parsedRules) => rawNode => {
somme: mecanismSum,
multiplication: mecanismProduct,
barème,
- 'barème linéaire': mecanismLinearScale,
- 'barème continu': mecanismContinuousScale,
+ 'barème linéaire': barèmeLinéaire,
+ 'barème continu': barèmeContinu,
'le maximum de': mecanismMax,
'le minimum de': mecanismMin,
complément: mecanismComplement,
diff --git a/source/engine/units.js b/source/engine/units.js
index 5c7ce6e29..295a742f8 100644
--- a/source/engine/units.js
+++ b/source/engine/units.js
@@ -23,6 +23,7 @@ export let serialiseUnit = rawUnit => {
? `/${denominators.join('')}`
: `${numerators.join('')} / ${denominators.join('')}`
+ // the unit '%' is only displayed when it is the only unit
if (string.length > 1) return string.replace(/%/g, '')
return string
}
diff --git a/test/mecanisms.test.js b/test/mecanisms.test.js
index d4f7b366c..ddbbd63c9 100644
--- a/test/mecanisms.test.js
+++ b/test/mecanisms.test.js
@@ -54,6 +54,7 @@ describe('Mécanismes', () =>
}
if (unit) {
+ expect(target.unit).not.to.be.equal(undefined)
expect(serialiseUnit(target.unit)).to.eql(unit)
}
})
diff --git a/test/mécanismes/barème-continu.yaml b/test/mécanismes/barème-continu.yaml
index 2931b671c..b204d2047 100644
--- a/test/mécanismes/barème-continu.yaml
+++ b/test/mécanismes/barème-continu.yaml
@@ -1,9 +1,9 @@
- nom: base
- unité: _
+ unité: £
formule: 300
- nom: assiette
- unité: _
+ unité: £
- test: Simple
formule:
@@ -14,7 +14,7 @@
0: 0%
0.4: 3.16%
1.1: 6.35%
-
+ unité attendue: £
exemples:
- nom: Premier point
situation:
@@ -39,11 +39,12 @@
- nom: base deux
- unité: _
+ unité: µ
formule: 300
- nom: assiette deux
- unité: _
+ unité: µ
+
- test: Retour de taux, pas d'assiette
formule:
barème continu:
@@ -54,6 +55,7 @@
0.75: 100%
1: 0%
retourne seulement le taux: oui
+ unité attendue: '%'
exemples:
- nom: Premier point
situation:
diff --git a/test/mécanismes/barème-linéaire.yaml b/test/mécanismes/barème-linéaire.yaml
index 97a55fb17..f2f2e9424 100644
--- a/test/mécanismes/barème-linéaire.yaml
+++ b/test/mécanismes/barème-linéaire.yaml
@@ -14,6 +14,7 @@
taux: 10%
- au-dessus de: 2000
taux: 15%
+ unité attendue: €
exemples:
- nom: "petite assiette"
@@ -51,6 +52,7 @@
- au-dessus de: 2000
montant: 400
+ unité attendue: €
exemples:
- nom: "petite assiette"
situation:
diff --git a/test/mécanismes/barème.yaml b/test/mécanismes/barème.yaml
index e9f589cee..5bc50b860 100644
--- a/test/mécanismes/barème.yaml
+++ b/test/mécanismes/barème.yaml
@@ -17,8 +17,7 @@
taux: 3%
- au-dessus de: 3
taux: 1%
-
-
+ unité attendue: €
exemples:
- nom: 'petite assiette'
situation:
@@ -52,6 +51,7 @@
taux: 9%
- au-dessus de: 2
taux: 29%
+ unité attendue: €
exemples:
- nom:
@@ -62,12 +62,14 @@
- nom: ma condition
-- nom: taux variable
+- test: taux variable
formule:
variations:
- si: ma condition
alors: 29%
- sinon: 56%
+ unité attendue: '%'
+ exemples: []
- nom: deuxième barème
test: Barème à taux variable
@@ -80,6 +82,7 @@
taux: taux variable
- au-dessus de: 1
taux: 90%
+ unité attendue: €
exemples:
- nom: taux faible
diff --git a/test/mécanismes/composantes.yaml b/test/mécanismes/composantes.yaml
index db0f82701..270fd2f7d 100644
--- a/test/mécanismes/composantes.yaml
+++ b/test/mécanismes/composantes.yaml
@@ -1,12 +1,17 @@
- test: Composantes
formule:
multiplication:
- assiette: 100
+ assiette: richesse
composantes:
- taux: 8%
- taux: 2%
+ unité attendue: crédits
exemples:
- nom:
situation:
valeur attendue: 10
+
+- nom: richesse
+ unité: crédits
+ formule: 100
From 413b6197ef360e35e5303e1bc436a48b4e54fcf0 Mon Sep 17 00:00:00 2001
From: Mael
Date: Fri, 19 Jul 2019 19:51:36 +0200
Subject: [PATCH 09/32] =?UTF-8?q?:bug:=20On=20arr=C3=AAte=20le=20parsing?=
=?UTF-8?q?=20r=C3=A9cursif=20quand=20formule=20d'inversion?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/engine/parseReference.js | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/source/engine/parseReference.js b/source/engine/parseReference.js
index dc25ef334..c222c9a4d 100644
--- a/source/engine/parseReference.js
+++ b/source/engine/parseReference.js
@@ -17,9 +17,13 @@ export let parseReference = (rules, rule, parsedRules, filter) => ({
let partialReference = fragments.join(' . '),
dottedName = disambiguateRuleReference(rules, rule, partialReference)
+ let inInversionFormula = rule.formule?.['inversion numérique']
+
let parsedRule =
parsedRules[dottedName] ||
- parseRule(rules, findRuleByDottedName(rules, dottedName), parsedRules)
+ // the 'inversion numérique' formula should not exist. The instructions to the evaluation should be enough to infer that an inversion is necessary (assuming it is possible, the client decides this)
+ (!inInversionFormula &&
+ parseRule(rules, findRuleByDottedName(rules, dottedName), parsedRules))
let evaluate = (cache, situation, parsedRules, node) => {
let dottedName = node.dottedName,
@@ -155,11 +159,7 @@ export let parseReferenceTransforms = (
if (!rule.période && !inlinePeriodTransform) {
if (supportedPeriods.includes(ruleToTransform.période))
throw new Error(
- `Attention, une variable sans période, ${
- rule.dottedName
- }, qui appelle une variable à période, ${
- ruleToTransform.dottedName
- }, c'est suspect !
+ `Attention, une variable sans période, ${rule.dottedName}, qui appelle une variable à période, ${ruleToTransform.dottedName}, c'est suspect !
Si la période de la variable appelée est neutralisée dans la formule de calcul, par exemple un montant mensuel divisé par 30 (comprendre 30 jours), utilisez "période: aucune" pour taire cette erreur et rassurer tout le monde.
`
From 5de2231267994d30d0d40efa1b038461ae3d7579 Mon Sep 17 00:00:00 2001
From: Mael
Date: Sat, 20 Jul 2019 18:30:41 +0200
Subject: [PATCH 10/32] Changement de la signature et des digits de
NumberFormatter
---
source/components/Distribution.js | 8 +++----
source/components/SchemeComparaison.js | 2 +-
source/components/Value.js | 32 +++++++++++++++++++-------
source/engine/mecanismViews/Barème.js | 11 ++++-----
4 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/source/components/Distribution.js b/source/components/Distribution.js
index 1fab70429..aa9d7b3cf 100644
--- a/source/components/Distribution.js
+++ b/source/components/Distribution.js
@@ -113,17 +113,17 @@ class Distribution extends Component {
-
+
+
Cotisations
-
+
{total.partPatronale + total.partSalariale}
=
-
+
>
)
@@ -154,7 +154,7 @@ let ChartItemBar = ({ styles, colour, montant, total }) => (
margin-left: 1em;
color: var(--textColourOnWhite);
`}>
-
+
{montant}
diff --git a/source/components/SchemeComparaison.js b/source/components/SchemeComparaison.js
index 5fe06573b..d13cdc5e3 100644
--- a/source/components/SchemeComparaison.js
+++ b/source/components/SchemeComparaison.js
@@ -626,7 +626,7 @@ const RuleValueLink = compose(
sitePaths.documentation.index + '/' + encodeRuleName(rule.dottedName)
}>
(value, language) =>
+export let numberFormatter = ({
+ style,
+ maximumFractionDigits,
+ minimumFractionDigits = 0,
+ language
+}) => value =>
NumberFormat(language, {
style,
currency: 'EUR',
- maximumFractionDigits: numFractionDigits,
- minimumFractionDigits: numFractionDigits
+ maximumFractionDigits,
+ minimumFractionDigits
}).format(value)
// let booleanTranslations = { true: '✅', false: '❌' }
@@ -34,7 +39,8 @@ export default withLanguage(
nodeValue: value,
unit,
nilValueSymbol,
- numFractionDigits = 2,
+ maximumFractionDigits,
+ minimumFractionDigits,
children,
negative,
language,
@@ -64,12 +70,23 @@ export default withLanguage(
) : valueType === 'boolean' ? (
booleanTranslations[language][nodeValue]
) : unitText === '€' ? (
- numberFormatter('currency', numFractionDigits)(nodeValue, language)
+ numberFormatter({
+ style: 'currency',
+ maximumFractionDigits,
+ minimumFractionDigits,
+ language
+ })(nodeValue)
) : unitText === '%' ? (
- numberFormatter('percent')(nodeValue)
+ numberFormatter({ style: 'percent', maximumFractionDigits: 3 })(
+ nodeValue
+ )
) : (
<>
- {numberFormatter('decimal', numFractionDigits)(nodeValue)}
+ {numberFormatter({
+ style: 'decimal',
+ minimumFractionDigits,
+ maximumFractionDigits
+ })(nodeValue)}
{unitText}
>
@@ -77,7 +94,6 @@ export default withLanguage(
return nodeValue == undefined ? null : (
- unit: {unitText}
{negative ? '-' : ''}
{formattedValue}
diff --git a/source/engine/mecanismViews/Barème.js b/source/engine/mecanismViews/Barème.js
index dcb9a90cf..9c19d8f1a 100644
--- a/source/engine/mecanismViews/Barème.js
+++ b/source/engine/mecanismViews/Barème.js
@@ -115,8 +115,6 @@ let Component = withLanguage(function Barème({
)
})
-let number = numberFormatter(undefined, 0)
-
let Tranche = ({
tranche: {
'en-dessous de': maxOnly,
@@ -136,16 +134,17 @@ let Tranche = ({
{maxOnly ? (
<>
- En-dessous de {number(maxOnly, language)}
+ En-dessous de {' '}
+ {numberFormatter({ language })(maxOnly)}
>
) : minOnly ? (
<>
- Au-dessus de {number(minOnly, language)}
+ Au-dessus de {numberFormatter({ language })(minOnly)}
>
) : (
<>
- De {number(min, language)} à {' '}
- {number(max, language)}
+ De {numberFormatter({ language })(min)}{' '}
+ à {numberFormatter({ language })(max)}
>
)}
From 60a8558daf2e5a469d14b0fecd4c7919cc3eaa2d Mon Sep 17 00:00:00 2001
From: Mael
Date: Sat, 20 Jul 2019 18:30:42 +0200
Subject: [PATCH 11/32] =?UTF-8?q?Affichage=20des=20unit=C3=A9s?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/engine/evaluation.js | 2 +-
source/engine/mecanismViews/Composantes.js | 8 +++++---
source/engine/mecanismViews/Product.js | 3 ++-
source/engine/mecanismViews/Somme.js | 15 ++++++++-------
source/engine/mecanismViews/Variations.js | 8 +++++---
source/engine/mecanismViews/common.js | 12 ++++++------
source/engine/mecanisms.js | 8 ++++----
source/engine/parse.js | 1 +
source/engine/parseReference.js | 20 +++++++++++---------
9 files changed, 43 insertions(+), 34 deletions(-)
diff --git a/source/engine/evaluation.js b/source/engine/evaluation.js
index e27bb97f6..ca59b46d3 100644
--- a/source/engine/evaluation.js
+++ b/source/engine/evaluation.js
@@ -16,7 +16,7 @@ import {
export let makeJsx = node =>
typeof node.jsx == 'function'
- ? node.jsx(node.nodeValue, node.explanation, node.lazyEval)
+ ? node.jsx(node.nodeValue, node.explanation, node.lazyEval, node.unit)
: node.jsx
export let collectNodeMissing = node => node.missingVariables || {}
diff --git a/source/engine/mecanismViews/Composantes.js b/source/engine/mecanismViews/Composantes.js
index 26787882e..ba44b47fc 100644
--- a/source/engine/mecanismViews/Composantes.js
+++ b/source/engine/mecanismViews/Composantes.js
@@ -10,7 +10,8 @@ import withLanguage from 'Components/utils/withLanguage'
let Comp = withLanguage(function Composantes({
language,
nodeValue,
- explanation
+ explanation,
+ unit
}) {
return (
@@ -51,6 +53,6 @@ let Comp = withLanguage(function Composantes({
})
// eslint-disable-next-line
-export default (nodeValue, explanation) => (
-
+export default (nodeValue, explanation, _, unit) => (
+
)
diff --git a/source/engine/mecanismViews/Product.js b/source/engine/mecanismViews/Product.js
index b8f74395d..1cb81521a 100644
--- a/source/engine/mecanismViews/Product.js
+++ b/source/engine/mecanismViews/Product.js
@@ -4,13 +4,14 @@ import { Trans } from 'react-i18next'
import { Node } from './common'
import './InversionNumérique.css'
-export default function ProductView(nodeValue, explanation) {
+export default function ProductView(nodeValue, explanation, _, unit) {
return (
// The rate and factor and threshold are given defaut neutral values. If there is nothing to explain, don't display them at all
(
+const SommeNode = ({ explanation, nodeValue, unit }) => (
}
+ unit={unit}
+ child={}
/>
)
export default SommeNode
-let Table = ({ explanation }) => (
+let Table = ({ explanation, unit }) => (
{explanation.map((v, i) => (
-
+
))}
@@ -30,7 +31,7 @@ class Row extends Component {
folded: true
}
render() {
- let { v, i } = this.props,
+ let { v, i, unit } = this.props,
rowFormula = path(['explanation', 'formule', 'explanation'], v),
isSomme = rowFormula && rowFormula.name == 'somme'
@@ -50,13 +51,13 @@ class Row extends Component {
)}
-
+
,
...(isSomme && !this.state.folded
? [
]
: [])
diff --git a/source/engine/mecanismViews/Variations.js b/source/engine/mecanismViews/Variations.js
index df68bb469..af9f868f4 100644
--- a/source/engine/mecanismViews/Variations.js
+++ b/source/engine/mecanismViews/Variations.js
@@ -12,7 +12,8 @@ import './Variations.css'
let Comp = withLanguage(function Variations({
language,
nodeValue,
- explanation
+ explanation,
+ unit
}) {
let [expandedVariation, toggleVariation] = useState(null)
@@ -23,6 +24,7 @@ let Comp = withLanguage(function Variations({
classes="mecanism variations"
name="variations"
inline
+ unit={unit}
value={nodeValue}
child={
<>
@@ -111,6 +113,6 @@ let Comp = withLanguage(function Variations({
)
})
// eslint-disable-next-line
-export default (nodeValue, explanation) => (
-
+export default (nodeValue, explanation, _, unit) => (
+
)
diff --git a/source/engine/mecanismViews/common.js b/source/engine/mecanismViews/common.js
index 11853fbd7..51b37dba7 100644
--- a/source/engine/mecanismViews/common.js
+++ b/source/engine/mecanismViews/common.js
@@ -35,7 +35,7 @@ export let NodeValuePointer = ({ data, unit }) => (
// Un élément du graphe de calcul qui a une valeur interprétée (à afficher)
export class Node extends Component {
render() {
- let { classes, name, value, child, inline } = this.props,
+ let { classes, name, value, child, inline, unit } = this.props,
termDefinition = contains('mecanism', classes) && name
return (
@@ -58,7 +58,7 @@ export class Node extends Component {
{name ? (
!isNil(value) && (
-
+
)
) : (
@@ -66,7 +66,7 @@ export class Node extends Component {
{value !== true && value !== false && !isNil(value) && (
=
)}
-
+
>
)}
@@ -98,7 +98,7 @@ export const Leaf = compose(
classes,
dottedName,
name,
- value,
+ nodeValue,
flatRules,
filter,
sitePaths,
@@ -120,12 +120,12 @@ export const Leaf = compose(
{rule.title || capitalise0(name)} {filter}
- {!isNil(value) && (
+ {!isNil(nodeValue) && (
-
+
)}
diff --git a/source/engine/mecanisms.js b/source/engine/mecanisms.js
index aa4441fa9..4c36925fe 100644
--- a/source/engine/mecanisms.js
+++ b/source/engine/mecanisms.js
@@ -138,7 +138,8 @@ export let mecanismVariations = (recurse, k, v, devariate) => {
jsx: Variations,
category: 'mecanism',
name: 'variations',
- type: 'numeric'
+ type: 'numeric',
+ unit: inferUnit('+', explanation.map(r => r.consequence.unit))
}
}
@@ -497,8 +498,8 @@ export let mecanismSum = (recurse, k, v) => {
return {
evaluate,
// eslint-disable-next-line
- jsx: (nodeValue, explanation) => (
-
+ jsx: (nodeValue, explanation, _, unit) => (
+
),
explanation,
category: 'mecanism',
@@ -620,7 +621,6 @@ export let mecanismProduct = (recurse, k, v) => {
}
}
-
export let mecanismContinuousScale = (recurse, k, v) => {
let objectShape = {
assiette: false,
diff --git a/source/engine/parse.js b/source/engine/parse.js
index 7eebe2488..663196bb4 100644
--- a/source/engine/parse.js
+++ b/source/engine/parse.js
@@ -201,6 +201,7 @@ let mecanismOperation = (k, operatorFunction, symbol) => (recurse, k, v) => {
diff --git a/source/engine/parseReference.js b/source/engine/parseReference.js
index c222c9a4d..879aece22 100644
--- a/source/engine/parseReference.js
+++ b/source/engine/parseReference.js
@@ -21,7 +21,7 @@ export let parseReference = (rules, rule, parsedRules, filter) => ({
let parsedRule =
parsedRules[dottedName] ||
- // the 'inversion numérique' formula should not exist. The instructions to the evaluation should be enough to infer that an inversion is necessary (assuming it is possible, the client decides this)
+ // the 'inversion numérique' formula should not exist. The instructions to the evaluation should be enough to infer that an inversion is necessary (assuming it is possible, the client decides this)
(!inInversionFormula &&
parseRule(rules, findRuleByDottedName(rules, dottedName), parsedRules))
@@ -97,14 +97,16 @@ export let parseReference = (rules, rule, parsedRules, filter) => ({
evaluate,
//eslint-disable-next-line react/display-name
jsx: nodeValue => (
-
+ <>
+
+ >
),
name: partialReference,
From adf556c36f862bcdb5a1beb9245c48210b083988 Mon Sep 17 00:00:00 2001
From: Mael
Date: Mon, 22 Jul 2019 11:57:27 +0200
Subject: [PATCH 12/32] :art: Alignement des valeurs des expressions dans /doc
---
source/components/rule/Algorithm.css | 14 +++++---------
source/engine/mecanismViews/Variations.js | 2 +-
source/engine/mecanisms.js | 2 +-
source/locales/en.yaml | 1 -
4 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/source/components/rule/Algorithm.css b/source/components/rule/Algorithm.css
index de8d70715..42d1b1053 100644
--- a/source/components/rule/Algorithm.css
+++ b/source/components/rule/Algorithm.css
@@ -23,24 +23,22 @@
display: inline-block;
}
-.node.inlineExpression:not(.comparison):not(.negation) {
+.node.inlineExpression:not(.comparison) {
padding-left: 0;
display: flex;
align-items: baseline;
flex-direction: row;
flex-wrap: wrap;
+ justify-content: space-between;
}
.nodeContent {
margin-right: 0.3em;
}
-#rule-rules
- .inlineExpression:not(.comparison):not(.negation)
- > .situationValue {
+#rule-rules .inlineExpression:not(.comparison) > .situationValue {
margin-left: 0.3em;
margin-bottom: 0.6em;
margin-top: 0.3em;
align-items: flex-end;
- flex: 1;
text-align: right;
}
@@ -210,8 +208,7 @@
.mecanism.cond *:not(.nodeContent) > .variable .name,
.mecanism.variations *:not(.nodeContent) > .variable .name,
-.inlineExpression.comparison,
-.inlineExpression.negation {
+.inlineExpression.comparison {
display: flex;
align-items: baseline;
}
@@ -223,8 +220,7 @@
> .variable
.name
.situationValue,
-.inlineExpression.comparison > .situationValue,
-.inlineExpression.negation > .situationValue {
+.inlineExpression.comparison > .situationValue {
order: -1;
}
diff --git a/source/engine/mecanismViews/Variations.js b/source/engine/mecanismViews/Variations.js
index af9f868f4..2683cf337 100644
--- a/source/engine/mecanismViews/Variations.js
+++ b/source/engine/mecanismViews/Variations.js
@@ -46,7 +46,7 @@ let Comp = withLanguage(function Variations({
}}>
{!satisfied && showValues && (
<>
- non applicable{' '}
+ non applicable
{expandedVariation !== i ? (
{
// la conséquence peut être un 'string' ou un autre aiguillage numérique
let parseCondition = ([condition, consequence]) => {
- let conditionNode = recurse(condition), // can be a 'comparison', a 'variable', TODO a 'negation'
+ let conditionNode = recurse(condition), // can be a 'comparison', a 'variable'
consequenceNode = mecanismNumericalSwitch(recurse, condition, consequence)
let evaluate = (cache, situationGate, parsedRules, node) => {
diff --git a/source/locales/en.yaml b/source/locales/en.yaml
index cebdd8d4a..c0a412399 100644
--- a/source/locales/en.yaml
+++ b/source/locales/en.yaml
@@ -28,7 +28,6 @@ radio_Non: No
radio_Aucun: None
oui: yes
non: no
-inlineExpressionNegation: Not
déplier: show more
replier: show less
Salaire brut: Gross salary
From 2b8adb46550b8e6c942c8a2cac48d50e539ec8c3 Mon Sep 17 00:00:00 2001
From: Mael
Date: Mon, 22 Jul 2019 12:06:43 +0200
Subject: [PATCH 13/32] :hammer: :sparkles: Simplification de la cotisation
maladie
---
source/règles/base.yaml | 40 ++++++++++++++++++++++++++--------------
1 file changed, 26 insertions(+), 14 deletions(-)
diff --git a/source/règles/base.yaml b/source/règles/base.yaml
index fff14d37e..fe2ba75f9 100644
--- a/source/règles/base.yaml
+++ b/source/règles/base.yaml
@@ -2398,23 +2398,11 @@
- attributs:
composante: maladie, maternité, invalidité, décès
dû par: employeur
- taux:
- variations:
- - si:
- toutes ces conditions:
- - cotisations . assiette < plafond de réduction employeur
- - statut JEI != oui
- - assimilé salarié != oui
- alors: 7%
- - sinon: 13%
+ taux: taux employeur
- attributs:
composante: maladie, maternité, invalidité, décès
dû par: salarié
- taux:
- variations:
- - si: régime alsace moselle
- alors: 1.5%
- - sinon: 0%
+ taux: taux salarié
- attributs:
composante: Contribution Solidarité Autonomie
abbréviation: CSA
@@ -2424,6 +2412,30 @@
- https://www.service-public.fr/professionnels-entreprises/vosdroits/F32872
taux: 0.3%
+
+- espace: contrat salarié . maladie
+ nom: taux employeur
+ période: aucune
+ formule:
+ variations:
+ - si:
+ toutes ces conditions:
+ - cotisations . assiette < plafond de réduction employeur
+ - statut JEI != oui
+ - assimilé salarié != oui
+ alors: 7%
+ - sinon: 13%
+
+- espace: contrat salarié . maladie
+ nom: taux salarié
+ période: aucune
+ formule:
+ variations:
+ - si: régime alsace moselle
+ alors: 1.5%
+ - sinon: 0%
+
+
- espace: contrat salarié . maladie
nom: plafond de réduction employeur
période: flexible
From 6b2d4b8dd3c34ae7a0c6d04e2b30c4f40d274d01 Mon Sep 17 00:00:00 2001
From: Mael
Date: Mon, 22 Jul 2019 12:25:06 +0200
Subject: [PATCH 14/32] =?UTF-8?q?:art:=20Am=C3=A9lioration=20du=20style=20?=
=?UTF-8?q?des=20composantes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/components/rule/Algorithm.css | 11 -----------
source/engine/mecanismViews/Composantes.css | 12 ++----------
source/engine/mecanismViews/Composantes.js | 21 ++++++++++++++++++---
source/règles/base.yaml | 10 +++++-----
4 files changed, 25 insertions(+), 29 deletions(-)
diff --git a/source/components/rule/Algorithm.css b/source/components/rule/Algorithm.css
index 42d1b1053..64feb8f03 100644
--- a/source/components/rule/Algorithm.css
+++ b/source/components/rule/Algorithm.css
@@ -112,13 +112,6 @@
margin-right: 0.6em;
}
-.maximum .description,
-.composanteName {
- font-weight: 500;
- margin-bottom: 0.4em;
- margin-left: 1em;
-}
-
.leaf .situationValue {
text-align: center;
}
@@ -145,10 +138,6 @@
margin-top: 0.6em;
}
-.composantes .composanteName::first-letter {
- text-transform: capitalize;
-}
-
.mecanism {
border: 1px solid;
max-width: 100%;
diff --git a/source/engine/mecanismViews/Composantes.css b/source/engine/mecanismViews/Composantes.css
index 575aae937..7bd637ecc 100644
--- a/source/engine/mecanismViews/Composantes.css
+++ b/source/engine/mecanismViews/Composantes.css
@@ -3,16 +3,8 @@
counter-reset: li;
padding-left: 1em;
}
-
-.composantes > ol > li.composante::before {
- counter-increment: li;
-}
-.composantes > ol > li.composante::before {
- content: counter(li) ')';
- color: grey;
- display: inline-block;
- width: 1em;
- margin-left: -1em;
+.composantes > ol > li > ul > li {
+ list-style-type: none;
}
.composantes .composanteAttributes {
diff --git a/source/engine/mecanismViews/Composantes.js b/source/engine/mecanismViews/Composantes.js
index ba44b47fc..45f331ddf 100644
--- a/source/engine/mecanismViews/Composantes.js
+++ b/source/engine/mecanismViews/Composantes.js
@@ -6,6 +6,7 @@ import { Trans } from 'react-i18next'
import { toPairs } from 'ramda'
import writtenNumbers from '../../locales/writtenNumbers.yaml'
import withLanguage from 'Components/utils/withLanguage'
+import colours from 'Engine/mecanismViews/colours'
let Comp = withLanguage(function Composantes({
language,
@@ -29,11 +30,25 @@ let Comp = withLanguage(function Composantes({
{explanation.map(c => [
-
-
+
+ span:first-child {
+ }
+ `}>
{toPairs(c.composante).map(([k, v]) => (
-
+
{k} :{' '}
diff --git a/source/règles/base.yaml b/source/règles/base.yaml
index fe2ba75f9..bc9a5dbd4 100644
--- a/source/règles/base.yaml
+++ b/source/règles/base.yaml
@@ -2100,11 +2100,11 @@
composantes:
- attributs:
- composante: base
+ nom: base
taux: 4%
- attributs:
- composante: contribution exceptionnelle temporaire
+ nom: contribution exceptionnelle temporaire
description: |
Instaurée le 1er octobre 2017, applicable jusqu’au 30 septembre 2020 au plus tard.
taux: 0.05%
@@ -2396,15 +2396,15 @@
assiette: cotisations . assiette
composantes:
- attributs:
- composante: maladie, maternité, invalidité, décès
+ nom: maladie, maternité, invalidité, décès
dû par: employeur
taux: taux employeur
- attributs:
- composante: maladie, maternité, invalidité, décès
+ nom: maladie, maternité, invalidité, décès
dû par: salarié
taux: taux salarié
- attributs:
- composante: Contribution Solidarité Autonomie
+ nom: Contribution Solidarité Autonomie
abbréviation: CSA
dû par: employeur
références:
From ab0b64da129b91457cb7d1e7f67a02671d46ae8d Mon Sep 17 00:00:00 2001
From: Mael
Date: Mon, 22 Jul 2019 12:36:50 +0200
Subject: [PATCH 15/32] =?UTF-8?q?:sparkles:=20D=C3=A9placement=20des=20Var?=
=?UTF-8?q?iations?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/engine/mecanisms.js | 155 +--------------------
source/engine/mecanisms/barème-linéaire.js | 6 +-
source/engine/mecanisms/barème.js | 4 +-
source/engine/mecanisms/utils.js | 14 --
source/engine/mecanisms/variations.js | 109 +++++++++++++++
source/engine/parse.js | 11 +-
6 files changed, 122 insertions(+), 177 deletions(-)
create mode 100644 source/engine/mecanisms/variations.js
diff --git a/source/engine/mecanisms.js b/source/engine/mecanisms.js
index dd27b1afa..5c7000f1c 100644
--- a/source/engine/mecanisms.js
+++ b/source/engine/mecanisms.js
@@ -1,9 +1,7 @@
-import { desugarScale } from 'Engine/mecanisms/barème'
-import { decompose, devariateExplanation } from 'Engine/mecanisms/utils'
+import { decompose } from 'Engine/mecanisms/utils'
import {
add,
any,
- aperture,
curry,
equals,
evolve,
@@ -12,9 +10,7 @@ import {
head,
is,
isEmpty,
- isNil,
keys,
- last,
map,
max,
mergeWith,
@@ -23,11 +19,7 @@ import {
pipe,
pluck,
prop,
- propEq,
reduce,
- reduced,
- reject,
- sort,
subtract,
toPairs
} from 'ramda'
@@ -48,100 +40,15 @@ import {
rewriteNode
} from './evaluation'
import Allègement from './mecanismViews/Allègement'
-import Barème from './mecanismViews/Barème'
-import BarèmeContinu from './mecanismViews/BarèmeContinu'
import { Node, SimpleRuleLink } from './mecanismViews/common'
import InversionNumérique from './mecanismViews/InversionNumérique'
import Product from './mecanismViews/Product'
import Somme from './mecanismViews/Somme'
-import Variations from './mecanismViews/Variations'
import { disambiguateRuleReference, findRuleByDottedName } from './rules'
import { anyNull, val } from './traverse-common-functions'
import uniroot from './uniroot'
import { inferUnit } from 'Engine/units'
-
-/* @devariate = true => This function will produce variations of a same mecanism (e.g. product) that share some common properties */
-export let mecanismVariations = (recurse, k, v, devariate) => {
- let explanation = devariate
- ? devariateExplanation(recurse, k, v)
- : v.map(({ si, alors, sinon }) =>
- sinon !== undefined
- ? { consequence: recurse(sinon), condition: undefined }
- : { consequence: recurse(alors), condition: recurse(si) }
- )
-
- let evaluate = (cache, situationGate, parsedRules, node) => {
- let evaluateVariationProp = prop =>
- prop === undefined
- ? undefined
- : evaluateNode(cache, situationGate, parsedRules, prop),
- // mark the satisfied variation if any in the explanation
- [, resolvedExplanation] = reduce(
- ([resolved, result], variation) => {
- if (resolved) return [true, [...result, variation]]
-
- // evaluate the condition
- let evaluatedCondition = evaluateVariationProp(variation.condition)
-
- if (evaluatedCondition == undefined) {
- // We've reached the eventual defaut case
- let evaluatedVariation = {
- consequence: evaluateVariationProp(variation.consequence),
- satisfied: true
- }
- return [true, [...result, evaluatedVariation]]
- }
-
- if (evaluatedCondition.nodeValue === null)
- // one case has missing variables => we can't go further
- return [true, [...result, { condition: evaluatedCondition }]]
-
- if (evaluatedCondition.nodeValue === true) {
- let evaluatedVariation = {
- condition: evaluatedCondition,
- consequence: evaluateVariationProp(variation.consequence),
- satisfied: true
- }
- return [true, [...result, evaluatedVariation]]
- }
- return [false, [...result, variation]]
- },
- [false, []]
- )(node.explanation),
- satisfiedVariation = resolvedExplanation.find(v => v.satisfied),
- nodeValue = satisfiedVariation
- ? satisfiedVariation.consequence.nodeValue
- : null
-
- let leftMissing = mergeAllMissing(
- reject(isNil, pluck('condition', resolvedExplanation))
- ),
- candidateVariations = filter(
- node => !node.condition || node.condition.nodeValue !== false,
- resolvedExplanation
- ),
- rightMissing = mergeAllMissing(
- reject(isNil, pluck('consequence', candidateVariations))
- ),
- missingVariables = satisfiedVariation
- ? collectNodeMissing(satisfiedVariation.consequence)
- : mergeMissing(bonus(leftMissing), rightMissing)
-
- return rewriteNode(node, nodeValue, resolvedExplanation, missingVariables)
- }
-
- // TODO - find an appropriate representation
-
- return {
- explanation,
- evaluate,
- jsx: Variations,
- category: 'mecanism',
- name: 'variations',
- type: 'numeric',
- unit: inferUnit('+', explanation.map(r => r.consequence.unit))
- }
-}
+import variations from 'Engine/mecanisms/variations'
export let mecanismOneOf = (recurse, k, v) => {
if (!is(Array, v)) throw new Error('should be array')
@@ -576,7 +483,7 @@ export let mecanismProduct = (recurse, k, v) => {
return decompose(recurse, k, v)
}
if (v.variations) {
- return mecanismVariations(recurse, k, v, true)
+ return variations(recurse, k, v, true)
}
let objectShape = {
@@ -621,62 +528,6 @@ export let mecanismProduct = (recurse, k, v) => {
}
}
-export let mecanismContinuousScale = (recurse, k, v) => {
- let objectShape = {
- assiette: false,
- multiplicateur: defaultNode(1)
- }
-
- let returnRate = v['retourne seulement le taux'] === 'oui'
- let effect = ({ assiette, multiplicateur, points }) => {
- if (anyNull([assiette, multiplicateur])) return null
- //We'll build a linear function given the two constraints that must be respected
- let result = pipe(
- toPairs,
- // we don't rely on the sorting of objects
- sort(([k1], [k2]) => k1 - k2),
- points => [...points, [Infinity, last(points)[1]]],
- aperture(2),
- reduce((_, [[lowerLimit, lowerRate], [upperLimit, upperRate]]) => {
- let x1 = val(multiplicateur) * lowerLimit,
- x2 = val(multiplicateur) * upperLimit,
- y1 = val(assiette) * val(recurse(lowerRate)),
- y2 = val(assiette) * val(recurse(upperRate))
- if (val(assiette) > x1 && val(assiette) <= x2) {
- // 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,
- taux = nodeValue / val(assiette)
- return reduced({
- nodeValue: returnRate ? taux : nodeValue,
- additionalExplanation: {
- seuil: val(assiette) / val(multiplicateur),
- taux
- }
- })
- }
- }, 0)
- )(points)
-
- return result
- }
- let explanation = {
- ...parseObject(recurse, objectShape, v),
- points: v.points,
- returnRate
- },
- evaluate = evaluateObject(objectShape, effect)
- return {
- evaluate,
- jsx: BarèmeContinu,
- explanation,
- category: 'mecanism',
- name: 'barème continu',
- type: 'numeric'
- }
-}
-
export let mecanismMax = (recurse, k, v) => {
let explanation = v.map(recurse)
diff --git a/source/engine/mecanisms/barème-linéaire.js b/source/engine/mecanisms/barème-linéaire.js
index 41e7437aa..d4543c600 100644
--- a/source/engine/mecanisms/barème-linéaire.js
+++ b/source/engine/mecanisms/barème-linéaire.js
@@ -1,6 +1,6 @@
import { defaultNode, evaluateObject } from 'Engine/evaluation'
import Barème from 'Engine/mecanismViews/Barème'
-import { mecanismVariations } from 'Engine/mecanisms'
+import variations from 'Engine/mecanisms/variations'
import { decompose } from 'Engine/mecanisms/utils'
import { val } from 'Engine/traverse-common-functions'
import { inferUnit, parseUnit } from 'Engine/units'
@@ -21,7 +21,7 @@ export default (recurse, k, v) => {
return decompose(recurse, k, v)
}
if (v.variations) {
- return mecanismVariations(recurse, k, v, true)
+ return variations(recurse, k, v, true)
}
let tranches = desugarScale(recurse)(v['tranches']),
objectShape = {
@@ -52,8 +52,6 @@ export default (recurse, k, v) => {
},
evaluate = evaluateObject(objectShape, effect)
- console.log('explanation', explanation)
-
return {
evaluate,
jsx: Barème('linéaire'),
diff --git a/source/engine/mecanisms/barème.js b/source/engine/mecanisms/barème.js
index 270389a70..4176232e0 100644
--- a/source/engine/mecanisms/barème.js
+++ b/source/engine/mecanisms/barème.js
@@ -1,5 +1,5 @@
import { defaultNode, E, rewriteNode } from 'Engine/evaluation'
-import { mecanismVariations } from 'Engine/mecanisms'
+import variations from 'Engine/mecanisms/variations'
import { decompose } from 'Engine/mecanisms/utils'
import Barème from 'Engine/mecanismViews/Barème'
import { val } from 'Engine/traverse-common-functions'
@@ -39,7 +39,7 @@ export default (recurse, k, v) => {
return decompose(recurse, k, v)
}
if (v.variations) {
- return mecanismVariations(recurse, k, v, true)
+ return variations(recurse, k, v, true)
}
let { assiette, multiplicateur } = v,
diff --git a/source/engine/mecanisms/utils.js b/source/engine/mecanisms/utils.js
index cf986ee25..60e499994 100644
--- a/source/engine/mecanisms/utils.js
+++ b/source/engine/mecanisms/utils.js
@@ -34,17 +34,3 @@ export let decompose = (recurse, k, v) => {
}
}
-export let devariateExplanation = (recurse, mecanismKey, v) => {
- let fixedProps = dissoc('variations')(v),
- explanation = v.variations.map(({ si, alors, sinon }) => ({
- consequence: recurse({
- [mecanismKey]: {
- ...fixedProps,
- ...(sinon || alors)
- }
- }),
- condition: sinon ? undefined : recurse(si)
- }))
-
- return explanation
-}
diff --git a/source/engine/mecanisms/variations.js b/source/engine/mecanisms/variations.js
new file mode 100644
index 000000000..b8887c23c
--- /dev/null
+++ b/source/engine/mecanisms/variations.js
@@ -0,0 +1,109 @@
+import { inferUnit } from 'Engine/units'
+import {
+ bonus,
+ collectNodeMissing,
+ evaluateNode,
+ mergeAllMissing,
+ mergeMissing,
+ rewriteNode
+} from 'Engine/evaluation'
+import { reject, pluck, isNil, filter, dissoc, reduce } from 'ramda'
+import Variations from 'Engine/mecanismViews/Variations'
+
+/* @devariate = true => This function will produce variations of a same mecanism (e.g. product) that share some common properties */
+export default (recurse, k, v, devariate) => {
+ let explanation = devariate
+ ? devariateExplanation(recurse, k, v)
+ : v.map(({ si, alors, sinon }) =>
+ sinon !== undefined
+ ? { consequence: recurse(sinon), condition: undefined }
+ : { consequence: recurse(alors), condition: recurse(si) }
+ )
+
+ let evaluate = (cache, situationGate, parsedRules, node) => {
+ let evaluateVariationProp = prop =>
+ prop === undefined
+ ? undefined
+ : evaluateNode(cache, situationGate, parsedRules, prop),
+ // mark the satisfied variation if any in the explanation
+ [, resolvedExplanation] = reduce(
+ ([resolved, result], variation) => {
+ if (resolved) return [true, [...result, variation]]
+
+ // evaluate the condition
+ let evaluatedCondition = evaluateVariationProp(variation.condition)
+
+ if (evaluatedCondition == undefined) {
+ // We've reached the eventual defaut case
+ let evaluatedVariation = {
+ consequence: evaluateVariationProp(variation.consequence),
+ satisfied: true
+ }
+ return [true, [...result, evaluatedVariation]]
+ }
+
+ if (evaluatedCondition.nodeValue === null)
+ // one case has missing variables => we can't go further
+ return [true, [...result, { condition: evaluatedCondition }]]
+
+ if (evaluatedCondition.nodeValue === true) {
+ let evaluatedVariation = {
+ condition: evaluatedCondition,
+ consequence: evaluateVariationProp(variation.consequence),
+ satisfied: true
+ }
+ return [true, [...result, evaluatedVariation]]
+ }
+ return [false, [...result, variation]]
+ },
+ [false, []]
+ )(node.explanation),
+ satisfiedVariation = resolvedExplanation.find(v => v.satisfied),
+ nodeValue = satisfiedVariation
+ ? satisfiedVariation.consequence.nodeValue
+ : null
+
+ let leftMissing = mergeAllMissing(
+ reject(isNil, pluck('condition', resolvedExplanation))
+ ),
+ candidateVariations = filter(
+ node => !node.condition || node.condition.nodeValue !== false,
+ resolvedExplanation
+ ),
+ rightMissing = mergeAllMissing(
+ reject(isNil, pluck('consequence', candidateVariations))
+ ),
+ missingVariables = satisfiedVariation
+ ? collectNodeMissing(satisfiedVariation.consequence)
+ : mergeMissing(bonus(leftMissing), rightMissing)
+
+ return rewriteNode(node, nodeValue, resolvedExplanation, missingVariables)
+ }
+
+ // TODO - find an appropriate representation
+
+ return {
+ explanation,
+ evaluate,
+ jsx: Variations,
+ category: 'mecanism',
+ name: 'variations',
+ type: 'numeric',
+ unit: inferUnit('+', explanation.map(r => r.consequence.unit))
+ }
+}
+
+export let devariateExplanation = (recurse, mecanismKey, v) => {
+ let fixedProps = dissoc('variations')(v),
+ explanation = v.variations.map(({ si, alors, sinon }) => ({
+ consequence: recurse({
+ [mecanismKey]: {
+ ...fixedProps,
+ ...(sinon || alors)
+ }
+ }),
+ condition: sinon ? undefined : recurse(si)
+ }))
+
+ return explanation
+}
diff --git a/source/engine/parse.js b/source/engine/parse.js
index 663196bb4..12e3e862f 100644
--- a/source/engine/parse.js
+++ b/source/engine/parse.js
@@ -2,10 +2,12 @@
// In a specific file
// TODO import them automatically
// TODO convert the legacy functions to new files
-import barème from 'Engine/mecanisms/barème.js'
-import barèmeContinu from 'Engine/mecanisms/barème-continu.js'
-import barèmeLinéaire from 'Engine/mecanisms/barème-linéaire.js'
+import barème from 'Engine/mecanisms/barème'
+import barèmeContinu from 'Engine/mecanisms/barème-continu'
+import barèmeLinéaire from 'Engine/mecanisms/barème-linéaire'
+import variations from 'Engine/mecanisms/variations'
import { Parser } from 'nearley'
+
import {
add,
curry,
@@ -42,7 +44,6 @@ import {
mecanismReduction,
mecanismSum,
mecanismSynchronisation,
- mecanismVariations,
mecanismOnePossibility
} from './mecanisms'
import { Node } from './mecanismViews/common'
@@ -145,7 +146,7 @@ export let parseObject = (rules, rule, parsedRules) => rawNode => {
'une possibilité': mecanismOnePossibility(rule.dottedName),
'inversion numérique': mecanismInversion(rule.dottedName),
allègement: mecanismReduction,
- variations: mecanismVariations,
+ variations,
synchronisation: mecanismSynchronisation,
...operationDispatch,
filter: () =>
From 78da370cb83d4c58a91d23bbe745a682a278fcce Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 12:11:26 +0200
Subject: [PATCH 16/32] =?UTF-8?q?:bug:=20Certaines=20cons=C3=A9quences=20d?=
=?UTF-8?q?es=20variations=20ne=20s'affichaient=20pas?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/engine/mecanisms/variations.js | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/source/engine/mecanisms/variations.js b/source/engine/mecanisms/variations.js
index b8887c23c..a2bee0173 100644
--- a/source/engine/mecanisms/variations.js
+++ b/source/engine/mecanisms/variations.js
@@ -22,9 +22,7 @@ export default (recurse, k, v, devariate) => {
let evaluate = (cache, situationGate, parsedRules, node) => {
let evaluateVariationProp = prop =>
- prop === undefined
- ? undefined
- : evaluateNode(cache, situationGate, parsedRules, prop),
+ prop && evaluateNode(cache, situationGate, parsedRules, prop),
// mark the satisfied variation if any in the explanation
[, resolvedExplanation] = reduce(
([resolved, result], variation) => {
@@ -34,7 +32,7 @@ export default (recurse, k, v, devariate) => {
let evaluatedCondition = evaluateVariationProp(variation.condition)
if (evaluatedCondition == undefined) {
- // We've reached the eventual defaut case
+ // No condition : we've reached the eventual defaut case
let evaluatedVariation = {
consequence: evaluateVariationProp(variation.consequence),
satisfied: true
@@ -43,8 +41,11 @@ export default (recurse, k, v, devariate) => {
}
if (evaluatedCondition.nodeValue === null)
- // one case has missing variables => we can't go further
- return [true, [...result, { condition: evaluatedCondition }]]
+ // the current variation case has missing variables => we can't go further
+ return [
+ true,
+ [...result, { ...variation, condition: evaluatedCondition }]
+ ]
if (evaluatedCondition.nodeValue === true) {
let evaluatedVariation = {
@@ -76,6 +77,7 @@ export default (recurse, k, v, devariate) => {
missingVariables = satisfiedVariation
? collectNodeMissing(satisfiedVariation.consequence)
: mergeMissing(bonus(leftMissing), rightMissing)
+ console.log(resolvedExplanation)
return rewriteNode(node, nodeValue, resolvedExplanation, missingVariables)
}
From 86a300245254bf54e46600a20af7e0153048e01d Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 14:04:05 +0200
Subject: [PATCH 17/32] =?UTF-8?q?:art:=20Symbole=20=C3=A9galit=C3=A9=20pou?=
=?UTF-8?q?r=20les=20valeurs=20de=20m=C3=A9ca=20et=20alignement=20en=20bas?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
D'après le peu de tests effectués (2) le résultat du mécanisme est mieux
en bas
---
source/components/rule/Algorithm.css | 2 +-
source/engine/mecanismViews/common.js | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/source/components/rule/Algorithm.css b/source/components/rule/Algorithm.css
index 64feb8f03..32d6b2c4c 100644
--- a/source/components/rule/Algorithm.css
+++ b/source/components/rule/Algorithm.css
@@ -153,7 +153,7 @@
.mecanism-result {
position: absolute;
display: none;
- top: -4px;
+ bottom: 0px;
right: 0;
}
#rule-rules.showValues .mecanism-result {
diff --git a/source/engine/mecanismViews/common.js b/source/engine/mecanismViews/common.js
index 51b37dba7..add8ea619 100644
--- a/source/engine/mecanismViews/common.js
+++ b/source/engine/mecanismViews/common.js
@@ -13,7 +13,7 @@ import mecanismColours from './colours'
import classnames from 'classnames'
import Value from 'Components/Value'
-export let NodeValuePointer = ({ data, unit }) => (
+export let NodeValuePointer = ({ data, unit, equalSign }) => (
(
line-height: 1.6em;
border-radius: 0.2rem;
`}>
+ {equalSign && = }
)
@@ -58,7 +59,7 @@ export class Node extends Component {
{name ? (
!isNil(value) && (
-
+
)
) : (
From a58853569ab55349daa821b8b56598465b1aa2e8 Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 14:12:33 +0200
Subject: [PATCH 18/32] =?UTF-8?q?:art:=20Symbole=20+=20pour=20s=C3=A9parer?=
=?UTF-8?q?=20les=20composantes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1 retour utilisateur pas familier avec ce concept de composantes
---
source/engine/mecanismViews/Composantes.js | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/source/engine/mecanismViews/Composantes.js b/source/engine/mecanismViews/Composantes.js
index 45f331ddf..e7406f439 100644
--- a/source/engine/mecanismViews/Composantes.js
+++ b/source/engine/mecanismViews/Composantes.js
@@ -29,19 +29,15 @@ let Comp = withLanguage(function Composantes({
:
- {explanation.map(c => [
+ {explanation.map((c, i) => [
span:first-child {
- }
`}>
{toPairs(c.composante).map(([k, v]) => (
@@ -58,6 +54,15 @@ let Comp = withLanguage(function Composantes({
))}
{makeJsx(c)}
+
+ {i === explanation.length - 1 ? null : '+'}
+
])}
From cb2cc9e8d2443475dca123b44ef7a186e0667f99 Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 14:16:50 +0200
Subject: [PATCH 19/32] Simplification du texte d'introduction des variations
et composantes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Le terme règle est obscur
---
source/engine/mecanismViews/Composantes.js | 4 ++--
source/engine/mecanismViews/Variations.js | 5 ++---
source/locales/en.yaml | 3 +--
3 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/source/engine/mecanismViews/Composantes.js b/source/engine/mecanismViews/Composantes.js
index e7406f439..7ff9ac851 100644
--- a/source/engine/mecanismViews/Composantes.js
+++ b/source/engine/mecanismViews/Composantes.js
@@ -23,8 +23,8 @@ let Comp = withLanguage(function Composantes({
unit={unit}
child={
<>
-
- Cette règle est la somme de {' '}
+
+ La somme de {' '}
{writtenNumbers[language][explanation.length]}{' '}
:
diff --git a/source/engine/mecanismViews/Variations.js b/source/engine/mecanismViews/Variations.js
index 2683cf337..8e32d01e6 100644
--- a/source/engine/mecanismViews/Variations.js
+++ b/source/engine/mecanismViews/Variations.js
@@ -28,9 +28,8 @@ let Comp = withLanguage(function Variations({
value={nodeValue}
child={
<>
-
- Cette règle présente {' '}
- {writtenNumbers[language][explanation.length]}{' '}
+
+ {writtenNumbers[language][explanation.length]}{' '}
:
diff --git a/source/locales/en.yaml b/source/locales/en.yaml
index c0a412399..503d70e41 100644
--- a/source/locales/en.yaml
+++ b/source/locales/en.yaml
@@ -177,8 +177,7 @@ legalNotice:
contact@mon-entreprise.beta.gouv.fr
0>
-Cette règle est la somme de: This rule is the sum of
-Cette règle présente: This rule has
+La somme de: This rule is the sum of
Si: If
Sinon: Else
Alors: Then
From 906dcf8c801f4b5ec7dca29a442710eabcccf0a4 Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 14:18:13 +0200
Subject: [PATCH 20/32] =?UTF-8?q?On=20=C3=A9vite=20de=20parler=20de=20r?=
=?UTF-8?q?=C3=A8gle=20pour=20la=20/doc,=20plut=C3=B4t=20de=20pages?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/components/rule/Rule.js | 2 +-
source/locales/en.yaml | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/source/components/rule/Rule.js b/source/components/rule/Rule.js
index f6b7624e4..f69279326 100644
--- a/source/components/rule/Rule.js
+++ b/source/components/rule/Rule.js
@@ -204,7 +204,7 @@ let NamespaceRulesList = compose(
return (
- Règles associées
+ Pages associées
{namespaceRules.map(r => (
diff --git a/source/locales/en.yaml b/source/locales/en.yaml
index 503d70e41..1d8ad2ab2 100644
--- a/source/locales/en.yaml
+++ b/source/locales/en.yaml
@@ -41,7 +41,7 @@ Quel est le salaire mensuel ?: What is the monthly salary?
back: Back to your simulation
ambiguous: More than one rule with this name found. Which one are you looking for ?
Références: Relevant legal information (fr)
-Règles du groupe: Rules of the group
+Pages associées: Related pages
Pas de sources officielles: No official information
Votre avis nous intéresse !: Your opinion matters!
afficher les sources complémentaires: display additional information sources
@@ -62,7 +62,6 @@ satisfaction-mailto: click here to directly write an email
Votre adresse e-mail: Your email address
envoyer: send
Rechercher: Search
-Règle non applicable: Not applicable
Situation incomplète: More information needed
Destinataire: Levied by
cotisation: contribution
From 8b8afd528b4a6606f14c2467887452089ef717c0 Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 14:21:35 +0200
Subject: [PATCH 21/32] =?UTF-8?q?Ajout=20de=20l'unit=C3=A9=20aux=20bar?=
=?UTF-8?q?=C3=A8mes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/engine/mecanismViews/Barème.js | 13 +++++++++----
source/engine/mecanismViews/BarèmeContinu.js | 7 ++++---
source/règles/base.yaml | 1 +
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/source/engine/mecanismViews/Barème.js b/source/engine/mecanismViews/Barème.js
index 9c19d8f1a..ae040adae 100644
--- a/source/engine/mecanismViews/Barème.js
+++ b/source/engine/mecanismViews/Barème.js
@@ -37,7 +37,8 @@ let Component = withLanguage(function Barème({
nodeValue,
explanation,
barèmeType,
- lazyEval
+ lazyEval,
+ unit
}) {
return (
@@ -46,6 +47,7 @@ let Component = withLanguage(function Barème({
classes="mecanism barème"
name={barèmeType === 'marginal' ? 'barème' : 'barème linéaire'}
value={nodeValue}
+ unit={unit}
child={
@@ -159,6 +161,9 @@ let Tranche = ({
}
//eslint-disable-next-line
-export default barèmeType => (nodeValue, explanation, lazyEval = identity) => (
-
-)
+export default barèmeType => (
+ nodeValue,
+ explanation,
+ lazyEval = identity,
+ unit
+) =>
diff --git a/source/engine/mecanismViews/BarèmeContinu.js b/source/engine/mecanismViews/BarèmeContinu.js
index 93cdf21e1..97b0613ca 100644
--- a/source/engine/mecanismViews/BarèmeContinu.js
+++ b/source/engine/mecanismViews/BarèmeContinu.js
@@ -7,7 +7,7 @@ import withLanguage from 'Components/utils/withLanguage'
import { BarèmeAttributes } from './Barème'
import { sortObjectByKeys } from 'Engine/mecanismViews/common'
-let Comp = withLanguage(function Barème({ nodeValue, explanation }) {
+let Comp = withLanguage(function Barème({ nodeValue, explanation, unit }) {
return (
{showValues => (
@@ -15,6 +15,7 @@ let Comp = withLanguage(function Barème({ nodeValue, explanation }) {
classes="mecanism barème"
name="barème continu"
value={nodeValue}
+ unit={unit}
child={
@@ -60,6 +61,6 @@ let Comp = withLanguage(function Barème({ nodeValue, explanation }) {
})
//eslint-disable-next-line
-export default (nodeValue, explanation) => (
-
+export default (nodeValue, explanation, _, unit) => (
+
)
diff --git a/source/règles/base.yaml b/source/règles/base.yaml
index bc9a5dbd4..c85f06c66 100644
--- a/source/règles/base.yaml
+++ b/source/règles/base.yaml
@@ -1013,6 +1013,7 @@
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
+ unité: €
références:
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
From 0233c793a07304db94a22040f296db073669c644 Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 14:33:35 +0200
Subject: [PATCH 22/32] =?UTF-8?q?:sparkles:=20D=C3=A9placement=20du=20m?=
=?UTF-8?q?=C3=A9canisme=20operation?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/engine/mecanisms/operation.js | 62 ++++++++++++++++++++++++++++
source/engine/parse.js | 60 +--------------------------
2 files changed, 64 insertions(+), 58 deletions(-)
create mode 100644 source/engine/mecanisms/operation.js
diff --git a/source/engine/mecanisms/operation.js b/source/engine/mecanisms/operation.js
new file mode 100644
index 000000000..3ccb083b2
--- /dev/null
+++ b/source/engine/mecanisms/operation.js
@@ -0,0 +1,62 @@
+import React from 'react'
+import { curry, map } from 'ramda'
+import { inferUnit } from 'Engine/units'
+import {
+ evaluateNode,
+ makeJsx,
+ mergeMissing,
+ rewriteNode
+} from 'Engine/evaluation'
+import { Node } from 'Engine/mecanismViews/common'
+
+export default (k, operatorFunction, symbol) => (recurse, k, v) => {
+ let evaluate = (cache, situation, parsedRules, node) => {
+ let explanation = map(
+ curry(evaluateNode)(cache, situation, parsedRules),
+ node.explanation
+ ),
+ value1 = explanation[0].nodeValue,
+ value2 = explanation[1].nodeValue,
+ nodeValue =
+ value1 == null || value2 == null
+ ? null
+ : operatorFunction(value1, value2),
+ missingVariables = mergeMissing(
+ explanation[0].missingVariables,
+ explanation[1].missingVariables
+ )
+
+ return rewriteNode(node, nodeValue, explanation, missingVariables)
+ }
+
+ let explanation = v.explanation.map(recurse)
+
+ let unit = inferUnit(k, [explanation[0].unit, explanation[1].unit])
+
+ let jsx = (nodeValue, explanation) => (
+
+
+ {makeJsx(explanation[0])}
+ {symbol || k}
+
+ {makeJsx(explanation[1])}
+
+ }
+ />
+ )
+
+ return {
+ ...v,
+ evaluate,
+ jsx,
+ operator: symbol || k,
+ // is this useful ? text: rawNode,
+ explanation,
+ unit
+ }
+}
diff --git a/source/engine/parse.js b/source/engine/parse.js
index 12e3e862f..a492fd82e 100644
--- a/source/engine/parse.js
+++ b/source/engine/parse.js
@@ -6,11 +6,11 @@ import barème from 'Engine/mecanisms/barème'
import barèmeContinu from 'Engine/mecanisms/barème-continu'
import barèmeLinéaire from 'Engine/mecanisms/barème-linéaire'
import variations from 'Engine/mecanisms/variations'
+import operation from 'Engine/mecanisms/operation'
import { Parser } from 'nearley'
import {
add,
- curry,
divide,
equals,
gt,
@@ -19,7 +19,6 @@ import {
without,
lt,
lte,
- map,
multiply,
propOr,
subtract,
@@ -29,7 +28,6 @@ import {
T
} from 'ramda'
import React from 'react'
-import { evaluateNode, makeJsx, mergeMissing, rewriteNode } from './evaluation'
import Grammar from './grammar.ne'
import {
mecanismAllOf,
@@ -46,9 +44,7 @@ import {
mecanismSynchronisation,
mecanismOnePossibility
} from './mecanisms'
-import { Node } from './mecanismViews/common'
import { parseReferenceTransforms } from './parseReference'
-import { inferUnit } from 'Engine/units'
export let parse = (rules, rule, parsedRules) => rawNode => {
let onNodeType = cond([
@@ -127,7 +123,7 @@ export let parseObject = (rules, rule, parsedRules) => rawNode => {
operationDispatch = fromPairs(
Object.entries(knownOperations).map(([k, [f, symbol]]) => [
k,
- mecanismOperation(k, f, symbol)
+ operation(k, f, symbol)
])
)
@@ -173,55 +169,3 @@ export let parseObject = (rules, rule, parsedRules) => rawNode => {
return action(parse(rules, rule, parsedRules), k, v)
}
-
-let mecanismOperation = (k, operatorFunction, symbol) => (recurse, k, v) => {
- let evaluate = (cache, situation, parsedRules, node) => {
- let explanation = map(
- curry(evaluateNode)(cache, situation, parsedRules),
- node.explanation
- ),
- value1 = explanation[0].nodeValue,
- value2 = explanation[1].nodeValue,
- nodeValue =
- value1 == null || value2 == null
- ? null
- : operatorFunction(value1, value2),
- missingVariables = mergeMissing(
- explanation[0].missingVariables,
- explanation[1].missingVariables
- )
-
- return rewriteNode(node, nodeValue, explanation, missingVariables)
- }
-
- let explanation = v.explanation.map(recurse)
-
- let unit = inferUnit(k, [explanation[0].unit, explanation[1].unit])
-
- let jsx = (nodeValue, explanation) => (
-
-
- {makeJsx(explanation[0])}
- {symbol || k}
-
- {makeJsx(explanation[1])}
-
- }
- />
- )
-
- return {
- ...v,
- evaluate,
- jsx,
- operator: symbol || k,
- // is this useful ? text: rawNode,
- explanation,
- unit
- }
-}
From fb73ed5cbf6c7f40759f6778eb3b2724d098b707 Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 14:44:01 +0200
Subject: [PATCH 23/32] :art: Alingement des expressions sur mobile
---
source/components/rule/Algorithm.css | 2 +-
source/engine/mecanismViews/common.js | 12 +++++++++---
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/source/components/rule/Algorithm.css b/source/components/rule/Algorithm.css
index 32d6b2c4c..f2a83e3cb 100644
--- a/source/components/rule/Algorithm.css
+++ b/source/components/rule/Algorithm.css
@@ -29,7 +29,7 @@
align-items: baseline;
flex-direction: row;
flex-wrap: wrap;
- justify-content: space-between;
+ justify-content: space-between
}
.nodeContent {
margin-right: 0.3em;
diff --git a/source/engine/mecanismViews/common.js b/source/engine/mecanismViews/common.js
index add8ea619..ef12ed632 100644
--- a/source/engine/mecanismViews/common.js
+++ b/source/engine/mecanismViews/common.js
@@ -63,12 +63,18 @@ export class Node extends Component {
)
) : (
- <>
+
{value !== true && value !== false && !isNil(value) && (
- =
+ =
)}
- >
+
)}
)
From a0e534324d53aaac42bfbc6aaf16fd204c208a27 Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 14:49:21 +0200
Subject: [PATCH 24/32] =?UTF-8?q?:art:=20Valeur=20des=20m=C3=A9ca=20:=20si?=
=?UTF-8?q?gne=20=3D=20en=20dehors=20de=20la=20bo=C3=AEte?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/engine/mecanismViews/common.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/source/engine/mecanismViews/common.js b/source/engine/mecanismViews/common.js
index ef12ed632..708dddd48 100644
--- a/source/engine/mecanismViews/common.js
+++ b/source/engine/mecanismViews/common.js
@@ -13,7 +13,7 @@ import mecanismColours from './colours'
import classnames from 'classnames'
import Value from 'Components/Value'
-export let NodeValuePointer = ({ data, unit, equalSign }) => (
+export let NodeValuePointer = ({ data, unit }) => (
(
line-height: 1.6em;
border-radius: 0.2rem;
`}>
- {equalSign && = }
)
@@ -59,7 +58,8 @@ export class Node extends Component {
{name ? (
!isNil(value) && (
-
+ =
+
)
) : (
From b72ec28108adbbb94f718ab9b6f3ca9b187c8e1d Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 14:51:27 +0200
Subject: [PATCH 25/32] :art: Marge inutile
Reliquat qui rendait l'affichage moche
---
source/components/rule/Header.css | 3 ---
1 file changed, 3 deletions(-)
diff --git a/source/components/rule/Header.css b/source/components/rule/Header.css
index b4adec5db..0f6ae4792 100644
--- a/source/components/rule/Header.css
+++ b/source/components/rule/Header.css
@@ -50,9 +50,6 @@
padding: 1em 2em;
}
-#ruleHeader #PeriodSwitch {
- margin: 0.3em 1em;
-}
#ruleHeader #PeriodSwitch img {
display: none;
}
From 9e80f2b36bddf070b164697033944091b108b050 Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 16:14:30 +0200
Subject: [PATCH 26/32] =?UTF-8?q?:fire:=20Type=20et=20p=C3=A9riode=20de=20?=
=?UTF-8?q?l'infobox,=20p=C3=A9riode=20pr=C3=A8s=20de=20valeur?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/components/PeriodSwitch.js | 8 +++---
source/components/rule/Header.js | 46 ++++++-------------------------
source/components/rule/Rule.css | 6 ----
source/components/rule/Rule.js | 41 +++++++++++++++++++++++++--
4 files changed, 51 insertions(+), 50 deletions(-)
diff --git a/source/components/PeriodSwitch.js b/source/components/PeriodSwitch.js
index d536666e6..a03983edb 100644
--- a/source/components/PeriodSwitch.js
+++ b/source/components/PeriodSwitch.js
@@ -52,8 +52,8 @@ export default compose(
return
})
return (
-
+
+
)
})
diff --git a/source/components/rule/Header.js b/source/components/rule/Header.js
index a2c938226..1be57ec85 100644
--- a/source/components/rule/Header.js
+++ b/source/components/rule/Header.js
@@ -1,9 +1,7 @@
-import PeriodSwitch from 'Components/PeriodSwitch'
import withColours from 'Components/utils/withColours'
import { path } from 'ramda'
import React from 'react'
import emoji from 'react-easy-emoji'
-import { Trans } from 'react-i18next'
import { capitalise0 } from '../../utils'
import { Markdown } from '../utils/markdown'
import Destinataire from './Destinataire'
@@ -21,8 +19,7 @@ let RuleHeader = withColours(
name,
title,
icon,
- colours,
- valuesToShow
+ colours
}) => (
)
diff --git a/source/components/rule/Rule.css b/source/components/rule/Rule.css
index 240583ca1..2bfa6c063 100644
--- a/source/components/rule/Rule.css
+++ b/source/components/rule/Rule.css
@@ -20,12 +20,6 @@ h2 small {
font-size: 75%;
}
-#rule #ruleValue {
- text-align: center;
- font-size: 200%;
- margin-bottom: 0.6em;
- margin-top: 0.4em;
-}
#rule #ruleDefault {
text-align: center;
diff --git a/source/components/rule/Rule.js b/source/components/rule/Rule.js
index f69279326..804551568 100644
--- a/source/components/rule/Rule.js
+++ b/source/components/rule/Rule.js
@@ -30,6 +30,7 @@ import Examples from './Examples'
import RuleHeader from './Header'
import References from './References'
import './Rule.css'
+import PeriodSwitch from 'Components/PeriodSwitch'
let LazySource = React.lazy(() => import('./RuleSource'))
@@ -64,8 +65,6 @@ export default compose(
let displayedRule = analysedExample || analysedRule
- console.log(displayedRule)
-
return (
<>
{this.state.viewSource ? (
@@ -103,7 +102,23 @@ export default compose(
/>
-
+
.value {
+ font-size: 220%;
+ }
+
+ margin: 0.6em 0;
+ > * {
+ margin: 0 0.6em;
+ }
+ `}>
+
{displayedRule.defaultValue != null && (
@@ -227,3 +246,19 @@ let NamespaceRulesList = compose(
)
})
+
+let Period = ({ period, valuesToShow }) =>
+ period ? (
+ valuesToShow && period === 'flexible' ? (
+
+ ) : (
+
+
+ {period}
+
+
+ )
+ ) : null
From 7ae3eaca6025c0d7d1a5693546ddb355fb6ed410 Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 16:28:40 +0200
Subject: [PATCH 27/32] =?UTF-8?q?:art:=20Espacement=20sous=20les=20noms=20?=
=?UTF-8?q?des=20m=C3=A9canismes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/components/rule/Algorithm.css | 1 -
source/engine/mecanismViews/common.js | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/source/components/rule/Algorithm.css b/source/components/rule/Algorithm.css
index f2a83e3cb..1b98a7ad9 100644
--- a/source/components/rule/Algorithm.css
+++ b/source/components/rule/Algorithm.css
@@ -180,7 +180,6 @@
}
.variable,
-.nodeHead,
.operator {
display: inline-block;
}
diff --git a/source/engine/mecanismViews/common.js b/source/engine/mecanismViews/common.js
index 708dddd48..cd1992694 100644
--- a/source/engine/mecanismViews/common.js
+++ b/source/engine/mecanismViews/common.js
@@ -43,7 +43,7 @@ export class Node extends Component {
className={classNames(classes, 'node', { inline })}
style={termDefinition ? { borderColor: mecanismColours(name) } : {}}>
{name && !inline && (
-
+
{name}
-
+
)}
{child}{' '}
{name ? (
From d940b54eacb19b54b02f2a15d920ca29ebde326a Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 16:39:43 +0200
Subject: [PATCH 28/32] =?UTF-8?q?:hammer:=20Plus=20d'unit=C3=A9s?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
source/règles/base.yaml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/source/règles/base.yaml b/source/règles/base.yaml
index c85f06c66..5e25bf302 100644
--- a/source/règles/base.yaml
+++ b/source/règles/base.yaml
@@ -1649,7 +1649,7 @@
question: Quel est l'effectif de l'entreprise ?
description: |
De nombreuses cotisations patronales varient selon l'effectif de l'entreprise.
- unité: _
+ unité: employés
suggestions:
1: 1
20: 20
@@ -4158,9 +4158,9 @@
- espace: protection sociale . retraite
nom: mois cotisés
+ unité: mois
formule: 172 * 3
notes: On prends l'hypotèse d'une retraite à taux plein pour un travailleur né en 1973 ou après
- unité: €
- espace: protection sociale . retraite
nom: complémentaire salarié
@@ -4182,12 +4182,14 @@
nom: points acquis
formule: points acquis par mois * mois cotisés
période: aucune
+ unité: points
références:
service-public.fr: https://www.service-public.fr/particuliers/vosdroits/F15396
- espace: protection sociale . retraite . complémentaire salarié
nom: points acquis par mois
période: mois
+ unité: points/mois
formule: contrat salarié . retraite complémentaire / prix d'achat du point
- espace: protection sociale . retraite . complémentaire salarié
From 1431c02f34ac4d978cba9f2ba5ce441e392e066d Mon Sep 17 00:00:00 2001
From: Mael
Date: Tue, 23 Jul 2019 18:28:09 +0200
Subject: [PATCH 29/32] Introduction du faux pourcentage (%)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Quand une variable est destinée à être saisie par l'utilisateur, on veut
qu'il saisisse 50, pas 0.5 pour exprimer 50%.
On pourrait lui faire saisir 50 et convertir en direct vers la vraie
valeur de 0.5, mais c'est compliqué aujourd'hui dans reduxForm
(l'attribut "normalize" ne suffit pas, car la valeur 0.5 sera visible
après un bref instant de debounce).
Je pense qu'il serai quand même mieux que nous stockions les variables
qui sont des ratios comme 0.5 et que l'UI se charge d'afficher et de
faire saisir ces valeurs sous forme 50%.
---
source/components/Value.js | 4 ++++
source/components/conversation/Input.js | 2 +-
source/engine/mecanisms/variations.js | 1 -
source/engine/units.js | 16 +++++++++++-----
source/règles/base.yaml | 10 +++++-----
test/mécanismes/multiplication.yaml | 2 +-
6 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/source/components/Value.js b/source/components/Value.js
index 6d21ecdb1..a158bdff1 100644
--- a/source/components/Value.js
+++ b/source/components/Value.js
@@ -80,6 +80,10 @@ export default withLanguage(
numberFormatter({ style: 'percent', maximumFractionDigits: 3 })(
nodeValue
)
+ ) : unitText === '(%)' ? (
+ numberFormatter({ style: 'percent', maximumFractionDigits: 3 })(
+ nodeValue / 100
+ )
) : (
<>
{numberFormatter({
diff --git a/source/components/conversation/Input.js b/source/components/conversation/Input.js
index 7319ff83a..518535545 100644
--- a/source/components/conversation/Input.js
+++ b/source/components/conversation/Input.js
@@ -55,7 +55,7 @@ export default compose(
/>
{suffixed && (
- {unit}
+ {unit === '(%)' ? '%' : unit}
{rulePeriod && (
{' '}
diff --git a/source/engine/mecanisms/variations.js b/source/engine/mecanisms/variations.js
index a2bee0173..e8c321fa3 100644
--- a/source/engine/mecanisms/variations.js
+++ b/source/engine/mecanisms/variations.js
@@ -77,7 +77,6 @@ export default (recurse, k, v, devariate) => {
missingVariables = satisfiedVariation
? collectNodeMissing(satisfiedVariation.consequence)
: mergeMissing(bonus(leftMissing), rightMissing)
- console.log(resolvedExplanation)
return rewriteNode(node, nodeValue, resolvedExplanation, missingVariables)
}
diff --git a/source/engine/units.js b/source/engine/units.js
index 295a742f8..96829f7b5 100644
--- a/source/engine/units.js
+++ b/source/engine/units.js
@@ -1,5 +1,6 @@
import { remove, isEmpty, unnest } from 'ramda'
+//TODO this function does not handle complex units like passenger-kilometer/flight
export let parseUnit = string => {
let [a, b = ''] = string.split('/'),
result = {
@@ -9,22 +10,27 @@ export let parseUnit = string => {
return result
}
+let printUnits = units => units.filter(unit => unit !== '%').join('-')
+
export let serialiseUnit = rawUnit => {
let unit = simplify(rawUnit),
{ numerators = [], denominators = [] } = unit
+
+ // the unit '%' is only displayed when it is the only unit
+ let merge = [...numerators, ...denominators]
+ if (merge.length === 1 && merge[0] === '%') return '%'
+
let n = !isEmpty(numerators)
let d = !isEmpty(denominators)
let string =
!n && !d
? ''
: n && !d
- ? numerators.join('')
+ ? printUnits(numerators)
: !n && d
- ? `/${denominators.join('')}`
- : `${numerators.join('')} / ${denominators.join('')}`
+ ? `/${printUnits(denominators)}`
+ : `${printUnits(numerators)} / ${printUnits(denominators)}`
- // the unit '%' is only displayed when it is the only unit
- if (string.length > 1) return string.replace(/%/g, '')
return string
}
diff --git a/source/règles/base.yaml b/source/règles/base.yaml
index 5e25bf302..16ed5358a 100644
--- a/source/règles/base.yaml
+++ b/source/règles/base.yaml
@@ -1667,10 +1667,10 @@
titre: Fraction d'alternants
description: |
Cette fraction détermine la contribution supplémentaire pour l'apprentissage pour les entreprises concernées.
- unité: '%'
+ unité: (%)
suggestions:
- 1: 1
- 5: 5
+ 1%: 1
+ 5%: 5
par défaut: 0
- espace: entreprise
@@ -2159,7 +2159,7 @@
nom: part employeur
description: Part de la complémentaire santé payée par l'employeur. Doit être de 50% minimum
question: Quel est la part de la complémentaire santé payée par l'employeur ?
- unité: '%'
+ unité: (%)
suggestions:
50%: 50
100%: 100
@@ -2172,7 +2172,7 @@
- espace: contrat salarié . complémentaire santé
nom: part salarié
description: Part de la complémentaire santé payée par l'employé. Ne peut pas être supérieure à 50%
- unité: '%'
+ unité: (%)
formule: 100 - part employeur
- espace: contrat salarié . complémentaire santé
diff --git a/test/mécanismes/multiplication.yaml b/test/mécanismes/multiplication.yaml
index 0e21faa6f..02ec7439a 100644
--- a/test/mécanismes/multiplication.yaml
+++ b/test/mécanismes/multiplication.yaml
@@ -76,7 +76,7 @@
plafond: mon plafond
taux: 0.5%
- unité attendue: €patates
+ unité attendue: €-patates
exemples:
- nom:
situation:
From a6c8372a3e672a019a9d5a6035f42b04079692ff Mon Sep 17 00:00:00 2001
From: Mael
Date: Wed, 24 Jul 2019 14:31:25 +0200
Subject: [PATCH 30/32] :fire: Note obsolete
---
source/règles/base.yaml | 1 -
1 file changed, 1 deletion(-)
diff --git a/source/règles/base.yaml b/source/règles/base.yaml
index 16ed5358a..4bcaf5a12 100644
--- a/source/règles/base.yaml
+++ b/source/règles/base.yaml
@@ -3660,7 +3660,6 @@
- espace: indépendant . cotisations et contributions . CSG et CRDS
nom: assiette
- note: Il faut vérifier que l'assiette de la CSG et CRDS est correcte. Pourquoi les cotisations sont-elles dans l'assiette ? La retraite complémentaire doit l'être aussi ?
période: flexible
formule:
somme:
From 18cbe0623f9438bd5b551258069e3893069ba7ea Mon Sep 17 00:00:00 2001
From: Mael
Date: Thu, 1 Aug 2019 18:10:22 +0200
Subject: [PATCH 31/32] On oublie cette histoire de faux pourcentages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduit au commit précédent, car je n'avais pas vu que l'option format
(couplée au normalize) de redux form existait.
---
source/components/Value.js | 4 ---
.../components/conversation/FormDecorator.js | 17 ++++++++--
source/components/conversation/Input.js | 1 -
source/règles/base.yaml | 31 +++++++++----------
4 files changed, 29 insertions(+), 24 deletions(-)
diff --git a/source/components/Value.js b/source/components/Value.js
index a158bdff1..6d21ecdb1 100644
--- a/source/components/Value.js
+++ b/source/components/Value.js
@@ -80,10 +80,6 @@ export default withLanguage(
numberFormatter({ style: 'percent', maximumFractionDigits: 3 })(
nodeValue
)
- ) : unitText === '(%)' ? (
- numberFormatter({ style: 'percent', maximumFractionDigits: 3 })(
- nodeValue / 100
- )
) : (
<>
{numberFormatter({
diff --git a/source/components/conversation/FormDecorator.js b/source/components/conversation/FormDecorator.js
index 6afc10a29..87a0555d2 100644
--- a/source/components/conversation/FormDecorator.js
+++ b/source/components/conversation/FormDecorator.js
@@ -35,12 +35,25 @@ export var FormDecorator = formType => RenderField =>
helpVisible: false
}
render() {
- let { stepAction, fieldName, inversion, setFormValue } = this.props
+ let {
+ stepAction,
+ fieldName,
+ inversion,
+ setFormValue,
+ unit
+ } = this.props
let submit = cause => stepAction('fold', fieldName, cause),
stepProps = {
...this.props,
submit,
- setFormValue: (value, name = fieldName) => setFormValue(name, value)
+ setFormValue: (value, name = fieldName) =>
+ setFormValue(name, value),
+ ...(unit === '%'
+ ? {
+ format: x => (x == null ? null : x * 100),
+ normalize: x => (x == null ? null : x / 100)
+ }
+ : {})
}
return (
diff --git a/source/components/conversation/Input.js b/source/components/conversation/Input.js
index 518535545..be4fd7eb2 100644
--- a/source/components/conversation/Input.js
+++ b/source/components/conversation/Input.js
@@ -55,7 +55,6 @@ export default compose(
/>
{suffixed && (
- {unit === '(%)' ? '%' : unit}
{rulePeriod && (
{' '}
diff --git a/source/règles/base.yaml b/source/règles/base.yaml
index 4bcaf5a12..7b62ca697 100644
--- a/source/règles/base.yaml
+++ b/source/règles/base.yaml
@@ -1657,20 +1657,17 @@
1000: 1000
par défaut: 1
-- espace: entreprise
- nom: ratio alternants
- formule: ratio alternants saisi / 100
- espace: entreprise
- nom: ratio alternants saisi
+ nom: ratio alternants
question: Quelle est la fraction de contrats d'alternance dans l'effectif moyen de l'entreprise ?
titre: Fraction d'alternants
description: |
Cette fraction détermine la contribution supplémentaire pour l'apprentissage pour les entreprises concernées.
- unité: (%)
+ unité: '%'
suggestions:
- 1%: 1
- 5%: 5
+ 1%: 0.1
+ 5%: 0.5
par défaut: 0
- espace: entreprise
@@ -2140,10 +2137,10 @@
# Répartition arbitraire, en sachant que l'employeur doit prendre en charge au minimum 50%
- attributs:
dû par: employeur
- taux: part employeur / 100
+ taux: part employeur
- attributs:
dû par: salarié
- taux: part salarié / 100
+ taux: part salarié
exemples:
- nom: forfait à 40€
situation:
@@ -2152,28 +2149,28 @@
- nom: forfait à 100€ payé par l'employeur
situation:
forfait: 100
- part employeur: 100
+ part employeur: 1
valeur attendue: 100
- espace: contrat salarié . complémentaire santé
nom: part employeur
description: Part de la complémentaire santé payée par l'employeur. Doit être de 50% minimum
question: Quel est la part de la complémentaire santé payée par l'employeur ?
- unité: (%)
+ unité: '%'
suggestions:
- 50%: 50
- 100%: 100
- par défaut: 50
+ 50%: 0.50
+ 100%: 1
+ par défaut: 0.50
contrôles:
- - si: part employeur < 50
+ - si: part employeur < 50%
niveau: avertissement
message: La part employeur de la complémentaire santé doit être de 50% au minimum
- espace: contrat salarié . complémentaire santé
nom: part salarié
description: Part de la complémentaire santé payée par l'employé. Ne peut pas être supérieure à 50%
- unité: (%)
- formule: 100 - part employeur
+ unité: '%'
+ formule: 100% - part employeur
- espace: contrat salarié . complémentaire santé
nom: forfait
From f0dd2ca416ff9273df5783b286303c091d95e9fd Mon Sep 17 00:00:00 2001
From: Mael
Date: Sat, 3 Aug 2019 15:30:19 +0200
Subject: [PATCH 32/32] =?UTF-8?q?Passer=20donne=20la=20valeur=20par=20d?=
=?UTF-8?q?=C3=A9faut,=20pas=20null?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes #610
---
source/actions/actions.js | 11 +++++----
.../components/conversation/Conversation.js | 23 +++++++++++++------
2 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/source/actions/actions.js b/source/actions/actions.js
index 395706a18..ea25b89e7 100644
--- a/source/actions/actions.js
+++ b/source/actions/actions.js
@@ -8,7 +8,7 @@ import type {
SetSituationBranchAction
} from 'Types/ActionsTypes'
// $FlowFixMe
-import { clearFields, reset } from 'redux-form'
+import { change, reset } from 'redux-form'
import { deletePersistedSimulation } from '../storage/persistSimulation'
import type { Thunk } from 'Types/ActionsTypes'
@@ -25,14 +25,15 @@ export const goToQuestion = (question: string): StepAction => ({
name: 'unfold',
step: question
})
-export const skipQuestion = (
- question: string
+export const validateStepWithValue = (
+ dottedName,
+ value: any
): Thunk => dispatch => {
- dispatch(clearFields('conversation', false, false, question))
+ dispatch(change('conversation', dottedName, value))
dispatch({
type: 'STEP_ACTION',
name: 'fold',
- step: question
+ step: dottedName
})
}
diff --git a/source/components/conversation/Conversation.js b/source/components/conversation/Conversation.js
index 70847684e..42e0547ff 100644
--- a/source/components/conversation/Conversation.js
+++ b/source/components/conversation/Conversation.js
@@ -1,4 +1,8 @@
-import { goToQuestion, resetSimulation, skipQuestion } from 'Actions/actions'
+import {
+ goToQuestion,
+ resetSimulation,
+ validateStepWithValue
+} from 'Actions/actions'
import { T } from 'Components'
import QuickLinks from 'Components/QuickLinks'
import { getInputComponent } from 'Engine/generateQuestions'
@@ -15,6 +19,7 @@ import {
import * as Animate from 'Ui/animate'
import Aide from './Aide'
import './conversation.css'
+import { findRuleByDottedName } from 'Engine/rules'
export default compose(
reduxForm({
@@ -28,7 +33,7 @@ export default compose(
previousAnswers: state.conversationSteps.foldedSteps,
nextSteps: nextStepsSelector(state)
}),
- { resetSimulation, skipQuestion, goToQuestion }
+ { resetSimulation, validateStepWithValue, goToQuestion }
)
)(function Conversation({
nextSteps,
@@ -37,14 +42,18 @@ export default compose(
customEndMessages,
flatRules,
resetSimulation,
- skipQuestion,
- goToQuestion
+ goToQuestion,
+ validateStepWithValue
}) {
- const goToNext = () => skipQuestion(nextSteps[0])
+ const setDefault = () =>
+ validateStepWithValue(
+ currentQuestion,
+ findRuleByDottedName(flatRules, currentQuestion).defaultValue
+ )
const goToPrevious = () => goToQuestion(previousAnswers.slice(-1)[0])
const handleKeyDown = ({ key }) => {
if (['Escape'].includes(key)) {
- goToNext()
+ setDefault()
}
}
return nextSteps.length ? (
@@ -67,7 +76,7 @@ export default compose(
>
)}
Passer →