diff --git a/source/engine/date.ts b/source/engine/date.ts new file mode 100644 index 000000000..50ad3199e --- /dev/null +++ b/source/engine/date.ts @@ -0,0 +1,18 @@ +const dateRegexp = /[\d]{2}\/[\d]{2}\/[\d]{4}/ + +export function convertToDateIfNeeded(...values: string[]) { + const dateStrings = values.map(dateString => '' + dateString) + if (!dateStrings.some(dateString => dateString.match(dateRegexp))) { + return values + } + dateStrings.forEach(dateString => { + if (!dateString.match(dateRegexp)) { + throw new TypeError( + `L'opérande '${dateString}' n'est pas une date valide` + ) + } + }) + return dateStrings + .map(date => date.split('/')) + .map(([jour, mois, année]) => new Date(+année, +mois - 1, +jour)) +} diff --git a/source/engine/grammar.ne b/source/engine/grammar.ne index 54dbd21ee..a548f1dd5 100644 --- a/source/engine/grammar.ne +++ b/source/engine/grammar.ne @@ -48,7 +48,7 @@ main -> | Comparison {% id %} | NonNumericTerminal {% id %} | Negation {% id %} - | %date {% date %} + | Date {% id %} NumericTerminal -> Variable {% id %} @@ -58,12 +58,19 @@ NumericTerminal -> Negation -> "-" %space Parentheses {% unaryOperation('calculation') %} + Parentheses -> "(" AdditionSubstraction ")" {% ([,e]) => e %} | "(" Negation ")" {% ([,e]) => e %} | NumericTerminal {% id %} -Comparison -> Comparable %space %comparison %space Comparable {% binaryOperation('comparison')%} +Date -> + Variable {% id %} + | %date {% date %} + +Comparison -> + Comparable %space %comparison %space Comparable {% binaryOperation('comparison')%} + | Date %space %comparison %space Date {% binaryOperation('comparison')%} Comparable -> ( AdditionSubstraction | NonNumericTerminal) {% ([[e]]) => e %} diff --git a/source/engine/grammarFunctions.js b/source/engine/grammarFunctions.js index a5d6c6069..30c03a3cc 100644 --- a/source/engine/grammarFunctions.js +++ b/source/engine/grammarFunctions.js @@ -74,7 +74,6 @@ export let date = ([{ value }], ...otherstuf) => { return { constant: { type: 'date', - date, nodeValue: `${jour}/${mois}/${année}` } } diff --git a/source/engine/mecanisms/operation.js b/source/engine/mecanisms/operation.js index fe97fed0e..5d662f2e0 100644 --- a/source/engine/mecanisms/operation.js +++ b/source/engine/mecanisms/operation.js @@ -3,25 +3,32 @@ import { Node } from 'Engine/mecanismViews/common' import { inferUnit } from 'Engine/units' import { curry, map } from 'ramda' import React from 'react' +import { convertToDateIfNeeded } from '../date.ts' export default (k, operatorFunction, symbol) => (recurse, k, v) => { let evaluate = (cache, situation, parsedRules, node) => { - let explanation = map( - curry(evaluateNode)(cache, situation, parsedRules), - node.explanation - ), - value1 = explanation[0].nodeValue, - value2 = explanation[1].nodeValue, - nodeValue = - value1 == null || value2 == null - ? null - : operatorFunction(value1, value2), - missingVariables = mergeMissing( - explanation[0].missingVariables, - explanation[1].missingVariables - ) + const explanation = map( + curry(evaluateNode)(cache, situation, parsedRules), + node.explanation + ) + const missingVariables = mergeMissing( + explanation[0].missingVariables, + explanation[1].missingVariables + ) - return { ...node, nodeValue, explanation, missingVariables } + const value1 = explanation[0].nodeValue + const value2 = explanation[1].nodeValue + if (value1 == null || value2 == null) { + return { ...node, nodeValue: null, explanation, missingVariables } + } + let nodeValue = operatorFunction(...convertToDateIfNeeded(value1, value2)) + + return { + ...node, + nodeValue, + explanation, + missingVariables + } } let explanation = v.explanation.map(recurse) diff --git a/test/mécanismes/date.yaml b/test/mécanismes/date.yaml index 11e752b00..4f9687888 100644 --- a/test/mécanismes/date.yaml +++ b/test/mécanismes/date.yaml @@ -4,6 +4,33 @@ - valeur attendue: 08/02/2015 - test: Défaut au premier jour du mois - formule: 02/2015 + formule: 01/02/2015 exemples: - valeur attendue: 01/02/2015 + +- test: Comparaison sur les dates + formule: 02/03/2019 > 21/02/2019 + exemples: + - valeur attendue: true + +- nom: date de création +- test: Comparaison sur les dates avec référence + formule: date de création < 01/01/2010 + exemples: + - situation: + date de création: 01/03/1992 + valeur attendue: true + - situation: + date de création: 09/02/2019 + valeur attendue: false + +- test: Applicable si + applicable si: date de création < 01/01/2010 + formule: 10 € + exemples: + - situation: + date de création: 01/03/1992 + valeur attendue: 10 + - situation: + date de création: 09/02/2019 + valeur attendue: 0