⚙️ Implémentation des contrôles a posteriori
parent
f9580f15b5
commit
05845db5e6
|
@ -73,6 +73,7 @@
|
|||
"test-watch": "yarn test-common --watch",
|
||||
"test-common": "mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --include componentTestSetup.js --require mock-local-storage --require test/helpers/browser.js \"./{,!(node_modules)/**/}!(webpack).test.js\"",
|
||||
"test": "yarn test-common",
|
||||
"test-one": "yarn mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --include componentTestSetup.js --require mock-local-storage --require test/helpers/browser.js",
|
||||
"test-components": "mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --include componentTestSetup.js --require mock-local-storage ---require test/helpers/browser.js \"source/components/**/*.test.js\" --watch",
|
||||
"test-lib": "yarn test-common --grep 'library'",
|
||||
"compile-lib": "yarn webpack --config source/webpack.lib.js",
|
||||
|
|
|
@ -58,14 +58,12 @@ export default compose(
|
|||
)(
|
||||
class TargetSelection extends Component {
|
||||
render() {
|
||||
let { colours, analysis, progress } = this.props
|
||||
let { colours, noUserInput, analysis, progress } = this.props
|
||||
|
||||
return (
|
||||
<div id="targetSelection">
|
||||
<QuickLinks />
|
||||
<Controls
|
||||
controls={chain(({ contrôles }) => contrôles, analysis.cache)}
|
||||
/>
|
||||
{!noUserInput && <Controls controls={analysis.controls} />}
|
||||
<div style={{ height: '10px' }}>
|
||||
<Progress percent={progress} />
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import { evaluateNode } from 'Engine/evaluation'
|
||||
import { values, unnest, filter, map, pipe, path } from 'ramda'
|
||||
|
||||
let getControls = path(['explanation', 'contrôles'])
|
||||
export let evaluateControls = (cache, situationGate, parsedRules) =>
|
||||
pipe(
|
||||
values,
|
||||
filter(getControls),
|
||||
map(rule =>
|
||||
getControls(rule).map(
|
||||
control =>
|
||||
!rule.inactiveParent && {
|
||||
...control,
|
||||
evaluated: evaluateNode(
|
||||
cache,
|
||||
situationGate,
|
||||
parsedRules,
|
||||
control.testExpression
|
||||
)
|
||||
}
|
||||
)
|
||||
),
|
||||
unnest,
|
||||
filter(control => control.evaluated.nodeValue === true)
|
||||
)(cache)
|
|
@ -30,6 +30,7 @@ import {
|
|||
} from './evaluation'
|
||||
import { anyNull, val, undefOrTrue } from './traverse-common-functions'
|
||||
import { ShowValuesConsumer } from 'Components/rule/ShowValuesContext'
|
||||
import { evaluateControls } from 'Engine/controls'
|
||||
|
||||
/*
|
||||
Dans ce fichier, les règles YAML sont parsées.
|
||||
|
@ -86,7 +87,7 @@ export let treat = (rules, rule) => rawNode => {
|
|||
export let treatRuleRoot = (rules, rule) => {
|
||||
/*
|
||||
The treatRuleRoot function will traverse the tree of the `rule` and produce an AST, an object containing other objects containing other objects...
|
||||
Some of the attributes of the rule are dynamic, they need to be parsed. It is the case of `non applicable si`, `applicable si`, `formule`, `contrôles`.
|
||||
Some of the attributes of the rule are dynamic, they need to be parsed. It is the case of `non applicable si`, `applicable si`, `formule`.
|
||||
These attributes' values themselves may have mechanism properties (e. g. `barème`) or inline expressions (e. g. `maVariable + 3`).
|
||||
These mechanisms or variables are in turn traversed by `treat()`. During this processing, 'evaluate' and'jsx' functions are attached to the objects of the AST. They will be evaluated during the evaluation phase, called "analyse".
|
||||
*/
|
||||
|
@ -159,20 +160,6 @@ export let treatRuleRoot = (rules, rule) => {
|
|||
formulaMissingVariables
|
||||
)
|
||||
|
||||
let evaluateControls = node.contrôles && val(parentDependency) !== false
|
||||
console.log(node.name, evaluateControls)
|
||||
let contrôles =
|
||||
evaluateControls &&
|
||||
node.contrôles.map(control => ({
|
||||
...control,
|
||||
evaluated: evaluateNode(
|
||||
cache,
|
||||
situationGate,
|
||||
parsedRules,
|
||||
control.testExpression
|
||||
)
|
||||
}))
|
||||
|
||||
cache.parseLevel--
|
||||
// if (keys(condMissing).length) console.log("".padStart(cache.parseLevel-1),{conditions:condMissing, formule:formMissing})
|
||||
// else console.log("".padStart(cache.parseLevel-1),{formule:formMissing})
|
||||
|
@ -180,10 +167,10 @@ export let treatRuleRoot = (rules, rule) => {
|
|||
...node,
|
||||
...evaluatedAttributes,
|
||||
...{ formule: evaluatedFormula },
|
||||
contrôles,
|
||||
nodeValue,
|
||||
isApplicable,
|
||||
missingVariables
|
||||
missingVariables,
|
||||
inactiveParent: parentDependency && val(parentDependency) == false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +345,9 @@ export let analyseMany = (parsedRules, targetNames) => situationGate => {
|
|||
cache[t.dottedName] || // This check exists because it is not done in treatRuleRoot's eval, while it is in treatVariable. This should be merged : we should probably call treatVariable here : targetNames could be expressions (hence with filters) TODO
|
||||
evaluateNode(cache, situationGate, parsedRules, t)
|
||||
)
|
||||
return { targets, cache }
|
||||
|
||||
let controls = evaluateControls(cache, situationGate, parsedRules)
|
||||
return { targets, cache, controls }
|
||||
}
|
||||
|
||||
export let analyse = (parsedRules, target) => {
|
||||
|
|
|
@ -25,11 +25,10 @@ export let treatVariable = (rules, rule, filter) => parseResult => {
|
|||
variable['non applicable si'] != null,
|
||||
situationValue = getSituationValue(situation, dottedName, variable),
|
||||
needsEvaluation =
|
||||
variable['contrôles'] ||
|
||||
(situationValue == null &&
|
||||
(variableHasCond ||
|
||||
variableHasFormula ||
|
||||
findParentDependency(rules, variable)))
|
||||
situationValue == null &&
|
||||
(variableHasCond ||
|
||||
variableHasFormula ||
|
||||
findParentDependency(rules, variable))
|
||||
|
||||
// if (dottedName.includes('jeune va')) debugger
|
||||
|
||||
|
|
|
@ -58,14 +58,30 @@ describe('controls', function() {
|
|||
})
|
||||
|
||||
it('Should allow imbricated conditions', function() {
|
||||
let situationGate = dottedName => ({ brut: 2000000 }[dottedName]),
|
||||
cache = analyseMany(parsedRules, ['net'])(situationGate).cache,
|
||||
controls = chain(prop('contrôles'), values(cache))
|
||||
|
||||
let controls = analyseMany(parsedRules, ['net'])(
|
||||
dottedName => ({ brut: 2000000 }[dottedName])
|
||||
).controls
|
||||
expect(
|
||||
controls.find(
|
||||
({ message }) => message === 'Vous êtes un contribuable hors-pair !'
|
||||
)
|
||||
).to.exist
|
||||
|
||||
let controls2 = analyseMany(parsedRules, ['net'])(
|
||||
dottedName => ({ brut: 100001 }[dottedName])
|
||||
).controls
|
||||
expect(controls2.find(({ message }) => message === 'Oulah ! Oulah !')).to
|
||||
.exist
|
||||
|
||||
let controls3 = analyseMany(parsedRules, ['net'])(
|
||||
dottedName => ({ brut: 100 }[dottedName])
|
||||
).controls
|
||||
expect(
|
||||
controls3.find(
|
||||
({ message }) =>
|
||||
message ===
|
||||
'Malheureux, je crois que vous vous êtes trompé dans votre saisie.'
|
||||
)
|
||||
).to.exist
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue