Renomme "désactive" en "rend non applicable"

Ajout de tests, amélioration de la doc
pull/615/head
Maxime Quandalle 2019-08-19 09:36:27 +02:00
parent b1c24033bd
commit 1ffb97c2f6
No known key found for this signature in database
GPG Key ID: 428641C03D29CA10
9 changed files with 80 additions and 68 deletions

View File

@ -1,13 +1,13 @@
/* @flow */
import withColours from 'Components/utils/withColours'
import withSitePaths from 'Components/utils/withSitePaths'
import { encodeRuleName, nameLeaf } from 'Engine/rules'
import { compose } from 'ramda'
import React from 'react'
import { Link } from 'react-router-dom'
import './RuleLink.css'
import type { Règle } from 'Types/RegleTypes'
import type { ThemeColours } from 'Components/utils/withColours'
import { encodeRuleName } from 'Engine/rules'
type Props = Règle & {
sitePaths: Object,
@ -29,7 +29,7 @@ const RuleLink = ({
to={newPath}
className="rule-link"
style={{ color: colour, ...style }}>
{title}
{title || nameLeaf(dottedName)}
</Link>
)
}

View File

@ -1,11 +1,8 @@
import classNames from 'classnames'
import { React, T } from 'Components'
import withSitePaths from 'Components/utils/withSitePaths'
import { makeJsx } from 'Engine/evaluation'
import { encodeRuleName } from 'Engine/rules'
import { any, compose, identity, path } from 'ramda'
import { Trans, withTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
import './Algorithm.css'
// The showValues prop is passed as a context. It used to be delt in CSS (not(.showValues) display: none), both coexist right now
import { ShowValuesProvider } from './ShowValuesContext'
@ -38,32 +35,6 @@ let Conditions = ({
) : null
}
let DisabledBy = withSitePaths(({ isDisabledBy, sitePaths }) => {
return (
isDisabledBy.length > 0 && (
<>
<h3>Exception : </h3>
<p>
Cette règle ne s'applique pas pour le{' '}
{isDisabledBy.map(r => (
<Link
style={{
textDecoration: 'underline'
}}
to={
sitePaths.documentation.index +
'/' +
encodeRuleName(r.dottedName)
}>
{r.title || r.name}
</Link>
))}
</p>
</>
)
)
})
export default compose(withTranslation())(
class Algorithm extends React.Component {
render() {
@ -93,7 +64,7 @@ export default compose(withTranslation())(
</section>
)}
</ShowValuesProvider>
<DisabledBy {...rule} />
{makeJsx(rule['rendu non applicable'])}
</section>
</div>
)

View File

@ -24,6 +24,7 @@ import {
} from 'Selectors/analyseSelectors'
import Animate from 'Ui/animate'
import { AttachDictionary } from '../AttachDictionary'
import RuleLink from '../RuleLink'
import { Markdown } from '../utils/markdown'
import Algorithm from './Algorithm'
import Examples from './Examples'
@ -62,7 +63,6 @@ export default compose(
flatRule = findRuleByDottedName(flatRules, dottedName)
let { type, name, title, description, question, ns, icon } = flatRule,
namespaceRules = findRuleByNamespace(flatRules, dottedName)
let displayedRule = analysedExample || analysedRule
return (
@ -164,9 +164,21 @@ export default compose(
rule={displayedRule}
showValues={valuesToShow || currentExample}
/>
{displayedRule['rend non applicable'] && (
<section id="non-applicable">
<h3>Rend non applicable : </h3>
<ul>
{displayedRule['rend non applicable'].map(ruleName => (
<li key={ruleName}>
<RuleLink dottedName={ruleName} />
</li>
))}
</ul>
</section>
)}
{flatRule.note && (
<section id="notes">
<h3>Note: </h3>
<h3>Note : </h3>
<Markdown source={flatRule.note} />
</section>
)}

View File

@ -11,7 +11,7 @@ export default (cache, situationGate, parsedRules, node) => {
'parentDependency',
'non applicable si',
'applicable si',
'désactivé'
'rendu non applicable'
]),
map(value => evaluateNode(cache, situationGate, parsedRules, value))
)(node),
@ -19,7 +19,7 @@ export default (cache, situationGate, parsedRules, node) => {
parentDependency,
'non applicable si': notApplicable,
'applicable si': applicable,
désactivé: disabled
'rendu non applicable': disabled
} = evaluatedAttributes,
isApplicable =
val(parentDependency) === false ||

View File

@ -113,9 +113,9 @@ non applicable si:
Peut être accompagnée du mécanisme 'applicable si'.
désactive:
rend non applicable:
description: |
Permet de désactiver certaines règles pour la situation saisie.
Permet de désactiver l'application de certaines règles pour la situation saisie.
> Ce mécanisme est utile pour encoder les régimes d'exceptions (par exemple le [régime des impatriés]()) sans avoir à modifier la définition des règles de base.

View File

@ -1,11 +1,12 @@
import { ShowValuesConsumer } from 'Components/rule/ShowValuesContext'
import RuleLink from 'Components/RuleLink'
import evaluate from 'Engine/evaluateRule'
import { parse } from 'Engine/parse'
import { evolve, map } from 'ramda'
import React from 'react'
import { evaluateNode, makeJsx, rewriteNode } from './evaluation'
import { Node } from './mecanismViews/common'
import { findParentDependency } from './rules'
import { disambiguateRuleReference, findParentDependency } from './rules'
export default (rules, rule, parsedRules) => {
// if (rule.dottedName.includes('distance journalière'))
@ -64,6 +65,10 @@ export default (rules, rule, parsedRules) => {
parsedRules
),
'applicable si': evolveCond('applicable si', rule, rules, parsedRules),
'rend non applicable': nonApplicableRules =>
nonApplicableRules.map(referenceName => {
return disambiguateRuleReference(rules, rule, referenceName)
}),
// formule de calcul
formule: value => {
let evaluate = (cache, situationGate, parsedRules, node) => {
@ -117,14 +122,13 @@ export default (rules, rule, parsedRules) => {
parsedRules[rule.dottedName] = {
// Pas de propriété explanation et jsx ici car on est parti du (mauvais) principe que 'non applicable si' et 'formule' sont particuliers, alors qu'ils pourraient être rangé avec les autres mécanismes
...parsedRoot,
désactivé,
evaluate,
parsed: true,
isDisabledBy: [],
unit: rule.unit || parsedRoot.formule?.explanation?.unit
}
const désactivé = {
parsedRules[rule.dottedName]['rendu non applicable'] = {
evaluate: (cache, situation, parsedRules, node) => {
const nodeValue = node.explanation.isDisabledBy
.map(disablerNode =>
@ -133,16 +137,31 @@ export default (rules, rule, parsedRules) => {
.some(x => x.nodeValue === true)
return rewriteNode(node, nodeValue, node.explanation, {})
},
jsx: (nodeValue, explanation) => <ShowValuesConsumer></ShowValuesConsumer>,
jsx: (nodeValue, { isDisabledBy }) => {
return (
isDisabledBy.length > 0 && (
<>
<h3>Exception{isDisabledBy.length > 1 && 's'}</h3>
<p>
Cette règle ne s'applique pas pour :{' '}
{isDisabledBy.map((rule, i) => (
<>
{i > 0 && ', '}
<RuleLink dottedName={rule.dottedName} />
</>
))}
</p>
</>
)
)
},
category: 'ruleProp',
rulePropType: 'cond',
name: 'désactivé',
name: 'rendu non applicable',
type: 'boolean',
explanation: parsedRules[rule.dottedName]
}
parsedRules[rule.dottedName]['désactivé'] = désactivé
return parsedRules[rule.dottedName]
}

View File

@ -1,13 +1,9 @@
import { evaluateControls } from 'Engine/controls'
import parseRule from 'Engine/parseRule'
import { chain, path } from 'ramda'
import { evaluateNode } from './evaluation'
import { parseReference } from './parseReference'
import {
disambiguateRuleReference,
findRule,
findRuleByDottedName
} from './rules'
import { evaluateControls } from 'Engine/controls';
import parseRule from 'Engine/parseRule';
import { chain, path } from 'ramda';
import { evaluateNode } from './evaluation';
import { parseReference } from './parseReference';
import { findRule, findRuleByDottedName, disambiguateRuleReference } from './rules';
/*
Dans ce fichier, les règles YAML sont parsées.
@ -49,19 +45,18 @@ export let parseAll = flatRules => {
/* First we parse each rule one by one. When a mechanism is encountered, it is recursively parsed. When a reference to a variable is encountered, a 'variable' node is created, we don't parse variables recursively. */
let parsedRules = {}
let disabledMapping = {}
/* A rule `A` can disable a rule `B` using the rule `rend non applicable: B` in the definition of `A`.
We need to map these exonerations to be able to retreive them from `B` */
let nonApplicableMapping = {}
flatRules.forEach(rule => {
const parsed = parseRule(flatRules, rule, parsedRules)
if (parsed['désactive']) {
disabledMapping[rule.dottedName] = parsed['désactive'].map(
referenceName => {
return disambiguateRuleReference(flatRules, rule, referenceName)
}
)
if (parsed['rend non applicable']) {
nonApplicableMapping[rule.dottedName] = parsed['rend non applicable']
}
})
Object.entries(disabledMapping).forEach(([a, b]) => {
Object.entries(nonApplicableMapping).forEach(([a, b]) => {
b.forEach(ruleName => {
parsedRules[ruleName].isDisabledBy.push(
parseReference(flatRules, parsedRules[ruleName], parsedRules)({

View File

@ -692,7 +692,7 @@
Certains dirigeants d'entreprise (c'est notamment le cas pour les SASU) sont considérés par la sécurité sociale comme assimilés aux salariés. Ils sont alors au régime général de la sécurité sociale, avec quelques contraintes cependant. Par exemple, ils ne cotisent pas au chômage, et n'y ont donc pas droit.
question: Le salarié est-il considéré comme "assimilé salarié" ?
par défaut: non
désactive:
rend non applicable:
- chômage
- réduction générale
- AGS
@ -1763,7 +1763,7 @@
par défaut: non
# L'association a but non lucratif ne paie pas d'IS de droit commun article 206 du Code général des impôts
# -> pas de taxe ni contribution d'apprentissage
désactive:
rend non applicable:
- contrat salarié . taxe d'apprentissage
- espace: entreprise
@ -1964,7 +1964,7 @@
description: |
Le statut de jeune entreprise innovante (JEI) a été créé par la loi de finances pour 2004 et permet aux PME de moins de 8 ans consacrant 15% au moins de leurs charges à de la Recherche et Développement de bénéficier de certaines exonérations.
par défaut: non
désactive:
rend non applicable:
- contrat salarié . réduction générale
- espace: contrat salarié . statut JEI
@ -2731,7 +2731,7 @@
applicable si:
toutes ces conditions:
- entreprise . effectif > 250
- entreprise . effectif >= 250
- entreprise . ratio alternants < 5%
période: flexible
@ -2829,7 +2829,7 @@
Les impatriés sont exonérés de cotisations retraite (régime de base et complémentaire) à condition de justifier d'une contribution minimale versée par ailleurs (par exemple dans une caisse de retraite ou un fond de pension étranger). Ils nacquièrent aucun droit pendant la durée dexonération.
note: La durée dapplication est fixée au maximum jusquau 31 décembre de la huitième année civile suivant la prise de fonctions dans lentreprise daccueil.
désactive:
rend non applicable:
- vieillesse
- retraite complémentaire
- protection sociale . retraite . base

View File

@ -0,0 +1,15 @@
- nom: impôt
formule: 1000
- nom: exilé fiscal
rend non applicable:
- impôt
- nom: contribution
formule: impôt
test: règle désactivé
exemples:
- nom: evasion fiscale
situation:
exilé fiscal: oui
valeur attendue: 0