refactor: réorganise le code du budget

- 1 seul fichier à modifier (budget.yaml) pour ajouter une année
- texte commun intégré dans le composant React
- simplification des calculs de totaux
- suppression de la traduction en anglais
pull/3155/head
Alice Dahan 2024-10-08 09:33:36 +02:00 committed by liliced
parent d16e72d53d
commit 59add12d32
7 changed files with 400 additions and 379 deletions

View File

@ -382,14 +382,6 @@ au bout de 10 ans: after 10 years
betawarning: "<0><0>This tool is in beta version</0>: we are working on
<3>validating the information and calculations</3>, but <6>errors may</6>
still occur.</0>"
budget:
description: My-company budget
tableCaption: Table showing the budget for the year {{year}} by expense item.
The first column shows the current year ({{year}}) on the first line, then
the expenditure items, and finally the total before and after tax. The other
columns show expenses for each quarter. The last column shows the totals for
each expense item, as well as the aggregated totals before and after tax.
title: Budget
cards:
simulator-resource:
cta: Access the simulator

View File

@ -405,15 +405,6 @@ au bout de 10 ans: au bout de 10 ans
betawarning: "<0><0>Cet outil est en version bêta</0> : nous travaillons à
<3>valider les informations et les calculs</3>, mais des <6>erreurs peuvent
être présentes.</6></0>"
budget:
description: Le budget de mon-entreprise
tableCaption: Tableau affichant le bugdet de l'année {{year}} par poste de
dépenses. La première colonne affiche l'année en cours ({{year}}) sur la
première ligne puis les postes de dépenses et pour finir le total HT et
total TTC. Les autres colonnes affichent les dépenses pour chaque trimestre.
La dernière colonne affiche les totaux pour chaque poste de dépenses ainsi
que les totaux HT et TTC agrégés.
title: Budget
cards:
simulator-resource:
cta: Accéder au simulateur

View File

@ -0,0 +1,169 @@
import { formatValue } from 'publicodes'
import { styled } from 'styled-components'
import { arraySum } from '@/utils'
type Budget = Record<string, Record<string, number>>
type Props = {
selectedYear: string
budget: Budget
}
export default function ResourcesAllocation({ selectedYear, budget }: Props) {
const quarters = [
{ label: 'T1', 'aria-label': 'Trimestre 1' },
{ label: 'T2', 'aria-label': 'Trimestre 2' },
{ label: 'T3', 'aria-label': 'Trimestre 3' },
{ label: 'T4', 'aria-label': 'Trimestre 4' },
]
const categories = [
...new Set(
quarters
.map((quarter) => Object.keys(budget[quarter.label] ?? {}))
.reduce((acc, curr) => [...acc, ...curr], [])
),
]
const totals = quarters.reduce((total, quarter) => {
const quarterTotal = arraySum(Object.values(budget[quarter.label]))
return {
...total,
[quarter.label]: {
'Total HT': quarterTotal,
'Total TTC': Math.round(quarterTotal * 1.2),
},
}
}, {} as Budget)
return (
<div
style={{
overflowX: 'auto',
}}
>
<StyledTable role="table">
<caption className="sr-only">
{`Tableau affichant le bugdet de l'année ${selectedYear} par poste de dépenses. La première colonne affiche l'année en cours (${selectedYear}) sur la première ligne puis les postes de dépenses et pour finir le total HT et total TTC. Les autres colonnes affichent les dépenses pour chaque trimestre. La dernière colonne affiche les totaux pour chaque poste de dépenses ainsi que les totaux HT et TTC agrégés.`}
</caption>
<thead>
<tr>
<th>{selectedYear}</th>
{quarters.map((quarter) => (
<th
scope="col"
key={quarter.label}
aria-label={quarter['aria-label']}
>
{quarter.label}
</th>
))}
<th scope="col">Total</th>
</tr>
</thead>
<tbody>
{categories.map((label) => (
<tr key={label}>
<th scope="row">{label}</th>
{quarters.map((quarter) => {
const value = budget[quarter.label][label]
return (
<td key={quarter.label}>
{value ? (
formatValue(value, {
displayedUnit: '€',
})
) : (
<span aria-label="Pas de budget alloué">-</span>
)}
</td>
)
})}
<td>
{/* Total de ligne */}
{formatValue(
arraySum(
quarters.map((quarter) => budget[quarter.label][label] ?? 0)
),
{
displayedUnit: '€',
}
)}
</td>
</tr>
))}
</tbody>
<tfoot>
{['Total HT', 'Total TTC'].map((total) => (
<tr key={total}>
<th scope="row">{total}</th>
{quarters.map((quarter) => {
const value = totals[quarter.label][total] ?? 0
return (
<td key={quarter.label}>
{formatValue(value, {
displayedUnit: '€',
})}
</td>
)
})}
<td>
{/* Total du total */}
{formatValue(
arraySum(
quarters.map((quarter) => totals[quarter.label][total])
),
{
displayedUnit: '€',
}
)}
</td>
</tr>
))}
</tfoot>
</StyledTable>
</div>
)
}
const StyledTable = styled.table`
text-align: left;
width: 100%;
td,
th {
padding: 6px;
font-family: ${({ theme }) => theme.fonts.main};
}
td:not(:first-child),
th:not(:first-child) {
width: 100px;
text-align: right;
}
tbody tr:nth-child(odd),
tfoot tr:nth-child(odd) {
background: ${({ theme }) =>
theme.darkMode
? theme.colors.extended.dark[700]
: theme.colors.bases.primary[100]};
color: inherit;
}
thead,
tfoot {
font-weight: bold;
}
tfoot tr:last-child {
color: ${({ theme }) =>
theme.darkMode
? theme.colors.bases.primary[300]
: theme.colors.bases.primary[700]};
background-color: inherit;
}
`

