[CDD][moteur] ajout de la maj chomage -> nouveau mécanisme
parent
8bcce2c294
commit
29e1c40ea0
|
@ -8,20 +8,20 @@
|
|||
|
||||
- Variable: durée
|
||||
attache: Salariat . CDD
|
||||
type: période
|
||||
contrainte: période
|
||||
description: Durée du contrat de travail
|
||||
|
||||
- Variable: motif de recours
|
||||
alias: motif # alias utilisé dans l'article L. 1242-1
|
||||
attache: Salariat . CDD
|
||||
description: |
|
||||
Le CDD est un contrat d'exception: son recours doit être autorisé par l'une des motifs suivants
|
||||
Le CDD est un contrat d'exception: son recours doit être autorisé par l'un des motifs suivants
|
||||
choix exclusifs:
|
||||
- saisonnier
|
||||
- jeune vacances
|
||||
- sénior
|
||||
- usage
|
||||
- accroissement temporaire d'activité
|
||||
- accroissement temporaire activité
|
||||
# remplacement salarié ?
|
||||
# mission ?
|
||||
# ambiguité : l'alternance / l'apprentissage / la fpro sont-ils des justification de CDD ?
|
||||
|
@ -49,7 +49,7 @@
|
|||
attache: Salariat . CDD . motif
|
||||
titre: Contrat saisonnier
|
||||
|
||||
- Variable: accroissement temporaire d'activité
|
||||
- Variable: accroissement temporaire activité
|
||||
attache: Salariat . CDD . motif
|
||||
titre: Accroissement temporaire d'activité
|
||||
|
||||
|
@ -66,7 +66,9 @@
|
|||
- Variable: usage # Similaire pour intérim, mais domaines différents
|
||||
attache: Salariat . CDD . motif
|
||||
titre: Contrat d'usage
|
||||
référence: https://www.service-public.fr/particuliers/vosdroits/F32476
|
||||
# alias: extra
|
||||
références:
|
||||
service-public.fr: https://www.service-public.fr/professionnels-entreprises/vosdroits/F33693
|
||||
# concerne: emploi temporaire par nature
|
||||
formule:
|
||||
choix exclusifs:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
- Indemnité: Fin de contrat
|
||||
- Indemnité: fin de contrat
|
||||
attache: CDD
|
||||
attributs:
|
||||
type: indemnité
|
||||
|
|
|
@ -5,18 +5,20 @@
|
|||
type: majoration
|
||||
|
||||
description: Majoration des contributions patronales d’assurance chômage pour les contrats à durée déterminée courts (CDD)
|
||||
concerne: Salariat . CDD . durée <= 3
|
||||
non applicable si:
|
||||
l'une de ces conditions:
|
||||
- Salariat . CDD . durée > 3
|
||||
- Salariat . CDD . événements . CDD poursuivi en CDI
|
||||
formule:
|
||||
linéaire:
|
||||
assiette: assiette cotisations sociales
|
||||
assiette: Salariat . salaire de base
|
||||
taux:
|
||||
logique numérique:
|
||||
- Salariat . CDD . événements . CDD poursuivi en CDI: 0%
|
||||
- Salariat . CDD . motif . accroissement temporaire d'activité:
|
||||
- Salariat . CDD . durée ≤ 1: 3% # TODO 1 mois, pas 1 rien, évidemment
|
||||
- Salariat . CDD . durée ≤ 3: 1.5%
|
||||
- Salariat . CDD . motif . usage:
|
||||
- Salariat . CDD . durée ≤ 3: 0.5%
|
||||
Salariat . CDD . motif . accroissement temporaire activité:
|
||||
Salariat . CDD . durée <= 1: 3% # TODO 1 mois, pas 1 rien, évidemment
|
||||
Salariat . CDD . durée <= 3: 1.5%
|
||||
Salariat . CDD . motif . usage:
|
||||
Salariat . CDD . durée <= 3: 0.5%
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
}
|
||||
|
||||
#sim #help {
|
||||
visibility: hidden;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 2px;
|
||||
font-style: italic;
|
||||
|
|
|
@ -14,6 +14,7 @@ class Aide extends Component {
|
|||
if (!steps.length) return null
|
||||
let [{dependencyOfVariables, helpText}] = steps
|
||||
return <section id="help">
|
||||
{/*
|
||||
{helpText}
|
||||
<div className="dependency-of">
|
||||
Cette question est nécessaire pour calculer :
|
||||
|
@ -23,6 +24,7 @@ class Aide extends Component {
|
|||
)}
|
||||
</ul>
|
||||
</div>
|
||||
*/}
|
||||
</section>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,18 +3,19 @@ import React, { Component } from 'react'
|
|||
export default class Results extends Component {
|
||||
render() {
|
||||
let {analysedSituation} = this.props
|
||||
console.log('analysedSituation', analysedSituation)
|
||||
return (
|
||||
<section id="results">
|
||||
<h2>Vos obligations</h2>
|
||||
<ul>
|
||||
{analysedSituation.map(({name, type, derived: [dependencies, value]}) =>
|
||||
{analysedSituation.map(({name, type, derived: {missingVariables, computedValue}}) =>
|
||||
<li key={name}>
|
||||
<h3>{type} {name}</h3>
|
||||
<p className="value">
|
||||
{dependencies && dependencies.length ?
|
||||
{missingVariables && missingVariables.length ?
|
||||
'Répondez aux questions !'
|
||||
: value != null ?
|
||||
value + '€'
|
||||
: computedValue != null ?
|
||||
computedValue + '€'
|
||||
: 'Non applicable'
|
||||
}
|
||||
</p>
|
||||
|
|
|
@ -6,15 +6,17 @@ import {parentName, nameLeaf} from './rules'
|
|||
|
||||
// composants des regexps
|
||||
let
|
||||
vn = '[A-Za-z\\u00C0-\\u017F\\s]+', //variableName
|
||||
sep = '\\s\\.\\s'
|
||||
vp = '[A-Za-z\\u00C0-\\u017F\\s]+', // variable part
|
||||
sep = '\\s\\.\\s',
|
||||
vn = `(${vp}(?:${sep}${vp})*)`
|
||||
|
||||
let expressionTests = {
|
||||
// 'negatedVariable': v => /!((?:[a-z0-9]|\s|_)+)/g.exec(v),
|
||||
// 'variableIsIncludedIn': v => /((?:[a-z0-9]|\s|_)+)⊂*/g.exec(v),
|
||||
'variableComparedToNumber': v => /([\w\s]+(?:\s\.\s[\w\s]+)*)\s([<>]=?)\s([0-9]+)/g.exec(v),
|
||||
// 'variableComparedToNumber': v => /([\w\s]+(?:\s\.\s[\w\s]+)*)\s([<>]=?)\s([0-9]+)/g.exec(v),
|
||||
'variableComparedToNumber': v => new RegExp(`^${vn}\\s([<>]=?)\\s([0-9]+)$`, 'g').exec(v),
|
||||
'variableEqualsString': v => /([\w\s]+(?:\s\.\s[\w\s]+)*)\s=\s([\w\s]+)/g.exec(v),
|
||||
'variable': v => new RegExp(`^(${vn}(?:${sep}${vn})*)$`, 'g').exec(v)
|
||||
'variable': v => new RegExp(`^${vn}$`, 'g').exec(v)
|
||||
}
|
||||
|
||||
export let recognizeExpression = value => {
|
||||
|
@ -29,6 +31,7 @@ export let recognizeExpression = value => {
|
|||
|
||||
match = expressionTests['variableComparedToNumber'](value)
|
||||
if (match) {
|
||||
|
||||
let [, variableName, symbol, number] = match
|
||||
return [variableName, situation => eval(`situation("${variableName}") ${symbol} ${number}`)] // eslint-disable-line no-unused-vars
|
||||
}
|
||||
|
@ -48,9 +51,9 @@ export let recognizeExpression = value => {
|
|||
// let yo = parentName(variableName),
|
||||
// ya = nameLeaf(variableName),
|
||||
// yi = situation(parentName(variableName))
|
||||
// debugger;
|
||||
return removeDiacritics(situation(variableName)) == 'oui' ||
|
||||
removeDiacritics(situation(parentName(variableName))) == nameLeaf(variableName)
|
||||
// debugger
|
||||
return situation(variableName) == 'oui' ||
|
||||
situation(parentName(variableName)) == nameLeaf(variableName)
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ export let searchRules = searchInput =>
|
|||
|
||||
export let findRuleByDottedName = dottedName => do {
|
||||
let found = entityRules.find(rule => rule.dottedName == dottedName)
|
||||
found || console.log('dottedName = ', dottedName, ' a déserté')
|
||||
found
|
||||
}
|
||||
|
||||
export let findGroup = R.pipe(
|
||||
|
|
|
@ -8,8 +8,10 @@ import {recognizeExpression} from './expressions'
|
|||
let selectedRules = rules.filter(rule =>
|
||||
R.contains(
|
||||
enrichRule(rule).name,
|
||||
['CIF CDD', 'Fin de contrat']
|
||||
// ['CIF CDD']
|
||||
[
|
||||
'CIF CDD', 'fin de contrat',
|
||||
'majoration chômage CDD'
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -18,11 +20,15 @@ let knownVariable = (situation, variableName) => typeof R.or(
|
|||
situation(parentName(variableName))
|
||||
) !== 'undefined'
|
||||
|
||||
let transformPercentage = s =>
|
||||
s.indexOf('%') > -1 ?
|
||||
+s.replace('%', '') / 100 :
|
||||
+s
|
||||
|
||||
let deriveRule = situationGate => R.pipe(
|
||||
R.toPairs,
|
||||
// Reduce to [variables needed to compute that variable, computed variable value]
|
||||
R.reduce(([variableNames, result], [key, value]) => {
|
||||
R.reduce(({missingVariables, computedValue}, [key, value]) => {
|
||||
if (key === 'concerne') {
|
||||
let [variableName, evaluation] = recognizeExpression(value)
|
||||
// Si cette variable a été renseignée
|
||||
|
@ -30,21 +36,19 @@ let deriveRule = situationGate => R.pipe(
|
|||
// Si l'expression n'est pas vraie...
|
||||
if (!evaluation(situationGate)) {
|
||||
// On court-circuite toute la variable, et on n'a besoin d'aucune information !
|
||||
return R.reduced([[]])
|
||||
return R.reduced({missingVariables: []})
|
||||
} else {
|
||||
// Sinon, on continue
|
||||
return [variableNames]
|
||||
return {missingVariables}
|
||||
}
|
||||
// sinon on demande la valeur de cette variable
|
||||
} else return [[...variableNames, variableName]]
|
||||
} else return { missingVariables: [...missingVariables, variableName] }
|
||||
}
|
||||
|
||||
if (key === 'non applicable si') {
|
||||
let conditions = value['l\'une de ces conditions']
|
||||
let [subVariableNames, reduced] = R.reduce(([variableNames], expression) => {
|
||||
|
||||
let [variableName, evaluation] = recognizeExpression(expression)
|
||||
|
||||
if (knownVariable(situationGate, variableName)) {
|
||||
if (evaluation(situationGate)) {
|
||||
return R.reduced([[], true])
|
||||
|
@ -54,8 +58,9 @@ let deriveRule = situationGate => R.pipe(
|
|||
}
|
||||
return [[...variableNames, variableName]]
|
||||
}, [[], null])(conditions)
|
||||
if (reduced) return R.reduced([[]])
|
||||
else return [variableNames.concat(subVariableNames)]
|
||||
|
||||
if (reduced) return R.reduced({missingVariables: []})
|
||||
else return {missingVariables: [...missingVariables, ...subVariableNames]}
|
||||
}
|
||||
|
||||
if (key === 'formule') {
|
||||
|
@ -67,30 +72,49 @@ let deriveRule = situationGate => R.pipe(
|
|||
assietteValue = situationGate(assietteVariableName),
|
||||
unknownAssiette = assietteValue == undefined
|
||||
|
||||
if (unknownAssiette) {
|
||||
return [[...variableNames, assietteVariableName]]
|
||||
} else {
|
||||
if (variableNames.length > 0) {
|
||||
return [variableNames]
|
||||
}
|
||||
}
|
||||
|
||||
// Arrivés là, cette formule devrait être calculable !
|
||||
let {missingVariables: tauxMissingVariables = [], computedValue} = typeof taux !== 'string' ?
|
||||
do {
|
||||
let numericalLogic = taux['logique numérique']
|
||||
if (!numericalLogic) throw 'On ne sait pas pour l\'instant traiter ce mécanisme de taux'
|
||||
|
||||
// A propos du taux
|
||||
if (typeof taux !== 'string' && typeof taux !== 'number') {
|
||||
throw 'Oups, pas de taux compliqués s\'il-vous-plaît'
|
||||
let treatNumericalLogic = numericalLogic => {
|
||||
if (typeof numericalLogic == 'string') {
|
||||
return new Object({computedValue: assietteValue * transformPercentage(numericalLogic)})
|
||||
} else {
|
||||
return R.pipe(
|
||||
R.toPairs(),
|
||||
R.reduce(({missingVariables}, [expression, subLogic]) => {
|
||||
let [variableName, evaluation] = recognizeExpression(expression)
|
||||
if (knownVariable(situationGate, variableName)) {
|
||||
if (evaluation(situationGate)) {
|
||||
return R.reduced(treatNumericalLogic(subLogic))
|
||||
} else {
|
||||
return {missingVariables}
|
||||
}
|
||||
} else return {missingVariables: [...missingVariables, variableName]}
|
||||
}, {missingVariables: []})
|
||||
)(numericalLogic)
|
||||
}}
|
||||
treatNumericalLogic(numericalLogic)
|
||||
} : ({computedValue: assietteValue * transformPercentage(taux)})
|
||||
|
||||
let formulaResult = {
|
||||
missingVariables: [
|
||||
...missingVariables,
|
||||
...(unknownAssiette ? [assietteVariableName] : []),
|
||||
...tauxMissingVariables
|
||||
],
|
||||
computedValue
|
||||
}
|
||||
let tauxValue = taux.indexOf('%') > -1 ?
|
||||
+taux.replace('%', '') / 100 :
|
||||
+taux
|
||||
|
||||
return R.reduced([null, assietteValue * tauxValue])
|
||||
return computedValue != null ? R.reduced(formulaResult) : formulaResult
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return [variableNames]
|
||||
}, [[], null])
|
||||
return {missingVariables}
|
||||
}, {missingVariables: []})
|
||||
)
|
||||
|
||||
let analyseRule = situationGate =>
|
||||
|
|
|
@ -52,7 +52,6 @@ export default reduceReducers(
|
|||
(state, action) => {
|
||||
if (action.type == STEP_ACTION || action.type == START_CONVERSATION) {
|
||||
let {newState, name} = action
|
||||
console.log('action', action)
|
||||
// une étape vient d'être validée : on va changer son état
|
||||
let newSteps = R.pipe(
|
||||
R.map(step => step.name == name ? {...step, state: newState} : step),
|
||||
|
@ -68,7 +67,7 @@ export default reduceReducers(
|
|||
),
|
||||
|
||||
missingVariables = R.pipe(
|
||||
R.map( ({name, derived: [missingVariables]}) =>
|
||||
R.map( ({name, derived: {missingVariables}}) =>
|
||||
(missingVariables || []).map(mv => [mv, name])
|
||||
),
|
||||
R.unnest,
|
||||
|
@ -91,10 +90,11 @@ export default reduceReducers(
|
|||
[R.isNil, () => variables.map(dottedName => {
|
||||
let rule = findRuleByDottedName(dottedName)
|
||||
return Object.assign(constructStepMeta(rule),
|
||||
rule.contrainte == 'nombre positif' ?
|
||||
rule.contrainte == 'nombre positif' ||
|
||||
rule.contrainte == 'période' ?
|
||||
{
|
||||
component: Input,
|
||||
defaultValue: 0,
|
||||
defaultValue: 1,
|
||||
valueType: euro,
|
||||
attributes: {
|
||||
inputMode: 'numeric',
|
||||
|
|
Loading…
Reference in New Issue