mon-entreprise/source/engine/evaluateRule.js

96 lines
2.5 KiB
JavaScript
Raw Normal View History

2019-07-29 07:13:05 +00:00
import { bonus, evaluateNode, mergeMissing } from 'Engine/evaluation'
import { map, mergeAll, pick, pipe } from 'ramda'
2019-11-07 11:34:03 +00:00
import { anyNull, undefOrTruthy, val } from './traverse-common-functions'
export const evaluateApplicability = (
cache,
situationGate,
parsedRules,
node
) => {
let evaluatedAttributes = pipe(
2019-11-07 11:34:03 +00:00
pick(['non applicable si', 'applicable si', 'rendu non applicable']),
map(value => evaluateNode(cache, situationGate, parsedRules, value))
)(node),
{
'non applicable si': notApplicable,
2019-07-29 07:13:05 +00:00
'applicable si': applicable,
'rendu non applicable': disabled
} = evaluatedAttributes,
2019-11-07 11:34:03 +00:00
parentDependencies = node.parentDependencies.map(parent =>
evaluateNode(cache, situationGate, parsedRules, parent)
),
isApplicable =
2019-11-07 11:34:03 +00:00
parentDependencies.some(parent => val(parent) === false) ||
val(notApplicable) === true ||
val(applicable) === false ||
val(disabled) === true
? false
2019-11-07 11:34:03 +00:00
: anyNull([notApplicable, applicable, ...parentDependencies])
? null
2019-11-07 11:34:03 +00:00
: !val(notApplicable) && undefOrTruthy(val(applicable)),
missingVariables =
isApplicable === false
? {}
: mergeAll([
2019-11-07 11:34:03 +00:00
...parentDependencies.map(parent => parent.missingVariables),
notApplicable?.missingVariables || {},
applicable?.missingVariables || {}
])
return {
nodeValue: isApplicable,
missingVariables,
2019-11-07 11:34:03 +00:00
...evaluatedAttributes
}
}
export default (cache, situationGate, parsedRules, node) => {
cache.parseLevel++
let applicabilityEvaluation = evaluateApplicability(
cache,
situationGate,
parsedRules,
node
),
{
missingVariables: condMissing,
nodeValue: isApplicable
} = applicabilityEvaluation,
evaluateFormula = () =>
node.formule
? evaluateNode(cache, situationGate, parsedRules, node.formule)
: {},
// evaluate the formula lazily, only if the applicability is known and true
evaluatedFormula = isApplicable
? evaluateFormula()
: isApplicable === false
? {
...node.formule,
missingVariables: {},
nodeValue: 0
}
: {
...node.formule,
missingVariables: {},
nodeValue: null
},
{ missingVariables: formulaMissingVariables, nodeValue } = evaluatedFormula,
missingVariables = mergeMissing(
bonus(condMissing, !!Object.keys(condMissing).length),
formulaMissingVariables
)
cache.parseLevel--
if (node.dottedName.startsWith('sum')) {
// console.log(node.dottedName, missingVariables, node)
}
return {
...node,
...applicabilityEvaluation,
...{ formule: evaluatedFormula },
nodeValue,
isApplicable,
missingVariables
}
}