diff --git a/règles/rémunération-travail/cdd/CIF.yaml b/règles/rémunération-travail/cdd/CIF.yaml index 6d151af45..1355b4017 100644 --- a/règles/rémunération-travail/cdd/CIF.yaml +++ b/règles/rémunération-travail/cdd/CIF.yaml @@ -7,10 +7,10 @@ non applicable si: une de ces conditions: - - événement . poursuite du CDD en CDI + - événement = 'poursuite du CDD en CDI' - contrat jeune vacances - - motif . classique . saisonnier - - motif . contrat aidé + - motif = 'saisonnier' + - motif = 'contrat aidé' formule: multiplication: diff --git a/règles/rémunération-travail/cdd/indemnité_fin_contrat.yaml b/règles/rémunération-travail/cdd/indemnité_fin_contrat.yaml index 14f951131..f44cf5229 100644 --- a/règles/rémunération-travail/cdd/indemnité_fin_contrat.yaml +++ b/règles/rémunération-travail/cdd/indemnité_fin_contrat.yaml @@ -13,18 +13,18 @@ non applicable si: une de ces conditions: # Evènements particuliers - - événement . poursuite du CDD en CDI - - événement . refus CDI avantageux + - événement = 'poursuite du CDD en CDI' + - événement = 'refus CDI avantageux' # Rupture TODO regrouper celà dans une nouvelle variante - - événement . rupture anticipée salarié - - événement . rupture pour faute grave ou force majeure - - événement . rupture pendant période essai + - événement = 'rupture anticipée salarié' + - événement = 'rupture pour faute grave ou force majeure' + - événement = 'rupture pendant période essai' - - motif . classique . usage - - motif . classique . saisonnier - - motif . complément formation - - motif . contrat aidé + - motif = 'usage' + - motif = 'saisonnier' + - motif = 'complément formation' + - motif = 'contrat aidé' - contrat jeune vacances diff --git a/règles/rémunération-travail/cdd/majoration-chomage.yaml b/règles/rémunération-travail/cdd/majoration-chomage.yaml index 432257427..769796cf3 100644 --- a/règles/rémunération-travail/cdd/majoration-chomage.yaml +++ b/règles/rémunération-travail/cdd/majoration-chomage.yaml @@ -10,7 +10,7 @@ non applicable si: une de ces conditions: - durée contrat > 3 #cette information est déjà contenue dans la formule, mais ça ne fait pas de mal de l'expliciter ici - - événement . poursuite du CDD en CDI + - événement = 'poursuite du CDD en CDI' formule: multiplication: @@ -18,10 +18,10 @@ plafond: 4 * plafond sécurité sociale taux: aiguillage numérique: - motif . classique . accroissement activité: + motif = 'accroissement activité': durée contrat <= 1: 3% # TODO 1 mois, pas 1 rien, évidemment durée contrat <= 3: 1.5% - motif . classique . usage: + motif = 'usage': durée contrat <= 3: 0.5% diff --git a/règles/rémunération-travail/entités/ok/CDD.événements.yaml b/règles/rémunération-travail/entités/ok/CDD.événements.yaml index 48285fad8..608e86aa6 100644 --- a/règles/rémunération-travail/entités/ok/CDD.événements.yaml +++ b/règles/rémunération-travail/entités/ok/CDD.événements.yaml @@ -24,6 +24,7 @@ nom: poursuite du CDD en CDI titre: Poursuite du CDD en CDI description: En fin de contrat, le CDD est reconduit en CDI sans interruption. + formule: contrat salarié . CDD . événement = 'poursuite du CDD en CDI' # TODO quand cette variable est appelée par une autre variable, # on devrait pouvoir poser la question, puis proposer un bouton qui permette d'aider l'utilisateur à # y répondre, en lui expliquant la formule suivante : @@ -37,19 +38,23 @@ nom: refus CDI avantageux titre: Refus d'un CDI avantageux description: Le salarié, au terme du CDD, refuse une reconduction en CDI pour un emploi similaire, et une rémunération au moins aussi avantageuse. + formule: contrat salarié . CDD . événement = 'refus CDI avantageux' - espace: contrat salarié . CDD . événement nom: rupture anticipée salarié titre: Rupture anticipée du salarié description: Rupture anticipée du contrat à l'initiative du salarié. + formule: contrat salarié . CDD . événement = 'rupture anticipée salarié' # ces variables peuvent être attachées à un groupe ruptures pour plus de clarté - espace: contrat salarié . CDD . événement nom: rupture pour faute grave ou force majeure titre: Rupture pour faute grave ou force majeure + formule: contrat salarié . CDD . événement = 'rupture pour faute grave ou force majeure' # ces variables peuvent être attachées à un groupe ruptures pour plus de clarté - espace: contrat salarié . CDD . événement nom: rupture pendant période essai titre: Rupture pendant la période d'essai + formule: contrat salarié . CDD . événement = 'rupture pendant période essai' # ces variables peuvent être attachées à un groupe ruptures pour plus de clarté diff --git a/source/engine/grammar.ne b/source/engine/grammar.ne index 362600b19..103c04153 100644 --- a/source/engine/grammar.ne +++ b/source/engine/grammar.ne @@ -16,7 +16,7 @@ Comparison -> Comparable _ ComparisonOperator _ Comparable {% d => ({ explanation: [d[0], d[4]] }) %} -Comparable -> (int | CalcExpression | Variable) {% d => d[0][0] %} +Comparable -> (int | CalcExpression | Variable | Constant) {% d => d[0][0] %} ComparisonOperator -> ">" | "<" | ">=" | "<=" | "=" @@ -61,6 +61,11 @@ Variable -> VariableFragment (_ Dot _ VariableFragment {% d => d[3] %}):* {% d type: 'numeric | boolean' }) %} +Constant -> "'" [a-zA-Z\u00C0-\u017F ]:+ "'" {% d => ({ + category: 'value', + type: 'string', + nodeValue: d[1].join('') +}) %} VariableFragment -> VariableWord (_ VariableWord {% d=> ' ' + d[1] %}):* {% d => d[0] + d[1].join('') %} @@ -72,4 +77,4 @@ Dot -> [\.] {% d => null %} _ -> [\s] {% d => null %} -int -> [0-9]:+ {% d => ({category: 'value', nodeValue: +d[0].join("")}) %} +int -> [0-9]:+ {% d => ({category: 'value', nodeValue: parseInt(+d[0].join(""))}) %} diff --git a/source/engine/traverse.js b/source/engine/traverse.js index 61e8c0c22..a9f03e1b1 100644 --- a/source/engine/traverse.js +++ b/source/engine/traverse.js @@ -79,7 +79,7 @@ let fillVariableNode = (rules, rule) => (parseResult) => { cached = dict[cacheName], // make parsedRules a dict object, that also serves as a cache of evaluation ? variable = cached ? cached : findRuleByDottedName(parsedRules, dottedName), - variableIsCalculable = variable.formule != null, + variableIsCalculable = variable.formule != null && !R.path(['formule', 'explanation', 'une possibilité'])(variable), parsedRule = variableIsCalculable && (cached ? cached : evaluateNode( situation, @@ -200,7 +200,8 @@ let treat = (rules, rule) => rawNode => { '<': 'lt', '<=': 'lte', '>': 'gt', - '>=': 'gte' + '>=': 'gte', + '=': 'equal' }[node.operator], explanation = R.map(R.curry(evaluateNode)(situation,parsedRules),node.explanation), value1 = explanation[0].nodeValue, @@ -223,7 +224,7 @@ let treat = (rules, rule) => rawNode => { [R.propEq('category', 'filteredVariable'), fillFiltered], [R.propEq('category', 'value'), node => ({ - evaluate: (situation, parsedRules, me) => ({...me, nodeValue: parseInt(node.nodeValue)}), + evaluate: (situation, parsedRules, me) => ({...me, nodeValue: node.nodeValue}), jsx: nodeValue => {nodeValue} }) ] @@ -293,7 +294,7 @@ let treat = (rules, rule) => rawNode => { 'le maximum de': mecanismMax, 'le minimum de': mecanismMin, 'complément': mecanismComplement, - 'une possibilité': R.always({}) + 'une possibilité': R.always({'une possibilité':'oui'}) }, action = R.propOr(mecanismError, k, dispatch) diff --git a/test/generateQuestions.test.js b/test/generateQuestions.test.js index 69f7eca0f..e242c15df 100644 --- a/test/generateQuestions.test.js +++ b/test/generateQuestions.test.js @@ -202,10 +202,22 @@ describe('buildNextSteps', function() { let rules = realRules.map(enrichRule), situation = analyseTopDown(rules,"surcoût CDD")(stateSelector), objectives = getObjectives(stateSelector, situation.root, situation.parsedRules), + missing = collectMissingVariables()(stateSelector,situation), result = buildNextSteps(stateSelector, rules, situation) expect(objectives).to.have.lengthOf(4) + + expect(missing).to.have.property('contrat salarié . CDD . événement') + expect(missing).to.have.property('contrat salarié . CDD . motif') + expect(missing).to.have.property('contrat salarié . salaire de base') + expect(missing).to.have.property('contrat salarié . CDD . contrat jeune vacances') + expect(missing).to.have.property('contrat salarié . CDD . durée contrat') + expect(missing).to.have.property('contrat salarié . CDD . congés non pris') + + // One question per missing variable ! + expect(R.keys(missing)).to.have.lengthOf(6) expect(result).to.have.lengthOf(6) + expect(R.path(["question","props","label"])(result[0])).to.equal("Pensez-vous être confronté à l'un de ces événements au cours du contrat ?") expect(R.path(["question","props","label"])(result[1])).to.equal("Quel est le motif de recours au CDD ?") expect(R.path(["question","props","label"])(result[2])).to.equal("Quel est le salaire brut ?")