Ajout d'une nouvelle simulation : salaire net

pull/6/head
Mael Thomas 2017-04-10 15:55:18 +02:00
parent 7c0db60e34
commit e182ccde72
7 changed files with 127 additions and 25 deletions

View File

@ -24,11 +24,10 @@
qui apporte à l'employeur plus de souplesse dans un cadre législatif précis, comportant en particulier des contreparties financières.
formule:
somme: #TODO à l'avenir, exprimer une somme par requête de type : obligation applicable au CDD
# - CDD . CIF CDD #cotisation
# - CDD . majoration chômage CDD #cotisation
# - CDD . prime de fin de contrat #indemnité
# - CDD . compensation des congés payés #indemnité
- AGIRC simple
- CDD . CIF CDD #cotisation
- CDD . majoration chômage CDD #cotisation
- CDD . prime de fin de contrat #indemnité
- CDD . compensation des congés payés #indemnité
- Variable: assiette cotisations sociales
attache: Salariat
@ -73,8 +72,17 @@
# TODO
# - Variable: salaire net
# formule: salaire brut moins cotisations sociales salarié
# Cette variable est le point de départ du simulateur "surcout CDD" :-D
- Variable: salaire net
attache: Salariat
description: >
C'est, en gros, le salaire brut moins les cotisations sociales. Ce salaire est plus important que le brut car c'est ce que le salrié reçoit sur son compte bancaire, et pourtant, le brut est très utilisé lors des négociations salariales.
formule:
somme: #TODO à l'avenir, exprimer une somme sous forme de requête
- AGIRC simple
# - Variable: salaire super brut
# formule:

View File

