taux-réduit-is
Maxime Quandalle 2021-01-27 18:19:51 +01:00
parent 8992d1663a
commit 61b428059a
5 changed files with 35 additions and 16 deletions

View File

@ -173,6 +173,7 @@ entreprise . exercice . durée maximale:
entreprise . impôt sur les sociétés:
unité: €/an
formule:
plafond: plafond taux réduit 1
barème:
assiette: bénéfice
multiplicateur: prorata temporis
@ -211,7 +212,7 @@ entreprise . impôt sur les sociétés:
- taux: 28%
plafond: plafond taux réduit 2
- taux: 33.3333%
arrondi: oui
# arrondi: oui
références:
Fiche impots.gouv.fr: https://www.impots.gouv.fr/portail/international-professionnel/impot-sur-les-societes
Fiche service-public.fr: https://www.service-public.fr/professionnels-entreprises/vosdroits/F23575
@ -225,7 +226,9 @@ entreprise . impôt sur les sociétés . plafond taux réduit 2:
valeur: 500000 €/an
entreprise . impôt sur les sociétés . éligible taux réduit:
formule:
type: booléen
question: Êtes-vous éligible aux taux réduits ?
par défaut:
toutes ces conditions:
- chiffre d'affaires <= 7630 k€/an * prorata temporis
- nom: capital détenu au moins à 75 pourcents par des personnes physiques

View File

@ -6,7 +6,7 @@ import { useCallback, useEffect, useState } from 'react'
import emoji from 'react-easy-emoji'
import { Trans } from 'react-i18next'
import { Explicable } from './Explicable'
import { binaryQuestion, InputCommonProps, RuleInputProps } from './RuleInput'
import { InputCommonProps, RuleInputProps } from './RuleInput'
/* Ceci est une saisie de type "radio" : l'utilisateur choisit une réponse dans
une liste, ou une liste de listes. Les données @choices sont un arbre de type:
@ -31,7 +31,7 @@ export type Choice = RuleNode & {
type QuestionProps = InputCommonProps & {
onSubmit: (source: string) => void
choices: Choice | typeof binaryQuestion
choices: Choice | Array<{ value: string | null; label: string }>
}
export default function Question({
@ -68,7 +68,9 @@ export default function Question({
}
}, [currentSelection])
const renderBinaryQuestion = (choices: typeof binaryQuestion) => {
const renderBinaryQuestion = (
choices: Array<{ value: string | null; label: string }>
) => {
return choices.map(({ value, label }) => (
<span
key={value}
@ -201,13 +203,13 @@ export const RadioLabel = (props: RadioLabelProps) => (
)
type RadioLabelContentProps = {
value: string
value: string | null
label: string
name: string
currentSelection?: null | string
icônes?: string
onChange: RuleInputProps['onChange']
onSubmit: (src: string, value: string) => void
onSubmit: (src: string, value: string | null) => void
}
function RadioLabelContent({

View File

@ -43,11 +43,6 @@ export type InputCommonProps<Name extends string = string> = Pick<
required: boolean
}
export const binaryQuestion = [
{ value: 'oui', label: 'Oui' },
{ value: 'non', label: 'Non' },
] as const
// This function takes the unknown rule and finds which React component should
// be displayed to get a user input through successive if statements
// That's not great, but we won't invest more time until we have more diverse
@ -118,6 +113,10 @@ export default function RuleInput<Name extends string = DottedName>({
(rule.rawNode.type === 'booléen' || rule.rawNode.type == undefined) &&
typeof evaluation.nodeValue !== 'number'
) {
// TODO : super hacky, we need to find a way to read the missing variables
// of the 'par défaut' expression
const defaultValueIsAnswerable =
typeof rule.rawNode?.['par défaut'] === 'object'
return useSwitch ? (
<ToggleSwitch
defaultChecked={value === true}
@ -131,6 +130,9 @@ export default function RuleInput<Name extends string = DottedName>({
choices={[
{ value: 'oui', label: 'Oui' },
{ value: 'non', label: 'Non' },
...(defaultValueIsAnswerable
? [{ value: null, label: 'Je ne sais pas' }]
: []),
]}
onSubmit={onSubmit}
/>

View File

@ -1,4 +1,5 @@
import { updateSituation } from 'Actions/actions'
import Conversation from 'Components/conversation/Conversation'
import RuleInput from 'Components/conversation/RuleInput'
import Value from 'Components/EngineValue'
import Notifications from 'Components/Notifications'
@ -6,6 +7,7 @@ import { SimulationGoal, SimulationGoals } from 'Components/SimulationGoals'
import Animate from 'Components/ui/animate'
import Warning from 'Components/ui/WarningBlock'
import { ThemeColorsContext } from 'Components/utils/colors'
import { useEngine } from 'Components/utils/EngineContext'
import useSimulationConfig from 'Components/utils/useSimulationConfig'
import { useContext } from 'react'
import emoji from 'react-easy-emoji'
@ -18,7 +20,11 @@ export default function ISSimulation() {
useSimulationConfig({
color,
'unité par défaut': '€/an',
objectifs: ['entreprise . impôt sur les sociétés'],
situation: {},
questions: {
liste: ['entreprise . impôt sur les sociétés . éligible taux réduit'],
},
})
return (
@ -37,6 +43,7 @@ export default function ISSimulation() {
<SimulationGoals className="plain">
<SimulationGoal dottedName="entreprise . bénéfice" autoFocus={true} />
</SimulationGoals>
<Conversation />
<Explanations />
</>
)
@ -85,6 +92,12 @@ function ExerciceDate() {
function Explanations() {
const situation = useSelector(situationSelector)
const engine = useEngine()
console.log(
engine.evaluate(
'entreprise . impôt sur les sociétés . plafond taux réduit 1'
)
)
const showResult = situation['entreprise . bénéfice']
if (!showResult) {
return null

View File

@ -39,7 +39,7 @@ export default function parseBarème(v, context): BarèmeNode {
}
}
function evaluateBarème(tranches, assiette, evaluate, cache) {
function evaluateBarème(tranches, assiette, evaluate) {
return tranches.map((tranche) => {
if (tranche.isAfterActive) {
return { ...tranche, nodeValue: 0 }
@ -69,7 +69,7 @@ function evaluateBarème(tranches, assiette, evaluate, cache) {
(Math.min(assiette.nodeValue, tranche.plafondValue) -
tranche.plancherValue) *
convertUnit(taux.unit, parseUnit(''), taux.nodeValue as number),
missingVariables: mergeAllMissing([taux, tranche]),
missingVariables: mergeAllMissing([assiette, taux, tranche]),
}
})
}
@ -88,8 +88,7 @@ const evaluate: EvaluationFunction<'barème'> = function (node) {
liftTemporalNode(multiplicateur as any)
)
const temporalTranches = liftTemporal2(
(tranches, assiette) =>
evaluateBarème(tranches, assiette, evaluate, this.cache),
(tranches, assiette) => evaluateBarème(tranches, assiette, evaluate),
temporalTranchesPlafond,
liftTemporalNode(assiette as any)
)