View File

@ -1,124 +0,0 @@
**Mon-Entreprise** est un service public numérique, cest pourquoi nous
sommes transparents sur les ressources allouées et la manière dont elles sont
employées.
## Principes
Nous suivons le [manifeste beta.gouv](https://beta.gouv.fr/manifeste)
dont nous rappelons les principes ici&nbsp;:
> - Les besoins des utilisateurs sont prioritaires sur les besoins de ladministration
> - Le mode de gestion de léquipe repose sur la confiance
> - Léquipe adopte une approche itérative et damélioration en continu
---
En 2019, le projet dispose dun budget de **250 000 € HT** pris en charge :
- Par la DINSIC (ancien nom de la [DINUM](https://www.numerique.gouv.fr/dinum/)) à hauteur de 150 000 € HT
- Par lAcoss (ancien nom de [l'Urssaf Caisse Nationale](https://www.urssaf.org/accueil.html)) à hauteur de 100 000 € HT
[➡ Voir la convention](https://static.data.gouv.fr/resources/conventions-de-partenariat/20190423-181035/convention-du-15-avril-2019.pdf)
| | |
| -------------------------- | ----------------: |
| Financement DINSIC | 150 000 € HT |
| Financement Acoss initial | 100 000 € HT |
| Rallonge Acoss fin dannée | 12 500 € HT |
| **Total HT** | **262 500 € HT** |
| **Total TTC** | **315 000 € TTC** |
En fin dannée une rallonge est attribuée pour la réalisation dun nouveau
simulateur et une expérimentation sur la paie.
---
En 2020, le budget est désormais pris en charge à 100% par lAcoss (ancien nom de
l'[Urssaf Caisse Nationale](https://www.urssaf.org/accueil.html)). En plus de sa
contribution financière, lAcoss fournit des ressources métier expertes provenant
du réseau des Urssaf.
Une enveloppe est allouée pour expérimenter la transformation du moteur de
simulations en moteur de paie complète. La solution proposée ne sera finalement
pas retenue pour la refonte des offres de service de lUrssaf. Voir le
[compte-rendu de lexpérimentation](https://pad.incubateur.net/s/ulS0EWvxK#).
Au quatrième trimestre mon-entreprise rejoint le
[programme Gamma](https://blog.beta.gouv.fr/dinsic/2020/08/20/acceleration-des-startups-d-etat-d-un-retour-d-experience-a-l-experimentation-d-un-programme-d-accompagnement-cible-1/)
qui accompagne laccélération des services publics crées par beta.gouv. Ce
programme est financé par la [DINUM](https://www.numerique.gouv.fr/dinum/).
---
En 2021 l[Urssaf Caisse Nationale](https://www.urssaf.org/accueil.html) prend en
charge à 100% le financement de mon-entreprise.
Au premier trimestre 2021, léquipe mon-entreprise continue de bénéficier de
laccompagnement du [programme
Gamma](https://beta.gouv.fr/approche/acceleration) financé par la
[DINUM](https://www.numerique.gouv.fr/dinum/).
---
En 2022 le projet devient mieux intégré au sein de
l[Urssaf Caisse Nationale](https://www.urssaf.org/accueil.html).
En complément du financement apporté par lUrssaf, le projet bénéficie du
programme [France Relance](https://france-relance.transformation.gouv.fr/).
---
En 2023, le financement complémentaire apporté par le programme
[France Relance](https://france-relance.transformation.gouv.fr/) prend fin.
---
En 2024 mon-entreprise est financée à 100% par
l[Urssaf Caisse Nationale](https://www.urssaf.org/accueil.html).
---
### Description des catégories
- **Développement 👨‍💻**
Les coûts de développement représentent la grande majorité de notre budget.
Nous sommes une petite équipe de développeurs et développeuses freelances,
pluridisciplinaires aussi bien sur les aspects techniques, stratégiques et
métiers. Les rémunérations suivent
[la grille de beta.gouv](https://doc.incubateur.net/communaute/travailler-a-beta-gouv/recrutement/remuneration).
- **Logiciels et hébergement 💻**
Notre modèle open-source nous permet daccéder gratuitement à la majorité des
outils que nous utilisons (hébergement de code, serveurs de tests, etc.). Le
site est hébergé sur [Netlify](https://www.netlify.com).
Nous achetons de la documentation spécialisée à destination des
professionnels du droit pour faciliter le suivi des évolutions législatives.
- **Déplacements 🚅**
Le réseau des Urssaf est présent dans toute la France. Nous organisons
plusieurs fois par an des ateliers avec des experts en région sur des
thématiques particulières. Sont aussi inclus dans cette catégorie la prise en
charge des frais de déplacement des membres de l'équipe qui n'habitent pas en
région parisienne.
- **Portage 🤝**
La marge du porteur attributaire du marché public de lUrssaf Caisse
Nationale, ainsi que les coûts liés à la société spécialement créée pour
effectuer le portage des indépendants qui travaillent sur le site
(administration, comptabilité, facturation, impôts, etc.).
> #### À propos de la TVA
>
> Contrairement aux entreprises du secteur privé, les administrations ne peuvent
> pas récupérer la TVA supportée sur leurs achats dans le cadre de leur
> activité.
>
> Le montant TTC inclut la TVA au taux de 20%.
>
> La TVA est collectée et reversée à lÉtat et diminue donc le montant du budget
> utilisable sur le projet.

View File

@ -1,4 +1,38 @@
2019:
description: |
En 2019, le projet dispose dun budget de **250 000 € HT** pris en charge :
- Par la DINSIC (ancien nom de la [DINUM](https://www.numerique.gouv.fr/dinum/)) à hauteur de 150 000 € HT
- Par lAcoss (ancien nom de [l'Urssaf Caisse Nationale](https://www.urssaf.org/accueil.html)) à hauteur de 100 000 € HT
[➡ Voir la convention](https://static.data.gouv.fr/resources/conventions-de-partenariat/20190423-181035/convention-du-15-avril-2019.pdf)
| | |
| -------------------------- | ----------------: |
| Financement DINSIC | 150 000 € HT |
| Financement Acoss initial | 100 000 € HT |
| Rallonge Acoss fin dannée | 12 500 € HT |
| **Total HT** | **262 500 € HT** |
| **Total TTC** | **315 000 € TTC** |
En fin dannée une rallonge est attribuée pour la réalisation dun nouveau
simulateur et une expérimentation sur la paie.
2020:
description: |
En 2020, le budget est désormais pris en charge à 100% par lAcoss (ancien nom de
l'[Urssaf Caisse Nationale](https://www.urssaf.org/accueil.html)). En plus de sa
contribution financière, lAcoss fournit des ressources métier expertes provenant
du réseau des Urssaf.
Une enveloppe est allouée pour expérimenter la transformation du moteur de
simulations en moteur de paie complète. La solution proposée ne sera finalement
pas retenue pour la refonte des offres de service de lUrssaf. Voir le
[compte-rendu de lexpérimentation](https://pad.incubateur.net/s/ulS0EWvxK#).
Au quatrième trimestre mon-entreprise rejoint le
[programme Gamma](https://blog.beta.gouv.fr/dinsic/2020/08/20/acceleration-des-startups-d-etat-d-un-retour-d-experience-a-l-experimentation-d-un-programme-d-accompagnement-cible-1/)
qui accompagne laccélération des services publics crées par beta.gouv. Ce
programme est financé par la [DINUM](https://www.numerique.gouv.fr/dinum/).
T1:
Développement: 73500
Logiciels et hébergement: 456
@ -17,6 +51,14 @@
Logiciels et hébergement: 782
Portage: 9631
2021:
description: |
En 2021 l[Urssaf Caisse Nationale](https://www.urssaf.org/accueil.html) prend en
charge à 100% le financement de mon-entreprise.
Au premier trimestre 2021, léquipe mon-entreprise continue de bénéficier de
laccompagnement du [programme
Gamma](https://beta.gouv.fr/approche/acceleration) financé par la
[DINUM](https://www.numerique.gouv.fr/dinum/).
T1:
Développement: 44850
Logiciels et hébergement: 454
@ -35,6 +77,12 @@
Logiciels et hébergement: 578
Portage: 7983
2022:
description: |
En 2022 le projet devient mieux intégré au sein de
l[Urssaf Caisse Nationale](https://www.urssaf.org/accueil.html).
En complément du financement apporté par lUrssaf, le projet bénéficie du
programme [France Relance](https://france-relance.transformation.gouv.fr/).
T1:
Développement: 72450
Portage: 9643
@ -52,8 +100,10 @@
Déploiement: 22900
Design: 28750
Portage: 10046
2023:
description: |
En 2023, le financement complémentaire apporté par le programme
[France Relance](https://france-relance.transformation.gouv.fr/) prend fin.
T1:
Développement: 47500
Logiciels et hébergement: 7203
@ -76,8 +126,10 @@
Logiciels et hébergement: 686
Portage: 2086
# Envoyé à l'Urssaf: 11723
2024:
description: |
En 2024 mon-entreprise est financée à 100% par
l[Urssaf Caisse Nationale](https://www.urssaf.org/accueil.html).
T1:
Développement: 24091
Logiciels et hébergement: 1069

View File

@ -1,86 +1,109 @@
import { formatValue } from 'publicodes'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { styled } from 'styled-components'
import { TrackPage } from '@/components/ATInternetTracking'
import MoreInfosOnUs from '@/components/MoreInfosOnUs'
import { Markdown } from '@/components/utils/markdown'
import { ScrollToTop } from '@/components/utils/Scroll'
import { Item } from '@/design-system'
import { Item, Message } from '@/design-system'
import { Emoji } from '@/design-system/emoji'
import { Select } from '@/design-system/field/Select'
import { Grid } from '@/design-system/layout'
import { H1, H2 } from '@/design-system/typography/heading'
import { Grid, Spacing } from '@/design-system/layout'
import { Strong } from '@/design-system/typography'
import { H1, H2, H3, H4 } from '@/design-system/typography/heading'
import { Link } from '@/design-system/typography/link'
import { Li, Ul } from '@/design-system/typography/list'
import { Body } from '@/design-system/typography/paragraphs'
import Meta from '../../components/utils/Meta'
import prose from './budget.md?raw'
import budget from './budget.yaml'
// Splitting the markdown file to insert React components in-between is a bit
// arcane, we may consider MDX in the future https://github.com/mdx-js/mdx.
const [
intro,
ressources2019,
ressources2020,
ressources2021,
ressources2022,
ressources2023,
ressources2024,
ressourcesDescription,
] = prose.split(/\r?\n-{3,}\r?\n/)
const ressources = {
2019: ressources2019,
2020: ressources2020,
2021: ressources2021,
2022: ressources2022,
2023: ressources2023,
2024: ressources2024,
} as const
const arraySum = (arr: number[]) => arr.reduce((a, b) => a + b, 0)
import rawBudget from './budget.yaml'
import ResourcesAllocation from './ResourcesAllocation'
export default function Budget() {
const years = ['2019', '2020', '2021', '2022', '2023', '2024'] as const
const quarters = [
{ label: 'T1', 'aria-label': 'Trimestre 1' },
{ label: 'T2', 'aria-label': 'Trimestre 2' },
{ label: 'T3', 'aria-label': 'Trimestre 3' },
{ label: 'T4', 'aria-label': 'Trimestre 4' },
]
const [selectedYear, setSelectedYear] = useState<(typeof years)[number]>(
const budget = rawBudget as Record<
string,
Record<string, string | Record<string, number>>
>
const years = Object.keys(budget)
type yearType = (typeof years)[number]
const budgetDescriptions = years.reduce((budgetDescriptions, year) => {
if (!budget[year].description) {
return budgetDescriptions
}
return {
...budgetDescriptions,
[year]: budget[year].description,
}
}, {}) as Record<yearType, string>
const budgetValues = years.reduce((budgetValues, year) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { description: _, ...budgetQuarters } = budget[year]
if (!Object.keys(budgetQuarters).length) {
return budgetValues
}
return {
...budgetValues,
[year]: budgetQuarters,
}
}, {}) as Record<yearType, Record<string, Record<string, number>>>
const [selectedYear, setSelectedYear] = useState<yearType>(
years[years.length - 1]
)
const categories = [
...new Set(
quarters
.map((q) => Object.keys(budget[selectedYear]?.[q.label] ?? {}))
.reduce((acc, curr) => [...acc, ...curr], [])
),
]
const { t, i18n } = useTranslation()
const { language } = i18n
return (
<>
<TrackPage chapter1="informations" name="budget" />
<Meta
title={t('budget.title', 'Budget')}
description={t('budget.description', 'Le budget de mon-entreprise')}
/>
<Meta title="Budget" description="Le budget de mon-entreprise" />
<ScrollToTop />
<H1>
Budget <Emoji emoji="💶" />
</H1>
<Markdown>{intro}</Markdown>
<Body>
<Strong>Mon-Entreprise</Strong> est un service public numérique, cest
pourquoi nous sommes transparents sur les ressources allouées et la
manière dont elles sont employées.
</Body>
<H2>Principes</H2>
<Body>
Nous suivons le{' '}
<Link
target="_blank"
rel="noreferrer"
aria-label="Consulter le manifeste de beta gouv, nouvelle fenêtre"
href="https://beta.gouv.fr/manifeste"
>
manifeste beta.gouv
</Link>
dont nous rappelons les principes ici :
</Body>
<Message type="info" border={false} icon>
<Ul>
<Li>
Les besoins des utilisateurs sont prioritaires sur les besoins de
ladministration
</Li>
<Li>Le mode de gestion de léquipe repose sur la confiance</Li>
<Li>
Léquipe adopte une approche itérative et damélioration en continu
</Li>
</Ul>
</Message>
<H2>Budget consommé</H2>
<Grid container>
<Grid item xs={8} sm={3} lg={2}>
<Select
label={'Année'}
label="Année"
defaultSelectedKey={selectedYear}
onSelectionChange={(year) => {
setSelectedYear(year as (typeof years)[number])
@ -97,193 +120,109 @@ export default function Budget() {
</Grid>
</Grid>
<Body as="div">
<Markdown>{ressources[selectedYear]}</Markdown>
</Body>
{selectedYear !== '2019' && (
{budgetDescriptions[selectedYear] && (
<Body as="div">
<Markdown>{budgetDescriptions[selectedYear]}</Markdown>
</Body>
)}
{budgetValues[selectedYear] && (
<>
<div
style={{
overflowX: 'auto',
}}
>
<RessourcesAllocationTable role="table">
<caption className="sr-only">
{t(
'budget.tableCaption',
"Tableau affichant le bugdet de l'année {{year}} par poste de dépenses. La première colonne affiche l'année en cours ({{year}}) sur la première ligne puis les postes de dépenses et pour finir le total HT et total TTC. Les autres colonnes affichent les dépenses pour chaque trimestre. La dernière colonne affiche les totaux pour chaque poste de dépenses ainsi que les totaux HT et TTC agrégés.",
{ year: selectedYear }
)}
</caption>
<thead>
<tr>
<th>{selectedYear}</th>
{quarters.map((q) => (
<th scope="col" key={q.label} aria-label={q['aria-label']}>
{q.label}
</th>
))}
<th>Total</th>
</tr>
</thead>
<tbody>
{categories.map((label) => (
<tr key={label}>
<th scope="row">{label}</th>
{quarters.map((q) => {
const value = budget[selectedYear]?.[q.label]?.[label]
<ResourcesAllocation
selectedYear={selectedYear}
budget={budgetValues[selectedYear]}
/>
return (
<td key={q.label}>
{value ? (
formatValue(value, {
displayedUnit: '€',
language,
})
) : (
<span aria-label="Pas de budget alloué">-</span>
)}
</td>
)
})}
<td>
{formatValue(
arraySum(
quarters.map(
(q) => budget[selectedYear]?.[q.label]?.[label] ?? 0
)
),
{
displayedUnit: '€',
language,
}
)}
</td>
</tr>
))}
</tbody>
<tfoot>
<tr>
<th scope="row">Total HT</th>
{quarters.map((q) => {
const value = arraySum(
Object.values(budget[selectedYear]?.[q.label] ?? {})
)
<H3>Description des catégories</H3>
return (
<td key={q.label}>
{value
? formatValue(value, {
displayedUnit: '€',
language,
})
: '-'}
</td>
)
})}
<td>
{formatValue(
arraySum(
quarters.map((q) =>
arraySum(
Object.values(budget[selectedYear]?.[q.label] ?? {})
)
)
),
{
displayedUnit: '€',
language,
}
)}
</td>
</tr>
<tr>
<th scope="row">Total TTC</th>
{quarters.map((q) => {
const value = Math.round(
arraySum(
Object.values(budget[selectedYear]?.[q.label] ?? {})
) * 1.2
)
<Ul>
<Li>
<Strong>
Développement <Emoji emoji="👨‍💻" />
</Strong>
<Body>
Les coûts de développement représentent la grande majorité de
notre budget. Nous sommes une petite équipe de développeurs et
développeuses freelances, pluridisciplinaires aussi bien sur les
aspects techniques, stratégiques et métiers. Les rémunérations
suivent{' '}
<Link
target="_blank"
rel="noreferrer"
aria-label="Consulter la grille de rémunération de beta gouv, nouvelle fenêtre"
href="https://doc.incubateur.net/communaute/travailler-a-beta-gouv/recrutement/remuneration"
>
la grille de beta.gouv
</Link>
.
</Body>
</Li>
<Li>
<Strong>
Logiciels et hébergement <Emoji emoji="💻" />
</Strong>
<Body>
Notre modèle open-source nous permet daccéder gratuitement à la
majorité des outils que nous utilisons (hébergement de code,
serveurs de tests, etc.). Le site est hébergé sur{' '}
<Link
target="_blank"
rel="noreferrer"
aria-label="Site de Netlify, nouvelle fenêtre"
href="https://www.netlify.com"
>
Netlify
</Link>
.
<Spacing md />
Nous achetons de la documentation spécialisée à destination des
professionnels du droit pour faciliter le suivi des évolutions
législatives.
</Body>
</Li>
<Li>
<Strong>
Déplacements <Emoji emoji="🚅" />
</Strong>
<Body>
Le réseau des Urssaf est présent dans toute la France. Nous
organisons plusieurs fois par an des ateliers avec des experts
en région sur des thématiques particulières. Sont aussi inclus
dans cette catégorie la prise en charge des frais de déplacement
des membres de l'équipe qui n'habitent pas en région parisienne.
</Body>
</Li>
<Li>
<Strong>
Portage <Emoji emoji="🤝" />
</Strong>
<Body>
La marge du porteur attributaire du marché public de lUrssaf
Caisse Nationale, ainsi que les coûts liés à la société
spécialement créée pour effectuer le portage des indépendants
qui travaillent sur le site (administration, comptabilité,
facturation, impôts, etc.).
</Body>
</Li>
</Ul>
return (
<td key={q.label}>
{value
? formatValue(value, {
displayedUnit: '€',
language,
})
: '-'}
</td>
)
})}
<td>
{formatValue(
Math.round(
arraySum(
quarters.map(
(q) =>
arraySum(
Object.values(
budget[selectedYear]?.[q.label] ?? {}
)
) * 1.2
)
)
),
{
displayedUnit: '€',
language,
}
)}
</td>
</tr>
</tfoot>
</RessourcesAllocationTable>
</div>
<Markdown>{ressourcesDescription}</Markdown>
<Message type="info" border={false} icon>
<H4>À propos de la TVA</H4>
<Body>
Contrairement aux entreprises du secteur privé, les
administrations ne peuvent pas récupérer la TVA supportée sur
leurs achats dans le cadre de leur activité.
<Spacing md />
Le montant TTC inclut la TVA au taux de 20%.
<Spacing md />
La TVA est collectée et reversée à lÉtat et diminue donc le
montant du budget utilisable sur le projet.
</Body>
</Message>
</>
)}
<MoreInfosOnUs />
</>
)
}
const RessourcesAllocationTable = styled.table`
text-align: left;
width: 100%;
td,
th {
padding: 6px;
font-family: ${({ theme }) => theme.fonts.main};
}
td:not(:first-child),
th:not(:first-child) {
width: 100px;
text-align: right;
}
tbody tr:nth-child(odd),
tfoot tr:nth-child(odd) {
background: ${({ theme }) =>
theme.darkMode
? theme.colors.extended.dark[700]
: theme.colors.bases.primary[100]};
color: inherit;
}
thead,
tfoot {
font-weight: bold;
}
tfoot tr:last-child {
color: ${({ theme }) =>
theme.darkMode
? theme.colors.bases.primary[300]
: theme.colors.bases.primary[700]};
background-color: inherit;
}
`

View File

@ -299,3 +299,5 @@ export const generateUuid = () => {
* @param x
*/
export const isNotNull = <T>(x: T | null): x is T => x !== null
export const arraySum = (arr: number[]) => arr.reduce((a, b) => a + b, 0)