@ -19,7 +19,6 @@ export default class Results extends Component {
// On travaille pour l'instant sur un objectif qui est une somme de plusieurs variables, et c'est ces variables que nous affichons comme résultats. D'où ce chemin :
let explanation = R.path(['formule', 'explanation', 'explanation'])(analysedSituation)
if (!explanation) return null
console.log('explanation', explanation)
return (
<section id="results">

View File

@ -8,25 +8,27 @@ import {START_CONVERSATION} from '../actions'
import Aide from './Aide'
import PageTypeIcon from './PageTypeIcon'
//TODO fusionner SimulationCDD & SimulationNet
let situationSelector = formValueSelector('conversation')
@reduxForm({form: 'conversation', destroyOnUnmount: false})
@connect(
state => ({
situation: variableName => situationSelector(state, variableName),
foldedSteps: state.foldedSteps,
unfoldedSteps: state.unfoldedSteps,
themeColours: state.themeColours,
analysedSituation: state.analysedSituation,
}),
situation: variableName => situationSelector(state, variableName),
foldedSteps: state.foldedSteps,
unfoldedSteps: state.unfoldedSteps,
themeColours: state.themeColours,
analysedSituation: state.analysedSituation,
}),
dispatch => ({
startConversation: () => dispatch({type: START_CONVERSATION}),
}),
startConversation: rootVariable => dispatch({type: START_CONVERSATION, rootVariable}),
}),
)
export default class CDD extends Component {
componentDidMount() {
// C'est ici que la génération du formulaire, et donc la traversée des variables commence
this.props.startConversation()
this.props.startConversation('surcoût CDD')
}
render() {
let {foldedSteps, unfoldedSteps, situation} = this.props

View File

@ -0,0 +1,90 @@
import React, {Component} from 'react'
import './CDD.css'
import Results from './Results'
import {reduxForm, formValueSelector} from 'redux-form'
import {connect} from 'react-redux'
import './conversation/conversation.css'
import {START_CONVERSATION} from '../actions'
import Aide from './Aide'
import PageTypeIcon from './PageTypeIcon'
//TODO fusionner SimulationCDD & SimulationNet
let situationSelector = formValueSelector('conversation')
@reduxForm({form: 'conversation', destroyOnUnmount: false})
@connect(
state => ({
situation: variableName => situationSelector(state, variableName),
foldedSteps: state.foldedSteps,
unfoldedSteps: state.unfoldedSteps,
themeColours: state.themeColours,
analysedSituation: state.analysedSituation,
}),
dispatch => ({
startConversation: rootVariable => dispatch({type: START_CONVERSATION, rootVariable}),
}),
)
export default class SimulationNet extends Component {
componentDidMount() {
// C'est ici que la génération du formulaire, et donc la traversée des variables commence
this.props.startConversation('salaire net')
}
render() {
let {foldedSteps, unfoldedSteps, situation} = this.props
return (
<div id="sim">
<PageTypeIcon type="simulation" />
<h1>Simulateur salaire net</h1>
<div id="conversation">
<div id="questions-answers">
<div id="foldedSteps">
{foldedSteps
.map(step => (
<step.component
key={step.name}
{...step}
step={step}
answer={situation(step.name)}
/>
))}
</div>
<div id="unfoldedSteps">
{unfoldedSteps.map(step => (
<step.component
key={step.name}
{...step}
step={step}
unfolded={true}
answer={situation(step.name)}
/>
))}
</div>
{unfoldedSteps.length == 0 &&
<div id="fin">
<img src={require('../images/fin.png')} />
<p>
Nous n'avons plus de questions : votre simulation est terminée.
</p><p>
Une remarque ? &nbsp;
<a href="mailto:contact@embauche.beta.gouv.fr">
Écrivez-nous
</a>
{' '}
<i
style={{cursor: 'pointer'}}
className="fa fa-envelope-o"
/>
{' '}
!
</p>
</div>}
</div>
<Aide />
</div>
<Results {...this.props} />
</div>
)
}
}

View File

@ -717,12 +717,11 @@ let treatRuleRoot = (situationGate, rule) => R.pipe(
- do they need variables that are not present in the user situation ?
- if not, do they have a computed value or are they non applicable ?
*/
export let analyseSituation = situationGate =>
//TODO l'objectif devrait être spécifié par la page qui lance un simulateur
export let analyseSituation = rootVariable => situationGate =>
treatRuleRoot(
situationGate,
findRuleByName('surcoût CDD')
findRuleByName(rootVariable)
)
export let variableType = name => {

View File

@ -48,9 +48,11 @@ let handleSteps = (state, action) => {
if (![START_CONVERSATION, STEP_ACTION].includes(action.type))
return state
let rootVariable = action.type == START_CONVERSATION ? action.rootVariable : state.analysedSituation.name
let returnObject = {
...state,
analysedSituation: analyse(state)
analysedSituation: analyse(rootVariable)(state)
}
if (action.type == START_CONVERSATION) {
@ -80,10 +82,10 @@ let handleSteps = (state, action) => {
}
}
let analyse = R.pipe(
let analyse = rootVariable => R.pipe(
situationGate,
// une liste des objectifs de la simulation (des 'rules' aussi nommées 'variables')
analyseSituation
analyseSituation(rootVariable)
)
let missingVariables

View File

@ -3,7 +3,8 @@ import { Route, IndexRoute, Link } from 'react-router'
import Layout from './containers/Layout'
import Home from './containers/Home'
import Rule from './components/Rule'
import CDD from './components/CDD'
import SimulationCDD from './components/SimulationCDD'
import SimulationNet from './components/SimulationNet'
import CDDIntro from './components/CDDIntro'
@ -24,7 +25,8 @@ export default (
<Route path="/" component={Layout}>
<Route path="regle/:name" component={Rule} />
<Route path="cdd-intro" component={CDDIntro} />
<Route path="cdd" component={CDD} />
<Route path="cdd" component={SimulationCDD} />
<Route path="net" component={SimulationNet} />
<IndexRoute component={Home} />
<Route path="*" component={RouteNotFound} />
</Route>