⚙️ Pas de salaire manquant si un autre type de salaire est présent

pull/138/head
mama 2017-11-14 18:34:17 +01:00
parent 1bdf249aad
commit 4241f3d249
1 changed files with 51 additions and 41 deletions

View File

@ -106,7 +106,8 @@ let fillVariableNode = (rules, rule) => parseResult => {
variable = cached
? cached
: findRuleByDottedName(parsedRules, dottedName),
variableIsCalculable = variable.formule != null,
inversion = findInversion(situation, parsedRules, variable),
variableIsCalculable = variable.formule != null || inversion != null,
parsedRule =
variableIsCalculable &&
(cached ? cached : evaluateNode(situation, parsedRules, variable)),
@ -115,9 +116,9 @@ let fillVariableNode = (rules, rule) => parseResult => {
nodeValue =
situationValue != null
? situationValue // cette variable a été directement renseignée
: !variableIsCalculable
? null // pas moyen de calculer car il n'y a pas de formule, elle restera donc nulle
: parsedRule.nodeValue, // la valeur du calcul fait foi
: variableIsCalculable
? parsedRule.nodeValue // la valeur du calcul fait foi
: null, // elle restera donc nulle
explanation = parsedRule,
missingVariables = variableIsCalculable ? [] : [dottedName]
@ -424,44 +425,53 @@ export let findInversion = (situationGate, rules, rule) => {
}
}
let doInversion = (situationGate, parsedRules, r) => {
let inversion = findInversion(situationGate, parsedRules, r)
if (!inversion) return null
let { fixedObjectiveValue, fixedObjectiveRule } = inversion
let fx = x =>
evaluateNode(
n => (r.dottedName === n || n === 'sys.filter' ? x : situationGate(n)),
parsedRules,
fixedObjectiveRule
).nodeValue
// si fx renvoie null pour une valeur numérique standard, disons 1000, on peut
// considérer que l'inversion est impossible du fait de variables manquantes
// TODO fx peut être null pour certains x, et valide pour d'autres : on peut implémenter ici le court-circuit
if (fx(1000) == null)
return {
nodeValue: null,
inversionMissingVariables: collectNodeMissing(
evaluateNode(
n =>
r.dottedName === n || n === 'sys.filter' ? 1000 : situationGate(n),
parsedRules,
fixedObjectiveRule
)
)
}
let tolerancePercentage = 0.00001,
// cette fonction détermine la racine d'une fonction sans faire trop d'itérations
nodeValue = uniroot(
x => fx(x) - fixedObjectiveValue,
0,
1000000000,
tolerancePercentage * fixedObjectiveValue,
100
)
return {
nodeValue
}
}
export let treatRuleRoot = (rules, rule) => {
let evaluate = (situationGate, parsedRules, r) => {
let inversion = findInversion(situationGate, parsedRules, r)
if (inversion) {
let { fixedObjectiveValue, fixedObjectiveRule } = inversion
let fx = x =>
evaluateNode(
n => r.dottedName === n || n === 'sys.filter' ? x : situationGate(n),
parsedRules,
fixedObjectiveRule
).nodeValue,
tolerancePercentage = 0.00001,
// cette fonction détermine la racine d'une fonction sans faire trop d'itérations
nodeValue = uniroot(
x => fx(x) - fixedObjectiveValue,
0,
1000000000,
tolerancePercentage * fixedObjectiveValue,
100
)
// si fx renvoie null pour une valeur numérique standard, disons 1000, on peut
// considérer que l'inversion est impossible du fait de variables manquantes
// TODO fx peut être null pour certains x, et valide pour d'autres : on peut implémenter ici le court-circuit
return fx(1000) == null
? {
...r,
nodeValue: null,
inversionMissingVariables: collectNodeMissing(
evaluateNode(
n => r.dottedName === n || n === 'sys.filter' ? 1000 : situationGate(n),
parsedRules,
fixedObjectiveRule
)
)
}
: { ...r, nodeValue }
}
let inversion = situationGate(r.dottedName) == undefined // avoid the inversion loop !
&& doInversion(situationGate, parsedRules, r)
if (inversion) return { ...r, ...inversion }
let evolveRule = R.curry(evaluateNode)(situationGate, parsedRules),
evaluated = R.evolve(
@ -617,8 +627,8 @@ export let getTargets = (target, rules) => {
export let analyse = (rules, targetInput) => situationGate => {
clearDict()
let
targetNames = typeof targetInput === 'string' ? [targetInput] : targetInput,
let targetNames =
typeof targetInput === 'string' ? [targetInput] : targetInput,
/*
La fonction treatRuleRoot va descendre l'arbre de la règle `rule` et produire un AST, un objet contenant d'autres objets contenant d'autres objets...
Aujourd'hui, une règle peut avoir (comme propriétés à parser) `non applicable si` et `formule`,