diff --git "a/modele-social/r\303\250gles/imp\303\264t.publicodes" "b/modele-social/r\303\250gles/imp\303\264t.publicodes" index 125c2d151e..8a8c8c37a8 100644 --- "a/modele-social/r\303\250gles/imp\303\264t.publicodes" +++ "b/modele-social/r\303\250gles/imp\303\264t.publicodes" @@ -29,7 +29,7 @@ impôt . méthode de calcul: description: | Nous avons implémenté trois façon de calculer l'impôt sur le revenu : - *Le taux personnalisé* : indiqué sur votre avis d'imposition - - *Le taux neutre* : pour un célibataire sans enfants + - *Le taux neutre* : pour un célibataire sans enfant - *Le barème standard * : la formule "officielle" utilisée par l'administration fiscale pour obtenir le taux d'imposition En remplissant votre taux personnalisé, vous serez au plus proche de votre situation réelle. Le taux neutre peut être intéressant dans le cas où vous n'avez pas transmis votre taux personnalisé à l'employeur et que vous souhaitez comparer les résultats du simulateur à votre fiche de paie. Le barème standard vous donne un résultat plus précis que le taux neutre pour un célibataire sans enfant. @@ -58,7 +58,7 @@ impôt . méthode de calcul . taux neutre: description: Si vous ne connaissez pas votre taux personnalisé, ou si vous voulez connaître votre impôt à la source dans le cas où vous avez choisi de ne pas communiquer à votre taux à l'employeur, le calcul au taux neutre - correspond à une imposition pour un célibataire sans enfants et sans autres + correspond à une imposition pour un célibataire sans enfant et sans autres revenus / charges. valeur: impôt . méthode de calcul = 'taux neutre' diff --git a/site/source/components/conversation/NumberInput.tsx b/site/source/components/conversation/NumberInput.tsx index c5598d8a88..417b6ab5c4 100644 --- a/site/source/components/conversation/NumberInput.tsx +++ b/site/source/components/conversation/NumberInput.tsx @@ -8,6 +8,7 @@ import { EngineContext } from '@/components/utils/EngineContext' import { NumberField } from '@/design-system/field' import { debounce } from '@/utils' +import localI18n from '../../locales/i18n' import InputSuggestions from './InputSuggestions' import { InputProps } from './RuleInput' @@ -28,7 +29,7 @@ export default function NumberInput({ const [currentValue, setCurrentValue] = useState( !missing && value != null && typeof value === 'number' ? value : undefined ) - const { i18n, t } = useTranslation() + const { i18n } = useTranslation() const parsedDisplayedUnit = displayedUnit ? parseUnit(displayedUnit) : unit const engine = useContext(EngineContext) useEffect(() => { @@ -70,8 +71,7 @@ export default function NumberInput({ getSerializedUnit( currentValue ?? 0, parsedDisplayedUnit, - i18n.language, - t + i18n.language ) } onChange={(valeur) => { @@ -108,12 +108,7 @@ export default function NumberInput({ } // TODO : put this inside publicodes -function getSerializedUnit( - value: number, - unit: Unit, - locale: string, - translate: (s?: string) => string | undefined -): string { +function getSerializedUnit(value: number, unit: Unit, locale: string): string { // removing euro, which is a currency not a unit unit = { ...unit, @@ -127,12 +122,17 @@ function getSerializedUnit( const formatUnit = getFormatUnit(unit) if (!formatUnit) { + const { translatedUnit, translatedPer } = getTranslatedUnit( + unit, + locale, + value > 2 + ) + return ( - translate( - serializeUnit(unit) - ?.replace(/\/([^\s])/, '/ $1') - .replace('/', 'par') - ) ?? '' + serializeUnit(translatedUnit) + ?.replace(/\/([^\s])/, ' / $1') + .replace('/', translatedPer) + .trim() ?? '' ) } @@ -183,6 +183,33 @@ function getFormatUnit(unit: Unit): Intl.NumberFormatOptions['unit'] | null { return formatUnit } +function getTranslatedUnit(unit: Unit, locale: string, plural: boolean) { + const unitsTranslations = Object.entries( + localI18n.getResourceBundle(locale, 'units') as Record + ) + const getTranslatedUnit = (unit: string, plural: boolean): string => { + const pluralizedUnit = unit + (plural ? '_plural' : '') + const key = unitsTranslations + .find(([unitKey]) => unitKey === pluralizedUnit)?.[1] + .replace(/_plural$/, '') + + return key || unit + } + + const translatedUnit = { + numerators: unit.numerators[0] + ? [getTranslatedUnit(unit.numerators[0], plural)] + : [], + denominators: unit.denominators[0] + ? [getTranslatedUnit(unit.denominators[0], false)] + : [], + } + const translatedPer = + unitsTranslations.find(([key]) => key === 'par')?.[1] || 'par' + + return { translatedUnit, translatedPer } +} + const StyledNumberInput = styled.div` display: flex; width: fit-content; diff --git a/site/source/locales/rules-en.yaml b/site/source/locales/rules-en.yaml index 921eb46641..adbbeb691f 100644 --- a/site/source/locales/rules-en.yaml +++ b/site/source/locales/rules-en.yaml @@ -6403,21 +6403,22 @@ impôt . méthode de calcul: titre.en: '[automatic] by default' titre.fr: par défaut description.en: > - We have implemented three ways to calculate income tax: + [automatic] We've implemented three ways of calculating income tax: - - *The personalized rate*: indicated on your tax notice + - the personalized rate*: indicated on your tax notice - - *The neutral rate*: for a single person without children + - the neutral rate*: for a single person with no children - - *The standard scale * : the "official" formula used by tax authorities to obtain the tax rate + - The standard scale*: the "official" formula used by the tax authorities to calculate the tax rate. - By filling in your personalized rate, you will be as close as possible to your real situation. The neutral rate can be interesting if you have not sent your personalized rate to the employer and you want to compare the results of the simulator with your pay slip. The standard scale gives you a more accurate result than the neutral rate for a single man without children. + + By filling in your personalized rate, you'll be as close as possible to your actual situation. The neutral rate can be useful if you haven't sent your personalized rate to your employer and want to compare the simulator's results with your payslip. The standard scale gives a more accurate result than the neutral rate for a single person without children. description.fr: > Nous avons implémenté trois façon de calculer l'impôt sur le revenu : - *Le taux personnalisé* : indiqué sur votre avis d'imposition - - *Le taux neutre* : pour un célibataire sans enfants + - *Le taux neutre* : pour un célibataire sans enfant - *Le barème standard * : la formule "officielle" utilisée par l'administration fiscale pour obtenir le taux d'imposition @@ -6442,14 +6443,15 @@ impôt . méthode de calcul . barème standard: titre.en: with the standard scale titre.fr: avec le barème standard impôt . méthode de calcul . taux neutre: - description.en: If you do not know your personalized rate, or if you want to - know your withholding tax if you have chosen not to communicate at your rate - to the employer, the calculation at the neutral rate corresponds to a tax - for a single person without children and without other income/charges. + description.en: + "[automatic] If you don't know your personalized tax rate, or if + you want to know your tax at source if you have chosen not to inform your + employer of your rate, the neutral rate calculation corresponds to taxation + for a single person with no children and no other income or expenses." description.fr: Si vous ne connaissez pas votre taux personnalisé, ou si vous voulez connaître votre impôt à la source dans le cas où vous avez choisi de ne pas communiquer à votre taux à l'employeur, le calcul au taux neutre - correspond à une imposition pour un célibataire sans enfants et sans autres + correspond à une imposition pour un célibataire sans enfant et sans autres revenus / charges. titre.en: with the neutral rate titre.fr: avec le taux neutre diff --git a/site/source/locales/units.yaml b/site/source/locales/units.yaml index b0b2b3eb40..6c801c8988 100644 --- a/site/source/locales/units.yaml +++ b/site/source/locales/units.yaml @@ -13,6 +13,7 @@ fr: titre-restaurant_plural: titres-restaurant part_plural: parts enfant_plural: enfants + par: par en: heure: hour heure_plural: hours @@ -45,3 +46,4 @@ en: part_plural: shares enfant: child enfant_plural: children + par: per