✨ Revoie les parcours avec entreprise existante
- Met à jour le style des notifications dans la conversation - Améliore la landing page - Améliore la vue de la situation des simulateurs - Les données de l'entreprise courante sont stockées en publicodes - Ajoute la possibilité de réinitialisé la simulation sans les données entreprisespull/2059/head
parent
53f66769e1
commit
3aa11ace73
|
@ -27,7 +27,7 @@
|
|||
"build": "node ../scripts/build-rules.js",
|
||||
"start": "onchange 'règles/**/*.yaml' -- yarn run build",
|
||||
"clean": "rimraf dist node_modules",
|
||||
"postinstall": "yarn run build",
|
||||
"prepack": "yarn run build",
|
||||
"up": "yarn version --minor && echo \"ℹ N'oubliez pas de poussez le tag git\"",
|
||||
"test": "node ../scripts/check-changelog.js"
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"build": "node ../scripts/build-rules.js",
|
||||
"start": "onchange 'règles/**/*.yaml' -- yarn run build",
|
||||
"clean": "rimraf dist node_modules",
|
||||
"postinstall": "yarn run build",
|
||||
"prepack": "yarn run build",
|
||||
"up": "yarn version --minor && echo \"ℹ N'oubliez pas de poussez le tag git\"",
|
||||
"test": "node ../scripts/check-changelog.js"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
bénéficiaire:
|
||||
valeur: non
|
||||
applicable si: entreprise . imposition . IS
|
||||
description: |
|
||||
Un bénéficiaire est un actionnaire dans une SAS ou un associé dans une
|
||||
SARL/EURL.
|
||||
|
|
|
@ -1,13 +1,37 @@
|
|||
dirigeant:
|
||||
question: Quel est le régime social du dirigeant ?
|
||||
dirigeant: oui
|
||||
dirigeant . gérant minoritaire:
|
||||
titre: Gérant minoritaire ou égalitaire
|
||||
question: Êtes-vous gérant minoritaire ou égalitaire de votre entreprise ?
|
||||
non applicable si:
|
||||
une de ces conditions:
|
||||
- entreprise . catégorie juridique . EI
|
||||
- entreprise . catégorie juridique . SARL . unipersonnelle
|
||||
- entreprise . catégorie juridique . SAS . unipersonnelle
|
||||
par défaut: non
|
||||
formule:
|
||||
une possibilité:
|
||||
choix obligatoire: oui
|
||||
possibilités:
|
||||
- auto-entrepreneur
|
||||
- assimilé salarié
|
||||
- indépendant
|
||||
|
||||
dirigeant . régime social:
|
||||
non applicable si:
|
||||
une de ces conditions:
|
||||
- entreprise . catégorie juridique . SELARL #TODO NON IMPLEMENTE
|
||||
- entreprise . catégorie juridique . SELAS #TODO NON IMPLEMENTE
|
||||
- entreprise . catégorie juridique . autre
|
||||
par défaut: non
|
||||
variations:
|
||||
- si: entreprise . catégorie juridique . EI . auto-entrepreneur
|
||||
alors: "'auto-entrepreneur'"
|
||||
- si:
|
||||
une de ces conditions:
|
||||
- entreprise . catégorie juridique . SAS
|
||||
- toutes ces conditions:
|
||||
- entreprise . catégorie juridique . SARL
|
||||
- gérant minoritaire
|
||||
alors: "'assimilé salarié'"
|
||||
- si:
|
||||
non applicable si: gérant minoritaire
|
||||
une de ces conditions:
|
||||
- entreprise . catégorie juridique . EI
|
||||
- entreprise . catégorie juridique . SARL
|
||||
alors: "'indépendant'"
|
||||
|
||||
dirigeant . rémunération: oui
|
||||
dirigeant . rémunération . totale:
|
||||
|
@ -81,14 +105,13 @@ dirigeant . rémunération . nette après impôt:
|
|||
dirigeant . assimilé salarié:
|
||||
description: |
|
||||
Certains dirigeants d'entreprise (c'est notamment le cas pour les SASU) sont considérés par la sécurité sociale comme assimilés aux salariés. Ils sont alors au régime général de la sécurité sociale, avec quelques contraintes cependant. Par exemple, ils ne cotisent pas au chômage, et n'y ont donc pas droit.
|
||||
formule: dirigeant = 'assimilé salarié'
|
||||
applicable si: régime social = 'assimilé salarié'
|
||||
valeur: oui
|
||||
remplace:
|
||||
- règle: contrat salarié
|
||||
par: "'CDI'"
|
||||
- règle: contrat salarié . statut cadre
|
||||
par: oui
|
||||
- règle: entreprise . imposition
|
||||
par: "'IS'"
|
||||
rend non applicable:
|
||||
- contrat salarié . convention collective
|
||||
- contrat salarié . activité partielle
|
||||
|
@ -152,14 +175,9 @@ dirigeant . assimilé salarié . réduction ACRE . notification taux annuel:
|
|||
simulateur ne prends pas encore en compte le calcul de l'ACRE mois par mois.
|
||||
|
||||
dirigeant . auto-entrepreneur:
|
||||
applicable si: régime social = 'auto-entrepreneur'
|
||||
valeur: oui
|
||||
rend non applicable: contrat salarié
|
||||
remplace:
|
||||
- règle: entreprise . imposition
|
||||
par: "'IR'"
|
||||
- règle: entreprise . imposition . IR . micro-fiscal
|
||||
par: oui
|
||||
|
||||
formule: dirigeant = 'auto-entrepreneur'
|
||||
icônes: 🚶
|
||||
description: |
|
||||
L'auto-entreprise est une entreprise individuelle simplifiée. À l'origine connu sous l'appellation « auto-entrepreneur », le régime de « micro-entrepreneur » est un régime de travailleur indépendant créé pour simplifier la gestion administrative, notamment en remplaçant toutes les cotisations sociales par un prélèvement unique mensuel.
|
||||
|
@ -337,40 +355,38 @@ dirigeant . auto-entrepreneur . cotisations et contributions . cotisations . tau
|
|||
remplace:
|
||||
règle: taux vente restauration hébergement
|
||||
par: taux ACRE * taux vente restauration hébergement
|
||||
|
||||
description: |
|
||||
Ce taux correspond à la réduction de cotisations qui s'applique pour
|
||||
l'auto-entrepreneur bénéficiant de l'Acre. Un taux de 75% signifie que
|
||||
l'auto-entrepreneur doit s'acquitter de 75% du montant d'origine des
|
||||
cotisations.
|
||||
unité: '%'
|
||||
formule:
|
||||
variations:
|
||||
- si: entreprise . date de création < 01/04/2019
|
||||
alors:
|
||||
grille:
|
||||
assiette: entreprise . durée d'activité
|
||||
tranches:
|
||||
- montant: 25%
|
||||
plafond: 1 an
|
||||
- montant: 50%
|
||||
plafond: 2 ans
|
||||
- montant: 90%
|
||||
plafond: 3 ans
|
||||
- si: entreprise . date de création < 01/04/2020
|
||||
alors:
|
||||
grille:
|
||||
assiette: entreprise . durée d'activité
|
||||
tranches:
|
||||
- montant: 25%
|
||||
plafond: 1 an
|
||||
- montant: 75%
|
||||
plafond: 2 ans
|
||||
- montant: 90%
|
||||
plafond: 3 ans
|
||||
- sinon:
|
||||
applicable si: entreprise . durée d'activité < 1 an
|
||||
valeur: 50%
|
||||
variations:
|
||||
- si: entreprise . date de création < 01/04/2019
|
||||
alors:
|
||||
grille:
|
||||
assiette: entreprise . durée d'activité
|
||||
tranches:
|
||||
- montant: 25%
|
||||
plafond: 1 an
|
||||
- montant: 50%
|
||||
plafond: 2 ans
|
||||
- montant: 90%
|
||||
plafond: 3 ans
|
||||
- si: entreprise . date de création < 01/04/2020
|
||||
alors:
|
||||
grille:
|
||||
assiette: entreprise . durée d'activité
|
||||
tranches:
|
||||
- montant: 25%
|
||||
plafond: 1 an
|
||||
- montant: 75%
|
||||
plafond: 2 ans
|
||||
- montant: 90%
|
||||
plafond: 3 ans
|
||||
- si: entreprise . durée d'activité < 1 an
|
||||
alors: 50%
|
||||
- sinon: 0%
|
||||
|
||||
références:
|
||||
FAQ Urssaf depuis 04/2020: https://www.autoentrepreneur.urssaf.fr/portail/accueil/une-question/questions-frequentes.html#jai-cree-mon-auto-entreprise-en
|
||||
|
@ -496,8 +512,9 @@ dirigeant . auto-entrepreneur . chiffre d'affaires:
|
|||
- net de cotisations
|
||||
|
||||
dirigeant . indépendant:
|
||||
applicable si: régime social = 'indépendant'
|
||||
valeur: oui
|
||||
rend non applicable: contrat salarié
|
||||
formule: dirigeant = 'indépendant'
|
||||
|
||||
dirigeant . indépendant . revenu professionnel:
|
||||
description: rémunération du dirigeant au régime des indépendant
|
||||
|
@ -970,15 +987,15 @@ dirigeant . indépendant . cotisations facultatives . plafond retraite compléme
|
|||
dirigeant . indépendant . cotisations et contributions . début activité:
|
||||
titre: Cotisations forfaitaires de début d'activité
|
||||
description: |
|
||||
Lorsque vous commencez votre activité, vos **revenus professionnels
|
||||
Lorsque vous commencez votre activité, vos **revenus professionnels**
|
||||
n’étant pas connus**, les cotisations et contributions des deux premières
|
||||
années sont calculées sur une **base forfaitaire**.
|
||||
|
||||
|
||||
Ces cotisations seront ajustées et régularisées en fonction de vos revenus réels de
|
||||
l’année d’exercice. Si votre revenu est supérieur à la base forfaitaire prise en compte
|
||||
pour le calcul des cotisations provisionnelles alors vous serez redevable d’un **complément
|
||||
de cotisations**.
|
||||
pour le calcul des cotisations provisionnelles alors vous serez redevable d’un
|
||||
**complément de cotisations**.
|
||||
|
||||
|
||||
Ce simulateur calcule les cotisations dites définitives sur la base des revenus réels de votre
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
entreprise:
|
||||
valeur: oui
|
||||
description: |
|
||||
Le contrat lie une entreprise, identifiée par un code SIREN, et un employé.
|
||||
|
||||
entreprise . SIREN:
|
||||
description: |
|
||||
Le numéro Siren est un numéro de 9 chiffres unique pour chaque entreprise. Ex : 401237780
|
||||
type: texte
|
||||
|
||||
entreprise . nom:
|
||||
type: texte
|
||||
|
||||
entreprise . date de création:
|
||||
question: Quelle est votre date de début d'activité ?
|
||||
par défaut: 01/01/2021
|
||||
|
@ -199,7 +208,7 @@ entreprise . chiffre d'affaires . franchise de TVA . seuil service:
|
|||
|
||||
entreprise . chiffre d'affaires . franchise de TVA . dépassement:
|
||||
type: notification
|
||||
valeur:
|
||||
formule:
|
||||
une de ces conditions:
|
||||
- chiffre d'affaires > seuil vente + seuil service
|
||||
- vente restauration hébergement > seuil vente
|
||||
|
@ -226,120 +235,6 @@ entreprise . résultat fiscal:
|
|||
- (- charges)
|
||||
- (- charges . dirigeant)
|
||||
|
||||
entreprise . imposition:
|
||||
question: Comment l'entreprise est-elle imposée ?
|
||||
description: |
|
||||
Indiquez si le régime d’imposition des revenus liés à l’activité indépendante relèvent :
|
||||
- de l’impôt sur le revenu : les bénéfices de l’entreprise sont imposés directement auprès du travailleur indépendant, au barème progressif de l’impôt sur le revenu.
|
||||
- de l’impôt sur les sociétés : les bénéfices de l’entreprise sont imposés au nom de la société, au taux de l’impôt sur les sociétés.
|
||||
formule:
|
||||
une possibilité:
|
||||
choix obligatoire: oui
|
||||
possibilités:
|
||||
- IR
|
||||
- IS
|
||||
par défaut: "'IR'"
|
||||
|
||||
entreprise . imposition . IR:
|
||||
valeur: imposition = 'IR'
|
||||
titre: Impôt sur le revenu
|
||||
|
||||
entreprise . imposition . IR . micro-fiscal:
|
||||
rend non applicable: dirigeant . indépendant . cotisations facultatives
|
||||
|
||||
question: Avez-vous opté pour le régime micro-fiscal ?
|
||||
description: |
|
||||
Avec le régime micro fiscal, les charges déductibles sont estimées forfaitairement,en fonction d’un pourcentage du chiffre d’affaires. Ce pourcentage dépend du type d’activité : 71% pour les activités de vente, restauration et hébergement (location de meublé de tourisme classé et chambre d’hôte), 50% pour les prestations de service commerciales ou artisanales, 34% pour les activités libérales.
|
||||
|
||||
Cette option permet de simplifier votre comptabilité et peut être avantageuse en termes de revenu imposable et soumis à cotisations et contributions sociales dans le cas où vos charges de fonctionnement sont faibles.
|
||||
par défaut: non
|
||||
|
||||
entreprise . imposition . IR . micro-fiscal . revenu abattu:
|
||||
remplace: résultat fiscal
|
||||
résoudre la référence circulaire: oui
|
||||
titre: abattement forfaitaire micro-fiscal
|
||||
description: |
|
||||
Le micro-entrepreneur est dispensé d'établir une déclaration professionnelle de bénéfices au titre des BNC ou BIC.
|
||||
|
||||
Il lui suffit de porter dans la déclaration complémentaire de revenu (n°2042-C Pro) le montant annuel du chiffre d'affaires brut (BIC) ou des recettes (BNC).
|
||||
somme:
|
||||
- entreprise . chiffre d'affaires . vente restauration hébergement
|
||||
- entreprise . chiffre d'affaires . service BIC
|
||||
- entreprise . chiffre d'affaires . service BNC
|
||||
abattement:
|
||||
produit:
|
||||
composantes:
|
||||
- assiette: entreprise . chiffre d'affaires . vente restauration hébergement
|
||||
taux: 71%
|
||||
- assiette: entreprise . chiffre d'affaires . service BIC
|
||||
taux: 50%
|
||||
- assiette: entreprise . chiffre d'affaires . service BNC
|
||||
taux: 34%
|
||||
plancher:
|
||||
variations:
|
||||
- si: entreprise . activité . mixte
|
||||
alors: 610 €/an
|
||||
- sinon: 305 €/an
|
||||
|
||||
entreprise . imposition . IR . micro-fiscal . alerte seuil dépassés:
|
||||
type: notification
|
||||
sévérité: avertissement
|
||||
formule: chiffre d'affaires . seuil micro dépassé
|
||||
description: Le seuil annuel de chiffre d'affaires pour le régime micro-fiscal est dépassé. [En savoir plus](/documentation/entreprise/chiffre-d'affaires/seuil-micro-dépassé)
|
||||
|
||||
entreprise . chiffre d'affaires . seuil micro dépassé:
|
||||
applicable si: imposition . IR
|
||||
description: |
|
||||
Le statut de micro-entreprise s'applique tant que le chiffre d'affaires annuel (effectivement encaissé au cours de l'année civile) ne dépasse pas les seuils du régime fiscal de la micro-entreprise.
|
||||
|
||||
En cas de dépassement **sur deux années consécutives**, l'entreprise bascule automatiquement dans le régime de [l'entreprise individuelle](/simulateurs/indépendant).
|
||||
|
||||
À la fin de la première année d'activité, le CA est proratisé par rapport à la durée d'activité.
|
||||
|
||||
Exemple :
|
||||
> Un contribuable crée une entreprise le 1er août et encaisse des recettes HT de `50 000 €` au cours des cinq mois d'activité de sa première année civile d'exploitation.
|
||||
> Les recettes de cette première année civile sont ajustées *prorata temporis* pour les comparer au plafond :
|
||||
>
|
||||
> `50 000€ x (365/153) = 119 280 €`
|
||||
|
||||
|
||||
Les charges ne sont pas déductibles pour le calcul du plafond (comme pour le calcul des cotisations)
|
||||
|
||||
|
||||
### Multi-activité
|
||||
|
||||
Lorsqu'un entrepreneur exerce 2 activités au sein de sa micro-entreprise, le
|
||||
seuil de chiffre d’affaires à respecter n’est pas pour autant doublé. En
|
||||
effet l'exercice de plusieurs activités avec la même micro-entreprise
|
||||
n’augmente pas les seuils.
|
||||
|
||||
références:
|
||||
Fiche service-public.fr: https://www.service-public.fr/professionnels-entreprises/vosdroits/F32353
|
||||
Article 50-0 du Code général des impôts: https://www.legifrance.gouv.fr/affichCode.do?idSectionTA=LEGISCTA000006199553&cidTexte=LEGITEXT000006069577
|
||||
Bofip (dépassement micro-bnc): https://bofip.impots.gouv.fr/bofip/4807-PGP.html
|
||||
Bofip (dépassement micro-bic): https://bofip.impots.gouv.fr/bofip/1802-PGP.html
|
||||
autoentrepreneur.urssaf.fr: https://www.autoentrepreneur.urssaf.fr/portail/accueil/une-question/questions-frequentes.html
|
||||
unité: €/an
|
||||
# TODO: les seuils micro sont dupliqués à plusieurs endroits (artiste-auteur .
|
||||
# revenus . BNC . contrôle micro-bnc, tableau de la comparaison de régime,
|
||||
# économie collaborative). Il faudrait référencer la même valeur partout où
|
||||
# elle est utilisée.
|
||||
une de ces conditions:
|
||||
- entreprise . chiffre d'affaires > 176200 €/an
|
||||
- entreprise . chiffre d'affaires . service > 72600 €/an
|
||||
|
||||
entreprise . imposition . IR . information sur le report de déficit:
|
||||
non applicable si: micro-fiscal
|
||||
type: notification
|
||||
formule: résultat fiscal < 0 €/an
|
||||
description: |
|
||||
Lorsque votre résultat fiscal est négatif, ce dernier vient réduire le revenu imposables du foyer fiscal.
|
||||
Un déficit peut être imputé jusqu'à 6 ans après sa réalisation.
|
||||
|
||||
[Voir les règles fiscales détaillées](https://bofip.impots.gouv.fr/bofip/2003-PGP.html/identifiant%3DBOI-BIC-DEF-20-10-20170301)
|
||||
références:
|
||||
bofip: https://bofip.impots.gouv.fr/bofip/2003-PGP.html/identifiant%3DBOI-BIC-DEF-20-10-20170301
|
||||
|
||||
entreprise . exercice: oui
|
||||
entreprise . exercice . début:
|
||||
type: date
|
||||
|
@ -380,123 +275,6 @@ entreprise . exercice . durée maximale:
|
|||
formule: durée >= 24 mois
|
||||
description: La durée maximale d'un exercice comptable est de 24 mois.
|
||||
|
||||
entreprise . imposition . IS:
|
||||
valeur: imposition = 'IS'
|
||||
titre: Impôt sur les sociétés
|
||||
|
||||
entreprise . imposition . IS . résultat imposable:
|
||||
titre: Résultat de l'exercice
|
||||
résumé: Imposable à l'impôt sur les sociétés
|
||||
valeur: résultat fiscal
|
||||
|
||||
entreprise . imposition . IS . information sur le report de déficit:
|
||||
type: notification
|
||||
formule: résultat imposable < 0 €/an
|
||||
# TODO: Support des références dans les notifications
|
||||
description: |
|
||||
Les déficits subits au cours d'un exercice peuvent être reportés sur les exercices suivants (report en avant), ou sur le seul exercice précédent (report en arrière).
|
||||
|
||||
entreprise . imposition . IS . résultat net:
|
||||
résumé: Après déduction des charges et de l'impôt sur les société
|
||||
somme:
|
||||
- chiffre d'affaires
|
||||
- (- charges)
|
||||
- (- dirigeant . rémunération . totale)
|
||||
- (- impôt sur les sociétés)
|
||||
par défaut: 0€
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés:
|
||||
unité: €/an
|
||||
formule:
|
||||
barème:
|
||||
assiette: résultat imposable
|
||||
multiplicateur: prorata temporis
|
||||
variations:
|
||||
- si: exercice . début >= 01/01/2022
|
||||
alors:
|
||||
tranches:
|
||||
- taux: 15%
|
||||
plafond: plafond taux réduit 1
|
||||
- taux: 25%
|
||||
- si: exercice . début >= 01/01/2021
|
||||
alors:
|
||||
tranches:
|
||||
- taux: 15%
|
||||
plafond: plafond taux réduit 1
|
||||
- taux: 26.5%
|
||||
- si: exercice . début >= 01/01/2020
|
||||
alors:
|
||||
tranches:
|
||||
- taux: 15%
|
||||
plafond: plafond taux réduit 1
|
||||
- taux: 28%
|
||||
- si: exercice . début >= 01/01/2019
|
||||
alors:
|
||||
tranches:
|
||||
- taux: 15%
|
||||
plafond: plafond taux réduit 1
|
||||
- taux: 28%
|
||||
plafond: plafond taux réduit 2
|
||||
- taux: 31%
|
||||
- si: exercice . début >= 01/01/2018
|
||||
alors:
|
||||
tranches:
|
||||
- taux: 15%
|
||||
plafond: plafond taux réduit 1
|
||||
- taux: 28%
|
||||
plafond: plafond taux réduit 2
|
||||
- taux: 33.3333%
|
||||
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
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés . plafond taux réduit 1:
|
||||
applicable si: éligible taux réduit
|
||||
valeur: 38120 €/an
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés . plafond taux réduit 2:
|
||||
applicable si: éligible taux réduit
|
||||
valeur: 500000 €/an
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés . éligible taux réduit:
|
||||
formule:
|
||||
toutes ces conditions:
|
||||
- chiffre d'affaires <= 7630 k€/an * prorata temporis
|
||||
- nom: capital détenu au moins à 75 pourcents par des personnes physiques
|
||||
valeur: oui
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés . prorata temporis:
|
||||
description: |
|
||||
Lorsque la durée de l’exercice n'est pas égale à un an, on pro-ratise les
|
||||
plafonds utilisés dans le barème de l'impôt sur les sociétés.
|
||||
unité: '%'
|
||||
formule: exercice . durée / 1 an
|
||||
# TODO: c'est un peu plus subtil que cela : « En cas d’exercice ouvert ou
|
||||
# arrêté en cours de mois calendaire, le nombre de jours résiduels concourt à
|
||||
# la détermination du rapport pour un montant égal au rapport existant entre
|
||||
# ce nombre et 30. »
|
||||
références:
|
||||
Bofip: https://bofip.impots.gouv.fr/bofip/2065-PGP.html/identifiant%3DBOI-IS-LIQ-20-20-20180801
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés . contribution sociale:
|
||||
# description: |
|
||||
# La contribution sociale sur les bénéfices est un impôt distinct de l'impôt sur les sociétés. Son montant n'est pas déductible des résultats.
|
||||
|
||||
# L'assiette bénéficie d'un abattement important, et seules les entreprises réalisant plus de 2,3 millions d'euros de bénéficie sont concernées par cette contribution.
|
||||
description: |
|
||||
La contribution sociale sur les bénéfices est un impôt distinct de l’impôt sur les sociétés. Son montant n’est pas déductible des résultats.
|
||||
|
||||
L’assiette bénéficie d’un abattement important, et seules les entreprises réalisant plus de 2,3 millions d’euros de bénéfices sont concernées par cette contribution.
|
||||
formule:
|
||||
produit:
|
||||
taux: 3.3%
|
||||
assiette:
|
||||
valeur: impôt sur les sociétés
|
||||
abattement: 763000 €/an * prorata temporis
|
||||
références:
|
||||
Bofip: https://bofip.impots.gouv.fr/bofip/3492-PGP.html/identifiant%3DBOI-IS-AUT-10-20-20130318
|
||||
|
||||
entreprise . charges:
|
||||
synonymes:
|
||||
- charges d'exploitation
|
||||
|
@ -865,6 +643,13 @@ entreprise . activité . débit de tabac:
|
|||
par défaut: non
|
||||
|
||||
établissement:
|
||||
formule: oui
|
||||
description: |
|
||||
Le salarié travaille dans un établissement de l'entreprise, identifié par un code SIRET.
|
||||
|
||||
établissement . SIRET:
|
||||
type: texte
|
||||
applicable si: entreprise . SIREN
|
||||
description: |
|
||||
Le salarié travaille dans un établissement de l'entreprise, identifié par un code SIRET.
|
||||
|
||||
|
@ -931,3 +716,9 @@ entreprise . activité . débit de tabac:
|
|||
applicable si: entreprise . date de création < 01/2015
|
||||
question: Votre établissement bénéficie-t-il du dispositif zone franche urbaine (ZFU) ?
|
||||
par défaut: non
|
||||
|
||||
établissement . ZFU . durée d'implantation en fin d'année:
|
||||
formule:
|
||||
durée:
|
||||
depuis: entreprise . date de création
|
||||
jusqu'à: 31/12/2019
|
|
@ -0,0 +1,235 @@
|
|||
entreprise . imposition:
|
||||
question: Comment l'entreprise est-elle imposée ?
|
||||
description: |
|
||||
Indiquez si le régime d’imposition des revenus liés à l’activité indépendante relèvent :
|
||||
- de l’impôt sur le revenu : les bénéfices de l’entreprise sont imposés directement auprès du travailleur indépendant, au barème progressif de l’impôt sur le revenu.
|
||||
- de l’impôt sur les sociétés : les bénéfices de l’entreprise sont imposés au nom de la société, au taux de l’impôt sur les sociétés.
|
||||
une possibilité:
|
||||
choix obligatoire: oui
|
||||
possibilités:
|
||||
- IR
|
||||
- IS
|
||||
par défaut:
|
||||
variations:
|
||||
- si: catégorie juridique . EI
|
||||
alors: "'IR'"
|
||||
- sinon: "'IS'"
|
||||
|
||||
entreprise . imposition . IR:
|
||||
applicable si: imposition = 'IR'
|
||||
titre: Impôt sur le revenu
|
||||
valeur: oui
|
||||
|
||||
entreprise . imposition . IR . micro-fiscal:
|
||||
rend non applicable: dirigeant . indépendant . cotisations facultatives
|
||||
|
||||
question: Avez-vous opté pour le régime micro-fiscal ?
|
||||
description: |
|
||||
Avec le régime micro fiscal, les charges déductibles sont estimées forfaitairement,en fonction d’un pourcentage du chiffre d’affaires. Ce pourcentage dépend du type d’activité : 71% pour les activités de vente, restauration et hébergement (location de meublé de tourisme classé et chambre d’hôte), 50% pour les prestations de service commerciales ou artisanales, 34% pour les activités libérales.
|
||||
|
||||
Cette option permet de simplifier votre comptabilité et peut être avantageuse en termes de revenu imposable et soumis à cotisations et contributions sociales dans le cas où vos charges de fonctionnement sont faibles.
|
||||
par défaut: non
|
||||
|
||||
entreprise . imposition . IR . micro-fiscal . revenu abattu:
|
||||
remplace: résultat fiscal
|
||||
résoudre la référence circulaire: oui
|
||||
titre: abattement forfaitaire micro-fiscal
|
||||
description: |
|
||||
Le micro-entrepreneur est dispensé d'établir une déclaration professionnelle de bénéfices au titre des BNC ou BIC.
|
||||
|
||||
Il lui suffit de porter dans la déclaration complémentaire de revenu (n°2042-C Pro) le montant annuel du chiffre d'affaires brut (BIC) ou des recettes (BNC).
|
||||
somme:
|
||||
- entreprise . chiffre d'affaires . vente restauration hébergement
|
||||
- entreprise . chiffre d'affaires . service BIC
|
||||
- entreprise . chiffre d'affaires . service BNC
|
||||
abattement:
|
||||
produit:
|
||||
composantes:
|
||||
- assiette: entreprise . chiffre d'affaires . vente restauration hébergement
|
||||
taux: 71%
|
||||
- assiette: entreprise . chiffre d'affaires . service BIC
|
||||
taux: 50%
|
||||
- assiette: entreprise . chiffre d'affaires . service BNC
|
||||
taux: 34%
|
||||
plancher:
|
||||
variations:
|
||||
- si: entreprise . activité . mixte
|
||||
alors: 610 €/an
|
||||
- sinon: 305 €/an
|
||||
|
||||
entreprise . imposition . IR . micro-fiscal . alerte seuil dépassés:
|
||||
type: notification
|
||||
sévérité: avertissement
|
||||
formule: chiffre d'affaires . seuil micro dépassé
|
||||
description: Le seuil annuel de chiffre d'affaires pour le régime micro-fiscal est dépassé. [En savoir plus](/documentation/entreprise/chiffre-d'affaires/seuil-micro-dépassé)
|
||||
|
||||
entreprise . chiffre d'affaires . seuil micro dépassé:
|
||||
applicable si: imposition . IR
|
||||
description: |
|
||||
Le statut de micro-entreprise s'applique tant que le chiffre d'affaires annuel (effectivement encaissé au cours de l'année civile) ne dépasse pas les seuils du régime fiscal de la micro-entreprise.
|
||||
|
||||
En cas de dépassement **sur deux années consécutives**, l'entreprise bascule automatiquement dans le régime de [l'entreprise individuelle](/simulateurs/indépendant).
|
||||
|
||||
À la fin de la première année d'activité, le CA est proratisé par rapport à la durée d'activité.
|
||||
|
||||
Exemple :
|
||||
> Un contribuable crée une entreprise le 1er août et encaisse des recettes HT de `50 000 €` au cours des cinq mois d'activité de sa première année civile d'exploitation.
|
||||
> Les recettes de cette première année civile sont ajustées *prorata temporis* pour les comparer au plafond :
|
||||
>
|
||||
> `50 000€ x (365/153) = 119 280 €`
|
||||
|
||||
|
||||
Les charges ne sont pas déductibles pour le calcul du plafond (comme pour le calcul des cotisations)
|
||||
|
||||
|
||||
### Multi-activité
|
||||
|
||||
Lorsqu'un entrepreneur exerce 2 activités au sein de sa micro-entreprise, le
|
||||
seuil de chiffre d’affaires à respecter n’est pas pour autant doublé. En
|
||||
effet l'exercice de plusieurs activités avec la même micro-entreprise
|
||||
n’augmente pas les seuils.
|
||||
|
||||
références:
|
||||
Fiche service-public.fr: https://www.service-public.fr/professionnels-entreprises/vosdroits/F32353
|
||||
Article 50-0 du Code général des impôts: https://www.legifrance.gouv.fr/affichCode.do?idSectionTA=LEGISCTA000006199553&cidTexte=LEGITEXT000006069577
|
||||
Bofip (dépassement micro-bnc): https://bofip.impots.gouv.fr/bofip/4807-PGP.html
|
||||
Bofip (dépassement micro-bic): https://bofip.impots.gouv.fr/bofip/1802-PGP.html
|
||||
autoentrepreneur.urssaf.fr: https://www.autoentrepreneur.urssaf.fr/portail/accueil/une-question/questions-frequentes.html
|
||||
unité: €/an
|
||||
# TODO: les seuils micro sont dupliqués à plusieurs endroits (artiste-auteur .
|
||||
# revenus . BNC . contrôle micro-bnc, tableau de la comparaison de régime,
|
||||
# économie collaborative). Il faudrait référencer la même valeur partout où
|
||||
# elle est utilisée.
|
||||
une de ces conditions:
|
||||
- entreprise . chiffre d'affaires > 176200 €/an
|
||||
- entreprise . chiffre d'affaires . service > 72600 €/an
|
||||
|
||||
entreprise . imposition . IR . information sur le report de déficit:
|
||||
non applicable si: micro-fiscal
|
||||
type: notification
|
||||
formule: résultat fiscal < 0 €/an
|
||||
description: |
|
||||
Lorsque votre résultat fiscal est négatif, ce dernier vient réduire le revenu imposables du foyer fiscal.
|
||||
Un déficit peut être imputé jusqu'à 6 ans après sa réalisation.
|
||||
|
||||
[Voir les règles fiscales détaillées](https://bofip.impots.gouv.fr/bofip/2003-PGP.html/identifiant%3DBOI-BIC-DEF-20-10-20170301)
|
||||
références:
|
||||
bofip: https://bofip.impots.gouv.fr/bofip/2003-PGP.html/identifiant%3DBOI-BIC-DEF-20-10-20170301
|
||||
|
||||
entreprise . imposition . IS:
|
||||
applicable si: imposition = 'IS'
|
||||
valeur: oui
|
||||
titre: Impôt sur les sociétés
|
||||
|
||||
entreprise . imposition . IS . résultat imposable:
|
||||
titre: Résultat de l'exercice
|
||||
résumé: Imposable à l'impôt sur les sociétés
|
||||
valeur: résultat fiscal
|
||||
|
||||
entreprise . imposition . IS . information sur le report de déficit:
|
||||
type: notification
|
||||
formule: résultat imposable < 0 €/an
|
||||
# TODO: Support des références dans les notifications
|
||||
description: |
|
||||
Les déficits subits au cours d'un exercice peuvent être reportés sur les exercices suivants (report en avant), ou sur le seul exercice précédent (report en arrière).
|
||||
|
||||
entreprise . imposition . IS . résultat net:
|
||||
résumé: Après déduction des charges et de l'impôt sur les société
|
||||
somme:
|
||||
- chiffre d'affaires
|
||||
- (- charges)
|
||||
- (- dirigeant . rémunération . totale)
|
||||
- (- impôt sur les sociétés)
|
||||
par défaut: 0€
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés:
|
||||
unité: €/an
|
||||
formule:
|
||||
barème:
|
||||
assiette: résultat imposable
|
||||
multiplicateur: prorata temporis
|
||||
variations:
|
||||
- si: exercice . début >= 01/01/2022
|
||||
alors:
|
||||
tranches:
|
||||
- taux: 15%
|
||||
plafond: plafond taux réduit 1
|
||||
- taux: 25%
|
||||
- si: exercice . début >= 01/01/2021
|
||||
alors:
|
||||
tranches:
|
||||
- taux: 15%
|
||||
plafond: plafond taux réduit 1
|
||||
- taux: 26.5%
|
||||
- si: exercice . début >= 01/01/2020
|
||||
alors:
|
||||
tranches:
|
||||
- taux: 15%
|
||||
plafond: plafond taux réduit 1
|
||||
- taux: 28%
|
||||
- si: exercice . début >= 01/01/2019
|
||||
alors:
|
||||
tranches:
|
||||
- taux: 15%
|
||||
plafond: plafond taux réduit 1
|
||||
- taux: 28%
|
||||
plafond: plafond taux réduit 2
|
||||
- taux: 31%
|
||||
- si: exercice . début >= 01/01/2018
|
||||
alors:
|
||||
tranches:
|
||||
- taux: 15%
|
||||
plafond: plafond taux réduit 1
|
||||
- taux: 28%
|
||||
plafond: plafond taux réduit 2
|
||||
- taux: 33.3333%
|
||||
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
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés . plafond taux réduit 1:
|
||||
applicable si: éligible taux réduit
|
||||
valeur: 38120 €/an
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés . plafond taux réduit 2:
|
||||
applicable si: éligible taux réduit
|
||||
valeur: 500000 €/an
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés . éligible taux réduit:
|
||||
formule:
|
||||
toutes ces conditions:
|
||||
- chiffre d'affaires <= 7630 k€/an * prorata temporis
|
||||
- nom: capital détenu au moins à 75 pourcents par des personnes physiques
|
||||
valeur: oui
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés . prorata temporis:
|
||||
description: |
|
||||
Lorsque la durée de l’exercice n'est pas égale à un an, on pro-ratise les
|
||||
plafonds utilisés dans le barème de l'impôt sur les sociétés.
|
||||
unité: '%'
|
||||
formule: exercice . durée / 1 an
|
||||
# TODO: c'est un peu plus subtil que cela : « En cas d’exercice ouvert ou
|
||||
# arrêté en cours de mois calendaire, le nombre de jours résiduels concourt à
|
||||
# la détermination du rapport pour un montant égal au rapport existant entre
|
||||
# ce nombre et 30. »
|
||||
références:
|
||||
Bofip: https://bofip.impots.gouv.fr/bofip/2065-PGP.html/identifiant%3DBOI-IS-LIQ-20-20-20180801
|
||||
|
||||
entreprise . imposition . IS . impôt sur les sociétés . contribution sociale:
|
||||
# description: |
|
||||
# La contribution sociale sur les bénéfices est un impôt distinct de l'impôt sur les sociétés. Son montant n'est pas déductible des résultats.
|
||||
|
||||
# L'assiette bénéficie d'un abattement important, et seules les entreprises réalisant plus de 2,3 millions d'euros de bénéficie sont concernées par cette contribution.
|
||||
description: |
|
||||
La contribution sociale sur les bénéfices est un impôt distinct de l’impôt sur les sociétés. Son montant n’est pas déductible des résultats.
|
||||
|
||||
L’assiette bénéficie d’un abattement important, et seules les entreprises réalisant plus de 2,3 millions d’euros de bénéfices sont concernées par cette contribution.
|
||||
formule:
|
||||
produit:
|
||||
taux: 3.3%
|
||||
assiette:
|
||||
valeur: impôt sur les sociétés
|
||||
abattement: 763000 €/an * prorata temporis
|
||||
références:
|
||||
Bofip: https://bofip.impots.gouv.fr/bofip/3492-PGP.html/identifiant%3DBOI-IS-AUT-10-20-20130318
|
|
@ -0,0 +1,79 @@
|
|||
entreprise . catégorie juridique:
|
||||
description: |
|
||||
Les catégories juridiques accessibles via l'API SIRENE
|
||||
par défaut: non
|
||||
une possibilité:
|
||||
choix obligatoire: oui
|
||||
possibilités:
|
||||
- EI
|
||||
- SARL
|
||||
- SAS
|
||||
- autre
|
||||
références:
|
||||
liste des catégories juridique de l'INSEE: https://www.insee.fr/fr/information/2028129
|
||||
note: On se base ici sur les catégories juridiques définies par l'INSEE
|
||||
|
||||
entreprise . catégorie juridique . EI:
|
||||
titre: 'EI ou EIRL'
|
||||
valeur: catégorie juridique = 'EI'
|
||||
|
||||
entreprise . catégorie juridique . EI . auto-entrepreneur:
|
||||
question: Êtes-vous auto-entrepreneur ?
|
||||
remplace:
|
||||
règle: imposition . IR . micro-fiscal
|
||||
par: oui
|
||||
|
||||
par défaut: oui
|
||||
|
||||
entreprise . catégorie juridique . EI . responsabilité limité:
|
||||
non applicable si: auto-entrepreneur # pour simplifier
|
||||
titre: 'EIRL'
|
||||
question: Votre entreprise est-elle une EIRL ?
|
||||
par défaut: non
|
||||
|
||||
entreprise . catégorie juridique . EI . imposition entreprise:
|
||||
non applicable si: responsabilité limité
|
||||
remplace: entreprise . imposition
|
||||
valeur: "'IR'"
|
||||
|
||||
entreprise . catégorie juridique . SARL:
|
||||
titre: 'EURL ou SARL'
|
||||
valeur: catégorie juridique = 'SARL'
|
||||
|
||||
entreprise . catégorie juridique . SARL . unipersonnelle:
|
||||
titre: EURL
|
||||
question: Votre entreprise est-elle une EURL ?
|
||||
par défaut: oui
|
||||
|
||||
entreprise . catégorie juridique . SELARL:
|
||||
titre: 'SELARL'
|
||||
valeur: catégorie juridique = 'SELARL'
|
||||
remplace:
|
||||
- règle: entreprise . activité
|
||||
par: "'libérale'"
|
||||
- règle: entreprise . activité . libérale réglementée
|
||||
par: oui
|
||||
|
||||
entreprise . catégorie juridique . SELAS:
|
||||
titre: 'SELARL'
|
||||
valeur: catégorie juridique = 'SELAS'
|
||||
remplace:
|
||||
- règle: entreprise . activité
|
||||
par: "'libérale'"
|
||||
- règle: entreprise . activité . libérale réglementée
|
||||
par: oui
|
||||
|
||||
entreprise . catégorie juridique . SAS:
|
||||
remplace: #TODO nous ne gérons pas encore les SASU à l'IR
|
||||
règle: entreprise . imposition
|
||||
par: "'IS'"
|
||||
titre: 'SASU ou SAS'
|
||||
valeur: catégorie juridique = 'SAS'
|
||||
|
||||
entreprise . catégorie juridique . SAS . unipersonnelle:
|
||||
titre: 'SASU'
|
||||
question: Votre entreprise est-elle une SASU ?
|
||||
par défaut: oui
|
||||
|
||||
entreprise . catégorie juridique . autre:
|
||||
valeur: catégorie juridique = 'autre'
|
|
@ -356,6 +356,7 @@ dirigeant . indépendant . PL . CNAVPL:
|
|||
l'organisme qui fédère les différentes caisses existantes (CIPAV, CARPIMKO,
|
||||
CARCDSF, CAVEC etc..)
|
||||
non applicable si: régime général
|
||||
valeur: oui
|
||||
|
||||
dirigeant . indépendant . PL . CNAVPL . retraite:
|
||||
titre: retraite de base (CNAVPL)
|
||||
|
|
|
@ -1255,6 +1255,7 @@ contrat salarié . stage . avertissement:
|
|||
description: >-
|
||||
Une convention de stage **n'est pas un contrat de travail**, et ne peut pas être conclue pour réaliser une tâche régulière correspondant à un poste de travail permanent, ou à un accroissement temporaire de l'activité de l'entreprise. [Code de l'éducation - Article L124-7](https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000029234119&cidTexte=LEGITEXT000006071191)
|
||||
|
||||
|
||||
Par ailleurs, une entreprise de moins de 20 salariés ne peut pas accueillir plus de **3 stagiaires**, et pas plus de **15% de l’effectif** pour les entreprises de plus de 20 salariés.
|
||||
|
||||
contrat salarié . stage . contrôle gratification minimale:
|
||||
|
@ -3419,7 +3420,7 @@ contrat salarié . régime des impatriés:
|
|||
contrat salarié . régime des impatriés . information:
|
||||
type: notification
|
||||
formule: oui
|
||||
description: >-
|
||||
description: |-
|
||||
Pour bénéficier de l'exonération de cotisations vieillesse, il faut remplir les conditions suivantes :
|
||||
- Pouvoir justifier d'une contribution minimale versée ailleurs pour une assurance vieillesse
|
||||
- Ne pas avoir été affilié, au cours des cinq années civiles précédant celle de la prise de fonctions, à un régime français obligatoire d'assurance vieillesse, sauf pour des activités accessoires, de caractère saisonnier ou pour les études.
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
},
|
||||
"resolutions": {
|
||||
"prettier": "^2.5.1",
|
||||
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
|
||||
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest",
|
||||
"publicodes": "portal:/home/johan/Projets/publicodes/packages/core",
|
||||
"publicodes-react": "portal:/home/johan/Projets/publicodes/packages/react-ui"
|
||||
},
|
||||
"packageManager": "yarn@3.2.0",
|
||||
"devDependencies": {
|
||||
|
|
|
@ -55,7 +55,7 @@ describe(`Navigation to income simulator using company name (${
|
|||
})
|
||||
it('should allow to retrieve company and show link corresponding to the legal status', function () {
|
||||
cy.contains(
|
||||
fr ? 'Rechercher une entreprise ' : 'Search for a company '
|
||||
fr ? 'Rechercher votre entreprise ' : 'Search for a company '
|
||||
).click()
|
||||
cy.get('input').first().type('menoz')
|
||||
cy.contains('834364291').click()
|
||||
|
@ -66,7 +66,7 @@ describe(`Navigation to income simulator using company name (${
|
|||
})
|
||||
it('should allow auto entrepreneur to access the corresponding income simulator', function () {
|
||||
cy.contains(
|
||||
fr ? 'Rechercher une entreprise ' : 'Search for a company '
|
||||
fr ? 'Rechercher votre entreprise ' : 'Search for a company '
|
||||
).click()
|
||||
cy.get('input').first().type('johan girod')
|
||||
cy.contains('834825614').click()
|
||||
|
|
|
@ -17,7 +17,7 @@ describe('Champs localisation (simulateur salarié)', function () {
|
|||
.type('Steenvoorde')
|
||||
cy.contains('Steenvoorde (59114)').click({ force: true })
|
||||
cy.contains('Suivant').click({ force: true })
|
||||
cy.contains('Voir mes paramètres').click({ force: true })
|
||||
cy.contains('Voir ma situation').click({ force: true })
|
||||
cy.contains('Steenvoorde')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -21,7 +21,7 @@ describe('Partage (simulateur salarié)', function () {
|
|||
.invoke('val')
|
||||
.should('match', /1[\s]539[\s]€/)
|
||||
|
||||
cy.contains('Voir mes paramètres').click()
|
||||
cy.contains('Voir ma situation').click()
|
||||
cy.contains('CDD')
|
||||
})
|
||||
it('should set URL from input value', function () {
|
||||
|
|
|
@ -11,7 +11,7 @@ describe('Simulateur salarié', function () {
|
|||
describe('part time contract', function () {
|
||||
before(function () {
|
||||
cy.get('button').contains('SMIC').click()
|
||||
cy.contains('Voir mes paramètres').click()
|
||||
cy.contains('Voir ma situation').click()
|
||||
cy.get('div[role="dialog"]').contains('Temps partiel').click()
|
||||
cy.contains('Oui').click()
|
||||
cy.wait(100)
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
import rules from 'modele-social'
|
||||
import { StrictMode, useContext, useMemo } from 'react'
|
||||
import { Helmet } from 'react-helmet-async'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { Redirect, Route, Switch } from 'react-router-dom'
|
||||
import styled, { css } from 'styled-components'
|
||||
import Footer from '@/components/layout/Footer/Footer'
|
||||
import Header from '@/components/layout/Header'
|
||||
import Route404 from '@/components/Route404'
|
||||
|
@ -18,9 +11,17 @@ import {
|
|||
import { SitePathsContext } from '@/components/utils/SitePathsContext'
|
||||
import { Container, Spacing } from '@/design-system/layout'
|
||||
import {
|
||||
companySituationSelector,
|
||||
configSituationSelector,
|
||||
situationSelector,
|
||||
} from '@/selectors/simulationSelectors'
|
||||
import rules from 'modele-social'
|
||||
import { StrictMode, useContext, useMemo } from 'react'
|
||||
import { Helmet } from 'react-helmet-async'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { Redirect, Route, Switch } from 'react-router-dom'
|
||||
import styled, { css } from 'styled-components'
|
||||
import Accessibilité from './pages/Accessibilité'
|
||||
import Budget from './pages/Budget/Budget'
|
||||
import Créer from './pages/Creer'
|
||||
|
@ -39,9 +40,13 @@ import Provider, { ProviderProps } from './Provider'
|
|||
import redirects from './redirects'
|
||||
import { constructLocalizedSitePath } from './sitePaths'
|
||||
import {
|
||||
retrievePersistedInFranceApp,
|
||||
setupInFranceAppPersistence,
|
||||
} from './storage/persistInFranceApp'
|
||||
retrievePersistedChoixStatutJuridique,
|
||||
setupChoixStatutJuridiquePersistence,
|
||||
} from './storage/persistChoixStatutJuridique'
|
||||
import {
|
||||
retrievePersistedCompanySituation,
|
||||
setupCompanySituationPersistence,
|
||||
} from './storage/persistCompanySituation'
|
||||
import { setupSimulationPersistence } from './storage/persistSimulation'
|
||||
|
||||
type RootProps = {
|
||||
|
@ -71,11 +76,13 @@ export default function Root({
|
|||
basename={basename}
|
||||
sitePaths={paths}
|
||||
onStoreCreated={(store) => {
|
||||
setupInFranceAppPersistence(store)
|
||||
setupChoixStatutJuridiquePersistence(store)
|
||||
setupCompanySituationPersistence(store)
|
||||
setupSimulationPersistence(store)
|
||||
}}
|
||||
initialStore={{
|
||||
inFranceApp: retrievePersistedInFranceApp(),
|
||||
choixStatutJuridique: retrievePersistedChoixStatutJuridique(),
|
||||
companySituation: retrievePersistedCompanySituation(),
|
||||
}}
|
||||
>
|
||||
<EngineProvider value={engine}>
|
||||
|
@ -87,14 +94,16 @@ export default function Root({
|
|||
}
|
||||
|
||||
const Router = () => {
|
||||
const userSituation = useSelector(situationSelector)
|
||||
const simulatorSituation = useSelector(situationSelector)
|
||||
const configSituation = useSelector(configSituationSelector)
|
||||
const companySituation = useSelector(companySituationSelector)
|
||||
const situation = useMemo(
|
||||
() => ({
|
||||
...companySituation,
|
||||
...configSituation,
|
||||
...userSituation,
|
||||
...simulatorSituation,
|
||||
}),
|
||||
[configSituation, userSituation]
|
||||
[configSituation, simulatorSituation, companySituation]
|
||||
)
|
||||
return (
|
||||
<SituationProvider situation={situation}>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { DottedName } from 'modele-social'
|
||||
import Engine from 'publicodes'
|
||||
import { SimulationConfig, Situation } from '@/reducers/rootReducer'
|
||||
import { SimulationConfig } from '@/reducers/rootReducer'
|
||||
import { CompanyCreationAction } from './companyCreationChecklistActions'
|
||||
import { CompanyStatusAction } from './companyStatusActions'
|
||||
import { ActionExistingCompany } from './existingCompanyActions'
|
||||
import { CompanyActions } from './companyActions'
|
||||
import { HiringChecklistAction } from './hiringChecklistAction'
|
||||
|
||||
export type Action =
|
||||
|
@ -23,7 +23,7 @@ export type Action =
|
|||
>
|
||||
| CompanyCreationAction
|
||||
| CompanyStatusAction
|
||||
| ActionExistingCompany
|
||||
| CompanyActions
|
||||
| HiringChecklistAction
|
||||
|
||||
export const resetSimulation = () =>
|
||||
|
@ -46,16 +46,11 @@ export const stepAction = (step: DottedName, source?: string) =>
|
|||
source,
|
||||
} as const)
|
||||
|
||||
export const setSimulationConfig = (
|
||||
config: SimulationConfig,
|
||||
url: string,
|
||||
initialSituation?: Situation
|
||||
) =>
|
||||
export const setSimulationConfig = (config: SimulationConfig, url: string) =>
|
||||
({
|
||||
type: 'SET_SIMULATION',
|
||||
url,
|
||||
config,
|
||||
initialSituation,
|
||||
} as const)
|
||||
|
||||
export const setActiveTarget = (targetName: DottedName) =>
|
||||
|
@ -72,7 +67,7 @@ export const updateSituation = (fieldName: DottedName, value: unknown) =>
|
|||
} as const)
|
||||
|
||||
export const batchUpdateSituation = (
|
||||
situation: Parameters<Engine<DottedName>['setSituation']>[0]
|
||||
situation: NonNullable<Parameters<Engine<DottedName>['setSituation']>[0]>
|
||||
) =>
|
||||
({
|
||||
type: 'BATCH_UPDATE_SITUATION',
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { FabriqueSocialEntreprise } from '@/api/fabrique-social'
|
||||
import { ApiCommuneJson } from '@/components/conversation/select/SelectCommune'
|
||||
|
||||
export type CompanyActions = ReturnType<
|
||||
typeof resetCompany | typeof setCompany | typeof addCommuneDetails
|
||||
>
|
||||
|
||||
export const resetCompany = () =>
|
||||
({
|
||||
type: 'COMPANY::RESET',
|
||||
} as const)
|
||||
|
||||
export const addCommuneDetails = (details: ApiCommuneJson) =>
|
||||
({
|
||||
type: 'COMPANY::ADD_COMMUNE_DETAILS',
|
||||
details,
|
||||
} as const)
|
||||
|
||||
export const setCompany = (entreprise: FabriqueSocialEntreprise) => {
|
||||
return {
|
||||
type: 'COMPANY::SET_EXISTING_COMPANY',
|
||||
entreprise,
|
||||
} as const
|
||||
}
|
|
@ -6,7 +6,7 @@ import { useHistory } from 'react-router'
|
|||
import { useNextQuestionUrl } from '@/selectors/companyStatusSelectors'
|
||||
import { LegalStatusRequirements } from '@/types/companyTypes'
|
||||
import { Action } from './actions'
|
||||
import { addCommuneDetails, setCompany } from './existingCompanyActions'
|
||||
import { addCommuneDetails, setCompany } from './companyActions'
|
||||
|
||||
export type CompanyStatusAction = ReturnType<
|
||||
| typeof isSoleProprietorship
|
||||
|
@ -78,21 +78,18 @@ const fetchCommuneDetails = async function (codeCommune: string) {
|
|||
const response = await fetch(
|
||||
`https://geo.api.gouv.fr/communes/${codeCommune}?fields=departement,region`
|
||||
)
|
||||
return await response.json()
|
||||
return (await response.json()) as ApiCommuneJson
|
||||
}
|
||||
|
||||
export const useSetEntreprise = () => {
|
||||
const dispatch = useDispatch()
|
||||
return async (entreprise: FabriqueSocialEntreprise) => {
|
||||
return (entreprise: FabriqueSocialEntreprise) => {
|
||||
if (entreprise === null) {
|
||||
return
|
||||
}
|
||||
dispatch(setCompany(entreprise))
|
||||
if (entreprise.firstMatchingEtablissement.is_siege) {
|
||||
const communeDetails: ApiCommuneJson = await fetchCommuneDetails(
|
||||
entreprise.firstMatchingEtablissement.codeCommuneEtablissement
|
||||
)
|
||||
dispatch(addCommuneDetails(communeDetails))
|
||||
}
|
||||
void fetchCommuneDetails(
|
||||
entreprise.firstMatchingEtablissement.codeCommuneEtablissement
|
||||
).then((communeDetails) => dispatch(addCommuneDetails(communeDetails)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
import { FabriqueSocialEntreprise } from '@/api/fabrique-social'
|
||||
import { ApiCommuneJson } from '@/components/conversation/select/SelectCommune'
|
||||
|
||||
export type ActionExistingCompany = ReturnType<
|
||||
| typeof specifyIfAutoEntrepreneur
|
||||
| typeof specifyIfDirigeantMajoritaire
|
||||
| typeof resetEntreprise
|
||||
| typeof setCompany
|
||||
| typeof addCommuneDetails
|
||||
>
|
||||
|
||||
export const specifyIfAutoEntrepreneur = (isAutoEntrepreneur: boolean) =>
|
||||
({
|
||||
type: 'EXISTING_COMPANY::SPECIFY_AUTO_ENTREPRENEUR',
|
||||
isAutoEntrepreneur,
|
||||
} as const)
|
||||
|
||||
export const specifyIfDirigeantMajoritaire = (
|
||||
isDirigeantMajoritaire: boolean
|
||||
) =>
|
||||
({
|
||||
type: 'EXISTING_COMPANY::SPECIFY_DIRIGEANT_MAJORITAIRE',
|
||||
isDirigeantMajoritaire,
|
||||
} as const)
|
||||
|
||||
export const resetEntreprise = () =>
|
||||
({
|
||||
type: 'EXISTING_COMPANY::RESET',
|
||||
} as const)
|
||||
|
||||
export const addCommuneDetails = (details: ApiCommuneJson) =>
|
||||
({
|
||||
type: 'EXISTING_COMPANY::ADD_COMMUNE_DETAILS',
|
||||
details,
|
||||
} as const)
|
||||
|
||||
export const setCompany = (entreprise: FabriqueSocialEntreprise) => {
|
||||
return {
|
||||
type: 'EXISTING_COMPANY::SET_COMPANY',
|
||||
entreprise,
|
||||
} as const
|
||||
}
|
|
@ -108,7 +108,6 @@ function ActivitéMixte() {
|
|||
const rule = useEngine().getRule('entreprise . activité . mixte')
|
||||
const defaultChecked =
|
||||
useEngine().evaluate('entreprise . activité . mixte').nodeValue === true
|
||||
|
||||
const onMixteChecked = useCallback(
|
||||
(checked: boolean) => {
|
||||
dispatch(
|
||||
|
@ -124,21 +123,23 @@ function ActivitéMixte() {
|
|||
)
|
||||
|
||||
return (
|
||||
<StyledActivitéMixteContainer>
|
||||
<Trans>
|
||||
<Switch
|
||||
size="XS"
|
||||
defaultSelected={defaultChecked}
|
||||
onChange={onMixteChecked}
|
||||
light
|
||||
>
|
||||
Activité mixte
|
||||
</Switch>
|
||||
</Trans>
|
||||
<ButtonHelp type="aide" title={rule.title} light>
|
||||
<Markdown>{rule.rawNode.description ?? ''}</Markdown>
|
||||
</ButtonHelp>
|
||||
</StyledActivitéMixteContainer>
|
||||
<div key={defaultChecked}>
|
||||
<StyledActivitéMixteContainer>
|
||||
<Trans>
|
||||
<Switch
|
||||
size="XS"
|
||||
defaultSelected={defaultChecked}
|
||||
onChange={onMixteChecked}
|
||||
light
|
||||
>
|
||||
Activité mixte
|
||||
</Switch>
|
||||
</Trans>
|
||||
<ButtonHelp type="aide" title={rule.title} light>
|
||||
<Markdown>{rule.rawNode.description ?? ''}</Markdown>
|
||||
</ButtonHelp>
|
||||
</StyledActivitéMixteContainer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import Engine, {
|
|||
isNotApplicable,
|
||||
isNotYetDefined,
|
||||
PublicodesExpression,
|
||||
UNSAFE_isNotApplicable,
|
||||
} from 'publicodes'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
@ -94,7 +93,9 @@ export function WhenApplicable({
|
|||
children: React.ReactNode
|
||||
}) {
|
||||
const engine = useEngine()
|
||||
if (UNSAFE_isNotApplicable(engine, dottedName)) return null
|
||||
if (engine.evaluate(dottedName).nodeValue == null) {
|
||||
return null
|
||||
}
|
||||
return <>{children}</>
|
||||
}
|
||||
export function WhenNotApplicable({
|
||||
|
@ -105,7 +106,9 @@ export function WhenNotApplicable({
|
|||
children: React.ReactNode
|
||||
}) {
|
||||
const engine = useEngine()
|
||||
if (!UNSAFE_isNotApplicable(engine, dottedName)) return null
|
||||
if (engine.evaluate(dottedName).nodeValue !== null) {
|
||||
return null
|
||||
}
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
|
@ -122,3 +125,17 @@ export function WhenAlreadyDefined({
|
|||
}
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
export function WhenNotAlreadyDefined({
|
||||
dottedName: dottedName,
|
||||
children,
|
||||
}: {
|
||||
dottedName: DottedName
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
const engine = useEngine()
|
||||
if (!isNotYetDefined(engine.evaluate(dottedName).nodeValue)) {
|
||||
return null
|
||||
}
|
||||
return <>{children}</>
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import styled from 'styled-components'
|
|||
import RuleLink from './RuleLink'
|
||||
import Emoji from './utils/Emoji'
|
||||
import { Markdown } from './utils/markdown'
|
||||
import { Message } from '@/design-system'
|
||||
|
||||
// To add a new notification to a simulator, you should create a publicodes rule
|
||||
// with the "type: notification" attribute. The display can be customized with
|
||||
|
@ -62,18 +63,23 @@ export default function Notifications() {
|
|||
).filter(({ dottedName }) => !hiddenNotifications?.includes(dottedName))
|
||||
|
||||
return (
|
||||
<NotificationsContainer id="notificationsBlock">
|
||||
<div
|
||||
css={`
|
||||
margin-top: 1rem;
|
||||
`}
|
||||
>
|
||||
{messages.map(({ sévérité, dottedName, résumé, description }) => (
|
||||
<Notification className="notification" key={dottedName}>
|
||||
<Emoji emoji={sévérité == 'avertissement' ? '⚠️' : '💁🏻'} />
|
||||
<NotificationContent className="notificationText">
|
||||
<Markdown>{résumé ?? description ?? ''}</Markdown>{' '}
|
||||
{résumé && (
|
||||
<RuleLink dottedName={dottedName as DottedName}>
|
||||
<Trans>En savoir plus</Trans>
|
||||
</RuleLink>
|
||||
)}
|
||||
</NotificationContent>
|
||||
<Message
|
||||
icon
|
||||
type={sévérité == 'avertissement' ? 'info' : 'primary'}
|
||||
key={dottedName}
|
||||
>
|
||||
<Markdown>{résumé ?? description ?? ''}</Markdown>{' '}
|
||||
{résumé && (
|
||||
<RuleLink dottedName={dottedName as DottedName}>
|
||||
<Trans>En savoir plus</Trans>
|
||||
</RuleLink>
|
||||
)}
|
||||
<HideButton
|
||||
className="hide"
|
||||
aria-label="close"
|
||||
|
@ -81,47 +87,12 @@ export default function Notifications() {
|
|||
>
|
||||
×
|
||||
</HideButton>
|
||||
</Notification>
|
||||
</Message>
|
||||
))}
|
||||
</NotificationsContainer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const NotificationsContainer = styled.ul`
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
`
|
||||
|
||||
const Notification = styled.li`
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
padding: 0.5rem 1rem;
|
||||
background-color: ${({ theme }) => theme.colors.bases.primary[100]};
|
||||
border: 2px solid;
|
||||
border-color: ${({ theme }) => theme.colors.bases.primary[500]};
|
||||
border-radius: 0.375rem;
|
||||
|
||||
margin-bottom: 1rem;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
& img {
|
||||
height: ${({ theme }) => theme.spacings.xl} !important;
|
||||
width: ${({ theme }) => theme.spacings.xl} !important;
|
||||
margin-right: ${({ theme }) => theme.spacings.sm} !important;
|
||||
}
|
||||
`
|
||||
|
||||
const NotificationContent = styled.div`
|
||||
flex-grow: 1;
|
||||
margin-right: 2rem;
|
||||
margin-left: 0.5rem;
|
||||
`
|
||||
|
||||
const HideButton = styled(Button)<GenericButtonOrLinkProps>`
|
||||
&& {
|
||||
display: flex;
|
||||
|
|
|
@ -65,7 +65,7 @@ export const PlacesDesEntreprisesButton = ({
|
|||
siret,
|
||||
}: {
|
||||
pathname: string
|
||||
siret?: string
|
||||
siret?: string | null
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const baseURL =
|
||||
|
|
|
@ -55,7 +55,7 @@ export default function SchemeComparaison({
|
|||
() =>
|
||||
engine.shallowCopy().setSituation({
|
||||
...situation,
|
||||
dirigeant: "'assimilé salarié'",
|
||||
'dirigeant . régime social': "'assimilé salarié'",
|
||||
}),
|
||||
[situation]
|
||||
)
|
||||
|
@ -63,7 +63,7 @@ export default function SchemeComparaison({
|
|||
() =>
|
||||
engine.shallowCopy().setSituation({
|
||||
...situation,
|
||||
dirigeant: "'auto-entrepreneur'",
|
||||
'dirigeant . régime social': "'auto-entrepreneur'",
|
||||
}),
|
||||
[situation]
|
||||
)
|
||||
|
@ -71,7 +71,7 @@ export default function SchemeComparaison({
|
|||
() =>
|
||||
engine.shallowCopy().setSituation({
|
||||
...situation,
|
||||
dirigeant: "'indépendant'",
|
||||
'dirigeant . régime social': "'indépendant'",
|
||||
}),
|
||||
[situation]
|
||||
)
|
||||
|
|
|
@ -7,7 +7,10 @@ import { CurrentSimulatorDataContext } from '../../pages/Simulateurs/metadata'
|
|||
import { useContext } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { situationSelector } from '@/selectors/simulationSelectors'
|
||||
import {
|
||||
companySituationSelector,
|
||||
situationSelector,
|
||||
} from '@/selectors/simulationSelectors'
|
||||
import styled from 'styled-components'
|
||||
import { TrackingContext } from '../../ATInternetTracking'
|
||||
import { useParamsFromSituation } from '../utils/useSearchParamsSimulationSharing'
|
||||
|
@ -16,7 +19,11 @@ import { PlacesDesEntreprisesButton } from '../PlaceDesEntreprises'
|
|||
|
||||
export function useUrl() {
|
||||
const language = useTranslation().i18n.language
|
||||
const situation = useSelector(situationSelector)
|
||||
const situation = {
|
||||
...useSelector(situationSelector),
|
||||
...useSelector(companySituationSelector),
|
||||
}
|
||||
delete situation['entreprise . SIREN']
|
||||
const searchParams = useParamsFromSituation(situation)
|
||||
const currentSimulatorData = useContext(CurrentSimulatorDataContext)
|
||||
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
import { Grid, styled } from '@mui/material'
|
||||
import { ConversationProps } from '@/components/conversation/Conversation'
|
||||
import PageFeedback from '@/components/Feedback'
|
||||
import ShareOrSaveSimulationBanner from '@/components/ShareSimulationBanner'
|
||||
import { PopoverWithTrigger } from '@/design-system'
|
||||
import { Spacing } from '@/design-system/layout'
|
||||
import { Link } from '@/design-system/typography/link'
|
||||
import {
|
||||
companySituationSelector,
|
||||
firstStepCompletedSelector,
|
||||
} from '@/selectors/simulationSelectors'
|
||||
import { Grid, styled } from '@mui/material'
|
||||
import React from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { firstStepCompletedSelector } from '@/selectors/simulationSelectors'
|
||||
import { TrackPage } from '../../ATInternetTracking'
|
||||
import Banner from '../Banner'
|
||||
import AnswerList from '../conversation/AnswerList'
|
||||
import PreviousSimulationBanner from './../PreviousSimulationBanner'
|
||||
import ExportRecover from './../simulationExplanation/ExportRecover'
|
||||
import { FadeIn, FromTop } from './../ui/animate'
|
||||
|
@ -42,6 +49,9 @@ export default function Simulation({
|
|||
customEndMessages,
|
||||
}: SimulationProps) {
|
||||
const firstStepCompleted = useSelector(firstStepCompletedSelector)
|
||||
const existingCompany = !!useSelector(companySituationSelector)[
|
||||
'entreprise . SIREN'
|
||||
]
|
||||
return (
|
||||
<>
|
||||
{!firstStepCompleted && <TrackPage name="accueil" />}
|
||||
|
@ -53,6 +63,7 @@ export default function Simulation({
|
|||
<div className="print-hidden">
|
||||
{!firstStepCompleted && (
|
||||
<>
|
||||
<Spacing sm />
|
||||
<PreviousSimulationBanner />
|
||||
{afterQuestionsSlot}
|
||||
</>
|
||||
|
@ -62,10 +73,30 @@ export default function Simulation({
|
|||
<FromTop>
|
||||
{results}
|
||||
<Questions customEndMessages={customEndMessages} />
|
||||
{afterQuestionsSlot || <Spacing sm />}
|
||||
<Spacing sm />
|
||||
{afterQuestionsSlot}
|
||||
</FromTop>
|
||||
)}
|
||||
{existingCompany && (
|
||||
<Banner icon="✏">
|
||||
Ce simulateur a été prérempli avec les données de votre
|
||||
entreprise.{' '}
|
||||
<PopoverWithTrigger
|
||||
trigger={(buttonProps) => (
|
||||
<Link {...buttonProps}>
|
||||
<Trans>Voir ma situation</Trans>
|
||||
</Link>
|
||||
)}
|
||||
>
|
||||
{(close) => <AnswerList onClose={close} />}
|
||||
</PopoverWithTrigger>
|
||||
</Banner>
|
||||
)}
|
||||
{firstStepCompleted && (
|
||||
<>
|
||||
<ShareOrSaveSimulationBanner />
|
||||
<Spacing lg />
|
||||
</FromTop>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</StyledGrid>
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
import { Helmet } from 'react-helmet-async'
|
||||
|
||||
let createQueryParams = (params) =>
|
||||
Object.keys(params)
|
||||
.map((k) => `${k}=${encodeURI(params[k])}`)
|
||||
.join('&')
|
||||
|
||||
let url = (hiddenVariables) =>
|
||||
'https://embauchegouv.typeform.com/to/dvbINf?' +
|
||||
createQueryParams(hiddenVariables)
|
||||
|
||||
let TypeFormEmbed = ({ hiddenVariables }) => (
|
||||
<div>
|
||||
<a
|
||||
className="typeform-share button"
|
||||
href={url(hiddenVariables)}
|
||||
data-mode="popup"
|
||||
data-auto-open
|
||||
data-hide-headers
|
||||
data-hide-footer
|
||||
target="_blank"
|
||||
/>
|
||||
<Helmet
|
||||
script={[
|
||||
{
|
||||
type: 'text/javascript',
|
||||
innerHTML:
|
||||
'(function() { var qs,js,q,s,d=document, gi=d.getElementById, ce=d.createElement, gt=d.getElementsByTagName, id="typef_orm_share", b="https://embed.typeform.com/"; if(!gi.call(d,id)){ js=ce.call(d,"script"); js.id=id; js.src=b+"embed.js"; q=gt.call(d,"script")[0]; q.parentNode.insertBefore(js,q) } })() ',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default TypeFormEmbed
|
|
@ -0,0 +1,34 @@
|
|||
import { Message } from '@/design-system'
|
||||
import { CardContainer } from '@/design-system/card/Card'
|
||||
import { Strong } from '@/design-system/typography'
|
||||
import { H4 } from '@/design-system/typography/heading'
|
||||
import { Body, Intro } from '@/design-system/typography/paragraphs'
|
||||
import styled from 'styled-components'
|
||||
import Value from '../EngineValue'
|
||||
|
||||
export function CompanyDetails() {
|
||||
return (
|
||||
<StyledCompanyContainer>
|
||||
<H4>
|
||||
{' '}
|
||||
<Value expression="entreprise . nom" linkToRule={false} />{' '}
|
||||
<Value expression="entreprise . SIREN" linkToRule={false} />
|
||||
</H4>
|
||||
<Body>
|
||||
Crée le{' '}
|
||||
<Strong>
|
||||
<Value
|
||||
expression="entreprise . date de création"
|
||||
linkToRule={false}
|
||||
/>
|
||||
</Strong>{' '}
|
||||
et domiciliée à{' '}
|
||||
<Strong>
|
||||
<Value expression="établissement . localisation" linkToRule={false} />
|
||||
</Strong>
|
||||
</Body>
|
||||
</StyledCompanyContainer>
|
||||
)
|
||||
}
|
||||
|
||||
const StyledCompanyContainer = styled(Message).attrs({ border: false })``
|
|
@ -1,26 +1,20 @@
|
|||
import { FabriqueSocialEntreprise } from '@/api/fabrique-social'
|
||||
import { Spacing } from '@/design-system/layout'
|
||||
import { Strong } from '@/design-system/typography'
|
||||
import { H3 } from '@/design-system/typography/heading'
|
||||
import { Body } from '@/design-system/typography/paragraphs'
|
||||
import { H4 } from '@/design-system/typography/heading'
|
||||
import { useMemo } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { Company } from '@/reducers/inFranceAppReducer'
|
||||
import styled from 'styled-components'
|
||||
|
||||
export default function CompanyDetails({
|
||||
export default function CompanySearchDetails({
|
||||
entreprise,
|
||||
}: {
|
||||
entreprise: FabriqueSocialEntreprise | Company
|
||||
entreprise: FabriqueSocialEntreprise
|
||||
}) {
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
const {
|
||||
siren,
|
||||
label,
|
||||
dateCreationUniteLegale,
|
||||
firstMatchingEtablissement,
|
||||
allMatchingEtablissements,
|
||||
} = entreprise
|
||||
const { siren, label, dateCreationUniteLegale, firstMatchingEtablissement } =
|
||||
entreprise
|
||||
|
||||
const DateFormatter = useMemo(
|
||||
() =>
|
||||
|
@ -40,12 +34,12 @@ export default function CompanyDetails({
|
|||
// </SmallBody>
|
||||
// )
|
||||
// }
|
||||
const siege = allMatchingEtablissements.find((e) => e.is_siege)
|
||||
return (
|
||||
<CompanyContainer>
|
||||
<H3
|
||||
<H4
|
||||
as="div"
|
||||
css={`
|
||||
margin-top: 0;
|
||||
margin: 0;
|
||||
`}
|
||||
>
|
||||
<>
|
||||
|
@ -53,33 +47,20 @@ export default function CompanyDetails({
|
|||
? highlightLabelToJSX(entreprise.highlightLabel)
|
||||
: label}{' '}
|
||||
<small>({siren})</small>
|
||||
</>{' '}
|
||||
</H3>
|
||||
|
||||
<InfoContainer as="div">
|
||||
{dateCreationUniteLegale && (
|
||||
<div>
|
||||
<Trans>Crée le</Trans>{' '}
|
||||
<Strong>
|
||||
{DateFormatter.format(new Date(dateCreationUniteLegale))}
|
||||
</Strong>
|
||||
</div>
|
||||
)}
|
||||
<div>{firstMatchingEtablissement.address}</div>
|
||||
{siege &&
|
||||
allMatchingEtablissements.length > 1 &&
|
||||
siege.address !== firstMatchingEtablissement.address && (
|
||||
<div>
|
||||
<Trans>Siège :</Trans> {siege.address}
|
||||
</div>
|
||||
)}
|
||||
</InfoContainer>
|
||||
</>
|
||||
</H4>
|
||||
<Spacing sm />
|
||||
<Trans>Crée le :</Trans>{' '}
|
||||
<Strong>{DateFormatter.format(new Date(dateCreationUniteLegale))}</Strong>
|
||||
<br />
|
||||
<Trans>Domiciliée à l'adresse :</Trans>{' '}
|
||||
<Strong>{firstMatchingEtablissement.address}</Strong>
|
||||
</CompanyContainer>
|
||||
)
|
||||
}
|
||||
|
||||
function highlightLabelToJSX(highlightLabel: string) {
|
||||
const highlightRE = /(.*?)<b><u>(\w+)<\/u><\/b>/gm
|
||||
const highlightRE = /(.*?)<b><u>(.+?)<\/u><\/b>/gm
|
||||
let parsedLength = 0
|
||||
const result = []
|
||||
let matches
|
||||
|
@ -97,16 +78,9 @@ function highlightLabelToJSX(highlightLabel: string) {
|
|||
}
|
||||
|
||||
const Highlight = styled.strong`
|
||||
text-decoration: underline;
|
||||
background-color: ${({ theme }) => theme.colors.bases.secondary[100]};
|
||||
`
|
||||
|
||||
const CompanyContainer = styled.div`
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
text-align: left;
|
||||
`
|
||||
|
||||
const InfoContainer = styled(Body)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`
|
|
@ -11,8 +11,8 @@ import useSearchCompany from '@/hooks/useSearchCompany'
|
|||
import { ReactNode, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
import CompanyDetails from './CompanyDetails'
|
||||
import { FromTop } from './ui/animate'
|
||||
import CompanySearchDetails from './SearchDetails'
|
||||
import { FromTop } from '../ui/animate'
|
||||
|
||||
const StyledCard = styled(Card)`
|
||||
flex-direction: row; // for Safari <= 13
|
||||
|
@ -100,9 +100,9 @@ function Results({
|
|||
<FromTop>
|
||||
<Grid container spacing={2} data-testid="company-search-results">
|
||||
{results.map((etablissement) => (
|
||||
<Grid key={etablissement.siren} item xs={12} xl={6}>
|
||||
<Grid key={etablissement.siren} item xs={12}>
|
||||
<StyledCard onPress={() => onSubmit?.(etablissement)} compact>
|
||||
<CompanyDetails entreprise={etablissement} />
|
||||
<CompanySearchDetails entreprise={etablissement} />
|
||||
</StyledCard>
|
||||
</Grid>
|
||||
))}
|
|
@ -1,40 +1,36 @@
|
|||
import { goToQuestion, resetSimulation } from '@/actions/actions'
|
||||
import { resetCompany } from '@/actions/companyActions'
|
||||
import Emoji from '@/components/utils/Emoji'
|
||||
import { useEngine } from '@/components/utils/EngineContext'
|
||||
import { useNextQuestions } from '@/components/utils/useNextQuestion'
|
||||
import { Button } from '@/design-system/buttons'
|
||||
import { H2 } from '@/design-system/typography/heading'
|
||||
import { Spacing } from '@/design-system/layout'
|
||||
import { H2, H3 } from '@/design-system/typography/heading'
|
||||
import { Link } from '@/design-system/typography/link'
|
||||
import { DottedName } from 'modele-social'
|
||||
import { EvaluatedNode, formatValue } from 'publicodes'
|
||||
import { useMemo } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import {
|
||||
answeredQuestionsSelector,
|
||||
companySituationSelector,
|
||||
situationSelector,
|
||||
} from '@/selectors/simulationSelectors'
|
||||
import { Grid } from '@mui/material'
|
||||
import { DottedName } from 'modele-social'
|
||||
import { EvaluatedNode } from 'publicodes'
|
||||
import { useMemo } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import styled from 'styled-components'
|
||||
import Value from '../EngineValue'
|
||||
import './AnswerList.css'
|
||||
|
||||
type AnswerListProps = {
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
const Header = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
`
|
||||
|
||||
const Title = styled(H2)`
|
||||
flex-grow: 1;
|
||||
`
|
||||
|
||||
export default function AnswerList({ onClose }: AnswerListProps) {
|
||||
const dispatch = useDispatch()
|
||||
const engine = useEngine()
|
||||
const situation = useSelector(situationSelector)
|
||||
const companySituation = useSelector(companySituationSelector)
|
||||
const passedQuestions = useSelector(answeredQuestionsSelector)
|
||||
const answeredAndPassedQuestions = useMemo(
|
||||
() =>
|
||||
|
@ -43,37 +39,79 @@ export default function AnswerList({ onClose }: AnswerListProps) {
|
|||
(answered) => !passedQuestions.some((passed) => answered === passed)
|
||||
)
|
||||
.concat(passedQuestions)
|
||||
.filter((answered) => !(answered in companySituation))
|
||||
.map((dottedName) => engine.evaluate(engine.getRule(dottedName))),
|
||||
[engine, passedQuestions, situation]
|
||||
[engine, passedQuestions, situation, companySituation]
|
||||
)
|
||||
|
||||
const nextSteps = useNextQuestions().map((dottedName) =>
|
||||
engine.evaluate(engine.getRule(dottedName))
|
||||
)
|
||||
const companyQuestions = useMemo(
|
||||
() =>
|
||||
(Object.keys(companySituation) as DottedName[]).map((dottedName) =>
|
||||
engine.evaluate(engine.getRule(dottedName))
|
||||
),
|
||||
[engine, companySituation]
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="answer-list">
|
||||
<H2>
|
||||
<Emoji emoji="📋 " />
|
||||
<Trans>Ma situation</Trans>
|
||||
</H2>
|
||||
|
||||
{!!answeredAndPassedQuestions.length && (
|
||||
<>
|
||||
<Header>
|
||||
<Title>
|
||||
<Emoji emoji="📋 " />
|
||||
<Trans>Mes réponses</Trans>
|
||||
</Title>
|
||||
<H3>
|
||||
<Trans>Données de simulation</Trans>
|
||||
</H3>
|
||||
|
||||
<StepsTable {...{ rules: answeredAndPassedQuestions, onClose }} />
|
||||
<Spacing sm />
|
||||
<div
|
||||
css={`
|
||||
text-align: center;
|
||||
`}
|
||||
>
|
||||
<Button
|
||||
size="XS"
|
||||
light
|
||||
onPress={() => {
|
||||
dispatch(resetSimulation())
|
||||
onClose()
|
||||
}}
|
||||
>
|
||||
<Emoji emoji="🗑" /> <Trans>Tout effacer</Trans>
|
||||
<Emoji emoji="🗑" /> <Trans>Recommencer la simulation</Trans>
|
||||
</Button>
|
||||
</Header>
|
||||
<StepsTable {...{ rules: answeredAndPassedQuestions, onClose }} />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{companyQuestions.length > 0 && (
|
||||
<>
|
||||
<H3>
|
||||
<Trans>Données de l'entreprise</Trans>
|
||||
</H3>
|
||||
<StepsTable {...{ rules: companyQuestions, onClose }} />
|
||||
<Spacing sm />
|
||||
<div
|
||||
css={`
|
||||
text-align: center;
|
||||
`}
|
||||
>
|
||||
<Button
|
||||
light
|
||||
size="XS"
|
||||
onClick={() => {
|
||||
dispatch(resetSimulation())
|
||||
dispatch(resetCompany())
|
||||
}}
|
||||
>
|
||||
<Emoji emoji="🗑" /> <Trans>Effacer toutes mes données</Trans>
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{!!nextSteps.length && (
|
||||
<>
|
||||
<H2>
|
||||
|
@ -87,16 +125,6 @@ export default function AnswerList({ onClose }: AnswerListProps) {
|
|||
)
|
||||
}
|
||||
|
||||
const TBody = styled.tbody`
|
||||
font-family: ${({ theme }) => theme.fonts.main};
|
||||
& > tr > td {
|
||||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
& > tr:nth-child(2n) {
|
||||
background-color: ${({ theme }) => theme.colors.bases.primary[100]};
|
||||
}
|
||||
`
|
||||
|
||||
function StepsTable({
|
||||
rules,
|
||||
onClose,
|
||||
|
@ -105,28 +133,45 @@ function StepsTable({
|
|||
onClose: () => void
|
||||
}) {
|
||||
const dispatch = useDispatch()
|
||||
const language = useTranslation().i18n.language
|
||||
return (
|
||||
<table>
|
||||
<TBody>
|
||||
{rules.map((rule) => (
|
||||
<tr key={rule.dottedName}>
|
||||
<td>
|
||||
<>
|
||||
{rules
|
||||
.filter((rule) => rule.nodeValue !== null)
|
||||
.map((rule) => (
|
||||
<StyledAnswerList
|
||||
container
|
||||
alignItems={'baseline'}
|
||||
key={rule.dottedName}
|
||||
>
|
||||
<Grid item md={8}>
|
||||
{rule.title}
|
||||
</Grid>
|
||||
<StyledAnswer item lg={4}>
|
||||
<Link
|
||||
onPress={() => {
|
||||
dispatch(goToQuestion(rule.dottedName))
|
||||
onClose()
|
||||
}}
|
||||
title="Modifier"
|
||||
>
|
||||
{rule.title}
|
||||
<Value expression={rule.dottedName} linkToRule={false} />{' '}
|
||||
<Emoji emoji="✏" alt="Modifier" />
|
||||
</Link>
|
||||
</td>
|
||||
<td>
|
||||
<span className="">{formatValue(rule, { language })}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</StyledAnswer>
|
||||
</StyledAnswerList>
|
||||
))}
|
||||
</TBody>
|
||||
</table>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const StyledAnswer = styled(Grid)`
|
||||
text-align: right;
|
||||
`
|
||||
const StyledAnswerList = styled(Grid)`
|
||||
padding: ${({ theme }) => theme.spacings.xs};
|
||||
margin: 0 -${({ theme }) => theme.spacings.xs};
|
||||
font-family: ${({ theme }) => theme.fonts.main};
|
||||
:nth-child(2n) {
|
||||
background-color: ${({ theme }) => theme.colors.bases.primary[100]};
|
||||
}
|
||||
`
|
||||
|
|
|
@ -24,10 +24,14 @@ import { ExplicableRule } from './Explicable'
|
|||
import SeeAnswersButton from './SeeAnswersButton'
|
||||
|
||||
export type ConversationProps = {
|
||||
displayNotification: boolean
|
||||
customEndMessages?: React.ReactNode
|
||||
}
|
||||
|
||||
export default function Conversation({ customEndMessages }: ConversationProps) {
|
||||
export default function Conversation({
|
||||
customEndMessages,
|
||||
displayNotification = true,
|
||||
}: ConversationProps) {
|
||||
const dispatch = useDispatch()
|
||||
const engine = useContext(EngineContext)
|
||||
const currentQuestion = useNextQuestions()[0]
|
||||
|
@ -107,7 +111,7 @@ export default function Conversation({ customEndMessages }: ConversationProps) {
|
|||
<SeeAnswersButton />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Notifications />
|
||||
{displayNotification && <Notifications />}
|
||||
</form>
|
||||
<QuickLinks />
|
||||
</>
|
||||
|
|
|
@ -9,10 +9,9 @@ export default function SeeAnswersButton() {
|
|||
<PopoverWithTrigger
|
||||
trigger={(buttonProps) => (
|
||||
<Button {...buttonProps} light size="XS">
|
||||
<Trans>Voir mes paramètres</Trans>
|
||||
<Trans>Voir ma situation</Trans>
|
||||
</Button>
|
||||
)}
|
||||
small
|
||||
>
|
||||
{(close) => <Answers onClose={close} />}
|
||||
</PopoverWithTrigger>
|
||||
|
|
|
@ -2,6 +2,7 @@ import Value from '@/components/EngineValue'
|
|||
import { FromBottom } from '@/components/ui/animate'
|
||||
import { useEngine } from '@/components/utils/EngineContext'
|
||||
import { Markdown } from '@/components/utils/markdown'
|
||||
import { Message } from '@/design-system'
|
||||
import { Button } from '@/design-system/buttons'
|
||||
import { Spacing } from '@/design-system/layout'
|
||||
import { H3 } from '@/design-system/typography/heading'
|
||||
|
@ -14,7 +15,7 @@ export default function CotisationsForfaitaires() {
|
|||
)
|
||||
return (
|
||||
<FromBottom>
|
||||
<div>
|
||||
<Message>
|
||||
<H3 as="h2">{rule.title}</H3>
|
||||
<Intro>
|
||||
<Trans i18nKey="pages.simulateurs.indépendant.cotisations-forfaitaires">
|
||||
|
@ -26,7 +27,7 @@ export default function CotisationsForfaitaires() {
|
|||
<Markdown>{rule.rawNode.description ?? ''}</Markdown>
|
||||
{rule.rawNode.références && (
|
||||
<>
|
||||
<Spacing lg />
|
||||
<Spacing md />
|
||||
<Button
|
||||
href={Object.values(rule.rawNode.références)[0]}
|
||||
size="XS"
|
||||
|
@ -34,9 +35,10 @@ export default function CotisationsForfaitaires() {
|
|||
>
|
||||
<Trans>Voir la fiche Urssaf</Trans>
|
||||
</Button>
|
||||
<Spacing lg />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Message>
|
||||
</FromBottom>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import { Trans } from 'react-i18next'
|
|||
import { useSelector } from 'react-redux'
|
||||
import { targetUnitSelector } from '@/selectors/simulationSelectors'
|
||||
import styled from 'styled-components'
|
||||
import { Message } from '@/design-system'
|
||||
|
||||
export default function InstitutionsPartenaires() {
|
||||
const unit = useSelector(targetUnitSelector)
|
||||
|
@ -30,44 +31,49 @@ export default function InstitutionsPartenaires() {
|
|||
Vos institutions partenaires
|
||||
</Trans>
|
||||
</H3>
|
||||
<InstitutionsTable>
|
||||
<WhenApplicable dottedName="dirigeant . indépendant . PL . CNAVPL">
|
||||
<CotisationsUrssaf rule="dirigeant . indépendant . PL . cotisations Urssaf" />
|
||||
<CaisseRetraite />
|
||||
</WhenApplicable>
|
||||
<WhenNotApplicable dottedName="dirigeant . indépendant . PL . CNAVPL">
|
||||
<CotisationsUrssaf rule="dirigeant . indépendant . cotisations et contributions" />
|
||||
</WhenNotApplicable>
|
||||
<ImpôtsDGFIP />
|
||||
<Condition expression="dirigeant . indépendant . PL . PAMC . participation CPAM > 0">
|
||||
<InstitutionLine>
|
||||
<InstitutionLogo
|
||||
href="https://www.ameli.fr/assure/droits-demarches/salaries-travailleurs-independants-et-personnes-sans-emploi/emploi-independant-non-salarie/praticien-auxiliaire-medical"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={assuranceMaladieSrc} title="Logo CPAM" />
|
||||
</InstitutionLogo>
|
||||
<Body>
|
||||
<Trans i18nKey="simulateurs.explanation.institutions.cpam">
|
||||
En tant que professionnel de santé conventionné, vous
|
||||
bénéficiez d'une prise en charge d'une partie de vos
|
||||
cotisations par l'Assurance Maladie.
|
||||
</Trans>
|
||||
</Body>
|
||||
<Body className="ui__ lead">
|
||||
<Emoji emoji="🎁" />{' '}
|
||||
<RuleLink dottedName="dirigeant . indépendant . PL . PAMC . participation CPAM">
|
||||
<Value
|
||||
unit={unit}
|
||||
displayedUnit="€"
|
||||
expression="- dirigeant . indépendant . PL . PAMC . participation CPAM"
|
||||
/>
|
||||
</RuleLink>
|
||||
</Body>
|
||||
</InstitutionLine>
|
||||
</Condition>
|
||||
</InstitutionsTable>
|
||||
<Grid container>
|
||||
<Grid item lg={12} xl={10}>
|
||||
<Message border={false}>
|
||||
<WhenApplicable dottedName="dirigeant . indépendant . PL . CNAVPL">
|
||||
<CotisationsUrssaf rule="dirigeant . indépendant . PL . cotisations Urssaf" />
|
||||
<CaisseRetraite />
|
||||
</WhenApplicable>
|
||||
<WhenNotApplicable dottedName="dirigeant . indépendant . PL . CNAVPL">
|
||||
<CotisationsUrssaf rule="dirigeant . indépendant . cotisations et contributions" />
|
||||
</WhenNotApplicable>
|
||||
<ImpôtsDGFIP />
|
||||
<Condition expression="dirigeant . indépendant . PL . PAMC . participation CPAM > 0">
|
||||
<InstitutionLine>
|
||||
<InstitutionLogo
|
||||
href="https://www.ameli.fr/assure/droits-demarches/salaries-travailleurs-independants-et-personnes-sans-emploi/emploi-independant-non-salarie/praticien-auxiliaire-medical"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={assuranceMaladieSrc} title="Logo CPAM" />
|
||||
</InstitutionLogo>
|
||||
<Body>
|
||||
<Trans i18nKey="simulateurs.explanation.institutions.cpam">
|
||||
En tant que professionnel de santé conventionné, vous
|
||||
bénéficiez d'une prise en charge d'une partie de vos
|
||||
cotisations par l'Assurance Maladie.
|
||||
</Trans>
|
||||
</Body>
|
||||
<Body className="ui__ lead">
|
||||
<Emoji emoji="🎁" />{' '}
|
||||
<RuleLink dottedName="dirigeant . indépendant . PL . PAMC . participation CPAM">
|
||||
<Value
|
||||
unit={unit}
|
||||
displayedUnit="€"
|
||||
expression="- dirigeant . indépendant . PL . PAMC . participation CPAM"
|
||||
/>
|
||||
</RuleLink>
|
||||
</Body>
|
||||
</InstitutionLine>
|
||||
</Condition>
|
||||
</Message>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Condition expression="dirigeant . indépendant . cotisations et contributions . exonérations . ACRE > 0">
|
||||
<SmallBody>
|
||||
<Trans i18nKey="simulateurs.explanation.institutions.notice acre">
|
||||
|
@ -202,37 +208,41 @@ export function InstitutionsPartenairesArtisteAuteur() {
|
|||
return (
|
||||
<section>
|
||||
<H3>Vos cotisations</H3>
|
||||
<InstitutionsTable>
|
||||
<CotisationsUrssaf
|
||||
rule="artiste-auteur . cotisations"
|
||||
extraNotice={
|
||||
<Condition expression="artiste-auteur . revenus . traitements et salaires > 0">
|
||||
<Trans i18nKey="simulateurs.explanation.institutions.précompte-artiste-auteur">
|
||||
Pour vos revenus en traitement et salaires, ces cotisations sont
|
||||
« précomptées », c'est à dire payées à la source par le
|
||||
diffuseur.
|
||||
</Trans>
|
||||
</Condition>
|
||||
}
|
||||
/>
|
||||
<Condition expression="artiste-auteur . cotisations . IRCEC > 0">
|
||||
<InstitutionLine>
|
||||
<InstitutionLogo
|
||||
href="http://www.ircec.fr/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={logosSrc['IRCEC']} title="logo IRCEC" />
|
||||
</InstitutionLogo>
|
||||
<Body>{descriptionIRCEC}</Body>
|
||||
<Value
|
||||
displayedUnit="€"
|
||||
unit={unit}
|
||||
expression="artiste-auteur . cotisations . IRCEC"
|
||||
<Grid container>
|
||||
<Grid item lg={12} xl={10}>
|
||||
<Message border={false}>
|
||||
<CotisationsUrssaf
|
||||
rule="artiste-auteur . cotisations"
|
||||
extraNotice={
|
||||
<Condition expression="artiste-auteur . revenus . traitements et salaires > 0">
|
||||
<Trans i18nKey="simulateurs.explanation.institutions.précompte-artiste-auteur">
|
||||
Pour vos revenus en traitement et salaires, ces cotisations
|
||||
sont « précomptées », c'est à dire payées à la source par le
|
||||
diffuseur.
|
||||
</Trans>
|
||||
</Condition>
|
||||
}
|
||||
/>
|
||||
</InstitutionLine>
|
||||
</Condition>
|
||||
</InstitutionsTable>
|
||||
<Condition expression="artiste-auteur . cotisations . IRCEC > 0">
|
||||
<InstitutionLine>
|
||||
<InstitutionLogo
|
||||
href="http://www.ircec.fr/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={logosSrc['IRCEC']} title="logo IRCEC" />
|
||||
</InstitutionLogo>
|
||||
<Body>{descriptionIRCEC}</Body>
|
||||
<Value
|
||||
displayedUnit="€"
|
||||
unit={unit}
|
||||
expression="artiste-auteur . cotisations . IRCEC"
|
||||
/>
|
||||
</InstitutionLine>
|
||||
</Condition>
|
||||
</Message>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
@ -246,22 +256,19 @@ export function InstitutionsPartenairesAutoEntrepreneur() {
|
|||
Vos institutions partenaires
|
||||
</Trans>
|
||||
</H2>
|
||||
<InstitutionsTable>
|
||||
<CotisationsUrssaf rule="dirigeant . auto-entrepreneur . cotisations et contributions" />
|
||||
<ImpôtsDGFIP />
|
||||
</InstitutionsTable>
|
||||
<Grid container>
|
||||
<Grid item lg={12} xl={10}>
|
||||
<Message border={false}>
|
||||
<CotisationsUrssaf rule="dirigeant . auto-entrepreneur . cotisations et contributions" />
|
||||
<ImpôtsDGFIP />
|
||||
</Message>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</FromBottom>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
const InstitutionsTable = styled(Grid).attrs({ item: true, xl: 10 })`
|
||||
border-radius: ${({ theme }) => theme.box.borderRadius};
|
||||
box-shadow: ${({ theme }) => theme.elevations[2]};
|
||||
padding: ${({ theme }) => theme.spacings.xs}
|
||||
${({ theme }) => theme.spacings.md};
|
||||
`
|
||||
|
||||
const InstitutionLogo = styled.a`
|
||||
img {
|
||||
max-width: 100%;
|
||||
|
@ -273,13 +280,9 @@ const InstitutionLine = styled.div`
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
padding: ${({ theme }) => theme.spacings.md};
|
||||
flex-wrap: wrap;
|
||||
|
||||
&:not(:first-child) {
|
||||
border-top: 1px solid var(--lighterColor);
|
||||
}
|
||||
|
||||
> ${InstitutionLogo} {
|
||||
display: block;
|
||||
width: 13ch;
|
||||
|
|
|
@ -2,13 +2,15 @@ import emojiFn from 'react-easy-emoji'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
type PropType = {
|
||||
emoji: string | undefined
|
||||
alt?: string
|
||||
title?: string
|
||||
}
|
||||
|
||||
// This custom component has several advantages over the direct use of the
|
||||
// `emojiFn` provided by `react-easy-emoji` :
|
||||
// - allow to configure the URL to self host twemoji images in production
|
||||
// - using a real React component works better with the translation scripts
|
||||
export default function Emoji({ emoji }: PropType) {
|
||||
export default function Emoji({ emoji, alt, title }: PropType) {
|
||||
const language = useTranslation().i18n.language
|
||||
|
||||
const siteUrl =
|
||||
|
@ -24,7 +26,11 @@ export default function Emoji({ emoji }: PropType) {
|
|||
? {
|
||||
baseUrl: siteUrl + '/twemoji/2/',
|
||||
ext: '.png',
|
||||
props: {
|
||||
alt,
|
||||
title,
|
||||
},
|
||||
}
|
||||
: undefined
|
||||
: { props: { alt, title }, ext: '.png' }
|
||||
)
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ const engineOptions = {
|
|||
return key || unit
|
||||
},
|
||||
}
|
||||
export function engineFactory(rules: Rules) {
|
||||
return new Engine(rules, engineOptions)
|
||||
export function engineFactory(rules: Rules, options = {}) {
|
||||
return new Engine(rules, { ...engineOptions, ...options })
|
||||
}
|
||||
|
||||
export const EngineContext = createContext<Engine>(new Engine())
|
||||
|
|
|
@ -129,21 +129,24 @@ export const useNextQuestions = function (): Array<DottedName> {
|
|||
(node) => engine.evaluate(node).missingVariables ?? {}
|
||||
)
|
||||
const nextQuestions = useMemo(() => {
|
||||
const next = getNextQuestions(
|
||||
let next = getNextQuestions(
|
||||
missingVariables,
|
||||
questionsConfig ?? {},
|
||||
answeredQuestions,
|
||||
situation
|
||||
)
|
||||
if (currentQuestion && currentQuestion !== next[0]) {
|
||||
return [currentQuestion, ...next.filter((val) => val !== currentQuestion)]
|
||||
next = [currentQuestion, ...next.filter((val) => val !== currentQuestion)]
|
||||
}
|
||||
return next
|
||||
return next.filter(
|
||||
(question) => engine.evaluate(question).nodeValue !== null
|
||||
)
|
||||
}, [
|
||||
missingVariables,
|
||||
questionsConfig,
|
||||
answeredQuestions,
|
||||
situation,
|
||||
engine,
|
||||
currentQuestion,
|
||||
])
|
||||
|
||||
|
|
|
@ -7,7 +7,11 @@ import { useEngine } from '@/components/utils/EngineContext'
|
|||
import { configSelector } from '@/selectors/simulationSelectors'
|
||||
import Engine, { ParsedRules, serializeEvaluation } from 'publicodes'
|
||||
import { DottedName } from 'modele-social'
|
||||
import { updateSituation, setActiveTarget } from '@/actions/actions'
|
||||
import {
|
||||
updateSituation,
|
||||
setActiveTarget,
|
||||
batchUpdateSituation,
|
||||
} from '@/actions/actions'
|
||||
|
||||
type Objectifs = (string | { objectifs: string[] })[]
|
||||
type ShortName = string
|
||||
|
@ -28,12 +32,13 @@ export default function useSearchParamsSimulationSharing() {
|
|||
)
|
||||
|
||||
useEffect(() => {
|
||||
const hasConfig = Object.keys(config).length > 0
|
||||
// TODO: this check is specific to `useSimulationConfig` and
|
||||
// `setSimulationConfig`, so we'd prefer not doing it here. Other ideas
|
||||
// include having the config in a provider rather than in state.
|
||||
const configLoadedInState = simulationUrl === currentUrl
|
||||
if (!hasConfig || !configLoadedInState) return
|
||||
// const hasConfig = Object.keys(config).length > 0
|
||||
|
||||
// // TODO: this check is specific to `useSimulationConfig` and
|
||||
// // `setSimulationConfig`, so we'd prefer not doing it here. Other ideas
|
||||
// // include having the config in a provider rather than in state.
|
||||
// const configLoadedInState = simulationUrl === currentUrl
|
||||
// if (!hasConfig || !configLoadedInState) return
|
||||
|
||||
// On load:
|
||||
if (!urlSituationIsExtracted) {
|
||||
|
@ -43,9 +48,8 @@ export default function useSearchParamsSimulationSharing() {
|
|||
dottedNameParamName
|
||||
)
|
||||
|
||||
Object.entries(newSituation).forEach(([dottedName, value]) => {
|
||||
dispatch(updateSituation(dottedName as DottedName, value))
|
||||
})
|
||||
dispatch(batchUpdateSituation(newSituation as Situation))
|
||||
|
||||
const newActiveTarget = Object.keys(newSituation).filter((dottedName) =>
|
||||
objectifs.includes(dottedName)
|
||||
)[0]
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import { setSimulationConfig } from '@/actions/actions'
|
||||
import { SimulationConfig } from '@/reducers/rootReducer'
|
||||
import { configSelector } from '@/selectors/simulationSelectors'
|
||||
import { useEffect } from 'react'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { useHistory } from 'react-router'
|
||||
import { Company } from '@/reducers/inFranceAppReducer'
|
||||
import { RootState, SimulationConfig, Situation } from '@/reducers/rootReducer'
|
||||
import { configSelector } from '@/selectors/simulationSelectors'
|
||||
|
||||
export default function useSimulationConfig(
|
||||
config: SimulationConfig | undefined,
|
||||
{ useExistingCompanyFromSituation = false } = {}
|
||||
config: SimulationConfig | undefined
|
||||
) {
|
||||
const dispatch = useDispatch()
|
||||
// TODO : Reading the URL here is buggy because when we do SPA navigation the
|
||||
|
@ -17,31 +15,10 @@ export default function useSimulationConfig(
|
|||
// accessible from the situation config but is defined in the metadata file.
|
||||
const url = useHistory().location.pathname.split('?')[0]
|
||||
|
||||
const existingCompany = useSelector(
|
||||
(state: RootState) => state.inFranceApp.existingCompany
|
||||
)
|
||||
const initialSituation = useExistingCompanyFromSituation
|
||||
? getCompanySituation(existingCompany)
|
||||
: undefined
|
||||
|
||||
const lastConfig = useSelector(configSelector)
|
||||
useEffect(() => {
|
||||
if (config && lastConfig !== config) {
|
||||
dispatch(setSimulationConfig(config ?? {}, url, initialSituation))
|
||||
dispatch(setSimulationConfig(config ?? {}, url))
|
||||
}
|
||||
}, [config, dispatch, lastConfig, initialSituation, url])
|
||||
}
|
||||
|
||||
export function getCompanySituation(company: Company | null): Situation {
|
||||
return {
|
||||
...(company?.localisation && {
|
||||
'établissement . localisation': { objet: company.localisation },
|
||||
}),
|
||||
...(company?.dateCreationUniteLegale && {
|
||||
'entreprise . date de création': company.dateCreationUniteLegale.replace(
|
||||
/(.*)-(.*)-(.*)/,
|
||||
'$3/$2/$1'
|
||||
),
|
||||
}),
|
||||
}
|
||||
}, [config, dispatch, lastConfig, url])
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import styled, { css } from 'styled-components'
|
||||
import styled, { css, ThemeProvider } from 'styled-components'
|
||||
import baseIcon from './baseIcon.svg'
|
||||
import infoIcon from './infoIcon.svg'
|
||||
import errorIcon from './errorIcon.svg'
|
||||
|
@ -11,7 +11,7 @@ type MessageProps = {
|
|||
children: React.ReactNode
|
||||
icon?: boolean
|
||||
border?: boolean
|
||||
type: MessageType
|
||||
type?: MessageType
|
||||
light?: boolean
|
||||
}
|
||||
export function Message({
|
||||
|
@ -25,42 +25,47 @@ export function Message({
|
|||
children = <Body>{children}</Body>
|
||||
}
|
||||
return (
|
||||
<StyledMessage type={type} border={border} light={light}>
|
||||
{icon &&
|
||||
(type === 'success' ? (
|
||||
<StyledIcon
|
||||
src={successIcon}
|
||||
title="succès"
|
||||
alt="icône signalant une alerte sur un succès"
|
||||
/>
|
||||
) : type === 'error' ? (
|
||||
<StyledIcon
|
||||
src={errorIcon}
|
||||
title="error"
|
||||
alt="icône signalant une alerte sur une erreur"
|
||||
/>
|
||||
) : type === 'info' ? (
|
||||
<StyledIcon
|
||||
src={infoIcon}
|
||||
title="info"
|
||||
alt="icône signalant une alerte sur une information"
|
||||
/>
|
||||
) : (
|
||||
<StyledIcon
|
||||
src={baseIcon}
|
||||
title="paragraph"
|
||||
alt="icône signalant un texte informatif"
|
||||
/>
|
||||
))}
|
||||
<div>{children}</div>
|
||||
</StyledMessage>
|
||||
<ThemeProvider theme={(theme) => ({ ...theme, darkMode: false })}>
|
||||
<StyledMessage type={type} border={border} light={light}>
|
||||
{icon &&
|
||||
(type === 'success' ? (
|
||||
<StyledIcon
|
||||
src={successIcon}
|
||||
title="succès"
|
||||
alt="icône signalant une alerte sur un succès"
|
||||
/>
|
||||
) : type === 'error' ? (
|
||||
<StyledIcon
|
||||
src={errorIcon}
|
||||
title="error"
|
||||
alt="icône signalant une alerte sur une erreur"
|
||||
/>
|
||||
) : type === 'info' ? (
|
||||
<StyledIcon
|
||||
src={infoIcon}
|
||||
title="info"
|
||||
alt="icône signalant une alerte sur une information"
|
||||
/>
|
||||
) : (
|
||||
<StyledIcon
|
||||
src={baseIcon}
|
||||
title="paragraph"
|
||||
alt="icône signalant un texte informatif"
|
||||
/>
|
||||
))}
|
||||
<div>{children}</div>
|
||||
</StyledMessage>
|
||||
</ThemeProvider>
|
||||
)
|
||||
}
|
||||
|
||||
const StyledMessage = styled.div<
|
||||
Pick<MessageProps, 'border' | 'type' | 'light'>
|
||||
Pick<MessageProps, 'border' | 'light'> & {
|
||||
type: NonNullable<MessageProps['type']>
|
||||
}
|
||||
>`
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: flex-start;
|
||||
${({ theme, type, border, light }) => {
|
||||
const colorSpace =
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import { ComponentStory, ComponentMeta } from '@storybook/react'
|
||||
import { Li, Ul } from '@/design-system/typography/list'
|
||||
|
||||
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
||||
export default {
|
||||
component: Ul,
|
||||
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
||||
} as ComponentMeta<typeof Ul>
|
||||
|
||||
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
|
||||
const Template: ComponentStory<typeof Ul> = (args) => (
|
||||
<Ul {...args}>
|
||||
<Li>Élément 1</Li>
|
||||
<Li>Élément 2</Li>
|
||||
<Li>Élément 3</Li>
|
||||
</Ul>
|
||||
)
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||
Basic.args = {}
|
||||
|
||||
export const XL = Template.bind({})
|
||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||
XL.args = {
|
||||
size: 'XL',
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import { stepAction, updateSituation } from '@/actions/actions'
|
||||
import { useEngine } from '@/components/utils/EngineContext'
|
||||
import { useNextQuestions } from '@/components/utils/useNextQuestion'
|
||||
import { answeredQuestionsSelector } from '@/selectors/simulationSelectors'
|
||||
import { DottedName } from 'modele-social'
|
||||
import { PublicodesExpression, RuleNode } from 'publicodes'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
export function useQuestionList(): [
|
||||
questions: Array<RuleNode & { dottedName: DottedName }>,
|
||||
onQuestionAnswered: (
|
||||
dottedName: DottedName
|
||||
) => (value?: PublicodesExpression) => void
|
||||
] {
|
||||
const answeredQuestions = useSelector(answeredQuestionsSelector)
|
||||
const nextQuestions = useNextQuestions()
|
||||
const engine = useEngine()
|
||||
|
||||
const questions = [...answeredQuestions, ...nextQuestions]
|
||||
.filter((dottedName) => engine.evaluate(dottedName).nodeValue !== null)
|
||||
.map((dottedName) => engine.getRule(dottedName))
|
||||
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const onQuestionAnswered =
|
||||
(dottedName: DottedName) => (value?: PublicodesExpression) => {
|
||||
if (!answeredQuestions.includes(dottedName)) {
|
||||
dispatch(stepAction(dottedName))
|
||||
}
|
||||
dispatch(updateSituation(dottedName, value))
|
||||
}
|
||||
|
||||
return [questions, onQuestionAnswered]
|
||||
}
|
|
@ -2982,21 +2982,23 @@ contrat salarié . régime des impatriés:
|
|||
titre.fr: régime des impatriés
|
||||
contrat salarié . régime des impatriés . information:
|
||||
description.en: >-
|
||||
[automatic] The following conditions must be met in order to benefit from
|
||||
the old-age contribution exemption: - Be able to prove a minimum
|
||||
contribution paid elsewhere for old-age insurance - Not have been
|
||||
affiliated, during the five calendar years preceding that of taking up the
|
||||
post, to a compulsory French old-age insurance scheme, except for ancillary
|
||||
activities of a seasonal nature or for studies.
|
||||
[automatic] In order to benefit from the exemption from old-age
|
||||
contributions, the following conditions must be met:
|
||||
|
||||
- Be able to justify a minimum contribution paid elsewhere for old age insurance
|
||||
|
||||
- Not to have been affiliated, during the five calendar years preceding that of the taking up of duties, to a compulsory French old age insurance scheme, except for accessory activities, of a seasonal nature or for studies.
|
||||
|
||||
|
||||
[Lire le texte de loi](https://www.legifrance.gouv.fr/affichCode.do;jsessionid=F5CFB7C90D1D1F529A2CDC9FFD20BD6E.tplgfr34s_3?idSectionTA=LEGISCTA000038510929&cidTexte=LEGITEXT000006073189&dateTexte=20190626)
|
||||
description.fr: >-
|
||||
Pour bénéficier de l'exonération de cotisations vieillesse, il faut remplir
|
||||
les conditions suivantes : - Pouvoir justifier d'une contribution minimale
|
||||
versée ailleurs pour une assurance vieillesse - Ne pas avoir été affilié, au
|
||||
cours des cinq années civiles précédant celle de la prise de fonctions, à un
|
||||
régime français obligatoire d'assurance vieillesse, sauf pour des activités
|
||||
accessoires, de caractère saisonnier ou pour les études.
|
||||
les conditions suivantes :
|
||||
|
||||
- Pouvoir justifier d'une contribution minimale versée ailleurs pour une assurance vieillesse
|
||||
|
||||
- Ne pas avoir été affilié, au cours des cinq années civiles précédant celle de la prise de fonctions, à un régime français obligatoire d'assurance vieillesse, sauf pour des activités accessoires, de caractère saisonnier ou pour les études.
|
||||
|
||||
|
||||
[Lire le texte de loi](https://www.legifrance.gouv.fr/affichCode.do;jsessionid=F5CFB7C90D1D1F529A2CDC9FFD20BD6E.tplgfr34s_3?idSectionTA=LEGISCTA000038510929&cidTexte=LEGITEXT000006073189&dateTexte=20190626)
|
||||
titre.en: '[automatic] information'
|
||||
|
@ -3487,12 +3489,13 @@ contrat salarié . stage:
|
|||
contrat salarié . stage . avertissement:
|
||||
description.en: >-
|
||||
[automatic] An internship agreement **is not an employment contract**, and
|
||||
cannot be concluded to carry out a regular task corresponding to a permanent
|
||||
job, or a temporary increase in the company's activity. [Education Code -
|
||||
Article
|
||||
cannot be concluded to perform a regular task corresponding to a permanent
|
||||
job, or to a temporary increase in the company's activity. [Code de
|
||||
l'éducation - Article
|
||||
L124-7](https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000029234119&cidTexte=LEGITEXT000006071191)
|
||||
|
||||
Furthermore, a company with less than 20 employees may not take on more than **3 trainees**, and no more than **15% of the workforce** for companies with more than 20 employees.
|
||||
|
||||
In addition, a company with less than 20 employees may not host more than **3 trainees**, and no more than **15% of the workforce** for companies with more than 20 employees.
|
||||
description.fr: >-
|
||||
Une convention de stage **n'est pas un contrat de travail**, et ne peut pas
|
||||
être conclue pour réaliser une tâche régulière correspondant à un poste de
|
||||
|
@ -3500,6 +3503,7 @@ contrat salarié . stage . avertissement:
|
|||
l'entreprise. [Code de l'éducation - Article
|
||||
L124-7](https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000029234119&cidTexte=LEGITEXT000006071191)
|
||||
|
||||
|
||||
Par ailleurs, une entreprise de moins de 20 salariés ne peut pas accueillir plus de **3 stagiaires**, et pas plus de **15% de l’effectif** pour les entreprises de plus de 20 salariés.
|
||||
titre.en: '[automatic] warning'
|
||||
titre.fr: avertissement
|
||||
|
@ -3891,8 +3895,6 @@ contrat salarié . vieillesse:
|
|||
titre.en: Basic pension contribution
|
||||
titre.fr: vieillesse
|
||||
dirigeant:
|
||||
question.en: '[automatic] What is the social regime of the manager?'
|
||||
question.fr: Quel est le régime social du dirigeant ?
|
||||
titre.en: '[automatic] manager'
|
||||
titre.fr: dirigeant
|
||||
dirigeant . assimilé salarié:
|
||||
|
@ -4163,6 +4165,11 @@ dirigeant . auto-entrepreneur . notification calcul ACRE annuel:
|
|||
d'acre sur une meme année.
|
||||
titre.en: '[automatic] notification annual ACRE calculation'
|
||||
titre.fr: notification calcul ACRE annuel
|
||||
dirigeant . gérant minoritaire:
|
||||
question.en: '[automatic] Are you a minority or equal shareholder of your company?'
|
||||
question.fr: Êtes-vous gérant minoritaire ou égalitaire de votre entreprise ?
|
||||
titre.en: '[automatic] Minority or equal shareholder manager'
|
||||
titre.fr: Gérant minoritaire ou égalitaire
|
||||
dirigeant . indépendant:
|
||||
titre.en: '[automatic] independent'
|
||||
titre.fr: indépendant
|
||||
|
@ -6181,6 +6188,9 @@ dirigeant . indépendant . revenus étrangers . montant:
|
|||
question.fr: Quel est leur montant ?
|
||||
titre.en: '[automatic] income received abroad'
|
||||
titre.fr: revenus perçu à l'étranger
|
||||
dirigeant . régime social:
|
||||
titre.en: '[automatic] social regime'
|
||||
titre.fr: régime social
|
||||
dirigeant . rémunération:
|
||||
titre.en: '[automatic] compensation'
|
||||
titre.fr: rémunération
|
||||
|
@ -7171,6 +7181,15 @@ entreprise . ACRE:
|
|||
entreprise . ACRE par défaut:
|
||||
titre.en: '[automatic] Default ACRE'
|
||||
titre.fr: ACRE par défaut
|
||||
entreprise . SIREN:
|
||||
description.en: >
|
||||
[automatic] The Siren number is a unique 9 digit number for each company. Ex
|
||||
: 401237780
|
||||
description.fr: >
|
||||
Le numéro Siren est un numéro de 9 chiffres unique pour chaque entreprise.
|
||||
Ex : 401237780
|
||||
titre.en: '[automatic] SIREN'
|
||||
titre.fr: SIREN
|
||||
entreprise . activité:
|
||||
description.en: '[automatic] Your type of activity will determine a large part
|
||||
of the contribution, contribution and tax calculations.'
|
||||
|
@ -7397,6 +7416,56 @@ entreprise . capital social:
|
|||
question.fr: Quele est le capital social de la société ?
|
||||
titre.en: '[automatic] Share capital'
|
||||
titre.fr: Capital social
|
||||
entreprise . catégorie juridique:
|
||||
description.en: |
|
||||
[automatic] Legal categories accessible via the SIRENE API
|
||||
description.fr: |
|
||||
Les catégories juridiques accessibles via l'API SIRENE
|
||||
note.en: '[automatic] We base ourselves here on the legal categories defined by INSEE'
|
||||
note.fr: On se base ici sur les catégories juridiques définies par l'INSEE
|
||||
titre.en: '[automatic] legal category'
|
||||
titre.fr: catégorie juridique
|
||||
entreprise . catégorie juridique . EI:
|
||||
titre.en: '[automatic] EI or EIRL'
|
||||
titre.fr: EI ou EIRL
|
||||
entreprise . catégorie juridique . EI . auto-entrepreneur:
|
||||
question.en: '[automatic] Are you an auto-entrepreneur?'
|
||||
question.fr: Êtes-vous auto-entrepreneur ?
|
||||
titre.en: '[automatic] auto-entrepreneur'
|
||||
titre.fr: auto-entrepreneur
|
||||
entreprise . catégorie juridique . EI . imposition entreprise:
|
||||
titre.en: '[automatic] taxation company'
|
||||
titre.fr: imposition entreprise
|
||||
entreprise . catégorie juridique . EI . responsabilité limité:
|
||||
question.en: '[automatic] Is your business an EIRL?'
|
||||
question.fr: Votre entreprise est-elle une EIRL ?
|
||||
titre.en: '[automatic] EIRL'
|
||||
titre.fr: EIRL
|
||||
entreprise . catégorie juridique . SARL:
|
||||
titre.en: '[automatic] EURL or SARL'
|
||||
titre.fr: EURL ou SARL
|
||||
entreprise . catégorie juridique . SARL . unipersonnelle:
|
||||
question.en: '[automatic] Is your company an EURL?'
|
||||
question.fr: Votre entreprise est-elle une EURL ?
|
||||
titre.en: '[automatic] EURL'
|
||||
titre.fr: EURL
|
||||
entreprise . catégorie juridique . SAS:
|
||||
titre.en: '[automatic] SASU or SAS'
|
||||
titre.fr: SASU ou SAS
|
||||
entreprise . catégorie juridique . SAS . unipersonnelle:
|
||||
question.en: '[automatic] Is your company a SASU?'
|
||||
question.fr: Votre entreprise est-elle une SASU ?
|
||||
titre.en: '[automatic] SASU'
|
||||
titre.fr: SASU
|
||||
entreprise . catégorie juridique . SELARL:
|
||||
titre.en: '[automatic] SELARL'
|
||||
titre.fr: SELARL
|
||||
entreprise . catégorie juridique . SELAS:
|
||||
titre.en: '[automatic] SELARL'
|
||||
titre.fr: SELARL
|
||||
entreprise . catégorie juridique . autre:
|
||||
titre.en: '[automatic] other'
|
||||
titre.fr: autre
|
||||
entreprise . charges:
|
||||
description.en: >
|
||||
[automatic]
|
||||
|
@ -8028,6 +8097,9 @@ entreprise . imposition . IS . résultat net:
|
|||
résumé.fr: Après déduction des charges et de l'impôt sur les société
|
||||
titre.en: '[automatic] net result'
|
||||
titre.fr: résultat net
|
||||
entreprise . nom:
|
||||
titre.en: '[automatic] name'
|
||||
titre.fr: nom
|
||||
entreprise . ratio alternants:
|
||||
description.en: >
|
||||
This fraction determines the additional contribution for learning for the
|
||||
|
@ -8991,6 +9063,9 @@ situation personnelle . domiciliation fiscale à l'étranger:
|
|||
question.fr: Votre établissement bénéficie-t-il du dispositif zone franche urbaine (ZFU) ?
|
||||
titre.en: ZFU
|
||||
titre.fr: ZFU
|
||||
établissement . ZFU . durée d'implantation en fin d'année:
|
||||
titre.en: '[automatic] duration of implementation at the end of the year'
|
||||
titre.fr: durée d'implantation en fin d'année
|
||||
établissement . localisation:
|
||||
description.en: |-
|
||||
When a company has more than one establishment, certain contributions are
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
"<0></0> Pour en savoir plus, rendez-vous sur le site <3>aquoiserventlescotisations":
|
||||
urssaf:
|
||||
fr</3>: <0></0> To find out more, go to <3>aquoiserventlescotisations.urssaf.fr</3>
|
||||
"<0><0>Il n'existe pas encore de simulateur de revenu pour votre type d'entreprise sur ce site.</0><1>Si vous souhaitez que nous développions un nouveau simulateur, laissez-nous message en cliquant sur le bouton \"Faire une suggestion\" en bas de cette page.</1></0>":
|
||||
<0><0>There is not yet an income simulator for your type of business on this
|
||||
site.</0><1>If you would like us to develop a new simulator, leave us a
|
||||
message by clicking on the "Make a suggestion" button at the bottom of this
|
||||
page.</1></0>
|
||||
<0>Activité mixte</0>: <0>Mixed activity</0>
|
||||
"<0>Covid-19 et chômage partiel </0>: <3>Calculez votre indemnité</3>": "<0>Covid-19 and Short-Time </0>Work: <3>Calculate Your Benefit</3>"
|
||||
<0>Oui</0>: <0>Yes</0>
|
||||
|
@ -56,11 +61,15 @@ Covid 19: Covid 19
|
|||
"Covid-19 : Découvrir les mesures de soutien aux entreprises": "Covid-19: Discovering Business Support Measures"
|
||||
Coût pour l'entreprise: Cost to the company
|
||||
Crée le: Created on
|
||||
"Crée le :": "Created on :"
|
||||
Créer une: Create a
|
||||
De: From
|
||||
Demande de mobilité: Demand for mobility
|
||||
Destinataire: Levied by
|
||||
Devenir: Become
|
||||
"Domiciliée à l'adresse :": "Domiciled at the address :"
|
||||
Données de l'entreprise: Company data
|
||||
Données de simulation: Simulation data
|
||||
Déclenchement: Applicability
|
||||
Découvrir: Discover
|
||||
"Décrivez votre projet ou votre problème en donnant quelques éléments de contexte. Nous identifions, parmi l’ensemble des partenaires publics et parapublics, le conseiller compétent pour votre demande. Celui-ci vous contacte par téléphone sous 5 jours et vous accompagne en fonction de votre situation.":
|
||||
|
@ -72,6 +81,7 @@ Démarches de création: Creation process checklist
|
|||
Désactivée: Inactive
|
||||
Détail annuel des cotisations: Annual detail of my contributions
|
||||
Effacer: Reset
|
||||
Effacer toutes mes données: Delete all my data
|
||||
Embauche: Hiring process
|
||||
Employeur: Employer
|
||||
En incluant l'indemnité de chômage partiel: Including short-time working allowance
|
||||
|
@ -113,6 +123,7 @@ Jusqu’au: Until
|
|||
La somme de: This rule is the sum of
|
||||
Liste des intégrations: List of integrations
|
||||
Liste des statuts juridiques: List of legal statutes
|
||||
Ma situation: My situation
|
||||
Mensuel: Monthly
|
||||
Mes réponses: My answers
|
||||
Modifier: Modify
|
||||
|
@ -160,8 +171,9 @@ Quelques exemples de salaires: Some salary exemples
|
|||
Quelques intégrations: Some integrations
|
||||
Recherche en cours...: Searching...
|
||||
Rechercher: Search
|
||||
Rechercher une entreprise: Search for a company
|
||||
Rechercher votre entreprise: Search for a company
|
||||
Recommencer: Start again
|
||||
Recommencer la simulation: Start the simulation again
|
||||
Rend non applicable les règles suivantes: Makes the following rules not applicable
|
||||
Renseigner mon entreprise: Find my company
|
||||
Responsabilité limitée: Limited liability
|
||||
|
@ -218,7 +230,7 @@ Voir la fiche de paie: See the pay slip
|
|||
Voir la répartition des cotisations: View contribution breakdown
|
||||
Voir le code source: See the source code
|
||||
Voir les autres simulateurs: See the other simulators
|
||||
Voir mes paramètres: See my situation
|
||||
Voir ma situation: See my situation
|
||||
Votre adresse e-mail: Your email address
|
||||
Votre entreprise: Your company
|
||||
Votre forme juridique: Your legal status
|
||||
|
@ -283,6 +295,12 @@ après:
|
|||
arrondi-to-decimals: Rounding to {explanation.decimals.nodeValue} decimal
|
||||
arrondi-to-decimals_plural: Rounding to {explanation.decimals.nodeValue} decimals
|
||||
assiette: base
|
||||
assistant-DRI:
|
||||
description: <0><0>This tool will help you to fill in your tax <2>return</2> on
|
||||
impot.gouv.fr. You will have at the end :</0><1><0>The list of boxes that
|
||||
concern you with the amount to fill in</0><1>An estimate of the social
|
||||
security contributions to be paid to the Urssaf in 2022</1></1></0><1>My
|
||||
company</1>
|
||||
associés:
|
||||
choix1: Alone
|
||||
choix2: Several partners
|
||||
|
@ -879,7 +897,7 @@ landing:
|
|||
create:
|
||||
body: Assistance in choosing a legal status and a complete list of the steps
|
||||
involved in setting up a business
|
||||
title: Starting a business
|
||||
title: I don't have a business yet
|
||||
manage:
|
||||
body: Personalized tools to anticipate the amount of social contributions to be
|
||||
paid and better manage your cash flow.
|
||||
|
@ -1628,8 +1646,8 @@ pages:
|
|||
remuneration. To do this, simply enter the total amount allocated in the
|
||||
\"total charged\" box. The simulation can then be refined by answering
|
||||
the various questions.</4>"
|
||||
shortname: SASU
|
||||
title: SASU Simulator
|
||||
shortname: SAS(U)
|
||||
title: SAS(U) Simulator
|
||||
titre: Revenue simulator for SAS(U) executive
|
||||
select-year:
|
||||
access: Access the {{year}} simulator
|
||||
|
@ -1863,7 +1881,7 @@ une de ces conditions: one of these applies
|
|||
économieCollaborative:
|
||||
WIP: <0>This assistant is under development.</0> Do not hesitate to send us all
|
||||
your remarks, ideas, questions by clicking on the "Make a suggestion" button
|
||||
above.
|
||||
at the bottom of the page.
|
||||
accueil:
|
||||
contenu: <0>Do you have income from <2>online platforms</2> (Airbnb, Abritel,
|
||||
Drivy, Blablacar, Leboncoin, etc.)? You must declare them in most cases.
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
urssaf:
|
||||
fr</3>: <0></0> Pour en savoir plus, rendez-vous sur le site
|
||||
<3>aquoiserventlescotisations.urssaf.fr</3>
|
||||
"<0><0>Il n'existe pas encore de simulateur de revenu pour votre type d'entreprise sur ce site.</0><1>Si vous souhaitez que nous développions un nouveau simulateur, laissez-nous message en cliquant sur le bouton \"Faire une suggestion\" en bas de cette page.</1></0>":
|
||||
<0><0>Il n'existe pas encore de simulateur de revenu pour votre type
|
||||
d'entreprise sur ce site.</0><1>Si vous souhaitez que nous développions un
|
||||
nouveau simulateur, laissez-nous message en cliquant sur le bouton "Faire une
|
||||
suggestion" en bas de cette page.</1></0>
|
||||
<0>Activité mixte</0>: <0>Activité mixte</0>
|
||||
<0>Oui</0>: <0>Oui</0>
|
||||
Assimilé salarié: Assimilé salarié
|
||||
|
@ -26,15 +31,23 @@ CompanySearchField:
|
|||
Continuer: Continuer
|
||||
Cotisations sociales: Cotisations sociales
|
||||
Crée le: Crée le
|
||||
"Crée le :": "Crée le :"
|
||||
Créer une: Créer une
|
||||
Devenir: Devenir
|
||||
"Domiciliée à l'adresse :": "Domiciliée à l'adresse :"
|
||||
Données de l'entreprise: Données de l'entreprise
|
||||
Données de simulation: Données de simulation
|
||||
Découvrir: Découvrir
|
||||
<<<<<<< HEAD
|
||||
"Décrivez votre projet ou votre problème en donnant quelques éléments de contexte. Nous identifions, parmi l’ensemble des partenaires publics et parapublics, le conseiller compétent pour votre demande. Celui-ci vous contacte par téléphone sous 5 jours et vous accompagne en fonction de votre situation.":
|
||||
Décrivez votre projet ou votre problème en donnant quelques éléments de
|
||||
contexte. Nous identifions, parmi l’ensemble des partenaires publics et
|
||||
parapublics, le conseiller compétent pour votre demande. Celui-ci vous
|
||||
contacte par téléphone sous 5 jours et vous accompagne en fonction de votre
|
||||
situation.
|
||||
=======
|
||||
Effacer toutes mes données: Effacer toutes mes données
|
||||
>>>>>>> 4a2520a52 (:sparkles: Revoie les parcours avec entreprise existante)
|
||||
En savoir plus: En savoir plus
|
||||
Entreprise Individuelle: Entreprise Individuelle
|
||||
Exonérations: Exonérations
|
||||
|
@ -55,6 +68,7 @@ J'ai compris: J'ai compris
|
|||
Jusqu’au: Jusqu’au
|
||||
Liste des intégrations: Liste des intégrations
|
||||
Liste des statuts juridiques: Liste des statuts juridiques
|
||||
Ma situation: Ma situation
|
||||
Mes réponses: Mes réponses
|
||||
Modifier: Modifier
|
||||
Montant de l'impôt sur les sociétés: Montant de l'impôt sur les sociétés
|
||||
|
@ -80,7 +94,8 @@ Prévisualisation: Prévisualisation
|
|||
Que cherchez-vous ?: Que cherchez-vous ?
|
||||
Quelques intégrations: Quelques intégrations
|
||||
Rechercher: Rechercher
|
||||
Rechercher une entreprise: Rechercher une entreprise
|
||||
Rechercher votre entreprise: Rechercher votre entreprise
|
||||
Recommencer la simulation: Recommencer la simulation
|
||||
Ressources utiles: Ressources utiles
|
||||
Retour: Retour
|
||||
Retour à la création: Retour à la création
|
||||
|
@ -108,7 +123,7 @@ Une idée ?<1></1>Contactez-nous !: Une idée ?<1></1>Contactez-n
|
|||
Voir la fiche Urssaf: Voir la fiche Urssaf
|
||||
Voir la fiche de paie: Voir la fiche de paie
|
||||
Voir les autres simulateurs: Voir les autres simulateurs
|
||||
Voir mes paramètres: Voir mes paramètres
|
||||
Voir ma situation: Voir ma situation
|
||||
Votre adresse e-mail: Votre adresse e-mail
|
||||
Votre forme juridique: Votre forme juridique
|
||||
Vous êtes dirigeant d'une SAS(U) ? <2>Accéder au simulateur de revenu dédié</2>: Vous êtes dirigeant d'une SAS(U) ? <2>Accéder au simulateur de revenu dédié</2>
|
||||
|
@ -162,6 +177,12 @@ après:
|
|||
(NIC).
|
||||
titre: Le numéro SIRET
|
||||
titre: Après la création
|
||||
assistant-DRI:
|
||||
description: <0><0>Cet outil vous aidera à remplir votre <2>déclaration de
|
||||
revenu</2> sur impot.gouv.fr. Vous aurez à la fin :</0><1><0>La liste des
|
||||
cases qui vous concernent avec le montant à remplir</0><1>Une estimation des
|
||||
cotisations sociales à payer à l'Urssaf en 2022</1></1></0><1>Mon
|
||||
entreprise</1>
|
||||
associés:
|
||||
choix1: Seul
|
||||
choix2: Plusieurs personnes
|
||||
|
@ -632,7 +653,7 @@ landing:
|
|||
create:
|
||||
body: Un accompagnement au choix du statut juridique et la liste complète des
|
||||
démarches de création
|
||||
title: Créer une entreprise
|
||||
title: Je n'ai pas encore d'entreprise
|
||||
manage:
|
||||
body: Des outils personnalisés pour anticiper le montant des cotisations
|
||||
sociales à payer et mieux gérer votre trésorerie.
|
||||
|
@ -1285,8 +1306,8 @@ pages:
|
|||
alloué à la rémunération du dirigeant. Il vous suffit pour cela saisir
|
||||
le montant total alloué dans la case \"total chargé\". La simulation
|
||||
peut ensuite être affinée en répondant aux différentes questions.</4>"
|
||||
shortname: SASU
|
||||
title: Simulateur de SASU
|
||||
shortname: SAS(U)
|
||||
title: Simulateur de SAS(U)
|
||||
select-year:
|
||||
access: Accéder au simulateur {{year}}
|
||||
back: Retourner au simulateur {{year}}
|
||||
|
@ -1468,7 +1489,7 @@ trouver:
|
|||
économieCollaborative:
|
||||
WIP: <0>Cet assistant est en cours de développement.</0> N'hésitez pas à nous
|
||||
faire part de toute vos remarques, idées, questions en cliquant sur le
|
||||
bouton "Faire une suggestion" ci dessus.
|
||||
bouton "Faire une suggestion" en bas de la page.
|
||||
accueil:
|
||||
contenu: <0>Vous avez des revenus issus des <2>plateformes en ligne</2> (Airbnb,
|
||||
Abritel, Drivy, Blablacar, Leboncoin, etc.) ? Vous devez les déclarer dans
|
||||
|
|
|
@ -14,7 +14,7 @@ import siret from './siret.jpg'
|
|||
export default function AfterRegistration() {
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const statutChoisi = useSelector(
|
||||
(state: RootState) => state.inFranceApp.companyStatusChoice
|
||||
(state: RootState) => state.choixStatutJuridique.companyStatusChoice
|
||||
)
|
||||
const { t } = useTranslation()
|
||||
const isAutoentrepreneur = statutChoisi?.match('auto-entrepreneur')
|
||||
|
|
|
@ -33,7 +33,7 @@ export default function CreateCompany({ statut }: CreateCompanyProps) {
|
|||
const { t, i18n } = useTranslation()
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const companyCreationChecklist = useSelector(
|
||||
(state: RootState) => state.inFranceApp.companyCreationChecklist
|
||||
(state: RootState) => state.choixStatutJuridique.companyCreationChecklist
|
||||
)
|
||||
const dispatch = useDispatch()
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ const PreviousAnswersItem = styled.li`
|
|||
export default function PreviousAnswers() {
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const legalStatus = useSelector(
|
||||
(state: RootState) => state.inFranceApp.companyLegalStatus
|
||||
(state: RootState) => state.choixStatutJuridique.companyLegalStatus
|
||||
)
|
||||
if (Object.values(legalStatus).length < 1) {
|
||||
return null
|
||||
|
|
|
@ -25,8 +25,8 @@ const useResetFollowingAnswers = () => {
|
|||
const answeredQuestion = useSelector(
|
||||
(state: RootState) =>
|
||||
Object.keys(
|
||||
state.inFranceApp.companyLegalStatus
|
||||
) as (keyof typeof state.inFranceApp.companyLegalStatus)[]
|
||||
state.choixStatutJuridique.companyLegalStatus
|
||||
) as (keyof typeof state.choixStatutJuridique.companyLegalStatus)[]
|
||||
)
|
||||
useEffect(() => {
|
||||
const companyStatusCurrentQuestionName = (toPairs(
|
||||
|
|
|
@ -22,7 +22,7 @@ export default function Créer() {
|
|||
const nextQuestionUrl = useNextQuestionUrl()
|
||||
const guideAlreadyStarted = useSelector(
|
||||
(state: RootState) =>
|
||||
!!Object.keys(state.inFranceApp.companyLegalStatus).length
|
||||
!!Object.keys(state.choixStatutJuridique.companyLegalStatus).length
|
||||
)
|
||||
return (
|
||||
<FromBottom>
|
||||
|
|
|
@ -11,7 +11,7 @@ import { RuleNode } from 'publicodes'
|
|||
import { useCallback, useContext } from 'react'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { situationSelector } from '@/selectors/simulationSelectors'
|
||||
import { Question } from './index'
|
||||
import { Question } from './PreviousVersion'
|
||||
|
||||
type SubSectionProp = {
|
||||
dottedName: DottedName
|
||||
|
|
|
@ -0,0 +1,306 @@
|
|||
import { Grid } from '@mui/material'
|
||||
import { updateSituation } from '@/actions/actions'
|
||||
import RuleInput from '@/components/conversation/RuleInput'
|
||||
import { Condition, WhenAlreadyDefined } from '@/components/EngineValue'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PreviousSimulationBanner from '@/components/PreviousSimulationBanner'
|
||||
import { FromTop } from '@/components/ui/animate'
|
||||
import Warning from '@/components/ui/WarningBlock'
|
||||
import Emoji from '@/components/utils/Emoji'
|
||||
import useSimulationConfig from '@/components/utils/useSimulationConfig'
|
||||
import { Strong } from '@/design-system/typography'
|
||||
import { H2, H3 } from '@/design-system/typography/heading'
|
||||
import { Li, Ul } from '@/design-system/typography/list'
|
||||
import { Body, Intro, SmallBody } from '@/design-system/typography/paragraphs'
|
||||
import { useCallback } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { situationSelector } from '@/selectors/simulationSelectors'
|
||||
import styled from 'styled-components'
|
||||
import { TrackPage } from '../../../ATInternetTracking'
|
||||
import simulationConfig from './config.yaml'
|
||||
import { ExplicationsResultatFiscal } from './ExplicationResultatFiscal'
|
||||
import { SimpleField, SubSection } from './Fields'
|
||||
import ResultatsSimples from './RésultatSimple'
|
||||
import ResultatsParFormulaire from './RésultatsParFormulaire'
|
||||
import illustration from './undraw_fill_in_mie5.svg'
|
||||
|
||||
/**
|
||||
* Nous avons proposé une nouvelle vision des résultat plus complète, avec une proposition d'aide pour
|
||||
* l'ensemble des cases liées aux cotisations sociales.
|
||||
*
|
||||
* Hors de propos pour 2021, étant donné que cela prendrait beaucoup de temps à valider par la DGFiP
|
||||
* En attendant, on propose la version "simple" (mais moins utile).
|
||||
*
|
||||
* Le but est de faire valider la version plus complète pour la déclaration de revenu 2021.
|
||||
*/
|
||||
const FEATURE_FLAG_RESULTATS_COMPLETS =
|
||||
!import.meta.env.SSR && document.location.search.includes('next')
|
||||
|
||||
export default function AideDéclarationIndépendant() {
|
||||
useSimulationConfig(simulationConfig)
|
||||
|
||||
const situation = useSelector(situationSelector)
|
||||
return (
|
||||
<>
|
||||
<Trans i18nKey="aide-déclaration-indépendant.description">
|
||||
<PageHeader picture={illustration}>
|
||||
<Intro>
|
||||
Cet outil est une aide à la déclaration de revenus à destination des{' '}
|
||||
<Strong>travailleurs indépendants</Strong>. Il vous permet de
|
||||
connaître le montant des charges sociales déductibles.
|
||||
</Intro>
|
||||
<SmallBody>
|
||||
Vous restez entièrement responsable d'éventuelles omissions ou
|
||||
inexactitudes dans votre déclaration.
|
||||
</SmallBody>
|
||||
</PageHeader>
|
||||
<Warning localStorageKey="aide-déclaration-indépendant.warning">
|
||||
<Body>
|
||||
<Strong>
|
||||
Cet outil vous concerne si vous êtes dans le cas suivant :
|
||||
</Strong>
|
||||
</Body>
|
||||
<Ul>
|
||||
<Li>
|
||||
Vous cotisez au régime général des travailleurs indépendants
|
||||
</Li>
|
||||
</Ul>
|
||||
<Body>
|
||||
<Strong>
|
||||
Il ne vous concerne pas si vous êtes dans un des cas suivants :
|
||||
</Strong>
|
||||
</Body>
|
||||
<Ul>
|
||||
<Li>
|
||||
Vous exercez une activité libérale relevant d’un régime de
|
||||
retraite des professions libérales en comptabilité d'engagement
|
||||
</Li>
|
||||
<Li>Votre entreprise est domiciliée dans les DOM</Li>
|
||||
</Ul>
|
||||
</Warning>
|
||||
<PreviousSimulationBanner />
|
||||
|
||||
<H2>Imposition</H2>
|
||||
<Body>
|
||||
Ces quelques questions permettent de déterminer le type de déclaration
|
||||
à remplir, ainsi que les modalités de calcul des cotisations sociales.
|
||||
</Body>
|
||||
</Trans>
|
||||
{Object.keys(situation).length ? (
|
||||
<TrackPage name="commence" />
|
||||
) : (
|
||||
<TrackPage name="accueil" />
|
||||
)}
|
||||
|
||||
<ImpositionSection />
|
||||
|
||||
<FromTop>
|
||||
<Grid container>
|
||||
<Grid item xs={12} sm={10} md={9} lg={8}>
|
||||
<Condition expression="déclaration indépendants . comptabilité . engagement">
|
||||
<Trans i18nKey="aide-déclaration-indépendant.entreprise.titre">
|
||||
<H2>Entreprise et activité</H2>
|
||||
</Trans>
|
||||
<SimpleField
|
||||
dottedName="entreprise . date de création"
|
||||
showSuggestions={false}
|
||||
/>
|
||||
<Condition expression="entreprise . date de création > 31/12/2021">
|
||||
<SmallBody
|
||||
css={`
|
||||
color: #ff2d96;
|
||||
`}
|
||||
>
|
||||
Cette aide à la déclaration concerne uniquement les
|
||||
entreprises déjà en activité en 2021
|
||||
</SmallBody>
|
||||
</Condition>
|
||||
|
||||
<SubSection dottedName="déclaration indépendants . nature de l'activité" />
|
||||
{/* PLNR */}
|
||||
<SimpleField dottedName="entreprise . activité . débit de tabac" />
|
||||
<SimpleField dottedName="dirigeant . indépendant . cotisations et contributions . déduction tabac" />
|
||||
<SimpleField dottedName="dirigeant . indépendant . PL . régime général . taux spécifique retraite complémentaire" />
|
||||
|
||||
<H2>
|
||||
<Trans>Situation personnelle</Trans>
|
||||
</H2>
|
||||
<SimpleField dottedName="situation personnelle . RSA" />
|
||||
<Condition expression="entreprise . imposition . IR . micro-fiscal = non">
|
||||
<SubSection dottedName="dirigeant . indépendant . IJSS" />
|
||||
</Condition>
|
||||
<SubSection dottedName="dirigeant . indépendant . conjoint collaborateur" />
|
||||
|
||||
<H2>
|
||||
<Trans>Exonérations</Trans>
|
||||
</H2>
|
||||
<Body>
|
||||
<Emoji emoji="🏗️" /> Les calculs de l'exonération COVID 2021
|
||||
sont en cours d'implémentation
|
||||
</Body>
|
||||
<SimpleField dottedName="déclaration indépendants . ACRE" />
|
||||
<SimpleField dottedName="établissement . ZFU" />
|
||||
<SubSection
|
||||
hideTitle
|
||||
dottedName="entreprise . effectif . seuil"
|
||||
/>
|
||||
|
||||
<SubSection
|
||||
dottedName="dirigeant . indépendant . cotisations et contributions . exonérations"
|
||||
hideTitle
|
||||
/>
|
||||
{FEATURE_FLAG_RESULTATS_COMPLETS && (
|
||||
<SubSection dottedName="dirigeant . indépendant . cotisations facultatives" />
|
||||
)}
|
||||
<H2>
|
||||
<Trans>International</Trans>
|
||||
</H2>
|
||||
<SimpleField dottedName="situation personnelle . domiciliation fiscale à l'étranger" />
|
||||
<Condition expression="entreprise . imposition . IR . micro-fiscal = non">
|
||||
<SubSection
|
||||
dottedName="dirigeant . indépendant . revenus étrangers"
|
||||
hideTitle
|
||||
/>
|
||||
</Condition>
|
||||
</Condition>
|
||||
|
||||
<Condition expression="déclaration indépendants . cotisations payées">
|
||||
<SubSection dottedName="déclaration indépendants . cotisations payées" />
|
||||
<SimpleField dottedName="déclaration indépendants . nature de l'activité" />
|
||||
<SimpleField dottedName="dirigeant . indépendant . conjoint collaborateur" />
|
||||
<SubSection dottedName="dirigeant . indépendant . cotisations facultatives" />
|
||||
{/* We can't use a subsection here cause revenu étrangers is not missing when CSG is replaced */}
|
||||
<H3>
|
||||
<Trans>Revenus étranger</Trans>
|
||||
</H3>
|
||||
<SimpleField dottedName="dirigeant . indépendant . revenus étrangers" />
|
||||
<Condition expression="dirigeant . indépendant . revenus étrangers">
|
||||
<SimpleField dottedName="dirigeant . indépendant . revenus étrangers . montant" />
|
||||
</Condition>
|
||||
</Condition>
|
||||
|
||||
<Condition expression="déclaration indépendants . cotisations payées version simple">
|
||||
<SimpleField dottedName="déclaration indépendants . cotisations payées version simple . cotisations sociales" />
|
||||
<SimpleField dottedName="déclaration indépendants . cotisations payées version simple . CSG déductible et CFP" />
|
||||
</Condition>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</FromTop>
|
||||
{FEATURE_FLAG_RESULTATS_COMPLETS ? (
|
||||
<>
|
||||
<SubSection dottedName="déclaration indépendants . régime d'imposition" />
|
||||
<Condition
|
||||
expression={{
|
||||
'une de ces conditions': [
|
||||
"déclaration indépendants . régime d'imposition . réel",
|
||||
"déclaration indépendants . régime d'imposition . déclaration contrôlée",
|
||||
'entreprise . imposition . IR . micro-fiscal',
|
||||
],
|
||||
}}
|
||||
>
|
||||
<TrackPage name="simulation terminée" />
|
||||
<ResultatsParFormulaire />
|
||||
</Condition>
|
||||
</>
|
||||
) : (
|
||||
<WhenAlreadyDefined dottedName="déclaration indépendants . résultat simple . cotisations obligatoires">
|
||||
<ResultatsSimples />
|
||||
</WhenAlreadyDefined>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function ImpositionSection() {
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const situation = useSelector(situationSelector)
|
||||
const setSituation = useCallback(
|
||||
(value, dottedName) => {
|
||||
dispatch(updateSituation(dottedName, value))
|
||||
},
|
||||
[dispatch]
|
||||
)
|
||||
return (
|
||||
<>
|
||||
<SimpleField dottedName="entreprise . imposition" />
|
||||
{situation['entreprise . imposition'] != null && (
|
||||
<>
|
||||
{/* <WhenApplicable dottedName="déclaration indépendants . comptabilité"> */}
|
||||
<SimpleField dottedName="déclaration indépendants . comptabilité" />
|
||||
{/* </WhenApplicable> */}
|
||||
<Condition
|
||||
expression={
|
||||
FEATURE_FLAG_RESULTATS_COMPLETS
|
||||
? 'oui'
|
||||
: 'déclaration indépendants . cotisations payées version simple = non'
|
||||
}
|
||||
>
|
||||
<FromTop key={situation['entreprise . imposition']}>
|
||||
<Condition expression="entreprise . imposition . IR">
|
||||
<SimpleField dottedName="entreprise . imposition . IR . micro-fiscal" />
|
||||
<Condition expression="entreprise . imposition . IR . micro-fiscal">
|
||||
<H2>
|
||||
Quel est votre chiffre d'affaires hors taxes en 2021 ?
|
||||
</H2>
|
||||
<SmallBody>
|
||||
Indiquez le montant hors taxes de votre chiffre d’affaires
|
||||
ou de vos recettes bruts (avant déduction de l’abattement
|
||||
forfaitaire pour frais et charges) et avant déduction des
|
||||
exonérations fiscales dont vous avez bénéficié
|
||||
</SmallBody>
|
||||
<SimpleField dottedName="entreprise . chiffre d'affaires . vente restauration hébergement" />
|
||||
<SimpleField dottedName="entreprise . chiffre d'affaires . service BIC" />
|
||||
<SimpleField dottedName="entreprise . chiffre d'affaires . service BNC" />
|
||||
</Condition>
|
||||
<Condition expression="entreprise . imposition . IR . micro-fiscal = non">
|
||||
<H2>
|
||||
Quel est votre résultat fiscal en 2021 ?<br />
|
||||
<small>
|
||||
Charges sociales et exonérations fiscales non incluses{' '}
|
||||
<ExplicationsResultatFiscal />
|
||||
</small>
|
||||
</H2>
|
||||
<SmallBody>
|
||||
Le résultat fiscal correspond aux produits moins les
|
||||
charges. Il peut être positif (bénéfice) ou négatif
|
||||
(déficit).
|
||||
</SmallBody>
|
||||
<BigInput>
|
||||
<RuleInput
|
||||
dottedName="dirigeant . rémunération . totale"
|
||||
onChange={setSituation}
|
||||
autoFocus
|
||||
/>
|
||||
</BigInput>
|
||||
</Condition>
|
||||
</Condition>
|
||||
<Condition expression="entreprise . imposition . IS">
|
||||
<H2>
|
||||
Quel est le montant net de votre rémunération en 2021 ?
|
||||
<br />
|
||||
<small>Sans tenir compte des charges sociales</small>
|
||||
</H2>
|
||||
<BigInput>
|
||||
<RuleInput
|
||||
dottedName="dirigeant . rémunération . nette"
|
||||
onChange={setSituation}
|
||||
autoFocus
|
||||
/>
|
||||
</BigInput>
|
||||
</Condition>
|
||||
</FromTop>
|
||||
</Condition>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const Question = styled.div`
|
||||
margin-top: 1em;
|
||||
`
|
||||
const BigInput = styled.div`
|
||||
font-size: 130%;
|
||||
`
|
|
@ -8,7 +8,7 @@ objectifs:
|
|||
- déclaration indépendants . formulaire 2035
|
||||
|
||||
situation:
|
||||
dirigeant: "'indépendant'"
|
||||
dirigeant . régime social: "'indépendant'"
|
||||
année: 2021
|
||||
déclaration indépendants: oui
|
||||
dirigeant . indépendant . PL . CIPAV: non # TODO En attendant la transitivité des remplacements
|
||||
|
|
|
@ -1,308 +1,93 @@
|
|||
import { Grid } from '@mui/material'
|
||||
import { updateSituation } from '@/actions/actions'
|
||||
import RuleInput from '@/components/conversation/RuleInput'
|
||||
import { resetCompany } from '@/actions/companyActions'
|
||||
import { useSetEntreprise } from '@/actions/companyStatusActions'
|
||||
import { CompanyDetails } from '@/components/company/Details'
|
||||
import { CompanySearchField } from '@/components/company/SearchField'
|
||||
import {
|
||||
Condition,
|
||||
WhenAlreadyDefined,
|
||||
WhenApplicable,
|
||||
WhenNotAlreadyDefined,
|
||||
} from '@/components/EngineValue'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PreviousSimulationBanner from '@/components/PreviousSimulationBanner'
|
||||
import { FromTop } from '@/components/ui/animate'
|
||||
import Warning from '@/components/ui/WarningBlock'
|
||||
import Emoji from '@/components/utils/Emoji'
|
||||
import useSimulationConfig from '@/components/utils/useSimulationConfig'
|
||||
import { SitePathsContext } from '@/components/utils/SitePathsContext'
|
||||
import { Message } from '@/design-system'
|
||||
import { Button } from '@/design-system/buttons'
|
||||
import { Spacing } from '@/design-system/layout'
|
||||
import { Strong } from '@/design-system/typography'
|
||||
import { H2, H3 } from '@/design-system/typography/heading'
|
||||
import { Link } from '@/design-system/typography/link'
|
||||
import { Li, Ul } from '@/design-system/typography/list'
|
||||
import { Body, Intro, SmallBody } from '@/design-system/typography/paragraphs'
|
||||
import { useCallback } from 'react'
|
||||
import { Body, Intro } from '@/design-system/typography/paragraphs'
|
||||
import { Grid } from '@mui/material'
|
||||
import { useContext } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { situationSelector } from '@/selectors/simulationSelectors'
|
||||
import styled from 'styled-components'
|
||||
import { TrackPage } from '../../../ATInternetTracking'
|
||||
import simulationConfig from './config.yaml'
|
||||
import { ExplicationsResultatFiscal } from './ExplicationResultatFiscal'
|
||||
import { SimpleField, SubSection } from './Fields'
|
||||
import ResultatsSimples from './RésultatSimple'
|
||||
import ResultatsParFormulaire from './RésultatsParFormulaire'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import illustration from './undraw_fill_in_mie5.svg'
|
||||
|
||||
/**
|
||||
* Nous avons proposé une nouvelle vision des résultat plus complète, avec une proposition d'aide pour
|
||||
* l'ensemble des cases liées aux cotisations sociales.
|
||||
*
|
||||
* Hors de propos pour 2021, étant donné que cela prendrait beaucoup de temps à valider par la DGFiP
|
||||
* En attendant, on propose la version "simple" (mais moins utile).
|
||||
*
|
||||
* Le but est de faire valider la version plus complète pour la déclaration de revenu 2021.
|
||||
*/
|
||||
const FEATURE_FLAG_RESULTATS_COMPLETS =
|
||||
!import.meta.env.SSR && document.location.search.includes('next')
|
||||
|
||||
export default function AideDéclarationIndépendant() {
|
||||
useSimulationConfig(simulationConfig)
|
||||
|
||||
const situation = useSelector(situationSelector)
|
||||
const setEntreprise = useSetEntreprise()
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const dispatch = useDispatch()
|
||||
return (
|
||||
<>
|
||||
<Trans i18nKey="aide-déclaration-indépendant.description">
|
||||
<Trans i18nKey="assistant-DRI.description">
|
||||
<PageHeader picture={illustration}>
|
||||
<Intro>
|
||||
Cet outil est une aide à la déclaration de revenus à destination des{' '}
|
||||
<Strong>travailleurs indépendants</Strong>. Il vous permet de
|
||||
connaître le montant des charges sociales déductibles.
|
||||
Cet outil vous aidera à remplir votre{' '}
|
||||
<Strong>déclaration de revenu</Strong> sur impot.gouv.fr. Vous aurez
|
||||
à la fin :
|
||||
</Intro>
|
||||
<SmallBody>
|
||||
Vous restez entièrement responsable d'éventuelles omissions ou
|
||||
inexactitudes dans votre déclaration.
|
||||
</SmallBody>
|
||||
<Ul size="XL">
|
||||
<Li>
|
||||
La liste des cases qui vous concernent avec le montant à remplir
|
||||
</Li>
|
||||
<Li>
|
||||
Une estimation des cotisations sociales à payer à l'Urssaf en 2022
|
||||
</Li>
|
||||
</Ul>
|
||||
</PageHeader>
|
||||
<Warning localStorageKey="aide-déclaration-indépendant.warning">
|
||||
<Body>
|
||||
<Strong>
|
||||
Cet outil vous concerne si vous êtes dans le cas suivant :
|
||||
</Strong>
|
||||
</Body>
|
||||
<Ul>
|
||||
<Li>
|
||||
Vous cotisez au régime général des travailleurs indépendants
|
||||
</Li>
|
||||
</Ul>
|
||||
<Body>
|
||||
<Strong>
|
||||
Il ne vous concerne pas si vous êtes dans un des cas suivants :
|
||||
</Strong>
|
||||
</Body>
|
||||
<Ul>
|
||||
<Li>
|
||||
Vous exercez une activité libérale relevant d’un régime de
|
||||
retraite des professions libérales en comptabilité d'engagement
|
||||
</Li>
|
||||
<Li>Votre entreprise est domiciliée dans les DOM</Li>
|
||||
</Ul>
|
||||
</Warning>
|
||||
<PreviousSimulationBanner />
|
||||
|
||||
<H2>Imposition</H2>
|
||||
<Body>
|
||||
Ces quelques questions permettent de déterminer le type de déclaration
|
||||
à remplir, ainsi que les modalités de calcul des cotisations sociales.
|
||||
</Body>
|
||||
<H2>Mon entreprise</H2>
|
||||
</Trans>
|
||||
{Object.keys(situation).length ? (
|
||||
<TrackPage name="commence" />
|
||||
) : (
|
||||
<TrackPage name="accueil" />
|
||||
)}
|
||||
|
||||
<ImpositionSection />
|
||||
|
||||
<FromTop>
|
||||
<Grid container>
|
||||
<Grid item xs={12} sm={10} md={9} lg={8}>
|
||||
<Condition expression="déclaration indépendants . comptabilité . engagement">
|
||||
<Trans i18nKey="aide-déclaration-indépendant.entreprise.titre">
|
||||
<H2>Entreprise et activité</H2>
|
||||
</Trans>
|
||||
<SimpleField
|
||||
dottedName="entreprise . date de création"
|
||||
showSuggestions={false}
|
||||
/>
|
||||
<Condition expression="entreprise . date de création > 31/12/2021">
|
||||
<SmallBody
|
||||
css={`
|
||||
color: #ff2d96;
|
||||
`}
|
||||
>
|
||||
Cette aide à la déclaration concerne uniquement les
|
||||
entreprises déjà en activité en 2021
|
||||
</SmallBody>
|
||||
</Condition>
|
||||
|
||||
<SubSection dottedName="déclaration indépendants . nature de l'activité" />
|
||||
{/* PLNR */}
|
||||
<SimpleField dottedName="entreprise . activité . débit de tabac" />
|
||||
<SimpleField dottedName="dirigeant . indépendant . cotisations et contributions . déduction tabac" />
|
||||
<SimpleField dottedName="dirigeant . indépendant . PL . régime général . taux spécifique retraite complémentaire" />
|
||||
|
||||
<H2>
|
||||
<Trans>Situation personnelle</Trans>
|
||||
</H2>
|
||||
<SimpleField dottedName="situation personnelle . RSA" />
|
||||
<Condition expression="entreprise . imposition . IR . micro-fiscal = non">
|
||||
<SubSection dottedName="dirigeant . indépendant . IJSS" />
|
||||
</Condition>
|
||||
<SubSection dottedName="dirigeant . indépendant . conjoint collaborateur" />
|
||||
|
||||
<H2>
|
||||
<Trans>Exonérations</Trans>
|
||||
</H2>
|
||||
<Body>
|
||||
<Emoji emoji="🏗️" /> Les calculs de l'exonération COVID 2021
|
||||
sont en cours d'implémentation
|
||||
</Body>
|
||||
<SimpleField dottedName="déclaration indépendants . ACRE" />
|
||||
<SimpleField dottedName="établissement . ZFU" />
|
||||
<Condition expression="établissement . ZFU">
|
||||
<SimpleField dottedName="entreprise . effectif . seuil" />
|
||||
</Condition>
|
||||
<SubSection
|
||||
dottedName="dirigeant . indépendant . cotisations et contributions . exonérations"
|
||||
hideTitle
|
||||
/>
|
||||
{FEATURE_FLAG_RESULTATS_COMPLETS && (
|
||||
<SubSection dottedName="dirigeant . indépendant . cotisations facultatives" />
|
||||
)}
|
||||
<H2>
|
||||
<Trans>International</Trans>
|
||||
</H2>
|
||||
<SimpleField dottedName="situation personnelle . domiciliation fiscale à l'étranger" />
|
||||
<Condition expression="entreprise . imposition . IR . micro-fiscal = non">
|
||||
<SubSection
|
||||
dottedName="dirigeant . indépendant . revenus étrangers"
|
||||
hideTitle
|
||||
/>
|
||||
</Condition>
|
||||
</Condition>
|
||||
|
||||
<Condition expression="déclaration indépendants . cotisations payées">
|
||||
<SubSection dottedName="déclaration indépendants . cotisations payées" />
|
||||
<SimpleField dottedName="déclaration indépendants . nature de l'activité" />
|
||||
<SimpleField dottedName="dirigeant . indépendant . conjoint collaborateur" />
|
||||
<SubSection dottedName="dirigeant . indépendant . cotisations facultatives" />
|
||||
{/* We can't use a subsection here cause revenu étrangers is not missing when CSG is replaced */}
|
||||
<H3>
|
||||
<Trans>Revenus étranger</Trans>
|
||||
</H3>
|
||||
<SimpleField dottedName="dirigeant . indépendant . revenus étrangers" />
|
||||
<Condition expression="dirigeant . indépendant . revenus étrangers">
|
||||
<SimpleField dottedName="dirigeant . indépendant . revenus étrangers . montant" />
|
||||
</Condition>
|
||||
</Condition>
|
||||
|
||||
<Condition expression="déclaration indépendants . cotisations payées version simple">
|
||||
<SimpleField dottedName="déclaration indépendants . cotisations payées version simple . cotisations sociales" />
|
||||
<SimpleField dottedName="déclaration indépendants . cotisations payées version simple . CSG déductible et CFP" />
|
||||
</Condition>
|
||||
</Grid>
|
||||
<Grid container>
|
||||
<Grid item lg={8}>
|
||||
<WhenNotAlreadyDefined dottedName="entreprise . SIREN">
|
||||
<Body>
|
||||
Cherchez avec votre nom, le nom de votre entreprise, le SIREN ou
|
||||
le SIRET
|
||||
</Body>
|
||||
<CompanySearchField onSubmit={setEntreprise} />
|
||||
</WhenNotAlreadyDefined>
|
||||
<WhenAlreadyDefined dottedName="entreprise . SIREN">
|
||||
<CompanyDetails />
|
||||
<Button onPress={() => dispatch(resetCompany())}>
|
||||
<Trans>Modifier</Trans>
|
||||
</Button>
|
||||
</WhenAlreadyDefined>
|
||||
</Grid>
|
||||
</FromTop>
|
||||
{FEATURE_FLAG_RESULTATS_COMPLETS ? (
|
||||
<>
|
||||
<SubSection dottedName="déclaration indépendants . régime d'imposition" />
|
||||
<Condition
|
||||
expression={{
|
||||
'une de ces conditions': [
|
||||
"déclaration indépendants . régime d'imposition . réel",
|
||||
"déclaration indépendants . régime d'imposition . déclaration contrôlée",
|
||||
'entreprise . imposition . IR . micro-fiscal',
|
||||
],
|
||||
}}
|
||||
>
|
||||
<TrackPage name="simulation terminée" />
|
||||
<ResultatsParFormulaire />
|
||||
</Condition>
|
||||
</>
|
||||
) : (
|
||||
<WhenAlreadyDefined dottedName="déclaration indépendants . résultat simple . cotisations obligatoires">
|
||||
<ResultatsSimples />
|
||||
</WhenAlreadyDefined>
|
||||
)}
|
||||
</Grid>
|
||||
<Condition expression="entreprise . catégorie juridique . SAS">
|
||||
<Spacing md />
|
||||
<Message type="info">
|
||||
<H3>Cet assistant ne gère pas le cas des dirigeants de SAS(U)</H3>
|
||||
<Body>
|
||||
Nous sommes désolés. Si vous rencontrez des difficultés à remplir
|
||||
votre déclaration, rapprochez-vous de votre comptable. Si vous êtes
|
||||
sans comptable, vous pouvez contacter le service des impôts.
|
||||
</Body>
|
||||
<Body>
|
||||
Si vous souhaitez que cet assistant à la déclaration gère votre cas
|
||||
dans le futur, laissez-nous message en cliquant sur le bouton "Faire
|
||||
une suggestion" en bas de la page.
|
||||
</Body>
|
||||
<Body>
|
||||
Ce site propose d'autres outils qui pourraient vous intéresser (par
|
||||
exemple un simulateur de revenu net après impôt).
|
||||
</Body>
|
||||
<Link to={sitePaths.gérer.index}>
|
||||
Découvrir les outils pour mon entreprise
|
||||
</Link>
|
||||
<Spacing md />
|
||||
</Message>
|
||||
</Condition>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function ImpositionSection() {
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const situation = useSelector(situationSelector)
|
||||
const setSituation = useCallback(
|
||||
(value, dottedName) => {
|
||||
dispatch(updateSituation(dottedName, value))
|
||||
},
|
||||
[dispatch]
|
||||
)
|
||||
return (
|
||||
<>
|
||||
<SimpleField dottedName="entreprise . imposition" />
|
||||
{situation['entreprise . imposition'] != null && (
|
||||
<>
|
||||
{/* <WhenApplicable dottedName="déclaration indépendants . comptabilité"> */}
|
||||
<SimpleField dottedName="déclaration indépendants . comptabilité" />
|
||||
{/* </WhenApplicable> */}
|
||||
<Condition
|
||||
expression={
|
||||
FEATURE_FLAG_RESULTATS_COMPLETS
|
||||
? 'oui'
|
||||
: 'déclaration indépendants . cotisations payées version simple = non'
|
||||
}
|
||||
>
|
||||
<FromTop key={situation['entreprise . imposition']}>
|
||||
<Condition expression="entreprise . imposition . IR">
|
||||
<SimpleField dottedName="entreprise . imposition . IR . micro-fiscal" />
|
||||
<Condition expression="entreprise . imposition . IR . micro-fiscal">
|
||||
<H2>
|
||||
Quel est votre chiffre d'affaires hors taxes en 2021 ?
|
||||
</H2>
|
||||
<SmallBody>
|
||||
Indiquez le montant hors taxes de votre chiffre d’affaires
|
||||
ou de vos recettes bruts (avant déduction de l’abattement
|
||||
forfaitaire pour frais et charges) et avant déduction des
|
||||
exonérations fiscales dont vous avez bénéficié
|
||||
</SmallBody>
|
||||
<SimpleField dottedName="entreprise . chiffre d'affaires . vente restauration hébergement" />
|
||||
<SimpleField dottedName="entreprise . chiffre d'affaires . service BIC" />
|
||||
<SimpleField dottedName="entreprise . chiffre d'affaires . service BNC" />
|
||||
</Condition>
|
||||
<Condition expression="entreprise . imposition . IR . micro-fiscal = non">
|
||||
<H2>
|
||||
Quel est votre résultat fiscal en 2021 ?<br />
|
||||
<small>
|
||||
Charges sociales et exonérations fiscales non incluses{' '}
|
||||
<ExplicationsResultatFiscal />
|
||||
</small>
|
||||
</H2>
|
||||
<SmallBody>
|
||||
Le résultat fiscal correspond aux produits moins les
|
||||
charges. Il peut être positif (bénéfice) ou négatif
|
||||
(déficit).
|
||||
</SmallBody>
|
||||
<BigInput>
|
||||
<RuleInput
|
||||
dottedName="dirigeant . rémunération . totale"
|
||||
onChange={setSituation}
|
||||
autoFocus
|
||||
/>
|
||||
</BigInput>
|
||||
</Condition>
|
||||
</Condition>
|
||||
<Condition expression="entreprise . imposition . IS">
|
||||
<H2>
|
||||
Quel est le montant net de votre rémunération en 2021 ?
|
||||
<br />
|
||||
<small>Sans tenir compte des charges sociales</small>
|
||||
</H2>
|
||||
<BigInput>
|
||||
<RuleInput
|
||||
dottedName="dirigeant . rémunération . nette"
|
||||
onChange={setSituation}
|
||||
autoFocus
|
||||
/>
|
||||
</BigInput>
|
||||
</Condition>
|
||||
</FromTop>
|
||||
</Condition>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const Question = styled.div`
|
||||
margin-top: 1em;
|
||||
`
|
||||
const BigInput = styled.div`
|
||||
font-size: 130%;
|
||||
`
|
||||
|
|
|
@ -8,7 +8,7 @@ import { RootState } from '@/reducers/rootReducer'
|
|||
import aideOrganismeSvg from './aideOrganisme.svg'
|
||||
|
||||
const aideMidiPyrenéesAutoEntrepreneur = (state: RootState) => {
|
||||
const company = state.inFranceApp.existingCompany
|
||||
const company = state.choixStatutJuridique.existingCompany
|
||||
if (!company) {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ type EmbaucherProps = {
|
|||
function Embaucher({ onChecklistInitialization, onItemCheck }: EmbaucherProps) {
|
||||
const { t } = useTranslation()
|
||||
const hiringChecklist = useSelector(
|
||||
(state: RootState) => state.inFranceApp.hiringChecklist
|
||||
(state: RootState) => state.choixStatutJuridique.hiringChecklist
|
||||
)
|
||||
return (
|
||||
<FromBottom>
|
||||
|
@ -247,7 +247,7 @@ function Embaucher({ onChecklistInitialization, onItemCheck }: EmbaucherProps) {
|
|||
|
||||
export default connect(
|
||||
(state: RootState) => ({
|
||||
hiringChecklist: state.inFranceApp.hiringChecklist,
|
||||
hiringChecklist: state.choixStatutJuridique.hiringChecklist,
|
||||
}),
|
||||
{
|
||||
onChecklistInitialization: initializeHiringChecklist,
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
import { Grid } from '@mui/material'
|
||||
import { specifyIfAutoEntrepreneur } from '@/actions/existingCompanyActions'
|
||||
import CompanyDetails from '@/components/CompanyDetails'
|
||||
import { DottedName } from '@/../../modele-social'
|
||||
import RuleInput from '@/components/conversation/RuleInput'
|
||||
import { WhenApplicable, WhenNotApplicable } from '@/components/EngineValue'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import { FromBottom } from '@/components/ui/animate'
|
||||
import { ScrollToTop } from '@/components/utils/Scroll'
|
||||
import { PlacesDesEntreprisesButton } from '@/components/PlaceDesEntreprises'
|
||||
import { FromTop } from '@/components/ui/animate'
|
||||
import { useEngine } from '@/components/utils/EngineContext'
|
||||
import { SitePathsContext } from '@/components/utils/SitePathsContext'
|
||||
import { Button } from '@/design-system/buttons'
|
||||
import useSimulationConfig from '@/components/utils/useSimulationConfig'
|
||||
import { Message } from '@/design-system'
|
||||
import { Container, Spacing } from '@/design-system/layout'
|
||||
import Popover from '@/design-system/Popover'
|
||||
import { H2 } from '@/design-system/typography/heading'
|
||||
import { Link } from '@/design-system/typography/link'
|
||||
import { Intro } from '@/design-system/typography/paragraphs'
|
||||
import { useContext, useEffect, useRef, useState } from 'react'
|
||||
import { H2, H3 } from '@/design-system/typography/heading'
|
||||
import { Body, Intro } from '@/design-system/typography/paragraphs'
|
||||
import { useQuestionList } from '@/hooks/useQuestionList'
|
||||
import { Grid } from '@mui/material'
|
||||
import Engine from 'publicodes'
|
||||
import { useContext } from 'react'
|
||||
import { Helmet } from 'react-helmet-async'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { Redirect } from 'react-router'
|
||||
import { Company } from '@/reducers/inFranceAppReducer'
|
||||
import { RootState } from '@/reducers/rootReducer'
|
||||
import styled from 'styled-components'
|
||||
import { TrackPage } from '../../ATInternetTracking'
|
||||
import { SimulateurCard } from '../Simulateurs/Home'
|
||||
|
@ -30,85 +30,82 @@ import { MobiliteCard } from './cards/MobiliteCard'
|
|||
import { SecuriteSocialeCard } from './cards/SecuriteSocialeCard'
|
||||
import forms from './forms.svg'
|
||||
import growth from './growth.svg'
|
||||
import { PlacesDesEntreprisesButton } from '@/components/PlaceDesEntreprises'
|
||||
|
||||
export type DirigeantOrNull = keyof SimulatorData | null
|
||||
|
||||
const infereDirigeantSimulateurFromCompanyDetails = (
|
||||
company: Company | null
|
||||
): DirigeantOrNull => {
|
||||
if (!company) {
|
||||
return null
|
||||
}
|
||||
if (company.isAutoEntrepreneur) {
|
||||
const infereSimulateurRevenuFromSituation = (
|
||||
engine: Engine<DottedName>
|
||||
): keyof SimulatorData | null => {
|
||||
if (
|
||||
engine.evaluate('entreprise . catégorie juridique . EI . auto-entrepreneur')
|
||||
.nodeValue
|
||||
) {
|
||||
return 'auto-entrepreneur'
|
||||
}
|
||||
if (
|
||||
company.statutJuridique &&
|
||||
['EIRL', 'EURL', 'EI'].includes(company.statutJuridique) &&
|
||||
inferPLSimulateurFromCompanyDetails(company)
|
||||
) {
|
||||
return inferPLSimulateurFromCompanyDetails(company)
|
||||
}
|
||||
if (company.statutJuridique === 'EI') {
|
||||
return 'entreprise-individuelle'
|
||||
}
|
||||
if (
|
||||
company.statutJuridique &&
|
||||
['EIRL', 'SASU', 'EURL'].includes(company.statutJuridique)
|
||||
) {
|
||||
return company.statutJuridique.toLowerCase() as 'eirl' | 'sasu' | 'eurl'
|
||||
}
|
||||
if (company.statutJuridique === 'SARL') {
|
||||
return 'indépendant'
|
||||
}
|
||||
|
||||
if (company.statutJuridique === 'SAS') {
|
||||
if (
|
||||
engine.evaluate('entreprise . catégorie juridique . SARL . unipersonnelle')
|
||||
.nodeValue
|
||||
) {
|
||||
return 'eurl'
|
||||
}
|
||||
if (
|
||||
engine.evaluate('entreprise . catégorie juridique . SAS . unipersonnelle')
|
||||
.nodeValue
|
||||
) {
|
||||
return 'sasu'
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
// Profession Libérale
|
||||
const inferPLSimulateurFromCompanyDetails = (
|
||||
company: Company | null
|
||||
): DirigeantOrNull => {
|
||||
if (!company) {
|
||||
return null
|
||||
if (
|
||||
engine.evaluate(
|
||||
'entreprise . catégorie juridique . EI . responsabilité limité'
|
||||
).nodeValue
|
||||
) {
|
||||
return 'eirl'
|
||||
}
|
||||
const activiteToSimulator = {
|
||||
'Activités comptables': 'expert-comptable',
|
||||
'Activité des médecins généralistes': 'médecin',
|
||||
'Activités de radiodiagnostic et de radiothérapie': 'médecin',
|
||||
'Activités chirurgicales': 'médecin',
|
||||
'Activité des médecins spécialistes': 'médecin',
|
||||
'Activités hospitalières': 'pamc',
|
||||
'Pratique dentaire': 'chirurgien-dentiste',
|
||||
'Commerce de détail de produits pharmaceutiques en magasin spécialisé':
|
||||
'pharmacien',
|
||||
'Activités des infirmiers et des sages-femmes': 'pamc',
|
||||
"Activités des professionnels de la rééducation, de l'appareillage et des pédicures-podologues":
|
||||
'auxiliaire-médical',
|
||||
"Laboratoires d'analyses médicales": 'pharmacien',
|
||||
'Arts du spectacle vivant': 'artiste-auteur',
|
||||
'Création artistique relevant des arts plastiques': 'artiste-auteur',
|
||||
'Autre création artistique': 'artiste-auteur',
|
||||
'Activités photographiques': 'artiste-auteur',
|
||||
} as Record<string, keyof SimulatorData>
|
||||
return activiteToSimulator[company.activitePrincipale] || null
|
||||
if (engine.evaluate('entreprise . catégorie juridique . EI').nodeValue) {
|
||||
const métierProfessionLibéral = engine.evaluate(
|
||||
'dirigeant . indépendant . PL . métier'
|
||||
).nodeValue
|
||||
switch (métierProfessionLibéral) {
|
||||
case 'avocat':
|
||||
return 'avocat'
|
||||
case 'expert-comptable':
|
||||
return 'expert-comptable'
|
||||
case 'santé . médecin':
|
||||
return 'médecin'
|
||||
case 'santé . chirurgien-dentiste':
|
||||
return 'chirurgien-dentiste'
|
||||
case 'santé . sage-femme':
|
||||
return 'sage-femme'
|
||||
case 'santé . auxiliaire médical':
|
||||
return 'auxiliaire-médical'
|
||||
case 'santé . pharmacien':
|
||||
return 'pharmacien'
|
||||
}
|
||||
if (engine.evaluate('dirigeant . indépendant . PL').nodeValue) {
|
||||
return 'profession-libérale'
|
||||
}
|
||||
return 'entreprise-individuelle'
|
||||
}
|
||||
const régimeSocial = engine.evaluate('dirigeant . régime social').nodeValue
|
||||
|
||||
if (régimeSocial === 'indépendant') {
|
||||
return 'indépendant'
|
||||
}
|
||||
// TODO : assimilé-salarié
|
||||
// if (
|
||||
// régimeSocial === 'assimilé-salarié'
|
||||
// ) {
|
||||
// return 'assimilé-salarié'
|
||||
// }
|
||||
return null
|
||||
}
|
||||
|
||||
export default function Gérer() {
|
||||
const { t, i18n } = useTranslation()
|
||||
const company = useSelector(
|
||||
(state: RootState) => state.inFranceApp.existingCompany
|
||||
)
|
||||
const dirigeantSimulateur =
|
||||
infereDirigeantSimulateurFromCompanyDetails(company)
|
||||
const dirigeantSimulateur = infereSimulateurRevenuFromSituation(useEngine())
|
||||
const simulateurs = useSimulatorsData()
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
if (!company) {
|
||||
const engine = useEngine()
|
||||
if (!engine.evaluate('entreprise . SIREN').nodeValue) {
|
||||
return <Redirect to={sitePaths.index} />
|
||||
}
|
||||
return (
|
||||
|
@ -118,191 +115,156 @@ export default function Gérer() {
|
|||
</Helmet>
|
||||
|
||||
<TrackPage name="accueil" />
|
||||
<ScrollToTop />
|
||||
<FromBottom>
|
||||
<PageHeader
|
||||
picture={growth}
|
||||
titre={<Trans i18nKey="gérer.titre">Gérer mon activité</Trans>}
|
||||
>
|
||||
<Intro>
|
||||
<Trans i18nKey="gérer.description">
|
||||
Vous souhaitez vous verser un revenu ou embaucher ? Vous aurez à
|
||||
payer des cotisations et des impôts. Anticipez leurs montants
|
||||
grâce aux simulateurs adaptés à votre situation.
|
||||
</Trans>
|
||||
</Intro>
|
||||
<CompanySection company={company} />
|
||||
<Spacing xl />
|
||||
</PageHeader>
|
||||
<PageHeader
|
||||
picture={growth}
|
||||
titre={<Trans i18nKey="gérer.titre">Gérer mon activité</Trans>}
|
||||
>
|
||||
<Intro>
|
||||
<Trans i18nKey="gérer.description">
|
||||
Vous souhaitez vous verser un revenu ou embaucher ? Vous aurez à
|
||||
payer des cotisations et des impôts. Anticipez leurs montants grâce
|
||||
aux simulateurs adaptés à votre situation.
|
||||
</Trans>
|
||||
</Intro>
|
||||
<AskCompanyMissingDetails />
|
||||
<Spacing xl />
|
||||
</PageHeader>
|
||||
|
||||
{dirigeantSimulateur && (
|
||||
<Container
|
||||
backgroundColor={(theme) => theme.colors.bases.primary[600]}
|
||||
darkMode
|
||||
>
|
||||
<FormsImage src={forms} alt="" />
|
||||
<Spacing xs />
|
||||
<Container
|
||||
backgroundColor={(theme) => theme.colors.bases.primary[600]}
|
||||
darkMode
|
||||
>
|
||||
<FromTop>
|
||||
<FormsImage src={forms} alt="" />
|
||||
<Spacing xs />
|
||||
<H2>Simulateurs pour votre entreprise</H2>
|
||||
<Grid container spacing={3} position="relative">
|
||||
{dirigeantSimulateur ? (
|
||||
<SimulateurCard fromGérer {...simulateurs[dirigeantSimulateur]} />
|
||||
) : (
|
||||
<Grid item>
|
||||
<Trans>
|
||||
<Message>
|
||||
<Intro>
|
||||
Il n'existe pas encore de simulateur de revenu pour votre
|
||||
type d'entreprise sur ce site.
|
||||
</Intro>
|
||||
<Body>
|
||||
Si vous souhaitez que nous développions un nouveau
|
||||
simulateur, laissez-nous message en cliquant sur le bouton
|
||||
"Faire une suggestion" en bas de cette page.
|
||||
</Body>
|
||||
</Message>
|
||||
</Trans>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<H2>Entreprise et revenus</H2>
|
||||
<Grid container spacing={3} position="relative">
|
||||
{dirigeantSimulateur !== null && (
|
||||
<SimulateurCard
|
||||
fromGérer
|
||||
{...simulateurs[dirigeantSimulateur]}
|
||||
/>
|
||||
)}
|
||||
|
||||
{company?.statutJuridique &&
|
||||
['EIRL', 'EI', 'EURL', 'SARL'].includes(
|
||||
company.statutJuridique
|
||||
) &&
|
||||
!company.isAutoEntrepreneur && (
|
||||
<WhenApplicable dottedName="dirigeant . indépendant">
|
||||
<SimulateurCard
|
||||
fromGérer
|
||||
{...simulateurs['aide-déclaration-indépendant']}
|
||||
/>
|
||||
</WhenApplicable>
|
||||
<WhenApplicable dottedName="entreprise . imposition . IS">
|
||||
<Grid item xs={12} md={6} lg={4} alignSelf="flex-end">
|
||||
<Grid container spacing={3} columns={2}>
|
||||
<SimulateurCard fromGérer {...simulateurs['is']} small />
|
||||
<SimulateurCard
|
||||
fromGérer
|
||||
{...simulateurs['aide-déclaration-indépendant']}
|
||||
{...simulateurs['dividendes']}
|
||||
small
|
||||
/>
|
||||
)}
|
||||
{company?.statutJuridique &&
|
||||
['SARL', 'SASU', 'SAS'].includes(company.statutJuridique) && (
|
||||
<Grid item xs={12} md={6} lg={4} alignSelf="flex-end">
|
||||
<Grid container spacing={3} columns={2}>
|
||||
<SimulateurCard fromGérer {...simulateurs['is']} small />
|
||||
<SimulateurCard
|
||||
fromGérer
|
||||
{...simulateurs['dividendes']}
|
||||
small
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
<Spacing xl />
|
||||
</Container>
|
||||
)}
|
||||
{dirigeantSimulateur !== 'auto-entrepreneur' && (
|
||||
<>
|
||||
<H2>
|
||||
<Trans>Salariés et embauche</Trans>
|
||||
</H2>
|
||||
<Grid container spacing={3}>
|
||||
<SimulateurCard fromGérer {...simulateurs['salarié']} />
|
||||
<SimulateurCard fromGérer {...simulateurs['chômage-partiel']} />
|
||||
</Grid>
|
||||
</>
|
||||
)}
|
||||
|
||||
<AideOrganismeLocal />
|
||||
|
||||
<H2>
|
||||
<Trans>Ressources utiles</Trans>
|
||||
</H2>
|
||||
<Grid container spacing={3}>
|
||||
{dirigeantSimulateur === 'indépendant' && i18n.language === 'fr' && (
|
||||
<Grid item sm={12} md={4}>
|
||||
<MobiliteCard />
|
||||
</Grid>
|
||||
)}
|
||||
{!company?.isAutoEntrepreneur && (
|
||||
<Grid item sm={12} md={4}>
|
||||
<DemarcheEmbaucheCard />
|
||||
</Grid>
|
||||
)}
|
||||
{company?.isAutoEntrepreneur && (
|
||||
<Grid item sm={12} md={4}>
|
||||
<AutoEntrepreneurCard />
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item sm={12} md={4}>
|
||||
<SecuriteSocialeCard />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</WhenApplicable>
|
||||
</Grid>
|
||||
|
||||
<Grid item sm={12} md={4}>
|
||||
<KbisCard dirigeant={dirigeantSimulateur} />
|
||||
</FromTop>
|
||||
<Spacing xl />
|
||||
</Container>
|
||||
{dirigeantSimulateur !== 'auto-entrepreneur' && (
|
||||
<FromTop>
|
||||
<H2>
|
||||
<Trans>Salariés et embauche</Trans>
|
||||
</H2>
|
||||
<Grid container spacing={3}>
|
||||
<SimulateurCard fromGérer {...simulateurs['salarié']} />
|
||||
<SimulateurCard fromGérer {...simulateurs['chômage-partiel']} />
|
||||
</Grid>
|
||||
</FromTop>
|
||||
)}
|
||||
|
||||
<AideOrganismeLocal />
|
||||
|
||||
<H2>
|
||||
<Trans>Ressources utiles</Trans>
|
||||
</H2>
|
||||
<Grid container spacing={3}>
|
||||
{dirigeantSimulateur === 'indépendant' && i18n.language === 'fr' && (
|
||||
<Grid item sm={12} md={4}>
|
||||
<MobiliteCard />
|
||||
</Grid>
|
||||
)}
|
||||
<WhenNotApplicable dottedName="entreprise . catégorie juridique . EI . auto-entrepreneur">
|
||||
<Grid item sm={12} md={4}>
|
||||
<DemarcheEmbaucheCard />
|
||||
</Grid>
|
||||
</WhenNotApplicable>
|
||||
<WhenApplicable dottedName="entreprise . catégorie juridique . EI . auto-entrepreneur">
|
||||
<Grid item sm={12} md={4}>
|
||||
<AutoEntrepreneurCard />
|
||||
</Grid>
|
||||
</WhenApplicable>
|
||||
|
||||
<Grid item sm={12} md={4}>
|
||||
<SecuriteSocialeCard />
|
||||
</Grid>
|
||||
|
||||
<Spacing lg />
|
||||
|
||||
<PlacesDesEntreprisesButton
|
||||
pathname="/aide-entreprise/mon-entreprise-urssaf-fr"
|
||||
siret={company.firstMatchingEtablissement.siret}
|
||||
/>
|
||||
</FromBottom>
|
||||
<Grid item sm={12} md={4}>
|
||||
<KbisCard dirigeant={dirigeantSimulateur} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<PlacesDesEntreprisesButton
|
||||
pathname="/aide-entreprise/mon-entreprise-urssaf-fr"
|
||||
siret={engine.evaluate('établissement . SIRET').nodeValue}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
type CompanySectionProps = {
|
||||
company: Company | null
|
||||
const companyDetailsConfig = {
|
||||
situation: {
|
||||
'contrat salarié': 'non',
|
||||
},
|
||||
objectifs: [
|
||||
'dirigeant . régime social',
|
||||
'entreprise . imposition',
|
||||
] as DottedName[],
|
||||
}
|
||||
export const AskCompanyMissingDetails = () => {
|
||||
useSimulationConfig(companyDetailsConfig)
|
||||
|
||||
export const CompanySection = ({ company }: CompanySectionProps) => {
|
||||
const [autoEntrepreneurModal, showAutoEntrepreneurModal] = useState(false)
|
||||
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const companyRef = useRef<Company | null>(null)
|
||||
useEffect(() => {
|
||||
if (companyRef.current !== company) {
|
||||
companyRef.current = company
|
||||
if (
|
||||
company?.statutJuridique === 'EI' &&
|
||||
company?.isAutoEntrepreneur == null &&
|
||||
!inferPLSimulateurFromCompanyDetails(company)
|
||||
) {
|
||||
showAutoEntrepreneurModal(true)
|
||||
}
|
||||
}
|
||||
}, [company])
|
||||
|
||||
const dispatch = useDispatch()
|
||||
const handleAnswerAutoEntrepreneur = (isAutoEntrepreneur: boolean) => {
|
||||
dispatch(specifyIfAutoEntrepreneur(isAutoEntrepreneur))
|
||||
showAutoEntrepreneurModal(false)
|
||||
const [questions, onQuestionAnswered] = useQuestionList()
|
||||
if (!questions.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<>
|
||||
{autoEntrepreneurModal && (
|
||||
<>
|
||||
<ScrollToTop />
|
||||
<Popover
|
||||
title={t('gérer.entreprise.auto', 'Êtes-vous auto-entrepreneur ?')}
|
||||
small
|
||||
>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item>
|
||||
<Button
|
||||
size="XS"
|
||||
onPress={() => handleAnswerAutoEntrepreneur(true)}
|
||||
>
|
||||
<Trans>Oui</Trans>
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
size="XS"
|
||||
onPress={() => handleAnswerAutoEntrepreneur(false)}
|
||||
>
|
||||
<Trans>Non</Trans>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Popover>
|
||||
</>
|
||||
)}
|
||||
|
||||
{company && (
|
||||
<>
|
||||
<CompanyDetails entreprise={company} />
|
||||
<Link to={sitePaths.index}>
|
||||
<Trans i18nKey="gérer.entreprise.changer">
|
||||
Changer l'entreprise sélectionnée
|
||||
</Trans>
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
<Body>
|
||||
Répondez à ces quelques questions rapides pour selectionner les outils
|
||||
et assistants qui vous conviennent le mieux.
|
||||
</Body>
|
||||
{questions.map((question) => (
|
||||
<FromTop key={question.dottedName}>
|
||||
<H3>{question.rawNode.question}</H3>
|
||||
<RuleInput
|
||||
dottedName={question.dottedName}
|
||||
onChange={onQuestionAnswered(question.dottedName)}
|
||||
/>
|
||||
</FromTop>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Grid } from '@mui/material'
|
||||
import CompanyDetails from '@/components/CompanyDetails'
|
||||
import CompanySearchDetails from '@/components/company/SearchDetails'
|
||||
import { SitePathsContext } from '@/components/utils/SitePathsContext'
|
||||
import { Card } from '@/design-system/card'
|
||||
import { H3 } from '@/design-system/typography/heading'
|
||||
import { useContext } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { Company } from '@/reducers/inFranceAppReducer'
|
||||
import { Company } from '@/reducers/choixStatutJuridiqueReducer'
|
||||
|
||||
type ContinueWithCompanyProps = {
|
||||
company: Company
|
||||
|
@ -29,7 +29,7 @@ export const ContinueWithCompany = ({ company }: ContinueWithCompanyProps) => {
|
|||
data-testid="currently-selected-company"
|
||||
bodyAs="div"
|
||||
>
|
||||
<CompanyDetails entreprise={company} />
|
||||
<CompanySearchDetails entreprise={company} />
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
|
|
@ -24,9 +24,6 @@ import SearchOrCreate from './SearchOrCreate'
|
|||
export default function Landing() {
|
||||
const simulators = useSimulatorsData()
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const company = useSelector(
|
||||
(state: RootState) => state.inFranceApp.existingCompany
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -59,7 +56,6 @@ export default function Landing() {
|
|||
darkMode
|
||||
backgroundColor={(theme) => theme.colors.bases.primary[600]}
|
||||
>
|
||||
{company && <ContinueWithCompany company={company} />}
|
||||
<SearchOrCreate />
|
||||
<Spacing xl />
|
||||
</Container>
|
||||
|
|
|
@ -1,49 +1,70 @@
|
|||
import { Grid } from '@mui/material'
|
||||
import { resetCompany } from '@/actions/companyActions'
|
||||
import { useSetEntreprise } from '@/actions/companyStatusActions'
|
||||
import { FabriqueSocialEntreprise } from '@/api/fabrique-social'
|
||||
import { CompanySearchField } from '@/components/CompanySearchField'
|
||||
import Emoji from '@/components/utils/Emoji'
|
||||
import { CompanyDetails } from '@/components/company/Details'
|
||||
import { CompanySearchField } from '@/components/company/SearchField'
|
||||
import Value from '@/components/EngineValue'
|
||||
import { useEngine } from '@/components/utils/EngineContext'
|
||||
import { SitePathsContext } from '@/components/utils/SitePathsContext'
|
||||
import { Message } from '@/design-system'
|
||||
import AnswerGroup from '@/design-system/answer-group'
|
||||
import { Button } from '@/design-system/buttons'
|
||||
import { H3 } from '@/design-system/typography/heading'
|
||||
import { Spacing } from '@/design-system/layout'
|
||||
import { H3, H4 } from '@/design-system/typography/heading'
|
||||
import { RootState } from '@/reducers/rootReducer'
|
||||
import { Grid } from '@mui/material'
|
||||
import { useCallback, useContext } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import { RootState } from '@/reducers/rootReducer'
|
||||
import styled from 'styled-components'
|
||||
|
||||
export default function SearchOrCreate() {
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const statutChoisi = useSelector(
|
||||
(state: RootState) => state.inFranceApp.companyStatusChoice
|
||||
(state: RootState) => state.choixStatutJuridique.companyStatusChoice
|
||||
)
|
||||
const companySIREN = useEngine().evaluate('entreprise . SIREN').nodeValue
|
||||
const handleCompanySubmit = useHandleCompanySubmit()
|
||||
|
||||
const dispatch = useDispatch()
|
||||
return (
|
||||
<Grid container spacing={3}>
|
||||
<Grid item lg={8} md={12}>
|
||||
<H3 as="h2">
|
||||
<Trans>Rechercher une entreprise</Trans>{' '}
|
||||
</H3>
|
||||
<CompanySearchField onSubmit={handleCompanySubmit} />
|
||||
</Grid>
|
||||
<Grid item lg md={12}>
|
||||
<ButtonContainer>
|
||||
<Button
|
||||
size="XL"
|
||||
to={
|
||||
statutChoisi
|
||||
? sitePaths.créer[statutChoisi]
|
||||
: sitePaths.créer.index
|
||||
}
|
||||
>
|
||||
<Trans i18nKey="landing.choice.create.title">
|
||||
Créer une entreprise
|
||||
</Trans>{' '}
|
||||
<Emoji emoji="💡" />
|
||||
</Button>
|
||||
</ButtonContainer>
|
||||
<Grid item xl={8} lg={10} md={12}>
|
||||
{companySIREN ? (
|
||||
<>
|
||||
<H3 as="h2">Votre entreprise</H3>
|
||||
<CompanyDetails />
|
||||
<Spacing md />
|
||||
<AnswerGroup>
|
||||
<Button to={sitePaths.gérer.index}>
|
||||
Continuer avec cette entreprise
|
||||
</Button>
|
||||
<Button light onPress={() => dispatch(resetCompany())}>
|
||||
Modifier
|
||||
</Button>
|
||||
</AnswerGroup>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<H3 as="h2">
|
||||
<Trans>Rechercher votre entreprise</Trans>{' '}
|
||||
</H3>
|
||||
<CompanySearchField onSubmit={handleCompanySubmit} />
|
||||
<Spacing md />
|
||||
|
||||
<Button
|
||||
size="XL"
|
||||
to={
|
||||
statutChoisi
|
||||
? sitePaths.créer[statutChoisi]
|
||||
: sitePaths.créer.index
|
||||
}
|
||||
>
|
||||
<Trans i18nKey="landing.choice.create.title">
|
||||
Je n'ai pas encore d'entreprise
|
||||
</Trans>
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
|
@ -62,12 +83,3 @@ function useHandleCompanySubmit() {
|
|||
)
|
||||
return handleCompanySubmit
|
||||
}
|
||||
|
||||
const ButtonContainer = styled.h2`
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
@media (min-width: ${({ theme }) => theme.breakpointsWidth.lg}) {
|
||||
position: relative;
|
||||
top: 4.25rem;
|
||||
}
|
||||
`
|
||||
|
|
|
@ -149,7 +149,8 @@ export default function VotreSituation() {
|
|||
<Trans i18nKey="économieCollaborative.WIP">
|
||||
<Strong>Cet assistant est en cours de développement.</Strong>{' '}
|
||||
N'hésitez pas à nous faire part de toute vos remarques, idées,
|
||||
questions en cliquant sur le bouton "Faire une suggestion" ci dessus.
|
||||
questions en cliquant sur le bouton "Faire une suggestion" en bas de
|
||||
la page.
|
||||
</Trans>
|
||||
</SmallBody>
|
||||
</FromBottom>
|
||||
|
|
|
@ -54,8 +54,7 @@ export default function PageData(props: PageDataProps) {
|
|||
const year = typeof année === 'number' && année != 2022 ? ` - ${année}` : ''
|
||||
|
||||
const inIframe = useIsEmbedded()
|
||||
const fromGérer = !!useLocation<{ fromGérer?: boolean }>().state?.fromGérer
|
||||
useSimulationConfig(config, { useExistingCompanyFromSituation: fromGérer })
|
||||
useSimulationConfig(config)
|
||||
useSearchParamsSimulationSharing()
|
||||
|
||||
// TODO : Move this logic elsewhere.
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import Banner from '@/components/Banner'
|
||||
import Value, { Condition } from '@/components/EngineValue'
|
||||
import Value, {
|
||||
Condition,
|
||||
WhenNotAlreadyDefined,
|
||||
} from '@/components/EngineValue'
|
||||
import PeriodSwitch from '@/components/PeriodSwitch'
|
||||
import RuleLink from '@/components/RuleLink'
|
||||
import Simulation from '@/components/Simulation'
|
||||
|
@ -45,23 +48,27 @@ export default function SalariéSimulation() {
|
|||
</ButtonContainer>
|
||||
</Body>
|
||||
}
|
||||
afterQuestionsSlot={
|
||||
<BrowserOnly>
|
||||
{/** L'équipe Code Du Travail Numérique ne souhaite pas référencer
|
||||
* le simulateur dirigeant de SASU sur son site. */}
|
||||
{!import.meta.env.SSR &&
|
||||
!document.referrer?.includes('code.travail.gouv.fr') && (
|
||||
<WhenNotAlreadyDefined dottedName="entreprise . catégorie juridique">
|
||||
<Banner icon={'👨✈️'}>
|
||||
<Trans>
|
||||
Vous êtes dirigeant d'une SAS(U) ?{' '}
|
||||
<Link to={sitePaths.simulateurs.sasu}>
|
||||
Accéder au simulateur de revenu dédié
|
||||
</Link>
|
||||
</Trans>
|
||||
</Banner>
|
||||
</WhenNotAlreadyDefined>
|
||||
)}
|
||||
</BrowserOnly>
|
||||
}
|
||||
>
|
||||
<SalariéSimulationGoals />
|
||||
<BrowserOnly>
|
||||
{/** L'équipe Code Du Travail Numérique ne souhaite pas référencer
|
||||
* le simulateur dirigeant de SASU sur son site. */}
|
||||
{!import.meta.env.SSR &&
|
||||
!document.referrer?.includes('code.travail.gouv.fr') && (
|
||||
<Banner icon={'👨✈️'}>
|
||||
<Trans>
|
||||
Vous êtes dirigeant d'une SAS(U) ?{' '}
|
||||
<Link to={sitePaths.simulateurs.sasu}>
|
||||
Accéder au simulateur de revenu dédié
|
||||
</Link>
|
||||
</Trans>
|
||||
</Banner>
|
||||
)}
|
||||
</BrowserOnly>
|
||||
</Simulation>
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
situation:
|
||||
dirigeant: "'artiste-auteur'"
|
||||
dirigeant: non
|
||||
contrat salarié: non
|
||||
unité par défaut: €/an
|
||||
objectifs:
|
||||
- artiste-auteur . cotisations
|
||||
|
|
|
@ -22,8 +22,9 @@ questions:
|
|||
liste noire:
|
||||
- entreprise . charges
|
||||
- entreprise . chiffre d'affaires
|
||||
- entreprise . activité . mixte
|
||||
|
||||
unité par défaut: €/an
|
||||
situation:
|
||||
entreprise . activité . mixte: non
|
||||
dirigeant: "'auto-entrepreneur'"
|
||||
entreprise . catégorie juridique: "'EI'"
|
||||
entreprise . catégorie juridique . EI . auto-entrepreneur: oui
|
||||
|
|
|
@ -12,6 +12,7 @@ questions:
|
|||
- établissement . localisation
|
||||
|
||||
unité par défaut: €/mois
|
||||
|
||||
situation:
|
||||
dirigeant: non
|
||||
contrat salarié . activité partielle: oui
|
||||
|
|
|
@ -27,7 +27,7 @@ questions:
|
|||
|
||||
unité par défaut: €/an
|
||||
situation:
|
||||
dirigeant: "'assimilé salarié'"
|
||||
entreprise . catégorie juridique: "'SAS'"
|
||||
entreprise . résultat fiscal: 0 €/an
|
||||
|
||||
#TODO : en attendant que la transitivité du remplacement soit implémentée (https://github.com/betagouv/publicodes/issues/55)
|
||||
|
|
|
@ -11,8 +11,7 @@ questions:
|
|||
|
||||
unité par défaut: €/an
|
||||
situation:
|
||||
dirigeant: "'assimilé salarié'" # [TODO] [dividendes-indep]
|
||||
bénéficiaire: oui
|
||||
dirigeant . régime social: "'assimilé salarié'" # [TODO] [dividendes-indep]
|
||||
entreprise . imposition: "'IS'"
|
||||
impôt . méthode de calcul: "'PFU'"
|
||||
dirigeant . rémunération . imposable: 0 €/an
|
||||
|
|
|
@ -17,6 +17,7 @@ questions:
|
|||
- entreprise . imposition
|
||||
- entreprise . exercice . début
|
||||
- entreprise . exercice . fin
|
||||
- entreprise . catégorie juridique
|
||||
liste:
|
||||
- entreprise
|
||||
- établissement
|
||||
|
@ -30,4 +31,4 @@ questions:
|
|||
- entreprise . activité . débit de tabac
|
||||
unité par défaut: €/an
|
||||
situation:
|
||||
dirigeant: "'indépendant'"
|
||||
dirigeant . régime social: "'indépendant'"
|
||||
|
|
|
@ -26,6 +26,6 @@ questions:
|
|||
- entreprise . ZFU
|
||||
unité par défaut: €/an
|
||||
situation:
|
||||
dirigeant: "'indépendant'"
|
||||
dirigeant . régime social: "'indépendant'"
|
||||
entreprise . activité: "'libérale'"
|
||||
entreprise . imposition: "'IR'"
|
||||
|
|
|
@ -17,6 +17,6 @@ questions:
|
|||
- entreprise . activité
|
||||
unité par défaut: €/an
|
||||
situation:
|
||||
dirigeant: "'auto-entrepreneur'"
|
||||
dirigeant . régime social: "'auto-entrepreneur'"
|
||||
entreprise . activité . mixte: non
|
||||
contrat salarié . ATMP . taux réduit: oui
|
||||
|
|
|
@ -128,8 +128,8 @@ const metadataSrc = (t: TFunction<'translation', string>) => {
|
|||
),
|
||||
},
|
||||
pathId: 'simulateurs.sasu',
|
||||
shortName: t('pages.simulateurs.sasu.shortname', 'SASU'),
|
||||
title: t('pages.simulateurs.sasu.title', 'Simulateur de SASU'),
|
||||
shortName: t('pages.simulateurs.sasu.shortname', 'SAS(U)'),
|
||||
title: t('pages.simulateurs.sasu.title', 'Simulateur de SAS(U)'),
|
||||
nextSteps: ['is', 'comparaison-statuts'],
|
||||
},
|
||||
eurl: {
|
||||
|
|
|
@ -4,12 +4,12 @@ import { SitePathsContext } from '@/components/utils/SitePathsContext'
|
|||
import { H2 } from '@/design-system/typography/heading'
|
||||
import { Link } from '@/design-system/typography/link'
|
||||
import { Body } from '@/design-system/typography/paragraphs'
|
||||
import { SimulationConfig } from '@/reducers/rootReducer'
|
||||
import React, { createContext, useContext, useMemo } from 'react'
|
||||
import { TFunction, Trans, useTranslation } from 'react-i18next'
|
||||
import { SimulationConfig } from '@/reducers/rootReducer'
|
||||
import { constructLocalizedSitePath, SitePathsType } from '../../sitePaths'
|
||||
import Créer from '../Creer/Home'
|
||||
import AideDéclarationIndépendant from '../Gerer/AideDéclarationIndépendant'
|
||||
import AideDéclarationIndépendant from '../Gerer/AideDéclarationIndépendant/PreviousVersion'
|
||||
import FormulaireMobilitéIndépendant from '../Gerer/DemandeMobilite'
|
||||
import AidesEmbauche from './AidesEmbauche'
|
||||
import ArtisteAuteur from './ArtisteAuteur'
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import { Action } from '@/actions/actions'
|
||||
import { FabriqueSocialEntreprise } from '@/api/fabrique-social'
|
||||
import { ApiCommuneJson } from '@/components/conversation/select/SelectCommune'
|
||||
import { omit } from '../utils'
|
||||
import { combineReducers } from 'redux'
|
||||
import { LegalStatus } from '@/selectors/companyStatusSelectors'
|
||||
import { LegalStatusRequirements } from '@/types/companyTypes'
|
||||
import { combineReducers } from 'redux'
|
||||
import { omit } from '../utils'
|
||||
|
||||
function companyLegalStatus(
|
||||
state: LegalStatusRequirements = {},
|
||||
|
@ -86,95 +84,14 @@ function companyStatusChoice(state: LegalStatus | null = null, action: Action) {
|
|||
return action.statusName
|
||||
}
|
||||
|
||||
type StatutJuridique =
|
||||
| 'EI'
|
||||
| 'EURL'
|
||||
| 'SARL'
|
||||
| 'SAS'
|
||||
| 'SA'
|
||||
| 'SASU'
|
||||
| 'NON_IMPLÉMENTÉ'
|
||||
|
||||
const infereLegalStatusFromCategorieJuridique = (
|
||||
catégorieJuridique: string
|
||||
): StatutJuridique => {
|
||||
/*
|
||||
Nous utilisons le code entreprise pour connaitre le statut juridique
|
||||
(voir https://www.insee.fr/fr/information/2028129)
|
||||
|
||||
En revanche, impossible de différencier EI et auto-entreprise
|
||||
https://www.sirene.fr/sirene/public/question.action?idQuestion=2933
|
||||
*/
|
||||
|
||||
if (catégorieJuridique === '1000') {
|
||||
return 'EI'
|
||||
}
|
||||
if (catégorieJuridique === '5498') {
|
||||
return 'EURL'
|
||||
}
|
||||
if (/^54..$/.exec(catégorieJuridique)) {
|
||||
return 'SARL'
|
||||
}
|
||||
if (/^55..$/.exec(catégorieJuridique)) {
|
||||
return 'SA'
|
||||
}
|
||||
if (catégorieJuridique === '5720') {
|
||||
return 'SASU'
|
||||
}
|
||||
if (/^57..$/.exec(catégorieJuridique)) {
|
||||
return 'SAS'
|
||||
}
|
||||
return 'NON_IMPLÉMENTÉ'
|
||||
}
|
||||
|
||||
export type Company = Omit<FabriqueSocialEntreprise, 'highlightLabel'> & {
|
||||
statutJuridique?: StatutJuridique
|
||||
isAutoEntrepreneur?: boolean
|
||||
isDirigeantMajoritaire?: boolean
|
||||
localisation?: ApiCommuneJson
|
||||
}
|
||||
|
||||
function existingCompany(
|
||||
state: Company | null = null,
|
||||
action: Action
|
||||
): Company | null {
|
||||
if (!action.type.startsWith('EXISTING_COMPANY::')) {
|
||||
return state
|
||||
}
|
||||
if (action.type === 'EXISTING_COMPANY::RESET') {
|
||||
return null
|
||||
}
|
||||
if (action.type === 'EXISTING_COMPANY::SET_COMPANY') {
|
||||
const statutJuridique = infereLegalStatusFromCategorieJuridique(
|
||||
action.entreprise.categorieJuridiqueUniteLegale
|
||||
)
|
||||
return {
|
||||
...omit(action.entreprise, 'highlightLabel'),
|
||||
statutJuridique,
|
||||
}
|
||||
}
|
||||
if (state && action.type === 'EXISTING_COMPANY::SPECIFY_AUTO_ENTREPRENEUR') {
|
||||
return { ...state, isAutoEntrepreneur: action.isAutoEntrepreneur }
|
||||
}
|
||||
if (
|
||||
state &&
|
||||
action.type === 'EXISTING_COMPANY::SPECIFY_DIRIGEANT_MAJORITAIRE'
|
||||
) {
|
||||
return { ...state, isDirigeantMajoritaire: action.isDirigeantMajoritaire }
|
||||
}
|
||||
if (state && action.type === 'EXISTING_COMPANY::ADD_COMMUNE_DETAILS') {
|
||||
return { ...state, localisation: action.details }
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
const inFranceAppReducer = combineReducers({
|
||||
const choixStatutJuridiqueReducer = combineReducers({
|
||||
companyLegalStatus,
|
||||
companyStatusChoice,
|
||||
companyCreationChecklist,
|
||||
existingCompany,
|
||||
hiringChecklist,
|
||||
})
|
||||
export default inFranceAppReducer
|
||||
export default choixStatutJuridiqueReducer
|
||||
|
||||
export type InFranceAppState = ReturnType<typeof inFranceAppReducer>
|
||||
export type ChoixStatutJuridiqueState = ReturnType<
|
||||
typeof choixStatutJuridiqueReducer
|
||||
>
|
|
@ -0,0 +1,129 @@
|
|||
import { DottedName } from '@/../../modele-social'
|
||||
import { Action } from '@/actions/actions'
|
||||
import { FabriqueSocialEntreprise } from '@/api/fabrique-social'
|
||||
import { Situation } from './rootReducer'
|
||||
|
||||
const SAVED_NAMESPACES = [
|
||||
'contrat salarié . ATMP',
|
||||
'contrat salarié . convention collective',
|
||||
'dirigeant . gérant minoritaire',
|
||||
'dirigeant . indépendant . PL . métier',
|
||||
'entreprise . ACRE',
|
||||
'entreprise . activité',
|
||||
'entreprise . catégorie juridique',
|
||||
'entreprise . date de création',
|
||||
'entreprise . effectif',
|
||||
'entreprise . exonérée de TVA',
|
||||
'entreprise . imposition',
|
||||
'entreprise . SIREN',
|
||||
'entreprise . nom',
|
||||
'établissement . adresse',
|
||||
'établissement . localisation',
|
||||
] as Array<DottedName>
|
||||
|
||||
export type Company = Omit<FabriqueSocialEntreprise, 'highlightLabel'>
|
||||
|
||||
export function companySituation(state: Situation = {}, action: Action) {
|
||||
switch (action.type) {
|
||||
case 'UPDATE_SITUATION':
|
||||
if (
|
||||
SAVED_NAMESPACES.some((namespace) =>
|
||||
action.fieldName.startsWith(namespace)
|
||||
)
|
||||
) {
|
||||
return {
|
||||
[action.fieldName]: action.value,
|
||||
...state,
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'COMPANY::SET_EXISTING_COMPANY':
|
||||
return getCompanySituation(action.entreprise)
|
||||
case 'COMPANY::RESET':
|
||||
return {}
|
||||
case 'COMPANY::ADD_COMMUNE_DETAILS':
|
||||
return {
|
||||
...state,
|
||||
'établissement . localisation': { objet: action.details },
|
||||
}
|
||||
case 'SET_SIMULATION':
|
||||
state['entreprise . SIREN'] ? state : {}
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
export function getCompanySituation(company: Company): Situation {
|
||||
return {
|
||||
'entreprise . date de création': company.dateCreationUniteLegale.replace(
|
||||
/(.*)-(.*)-(.*)/,
|
||||
'$3/$2/$1'
|
||||
),
|
||||
'entreprise . catégorie juridique': `'${getCatégorieFromCode(
|
||||
company.categorieJuridiqueUniteLegale
|
||||
)}'`,
|
||||
'entreprise . SIREN': `'${company.siren}'`,
|
||||
'entreprise . nom': `'${company.label}'`,
|
||||
'établissement . SIRET': `'${company.firstMatchingEtablissement.siret}'`,
|
||||
}
|
||||
}
|
||||
|
||||
type CatégorieJuridique = 'EI' | 'SARL' | 'SAS' | 'SELARL' | 'SELAS' | 'AUTRE'
|
||||
|
||||
const getCatégorieFromCode = (code: string): CatégorieJuridique => {
|
||||
/*
|
||||
Nous utilisons le code entreprise pour connaitre le statut juridique
|
||||
(voir https://www.insee.fr/fr/information/2028129)
|
||||
|
||||
En revanche, impossible de différencier EI et auto-entreprise
|
||||
https://www.sirene.fr/sirene/public/question.action?idQuestion=2933
|
||||
*/
|
||||
|
||||
if (code === '1000') {
|
||||
return 'EI'
|
||||
}
|
||||
if (code === '5485') {
|
||||
return 'SELARL'
|
||||
}
|
||||
if (code === '5470') {
|
||||
return 'AUTRE'
|
||||
}
|
||||
if (/^54..$/.exec(code)) {
|
||||
return 'SARL'
|
||||
}
|
||||
if (code === '5785') {
|
||||
return 'SELAS'
|
||||
}
|
||||
if (code === '5710') {
|
||||
return 'SAS'
|
||||
}
|
||||
return 'AUTRE'
|
||||
}
|
||||
|
||||
// // Profession Libérale
|
||||
// const inferPLSimulateurFromCompanyDetails = (
|
||||
// company: Company | null
|
||||
// ): DirigeantOrNull => {
|
||||
// if (!company) {
|
||||
// return null
|
||||
// }
|
||||
// const activiteToSimulator = {
|
||||
// 'Activités comptables': 'expert-comptable',
|
||||
// 'Activité des médecins généralistes': 'médecin',
|
||||
// 'Activités de radiodiagnostic et de radiothérapie': 'médecin',
|
||||
// 'Activités chirurgicales': 'médecin',
|
||||
// 'Activité des médecins spécialistes': 'médecin',
|
||||
// 'Activités hospitalières': 'pamc',
|
||||
// 'Pratique dentaire': 'chirurgien-dentiste',
|
||||
// 'Commerce de détail de produits pharmaceutiques en magasin spécialisé':
|
||||
// 'pharmacien',
|
||||
// 'Activités des infirmiers et des sages-femmes': 'pamc',
|
||||
// "Activités des professionnels de la rééducation, de l'appareillage et des pédicures-podologues":
|
||||
// 'auxiliaire-médical',
|
||||
// "Laboratoires d'analyses médicales": 'pharmacien',
|
||||
// 'Arts du spectacle vivant': 'artiste-auteur',
|
||||
// 'Création artistique relevant des arts plastiques': 'artiste-auteur',
|
||||
// 'Autre création artistique': 'artiste-auteur',
|
||||
// 'Activités photographiques': 'artiste-auteur',
|
||||
// } as Record<string, keyof SimulatorData>
|
||||
// return activiteToSimulator[company.activitePrincipale] || null
|
||||
// }
|
|
@ -1,15 +1,15 @@
|
|||
import { Action } from '@/actions/actions'
|
||||
import { getCompanySituation } from '@/components/utils/useSimulationConfig'
|
||||
import { ApiCommuneJson } from '@/components/conversation/select/SelectCommune'
|
||||
import { PreviousSimulation } from '@/selectors/previousSimulationSelectors'
|
||||
import { DottedName } from 'modele-social'
|
||||
import { defaultTo, without } from 'ramda'
|
||||
import { omit } from '../utils'
|
||||
import reduceReducers from 'reduce-reducers'
|
||||
import { combineReducers, Reducer } from 'redux'
|
||||
import { PreviousSimulation } from '@/selectors/previousSimulationSelectors'
|
||||
import { objectifsSelector } from '../selectors/simulationSelectors'
|
||||
import inFranceAppReducer from './inFranceAppReducer'
|
||||
import { omit } from '../utils'
|
||||
import { companySituation } from './companySituationReducer'
|
||||
import choixStatutJuridique from './choixStatutJuridiqueReducer'
|
||||
import previousSimulationRootReducer from './previousSimulationRootReducer'
|
||||
import { ApiCommuneJson } from '@/components/conversation/select/SelectCommune'
|
||||
|
||||
function explainedVariable(
|
||||
state: DottedName | null = null,
|
||||
|
@ -73,7 +73,6 @@ export type Simulation = {
|
|||
url: string
|
||||
hiddenNotifications: Array<string>
|
||||
situation: Situation
|
||||
initialSituation: Situation
|
||||
targetUnit: string
|
||||
foldedSteps: Array<DottedName>
|
||||
unfoldedStep?: DottedName | null
|
||||
|
@ -84,15 +83,14 @@ function simulation(
|
|||
action: Action
|
||||
): Simulation | null {
|
||||
if (action.type === 'SET_SIMULATION') {
|
||||
const { config, url, initialSituation } = action
|
||||
const { config, url } = action
|
||||
return {
|
||||
config,
|
||||
url,
|
||||
hiddenNotifications: [],
|
||||
situation: initialSituation ?? {},
|
||||
initialSituation: initialSituation ?? {},
|
||||
situation: {},
|
||||
targetUnit: config['unité par défaut'] || '€/mois',
|
||||
foldedSteps: Object.keys(initialSituation ?? {}) as Array<DottedName>,
|
||||
foldedSteps: [],
|
||||
unfoldedStep: null,
|
||||
}
|
||||
}
|
||||
|
@ -111,23 +109,11 @@ function simulation(
|
|||
return {
|
||||
...state,
|
||||
hiddenNotifications: [],
|
||||
situation: state.initialSituation,
|
||||
situation: {},
|
||||
foldedSteps: [],
|
||||
unfoldedStep: null,
|
||||
}
|
||||
case 'BATCH_UPDATE_SITUATION': {
|
||||
return (
|
||||
Object.entries(action.situation as any) as Array<[DottedName, unknown]>
|
||||
).reduce<Simulation | null>(
|
||||
(newState, [fieldName, value]) =>
|
||||
simulation(newState, {
|
||||
type: 'UPDATE_SITUATION',
|
||||
fieldName,
|
||||
value,
|
||||
}),
|
||||
state
|
||||
)
|
||||
}
|
||||
|
||||
case 'UPDATE_SITUATION': {
|
||||
const objectifs = without(
|
||||
['entreprise . charges'],
|
||||
|
@ -175,32 +161,34 @@ function simulation(
|
|||
}
|
||||
return state
|
||||
}
|
||||
const existingCompanyReducer = (state: RootState, action: Action) => {
|
||||
if (action.type.startsWith('EXISTING_COMPANY::') && state.simulation) {
|
||||
return {
|
||||
...state,
|
||||
simulation: {
|
||||
...state.simulation,
|
||||
situation: {
|
||||
...state.simulation.situation,
|
||||
...getCompanySituation(state.inFranceApp.existingCompany),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
function batchUpdateSituationReducer(state: RootState, action: Action) {
|
||||
if (action.type !== 'BATCH_UPDATE_SITUATION') {
|
||||
return state
|
||||
}
|
||||
return state
|
||||
return Object.entries(action.situation).reduce<RootState | null>(
|
||||
(newState, [fieldName, value]) =>
|
||||
mainReducer(newState ?? undefined, {
|
||||
type: 'UPDATE_SITUATION',
|
||||
fieldName,
|
||||
value,
|
||||
}),
|
||||
state
|
||||
)
|
||||
}
|
||||
|
||||
const mainReducer = combineReducers({
|
||||
explainedVariable,
|
||||
simulation,
|
||||
companySituation,
|
||||
previousSimulation: defaultTo(null) as Reducer<PreviousSimulation | null>,
|
||||
activeTargetInput,
|
||||
inFranceApp: inFranceAppReducer,
|
||||
choixStatutJuridique,
|
||||
})
|
||||
|
||||
export default reduceReducers<RootState>(
|
||||
mainReducer as any,
|
||||
existingCompanyReducer as Reducer<RootState>,
|
||||
mainReducer as Reducer<RootState>,
|
||||
batchUpdateSituationReducer as Reducer<RootState>,
|
||||
previousSimulationRootReducer as Reducer<RootState>
|
||||
) as Reducer<RootState>
|
||||
|
||||
|
|
|
@ -126,12 +126,12 @@ const possibleStatus = (
|
|||
)
|
||||
|
||||
export const possibleStatusSelector = (state: {
|
||||
inFranceApp: State
|
||||
choixStatutJuridique: State
|
||||
}): Record<LegalStatus, boolean> =>
|
||||
possibleStatus(state.inFranceApp.companyLegalStatus)
|
||||
possibleStatus(state.choixStatutJuridique.companyLegalStatus)
|
||||
|
||||
export const nextQuestionSelector = (state: RootState): Question | null => {
|
||||
const legalStatusRequirements = state.inFranceApp.companyLegalStatus
|
||||
const legalStatusRequirements = state.choixStatutJuridique.companyLegalStatus
|
||||
const questionAnswered = Object.keys(
|
||||
legalStatusRequirements
|
||||
) as Array<Question>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { DottedName } from 'modele-social'
|
||||
import { RootState, SimulationConfig, Situation } from '@/reducers/rootReducer'
|
||||
import { DottedName } from 'modele-social'
|
||||
|
||||
export const configSelector = (state: RootState): Partial<SimulationConfig> =>
|
||||
state.simulation?.config ?? {}
|
||||
|
@ -13,7 +13,7 @@ export const objectifsSelector = (state: RootState) => {
|
|||
.flat()
|
||||
|
||||
const objectifs = [...primaryObjectifs, ...(config['objectifs cachés'] ?? [])]
|
||||
return objectifs
|
||||
return objectifs as Array<DottedName>
|
||||
}
|
||||
|
||||
const emptySituation: Situation = {}
|
||||
|
@ -21,23 +21,15 @@ const emptySituation: Situation = {}
|
|||
export const situationSelector = (state: RootState) =>
|
||||
state.simulation?.situation ?? emptySituation
|
||||
|
||||
export const initialSituationSelector = (state: RootState) =>
|
||||
state.simulation?.initialSituation ?? emptySituation
|
||||
|
||||
export const configSituationSelector = (state: RootState) =>
|
||||
configSelector(state).situation ?? emptySituation
|
||||
|
||||
export const companySituationSelector = (state: RootState) =>
|
||||
state.companySituation
|
||||
|
||||
export const firstStepCompletedSelector = (state: RootState) => {
|
||||
const situation = situationSelector(state)
|
||||
const baseSituation = configSituationSelector(state)
|
||||
const initialSituation = initialSituationSelector(state)
|
||||
return (
|
||||
Object.keys(situation).filter(
|
||||
(dottedName) =>
|
||||
!Object.keys(baseSituation).includes(dottedName) &&
|
||||
!Object.keys(initialSituation).includes(dottedName)
|
||||
).length > 0
|
||||
)
|
||||
return Object.keys(situation).length > 0
|
||||
}
|
||||
|
||||
export const targetUnitSelector = (state: RootState) =>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Action } from '@/actions/actions'
|
||||
import { InFranceAppState } from '@/reducers/inFranceAppReducer'
|
||||
import { ChoixStatutJuridiqueState } from '@/reducers/choixStatutJuridiqueReducer'
|
||||
import { RootState } from '@/reducers/rootReducer'
|
||||
import { Store } from 'redux'
|
||||
import { debounce } from '../utils'
|
||||
|
@ -9,18 +9,22 @@ const VERSION = 7
|
|||
|
||||
const LOCAL_STORAGE_KEY = 'mon-entreprise::persisted-infranceapp::v' + VERSION
|
||||
|
||||
export function setupInFranceAppPersistence(store: Store<RootState, Action>) {
|
||||
export function setupChoixStatutJuridiquePersistence(
|
||||
store: Store<RootState, Action>
|
||||
) {
|
||||
const listener = () => {
|
||||
const state = store.getState()
|
||||
safeLocalStorage.setItem(
|
||||
LOCAL_STORAGE_KEY,
|
||||
JSON.stringify(state.inFranceApp)
|
||||
JSON.stringify(state.choixStatutJuridique)
|
||||
)
|
||||
}
|
||||
store.subscribe(debounce(1000, listener))
|
||||
}
|
||||
|
||||
export function retrievePersistedInFranceApp(): InFranceAppState {
|
||||
export function retrievePersistedChoixStatutJuridique(): ChoixStatutJuridiqueState {
|
||||
const serializedState = safeLocalStorage.getItem(LOCAL_STORAGE_KEY)
|
||||
return serializedState ? JSON.parse(serializedState) : undefined
|
||||
return serializedState && serializedState !== 'undefined'
|
||||
? JSON.parse(serializedState)
|
||||
: undefined
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import { Action } from '@/actions/actions'
|
||||
|
||||
import { RootState, Situation } from '@/reducers/rootReducer'
|
||||
import { Store } from 'redux'
|
||||
import { debounce } from '../utils'
|
||||
import * as safeLocalStorage from './safeLocalStorage'
|
||||
|
||||
const VERSION = 1
|
||||
|
||||
const LOCAL_STORAGE_KEY = `mon-entreprise::companySituation::v${VERSION}`
|
||||
|
||||
export function setupCompanySituationPersistence(
|
||||
store: Store<RootState, Action>
|
||||
) {
|
||||
const listener = () => {
|
||||
const state = store.getState()
|
||||
safeLocalStorage.setItem(
|
||||
LOCAL_STORAGE_KEY,
|
||||
JSON.stringify(state.companySituation)
|
||||
)
|
||||
}
|
||||
store.subscribe(debounce(1000, listener))
|
||||
}
|
||||
|
||||
export function retrievePersistedCompanySituation(): Situation | undefined {
|
||||
const serializedState = safeLocalStorage.getItem(LOCAL_STORAGE_KEY)
|
||||
return serializedState && serializedState !== 'undefined'
|
||||
? (JSON.parse(serializedState) as Situation)
|
||||
: undefined
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, it, expect } from 'vitest'
|
||||
import { nextQuestionSelector } from '@/selectors/companyStatusSelectors'
|
||||
const state = (companyLegalStatus) => ({
|
||||
inFranceApp: {
|
||||
choixStatutJuridique: {
|
||||
companyLegalStatus,
|
||||
existingCompany: null,
|
||||
companyStatusChoice: null,
|
||||
|
|
|
@ -29,7 +29,7 @@ const initialSimulation: Simulation = {
|
|||
url: '/someurl',
|
||||
hiddenNotifications: [],
|
||||
situation: {},
|
||||
initialSituation: {},
|
||||
companySituation: {},
|
||||
targetUnit: '€/mois',
|
||||
foldedSteps: ['somestep' as DottedName],
|
||||
unfoldedStep: null,
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
pfu:
|
||||
- bénéficiaire . dividendes . bruts: 200 €/an
|
||||
impôt . méthode de calcul: "'PFU'"
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
- bénéficiaire . dividendes . bruts: 20000000 €/an
|
||||
impôt . méthode de calcul: "'PFU'"
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
|
||||
barème défauts:
|
||||
- bénéficiaire . dividendes . bruts: 200 €/an
|
||||
impôt . méthode de calcul: "'barème standard'"
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
- bénéficiaire . dividendes . bruts: 20000000 €/an
|
||||
impôt . méthode de calcul: "'barème standard'"
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
- bénéficiaire . dividendes . bruts: 200 €/an
|
||||
impôt . méthode de calcul: "'barème standard'"
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
impôt . foyer fiscal . revenu imposable . autres revenus imposables: 500000 €/an
|
||||
- bénéficiaire . dividendes . bruts: 20000 €/an
|
||||
impôt . méthode de calcul: "'barème standard'"
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
impôt . foyer fiscal . revenu imposable . autres revenus imposables: 50000 €/an
|
||||
|
||||
barème couple 2 enfants:
|
||||
- bénéficiaire . dividendes . bruts: 200 €/an
|
||||
impôt . méthode de calcul: "'barème standard'"
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
impôt . foyer fiscal . enfants à charge: 2
|
||||
impôt . foyer fiscal . situation de famille: "'couple'"
|
||||
- bénéficiaire . dividendes . bruts: 20000000 €/an
|
||||
impôt . méthode de calcul: "'barème standard'"
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
impôt . foyer fiscal . enfants à charge: 2
|
||||
impôt . foyer fiscal . situation de famille: "'couple'"
|
||||
- bénéficiaire . dividendes . bruts: 200 €/an
|
||||
impôt . méthode de calcul: "'barème standard'"
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
impôt . foyer fiscal . revenu imposable . autres revenus imposables: 500000 €/an
|
||||
impôt . foyer fiscal . enfants à charge: 2
|
||||
impôt . foyer fiscal . situation de famille: "'couple'"
|
||||
- bénéficiaire . dividendes . bruts: 20000 €/an
|
||||
impôt . méthode de calcul: "'barème standard'"
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
impôt . foyer fiscal . revenu imposable . autres revenus imposables: 50000 €/an
|
||||
impôt . foyer fiscal . enfants à charge: 2
|
||||
impôt . foyer fiscal . situation de famille: "'couple'"
|
||||
|
|
|
@ -86,16 +86,6 @@ atmp:
|
|||
- contrat salarié . rémunération . brut de base: 2000 €/mois
|
||||
contrat salarié . ATMP . taux collectif ATMP: 5%
|
||||
|
||||
assimilé salarié:
|
||||
- dirigeant: "'assimilé salarié'"
|
||||
contrat salarié . rémunération . brut de base: 5000 €/mois
|
||||
- dirigeant: "'assimilé salarié'"
|
||||
contrat salarié . rémunération . brut de base: 1500 €/mois
|
||||
entreprise . ACRE: oui
|
||||
- dirigeant: "'assimilé salarié'"
|
||||
contrat salarié . rémunération . brut de base: 3000 €/mois
|
||||
entreprise . ACRE: oui
|
||||
|
||||
aides:
|
||||
- contrat salarié . rémunération . brut de base: 2000 €/mois
|
||||
contrat salarié . statut JEI: oui
|
||||
|
@ -266,7 +256,7 @@ JEI:
|
|||
- contrat salarié . rémunération . brut de base: 20000 €/mois
|
||||
contrat salarié . statut JEI: oui
|
||||
- contrat salarié . rémunération . brut de base: 4000 €/mois
|
||||
dirigeant: "'assimilé salarié'"
|
||||
dirigeant . régime social: "'assimilé salarié'"
|
||||
contrat salarié . statut JEI: oui
|
||||
|
||||
frais pro - titres restaurant:
|
||||
|
|
|
@ -29,7 +29,9 @@ import employeeSituations from './simulations-salarié.yaml'
|
|||
|
||||
type SituationsSpecs = Record<string, Simulation['situation'][]>
|
||||
const roundResult = (arr: number[]) => arr.map((x) => Math.round(x))
|
||||
const engine = engineFactory(rules)
|
||||
const engine = engineFactory(rules, {
|
||||
logger: { warn: () => {}, error: (m) => console.error(m), log: () => {} },
|
||||
})
|
||||
const runSimulations = (
|
||||
situationsSpecs: SituationsSpecs,
|
||||
objectifs: DottedName[],
|
||||
|
@ -108,7 +110,7 @@ it('calculate simulations-rémunération-dirigeant (assimilé salarié)', () =>
|
|||
remunerationDirigeantConfig.objectifs,
|
||||
{
|
||||
...remunerationDirigeantConfig.situation,
|
||||
dirigeant: "'assimilé salarié'",
|
||||
'dirigeant . régime social': "'assimilé salarié'",
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -119,7 +121,8 @@ it('calculate simulations-rémunération-dirigeant (auto-entrepreneur)', () => {
|
|||
remunerationDirigeantConfig.objectifs,
|
||||
{
|
||||
...remunerationDirigeantConfig.situation,
|
||||
dirigeant: "'auto-entrepreneur'",
|
||||
'entreprise . catégorie juridique': "'EI'",
|
||||
'entreprise . catégorie juridique . EI . auto-entrepreneur': 'oui',
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -130,7 +133,8 @@ it('calculate simulations-rémunération-dirigeant (indépendant)', () => {
|
|||
remunerationDirigeantConfig.objectifs,
|
||||
{
|
||||
...remunerationDirigeantConfig.situation,
|
||||
dirigeant: "'indépendant'",
|
||||
'dirigeant . régime social': "'indépendant'",
|
||||
'entreprise . imposition': "'IR'",
|
||||
}
|
||||
)
|
||||
})
|
||||
|
|
18
yarn.lock
18
yarn.lock
|
@ -15827,30 +15827,28 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"publicodes-react@npm:^1.0.0-beta.32":
|
||||
version: 1.0.0-beta.32
|
||||
resolution: "publicodes-react@npm:1.0.0-beta.32"
|
||||
"publicodes-react@portal:/home/johan/Projets/publicodes/packages/react-ui::locator=root%40workspace%3A.":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "publicodes-react@portal:/home/johan/Projets/publicodes/packages/react-ui::locator=root%40workspace%3A."
|
||||
dependencies:
|
||||
styled-components: ^5.1.0
|
||||
peerDependencies:
|
||||
publicodes: 1.0.0-beta.32
|
||||
react: ^17.0.2
|
||||
checksum: 2cdf91420982e909869cf9ddc1754943d4e5e8bef7545e4d5afdfc202eb1bbdcb33197bb4ad2978f6cfd02aad3229ec53061ff06680c9f2917638fde79b98b28
|
||||
languageName: node
|
||||
linkType: hard
|
||||
linkType: soft
|
||||
|
||||
"publicodes@npm:^1.0.0-beta.32":
|
||||
version: 1.0.0-beta.32
|
||||
resolution: "publicodes@npm:1.0.0-beta.32"
|
||||
"publicodes@portal:/home/johan/Projets/publicodes/packages/core::locator=root%40workspace%3A.":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "publicodes@portal:/home/johan/Projets/publicodes/packages/core::locator=root%40workspace%3A."
|
||||
dependencies:
|
||||
moo: ^0.5.1
|
||||
nearley: ^2.19.2
|
||||
yaml: ^1.9.2
|
||||
peerDependencies:
|
||||
"@types/mocha": ^9.0.0
|
||||
checksum: 674a5f1ee9f755cf8f9fd2312523ee70f3963b1c8cb9e0249919ad48269f3dbe831d4fe3e1c13400216bd21b34d2bbd5f71e571b3adc210ebdb1c2dc18ee72d6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
linkType: soft
|
||||
|
||||
"pump@npm:^2.0.0":
|
||||
version: 2.0.1
|
||||
|
|
Loading…
Reference in New Issue