diff --git a/publicode/rules.js b/publicode/rules.js
index d40c87050..e6b913330 100644
--- a/publicode/rules.js
+++ b/publicode/rules.js
@@ -18,14 +18,14 @@ const rules = {
// TODO: rule order shouldn't matter but there is a bug if "impot" is after
// "dirigeant".
...impot,
+ ...déclarationIndépendant,
...artisteAuteur,
...dirigeant,
...entrepriseEtablissement,
...protectionSociale,
...salarié,
...conventionsCollectives,
- ...situationPersonnelle,
- ...déclarationIndépendant
+ ...situationPersonnelle
}
export default rules
diff --git a/publicode/rules/déclaration-revenu-indépendant.yaml b/publicode/rules/déclaration-revenu-indépendant.yaml
index dba6bea1d..4c957a1a8 100644
--- a/publicode/rules/déclaration-revenu-indépendant.yaml
+++ b/publicode/rules/déclaration-revenu-indépendant.yaml
@@ -3,12 +3,17 @@
aide déclaration revenu indépendant 2019:
description: Ces règles sont écrites pour aider à remplir les déclarations sociale et
fiscale des indépendant de 2020 sur les revenus 2019
+ par défaut: non
+
+aide déclaration revenu indépendant 2019 . professions libérale:
remplace:
- - règle: dirigeant
- par: "'indépendant'"
- règle: entreprise . catégorie d'activité . libérale règlementée
par: non
- formule: non
+ contrôles:
+ - si: entreprise . date de création < 01/01/2019
+ avertissement: >-
+ Cette aide à la déclaration ne prends pas en compte les professions
+ libérales affiliées à la CIPAV.
aide déclaration revenu indépendant 2019 . plafond sécurité sociale 2019:
remplace: plafond sécurité sociale temps plein
diff --git a/source/components/utils/useDisplayOnIntersecting.ts b/source/components/utils/useDisplayOnIntersecting.ts
index 4709a594a..49d19c2a5 100644
--- a/source/components/utils/useDisplayOnIntersecting.ts
+++ b/source/components/utils/useDisplayOnIntersecting.ts
@@ -3,8 +3,12 @@ import { useEffect, useRef, useState } from 'react'
export default function({
root = null,
rootMargin,
- threshold = 0
-}: IntersectionObserverInit): [React.RefObject, boolean] {
+ threshold = 0,
+ unobserve = true
+}: IntersectionObserverInit & { unobserve?: boolean }): [
+ React.RefObject,
+ boolean
+] {
const ref = useRef(null)
const [wasOnScreen, setWasOnScreen] = useState(false)
@@ -13,7 +17,10 @@ export default function({
([entry]) => {
if (entry.isIntersecting) {
setWasOnScreen(entry.isIntersecting)
- ref.current && observer.unobserve(ref.current)
+ ref.current && unobserve && observer.unobserve(ref.current)
+ }
+ if (!entry.isIntersecting && !unobserve) {
+ setWasOnScreen(entry.isIntersecting)
}
},
{
@@ -27,9 +34,9 @@ export default function({
observer.observe(node)
}
return () => {
- node && observer.unobserve(node)
+ node && unobserve && observer.unobserve(node)
}
- }, [root, rootMargin, threshold])
+ }, [root, rootMargin, threshold, ref.current])
return [ref, wasOnScreen]
}
diff --git a/source/engine/RuleInput.tsx b/source/engine/RuleInput.tsx
index 566cde769..58944bd2a 100644
--- a/source/engine/RuleInput.tsx
+++ b/source/engine/RuleInput.tsx
@@ -24,6 +24,7 @@ type Props = {
onChange: (value: Value) => void
useSwitch?: boolean
isTarget?: boolean
+ autoFocus?: boolean
value?: Value
className?: string
onSubmit?: (value: Value) => void
@@ -40,6 +41,7 @@ export default function InputComponent({
value,
useSwitch = false,
isTarget = false,
+ autoFocus = false,
className,
onSubmit
}: Props) {
@@ -53,6 +55,7 @@ export default function InputComponent({
value,
onChange,
onSubmit,
+ autoFocus,
className,
title: rule.title,
question: rule.question,
diff --git a/source/sites/mon-entreprise.fr/pages/Simulateurs/dnrti.tsx b/source/sites/mon-entreprise.fr/pages/Simulateurs/dnrti.tsx
index 22410d49a..1da86a312 100644
--- a/source/sites/mon-entreprise.fr/pages/Simulateurs/dnrti.tsx
+++ b/source/sites/mon-entreprise.fr/pages/Simulateurs/dnrti.tsx
@@ -1,9 +1,11 @@
import { setSimulationConfig, updateSituation } from 'Actions/actions'
import RuleLink from 'Components/RuleLink'
import 'Components/TargetSelection.css'
+import useDisplayOnIntersecting from 'Components/utils/useDisplayOnIntersecting'
import { formatValue } from 'Engine/format'
import InputComponent from 'Engine/RuleInput'
-import React, { useEffect, useState } from 'react'
+import React, { useCallback, useEffect, useState } from 'react'
+import Skeleton from 'react-loading-skeleton'
import { useDispatch, useSelector } from 'react-redux'
import { RootState } from 'Reducers/rootReducer'
import {
@@ -28,19 +30,52 @@ const simulationConfig = {
'aide déclaration revenu indépendant 2019 . assiette sociale'
],
situation: {
+ dirigeant: 'indépendant',
'aide déclaration revenu indépendant 2019': 'oui'
},
'unités par défaut': ['€/an']
}
+const lauchComputationWhenResultsInViewport = () => {
+ const [resultsRef, resultsInViewPort] = useDisplayOnIntersecting({
+ threshold: 0,
+ unobserve: false
+ })
+ const [currentIncome, setCurrentIncome] = useState(null)
+ const [displayForm, setDisplayForm] = useState(false)
+ const updateIncome = useCallback(
+ income => {
+ setDisplayForm(income != null)
+ setCurrentIncome(income)
+ },
+ [setDisplayForm, setCurrentIncome]
+ )
+ const dispatch = useDispatch()
+ useEffect(() => {
+ if (resultsInViewPort && displayForm) {
+ dispatch(
+ updateSituation('dirigeant . rémunération totale', currentIncome)
+ )
+ } else {
+ dispatch(updateSituation('dirigeant . rémunération totale', null))
+ }
+ }, [resultsInViewPort, displayForm, currentIncome])
+
+ return { updateIncome, resultsRef, displayForm }
+}
export default function DNRTI() {
const dispatch = useDispatch()
const analysis = useSelector(analysisWithDefaultsSelector)
+ const rules = useSelector(flatRulesSelector)
const company = useSelector(
(state: RootState) => state.inFranceApp.existingCompany
)
dispatch(setSimulationConfig(simulationConfig, true))
-
+ const {
+ resultsRef,
+ displayForm,
+ updateIncome
+ } = lauchComputationWhenResultsInViewport()
return (
<>
@@ -65,48 +100,63 @@ export default function DNRTI() {
d'engagement
-
-
-
- Revenus d'activité
- Quel est votre revenu professionnel en 2019 ?
+
+ Indiquez votre résultat net fiscal avant déduction des charges sociales
+ et exonérations fiscales.
+
+
+
-
-
-
- {/* PLNR */}
-
-
-
-
- Situation personnelle
-
-
-
-
- Exonérations
-
-
-
-
- International
-
-
- {/* DOM - Départements d'Outre-Mer
+
+ {displayForm && (
+ <>
+
+ Votre entreprise
- Pas encore implémenté
-
*/}
-
-
+ Vous pouvez renseigner votre entreprise pour pré-remplir le
+ formulaire
+
+
+
+
+
+
+ {/* PLNR */}
+
+
+
+
+ Situation personnelle
+
+
+
+
+ Exonérations
+
+
+
+
+ International
+
+
+
+
+
+
+
+ >
+ )}
>
)
}
@@ -161,13 +211,19 @@ function SimpleField({ dottedName, question, summary }: SimpleFieldProps) {
const rules = useSelector((state: RootState) => state.rules)
const value = useSelector(situationSelector)[dottedName]
const [currentValue, setCurrentValue] = useState(value)
+ const dispatchValue = useCallback(
+ value => {
+ dispatch(updateSituation(dottedName, value))
+ dispatch({
+ type: 'STEP_ACTION',
+ name: 'fold',
+ step: dottedName
+ })
+ },
+ [dispatch, dottedName]
+ )
const update = (value: unknown) => {
- dispatch(updateSituation(dottedName, value))
- dispatch({
- type: 'STEP_ACTION',
- name: 'fold',
- step: dottedName
- })
+ dispatchValue(value)
setCurrentValue(value)
}
useEffect(() => {
@@ -203,12 +259,13 @@ function SimpleField({ dottedName, question, summary }: SimpleFieldProps) {
}
function Results() {
- const results = simulationConfig.objectifs
- .map(objectif => useRule(objectif))
- .filter(r => r.nodeValue)
- if (!results.length) {
- return null
- }
+ const results = simulationConfig.objectifs.map(dottedName =>
+ useSelector((state: RootState) => {
+ return ruleAnalysisSelector(state, { dottedName })
+ })
+ )
+ const onGoingComputation = !results.filter(node => node.nodeValue != null)
+ .length
return (
Aide à la déclaration 📄
-
- {results.map(r => (
- <>
-
- {r.title} {r.summary}
-
- {r.description && {r.description}
}
-
-
- {r.nodeValue
- ? formatValue({
+ {onGoingComputation && (
+
+ Calcul en cours...
+
+ )}
+ <>
+
+ {results.map(r => (
+
+
+ {r.title} {r.summary}
+
+ {r.description && {r.description}
}
+
+
+ {r.nodeValue ? (
+ formatValue({
value: r.nodeValue,
language: 'fr',
unit: '€',
maximumFractionDigits: 0
- })
- : '-'}
-
-
- >
- ))}
-
-
-
-
-
+ })
+ ) : (
+
+ )}
+
+
+
+ ))}
+
+
+
+
+
+ >
)
}
@@ -268,3 +334,6 @@ const FormBlock = styled.section`
const Question = styled.div`
margin-top: 1em;
`
+const BigInput = styled.div`
+ font-size: 130%;
+`