2018-01-08 15:07:26 +00:00
import {
2018-04-12 13:43:02 +00:00
add ,
2018-01-08 15:07:26 +00:00
map ,
pluck ,
any ,
equals ,
reduce ,
2018-04-12 13:43:02 +00:00
mergeWith ,
2018-01-08 15:07:26 +00:00
fromPairs ,
keys ,
values ,
evolve ,
2019-01-14 14:14:57 +00:00
filter ,
is
2018-01-08 15:07:26 +00:00
} from 'ramda'
2017-07-13 10:25:46 +00:00
2017-07-31 16:16:25 +00:00
export let makeJsx = node =>
2018-01-03 15:54:19 +00:00
typeof node . jsx == 'function'
2017-07-31 16:16:25 +00:00
? node . jsx ( node . nodeValue , node . explanation )
: node . jsx
2017-07-13 19:55:59 +00:00
2018-04-12 13:43:02 +00:00
export let collectNodeMissing = node => node . missingVariables || { }
2018-06-29 13:46:42 +00:00
export let bonus = ( missings , hasCondition = true ) =>
hasCondition ? map ( x => x + 0.0001 , missings || { } ) : missings
export let mergeAllMissing = missings =>
reduce ( mergeWith ( add ) , { } , map ( collectNodeMissing , missings ) )
export let mergeMissing = ( left , right ) =>
mergeWith ( add , left || { } , right || { } )
2017-07-13 10:25:46 +00:00
2017-12-12 19:10:22 +00:00
export let evaluateNode = ( cache , situationGate , parsedRules , node ) =>
node . evaluate ? node . evaluate ( cache , situationGate , parsedRules , node ) : node
2017-07-13 10:25:46 +00:00
2018-04-10 12:13:37 +00:00
export let rewriteNode = ( node , nodeValue , explanation , missingVariables ) => ( {
2018-01-03 15:54:19 +00:00
... node ,
nodeValue ,
2018-04-10 11:00:03 +00:00
explanation ,
2018-04-10 12:13:37 +00:00
missingVariables
2018-01-03 15:54:19 +00:00
} )
export let evaluateArray = ( reducer , start ) => (
cache ,
situationGate ,
parsedRules ,
node
) => {
let evaluateOne = child =>
evaluateNode ( cache , situationGate , parsedRules , child ) ,
2018-01-08 15:07:26 +00:00
explanation = map ( evaluateOne , node . explanation ) ,
values = pluck ( 'nodeValue' , explanation ) ,
nodeValue = any ( equals ( null ) , values )
2018-01-03 15:54:19 +00:00
? null
2018-04-10 11:00:03 +00:00
: reduce ( reducer , start , values ) ,
2018-06-29 13:46:42 +00:00
missingVariables =
node . nodeValue == null ? mergeAllMissing ( explanation ) : { }
// console.log("".padStart(cache.parseLevel), missingVariables)
2018-04-10 12:27:25 +00:00
return rewriteNode ( node , nodeValue , explanation , missingVariables )
2017-07-16 21:58:06 +00:00
}
2018-01-08 15:07:26 +00:00
export let evaluateArrayWithFilter = ( evaluationFilter , reducer , start ) => (
2018-01-03 15:54:19 +00:00
cache ,
situationGate ,
parsedRules ,
node
) => {
let evaluateOne = child =>
evaluateNode ( cache , situationGate , parsedRules , child ) ,
2018-01-08 15:07:26 +00:00
explanation = map (
2018-01-03 15:54:19 +00:00
evaluateOne ,
2018-01-08 15:07:26 +00:00
filter ( evaluationFilter ( situationGate ) , node . explanation )
2018-01-03 15:54:19 +00:00
) ,
2018-01-08 15:07:26 +00:00
values = pluck ( 'nodeValue' , explanation ) ,
nodeValue = any ( equals ( null ) , values )
2018-01-03 15:54:19 +00:00
? null
2018-04-10 11:00:03 +00:00
: reduce ( reducer , start , values ) ,
2018-06-29 13:46:42 +00:00
missingVariables =
node . nodeValue == null ? mergeAllMissing ( explanation ) : { }
2017-07-13 10:25:46 +00:00
2018-04-10 12:27:25 +00:00
return rewriteNode ( node , nodeValue , explanation , missingVariables )
2017-07-13 10:25:46 +00:00
}
export let parseObject = ( recurse , objectShape , value ) => {
let recurseOne = key => defaultValue => {
2018-12-05 17:58:38 +00:00
if ( ! value [ key ] && ! defaultValue )
throw new Error (
` Il manque une valeur ' ${ key } ' dans ${ JSON . stringify ( value ) } `
)
2018-01-03 15:54:19 +00:00
return value [ key ] ? recurse ( value [ key ] ) : defaultValue
}
2018-01-08 15:07:26 +00:00
let transforms = fromPairs ( map ( k => [ k , recurseOne ( k ) ] , keys ( objectShape ) ) )
return evolve ( transforms , objectShape )
2017-07-13 10:25:46 +00:00
}
2018-01-03 15:54:19 +00:00
export let evaluateObject = ( objectShape , effect ) => (
cache ,
situationGate ,
parsedRules ,
node
) => {
let evaluateOne = child =>
2018-06-29 13:46:42 +00:00
evaluateNode ( cache , situationGate , parsedRules , child )
2017-07-13 10:25:46 +00:00
2018-01-08 15:07:26 +00:00
let transforms = map ( k => [ k , evaluateOne ] , keys ( objectShape ) ) ,
2019-01-14 14:14:57 +00:00
automaticExplanation = evolve ( fromPairs ( transforms ) ) ( node . explanation )
// the result of effect can either be just a nodeValue, or an object {additionalExplanation, nodeValue}. The latter is useful for a richer JSX visualisation of the mecanism : the view should not duplicate code to recompute intermediate values (e.g. for a marginal 'barème', the marginal 'tranche')
let evaluated = effect ( automaticExplanation ) ,
explanation = is ( Object , evaluated )
? { ... automaticExplanation , ... evaluated . additionalExplanation }
: automaticExplanation ,
nodeValue = is ( Object , evaluated ) ? evaluated . nodeValue : evaluated ,
2018-04-12 13:43:02 +00:00
missingVariables = mergeAllMissing ( values ( explanation ) )
2018-06-29 13:46:42 +00:00
// console.log("".padStart(cache.parseLevel),map(node => length(flatten(collectNodeMissing(node))) ,explanation))
2018-04-10 12:27:25 +00:00
return rewriteNode ( node , nodeValue , explanation , missingVariables )
2017-07-13 10:25:46 +00:00
}