1
0
Fork 0
mirror of https://github.com/betagouv/mon-entreprise synced 2025-02-11 00:25:02 +00:00
mon-entreprise/source/engine/evaluateRule.ts
Alexandre Hajjar 4f882e3727 Eslint, prettier and tsc fixes
* eslint fixes batch
* fix @typescript-eslint/camelcase (=> warn)
* fix @typescript-eslint/consistent-type-assertions
* fix no-prototype-builtins
* @typescript-eslint/prefer-string-starts-ends-with => warn
* fix @typescript-eslint/prefer-regexp-exec
* fix prefer-const
* fix no-case-declarations
* fix @typescript-eslint/no-var-requires
* fix react/jsx-key
* fix react-hooks/rules-of-hooks
* fix typescript errors following eslint fixes. Includes downgrading:
** @typescript-eslint/no-unnecessary-type-assertion
** @typescript-eslint/no-inferrable-types
* apply prettier
* use `object` type whenever possible
2020-05-05 18:24:14 +02:00

120 lines
3.1 KiB
TypeScript

import { bonus, evaluateNode, mergeMissing } from 'Engine/evaluation'
import { ParsedRule } from 'Engine/types'
import { map, mergeAll, pick, pipe } from 'ramda'
import { typeWarning } from './error'
import { convertNodeToUnit } from './nodeUnits'
export const evaluateApplicability = (
cache,
situationGate,
parsedRules,
node: ParsedRule
) => {
const evaluatedAttributes = pipe(
pick(['non applicable si', 'applicable si', 'rendu non applicable']) as (
x: any
) => any,
map(value => evaluateNode(cache, situationGate, parsedRules, value))
)(node) as any,
{
'non applicable si': notApplicable,
'applicable si': applicable,
'rendu non applicable': disabled
} = evaluatedAttributes,
parentDependencies = node.parentDependencies.map(parent =>
evaluateNode(cache, situationGate, parsedRules, parent)
),
isApplicable =
parentDependencies.some(parent => parent?.nodeValue === false) ||
notApplicable?.nodeValue === true ||
applicable?.nodeValue === false ||
disabled?.nodeValue === true
? false
: [notApplicable, applicable, ...parentDependencies].some(
n => n?.nodeValue === null
)
? null
: !notApplicable?.nodeValue &&
(applicable?.nodeValue == undefined || !!applicable?.nodeValue),
missingVariables =
isApplicable === false
? {}
: mergeAll([
...parentDependencies.map(parent => parent.missingVariables),
notApplicable?.missingVariables || {},
disabled?.missingVariables || {},
applicable?.missingVariables || {}
])
return {
...node,
isApplicable,
nodeValue: isApplicable,
missingVariables,
parentDependencies,
...evaluatedAttributes
}
}
export default (cache, situationGate, parsedRules, node) => {
cache._meta.contextRule.push(node.dottedName)
const applicabilityEvaluation = evaluateApplicability(
cache,
situationGate,
parsedRules,
node
)
const {
missingVariables: condMissing,
nodeValue: isApplicable
} = applicabilityEvaluation
const evaluateFormula = () =>
node.formule
? evaluateNode(cache, situationGate, parsedRules, node.formule)
: {}
// evaluate the formula lazily, only if the applicability is known and true
let evaluatedFormula = isApplicable
? evaluateFormula()
: isApplicable === false
? {
...node.formule,
missingVariables: {},
nodeValue: 0
}
: {
...node.formule,
missingVariables: {},
nodeValue: null
}
if (node.unit) {
try {
evaluatedFormula = convertNodeToUnit(node.unit, evaluatedFormula)
} catch (e) {
typeWarning(
node.dottedName,
"L'unité de la règle est incompatible avec celle de sa formule",
e
)
}
}
const missingVariables = mergeMissing(
bonus(condMissing, !!Object.keys(condMissing).length),
evaluatedFormula.missingVariables
)
// console.log(node.dottedName, evaluatedFormula.unit)
const temporalValue = evaluatedFormula.temporalValue
cache._meta.contextRule.pop()
return {
...node,
...applicabilityEvaluation,
...(node.formule && { formule: evaluatedFormula }),
nodeValue: evaluatedFormula.nodeValue,
unit: node.unit ?? evaluatedFormula.unit,
temporalValue,
isApplicable,
missingVariables
}
}