Simplifie la gestion des situations dans la config

pull/445/head
Johan Girod 2019-01-08 21:18:04 +01:00
parent fd280b2e06
commit 7d029382d5
10 changed files with 82 additions and 74 deletions

View File

@ -8,7 +8,7 @@ import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { formValueSelector } from 'redux-form'
import {
analysisListWithDefaultsSelector,
analysisWithDefaultsSelector,
flatRulesSelector
} from 'Selectors/analyseSelectors'
import AnimatedTargetValue from './AnimatedTargetValue'
@ -21,7 +21,7 @@ export default compose(
state.simulationConfig?.objectifs[0]
),
simulationBranches: state.simulationConfig?.branches,
analyses: analysisListWithDefaultsSelector(state),
analyses: analysisWithDefaultsSelector(state),
chiffreAffaires: formValueSelector('conversation')(
state,
"entreprise . chiffre d'affaires"

View File

@ -5,7 +5,6 @@ import { compose, isEmpty } from 'ramda'
import React from 'react'
import { connect } from 'react-redux'
import {
analysisWithDefaultsSelector,
nextStepsSelector,
noUserInputSelector
} from 'Selectors/analyseSelectors'
@ -16,7 +15,6 @@ export default compose(
connect(state => ({
previousAnswers: state.conversationSteps.foldedSteps,
noNextSteps: nextStepsSelector(state).length == 0,
analyses: analysisWithDefaultsSelector(state),
noUserInput: noUserInputSelector(state)
}))
)(

View File

@ -30,6 +30,7 @@ export default compose(
form: 'conversation',
destroyOnUnmount: false
}),
withColours,
withRouter,
connect(
state => ({
@ -84,7 +85,7 @@ export default compose(
conversationStarted,
activeInput,
setActiveInput,
analysis: analysis,
analysis,
noUserInput,
blockingInputControls,
match
@ -222,11 +223,10 @@ const TargetValue = connect(
class TargetValue extends Component {
render() {
let { targets, target, noUserInput, blockingInputControls } = this.props
let targetWithValue =
targets && targets.find(propEq('dottedName', target.dottedName)),
value = targetWithValue && targetWithValue.nodeValue
console.log(target.dottedName, targets, targetWithValue)
return (
<div
className={classNames({

View File

@ -17,7 +17,7 @@ export default compose(
nodeValue,
unité: unit,
dottedName
} = this.props.analysis[0].targets[0]
} = this.props.analysis.targets[0]
return (
<div id="targets">
<span className="icon"></span>

View File

@ -1,5 +1,5 @@
objectifs:
- revenu net d'impôt
- contrat salarié . salaire . brut de base
questions:
- entreprise . chiffre d'affaires
- entreprise . catégorie d'activité

View File

@ -3,9 +3,11 @@ objectifs:
questions:
- entreprise . chiffre d'affaires
- entreprise . catégorie d'activité
situation:
indépendant: oui
micro entreprise: non
contrat salarié: non
branches:
- nom: Indépendant
situation:
indépendant: oui
micro entreprise: non
contrat salarié: non
raccourcis:
indépendant . revenu brut: entreprise . chiffre d'affaires

View File

@ -2,16 +2,14 @@ titre: |
Calcul du **revenu du travailleur indépendant ou dirigeant d'entreprise**, en fonction de son choix de régime social.
Nous faisons l'hypothèse suivante : l'impôt est calculé pour un célibataire sans enfants et sans autre revenu.
Version beta, beaucoup d'améliorations à venir !
objectifs:
objectifs:
- revenu net d'impôt
questions:
questions:
- entreprise . chiffre d'affaires
- entreprise . catégorie d'activité
branches:
- nom: Micro-entreprise
situation:
micro entreprise: oui
indépendant: non
contrat salarié: non
situation:
micro entreprise: oui
indépendant: non
contrat salarié: non

View File

@ -20,11 +20,8 @@ import {
head,
intersection,
isEmpty,
map,
mergeDeepWith,
pick,
pipe,
reduce
pick
} from 'ramda'
import { getFormValues } from 'redux-form'
import { createSelector, createSelectorCreator, defaultMemoize } from 'reselect'
@ -39,6 +36,8 @@ const createDeepEqualSelector = createSelectorCreator(defaultMemoize, equals)
*
* */
const mapOrApply = (fn, x) => (Array.isArray(x) ? x.map(fn) : fn(x))
export let flatRulesSelector = createSelector(
state => state.lang,
(state, props) => props && props.rules,
@ -64,10 +63,7 @@ export let situationSelector = createDeepEqualSelector(
export let noUserInputSelector = createSelector(
[situationSelector],
situation =>
!situation ||
console.log(situation) ||
isEmpty(dissoc('période', situation))
situation => !situation || isEmpty(dissoc('période', situation))
)
export let formattedSituationSelector = createSelector(
@ -82,33 +78,41 @@ let validatedStepsSelector = createSelector(
],
(foldedSteps, target) => [...foldedSteps, target]
)
let branchesSelector = state => state.simulationConfig?.branches || [{}]
let branchesSelector = state => state.simulationConfig?.branches
let configSituationSelector = state => state.simulationConfig?.situation
const createSituationBrancheSelector = situationSelector =>
createSelector(
[situationSelector, branchesSelector, configSituationSelector],
(situation, branches, configSituation = {}) => {
if (branches) {
return branches.map(({ situation: branchSituation }) => ({
...situation,
...configSituation.situation,
...branchSituation
}))
}
if (configSituation) {
return { ...situation, ...configSituation.situation }
}
return situation
}
)
let situationBranchesSelector = createSelector(
[formattedSituationSelector, branchesSelector],
(situation, branches) =>
branches.map(({ situation: branchSituation }) => ({
...situation,
...branchSituation
}))
export let situationBranchesSelector = createSituationBrancheSelector(
formattedSituationSelector
)
export let validatedSituationSelector = createSelector(
[formattedSituationSelector, validatedStepsSelector],
(situation, validatedSteps) => pick(validatedSteps, situation)
)
export let validatedSituationBranchesSelector = createSelector(
[validatedSituationSelector, branchesSelector],
(situation, branches) =>
branches.map(({ situation: branchSituation }) => ({
...situation,
...branchSituation
}))
export let validatedSituationBranchesSelector = createSituationBrancheSelector(
validatedSituationSelector
)
let situationsWithDefaultsSelector = createSelector(
[ruleDefaultsSelector, situationBranchesSelector],
(defaults, situations) =>
situations.map(situation => ({ ...defaults, ...situation }))
mapOrApply(situation => ({ ...defaults, ...situation }), situations)
)
let analyseRule = (parsedRules, ruleDottedName, situationGate) =>
@ -125,12 +129,12 @@ export let ruleAnalysisSelector = createSelector(
shortcutsSelector
],
(rules, dottedName, situations, situationBranch, valueShortcuts) =>
analyseRule(
rules,
dottedName,
dottedName =>
situations[situationBranch][valueShortcuts[dottedName] || dottedName]
)
analyseRule(rules, dottedName, dottedName => {
const currentSituation = Array.isArray(situations)
? situations[situationBranch]
: situations
return currentSituation[valueShortcuts[dottedName] || dottedName]
})
)
let exampleSituationSelector = createSelector(
@ -141,7 +145,7 @@ let exampleSituationSelector = createSelector(
],
(rules, situations, example) =>
example && {
...situations[0],
...(situations[0] || situations),
...disambiguateExampleSituation(
rules,
findRuleByDottedName(rules, example.dottedName)
@ -167,23 +171,19 @@ let makeAnalysisSelector = situationSelector =>
situationSelector,
shortcutsSelector
],
(parsedRules, targetNames, situations, valueShortcuts) => {
let analyses = situations.map(situation =>
analyseMany(parsedRules, targetNames)(
dottedName => situation[valueShortcuts[dottedName] || dottedName]
)
(parsedRules, targetNames, situations, valueShortcuts) =>
mapOrApply(
situation =>
analyseMany(parsedRules, targetNames)(
dottedName => situation[valueShortcuts[dottedName] || dottedName]
),
situations
)
return analyses
}
)
export let analysisListWithDefaultsSelector = makeAnalysisSelector(
export let analysisWithDefaultsSelector = makeAnalysisSelector(
situationsWithDefaultsSelector
)
export let analysisWithDefaultsSelector = createSelector(
[analysisListWithDefaultsSelector],
analysisList => analysisList[0]
)
let analysisValidatedOnlySelector = makeAnalysisSelector(
validatedSituationBranchesSelector
@ -209,11 +209,16 @@ let initialAnalysisSelector = createSelector(
let currentMissingVariablesByTargetSelector = createSelector(
[analysisValidatedOnlySelector],
analyses =>
pipe(
map(analysis => collectMissingVariablesByTarget(analysis.targets)),
reduce((memo, next) => mergeDeepWith(add)(memo, next), {})
)(analyses)
analyses => {
const variables = mapOrApply(
analysis => collectMissingVariablesByTarget(analysis.targets),
analyses
)
if (Array.isArray(variables)) {
return variables.reduce((acc, next) => mergeDeepWith(add)(acc, next), {})
}
return variables
}
)
export let missingVariablesByTargetSelector = createSelector(
@ -227,10 +232,15 @@ export let missingVariablesByTargetSelector = createSelector(
export let nextStepsSelector = createSelector(
[
currentMissingVariablesByTargetSelector,
state => state.simulationConfig?.questions
state => state.simulationConfig?.questions,
shortcutsSelector
],
(mv, questions) => {
(mv, questions, valueShortcuts) => {
let nextSteps = getNextSteps(mv)
console.log('yalla', nextSteps, questions)
// .map(
// dottedName => valueShortcuts[dottedName] || dottedName
// )
if (questions) return intersection(nextSteps, questions)
return nextSteps
}

View File

@ -156,7 +156,7 @@ function analysisToFicheDePaie(
règleAvecMontant,
règleAvecValeur,
règleLocalisée,
[analysis]
analysis
): ?FicheDePaie {
if (!analysis.cache) {
return null

View File

@ -50,7 +50,7 @@ export const règleValeurSelector = createSelector(
analysisWithDefaultsSelector,
validatedSituationBranchesSelector,
règleLocaliséeSelector,
([analysis]: Analysis, situations, règleLocalisée: string => Règle) => (
(analysis: Analysis, situations, règleLocalisée: string => Règle) => (
dottedName: string
): RègleValeur => {
if (!analysis || !analysis.cache) {