Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(banque de france): add banque de france data #1486

Merged
merged 1 commit into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions app/(header-default)/donnees-financieres/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HorizontalSeparator } from '#components-ui/horizontal-separator';
import { DonneesPriveesSection } from '#components/donnees-privees-section';
import { FinancesAssociationSection } from '#components/finances-section/association';
import { FinancesSocieteSection } from '#components/finances-section/societe';
import { FinancesSocieteBilansSection } from '#components/finances-section/societe-bilans';
import { SubventionsAssociationSection } from '#components/subventions-association-section';
import Title from '#components/title-section';
import { FICHE } from '#components/title-section/tabs';
Expand Down Expand Up @@ -39,6 +40,9 @@ const FinancePage = async (props: AppRouterProps) => {
const session = await getSession();
const { slug, isBot } = await extractParamsAppRouter(props);
const uniteLegale = await cachedGetUniteLegale(slug, isBot);
const isMoreThanThreeYearsOld =
new Date(uniteLegale.dateDebutActivite).getFullYear() + 3 <=
new Date().getFullYear();
Comment on lines +43 to +45
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@XavierJp
I've added a 3 years old condition.


return (
<>
Expand All @@ -63,10 +67,18 @@ const FinancePage = async (props: AppRouterProps) => {
<>
{estDiffusible(uniteLegale) ||
hasRights(session, ApplicationRights.nonDiffusible) ? (
<FinancesSocieteSection
uniteLegale={uniteLegale}
session={session}
/>
<>
<FinancesSocieteSection
uniteLegale={uniteLegale}
session={session}
/>
{isMoreThanThreeYearsOld && (
<FinancesSocieteBilansSection
uniteLegale={uniteLegale}
session={session}
/>
)}
</>
) : (
<DonneesPriveesSection title="Indicateurs financiers" />
)}
Expand Down
2 changes: 2 additions & 0 deletions app/api/data-fetching/routes-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getAssociationFromSlug } from '#models/association';
import { getEORIValidation } from '#models/eori-validation';
import { getAssociationProtected } from '#models/espace-agent/association-protected';
import { getBeneficiaires } from '#models/espace-agent/beneficiaires';
import { getBilansProtected } from '#models/espace-agent/bilans';
import { getOpqibi } from '#models/espace-agent/certificats/opqibi';
import { getQualibat } from '#models/espace-agent/certificats/qualibat';
import { getQualifelec } from '#models/espace-agent/certificats/qualifelec';
Expand Down Expand Up @@ -29,6 +30,7 @@ export const APIRoutesHandlers = {
[APIRoutesPaths.EspaceAgentAssociationProtected]: getAssociationProtected,
[APIRoutesPaths.EspaceAgentEffectifsAnnuelsProtected]:
getEffectifsAnnuelsProtected,
[APIRoutesPaths.EspaceAgentBilansProtected]: getBilansProtected,
[APIRoutesPaths.EspaceAgentChiffreAffairesProtected]:
getChiffreAffairesProtected,
[APIRoutesPaths.EspaceAgentTravauxPublics]: withUseCase(getTravauxPublic),
Expand Down
1 change: 1 addition & 0 deletions app/api/data-fetching/routes-paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export enum APIRoutesPaths {
EspaceAgentEffectifsAnnuelsProtected = 'espace-agent/effectifs-annuels-protected',
EspaceAgentChiffreAffairesProtected = 'espace-agent/chiffre-affaires-protected',
EspaceAgentTravauxPublics = 'espace-agent/travaux-publics',
EspaceAgentBilansProtected = 'espace-agent/bilans-protected',
RneDirigeants = 'rne-dirigeants',
Observations = 'observations',
Association = 'association',
Expand Down
7 changes: 4 additions & 3 deletions app/api/data-fetching/routes-scopes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ export const APIRoutesScopes: Record<APIRoutesPaths, ApplicationRights> = {
// BTP
[APIRoutesPaths.EspaceAgentTravauxPublics]: ApplicationRights.travauxPublics,
// fiscal & social
[APIRoutesPaths.EspaceAgentEffectifsAnnuelsProtected]:
ApplicationRights.effectifsAnnuels,
[APIRoutesPaths.EspaceAgentConformite]: ApplicationRights.conformite,
[APIRoutesPaths.EspaceAgentBilansProtected]: ApplicationRights.bilans,
[APIRoutesPaths.EspaceAgentChiffreAffairesProtected]:
ApplicationRights.chiffreAffaires,
[APIRoutesPaths.EspaceAgentConformite]: ApplicationRights.conformite,
[APIRoutesPaths.EspaceAgentEffectifsAnnuelsProtected]:
ApplicationRights.effectifsAnnuels,
};
54 changes: 54 additions & 0 deletions clients/api-entreprise/bilans/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import routes from '#clients/routes';
import { IBilansProtected } from '#models/espace-agent/bilans';
import { Siren } from '#utils/helpers';
import clientAPIEntreprise from '../client';
import { IAPIEntrepriseBanqueDeFranceBilans } from './types';

/**
* GET association from API Entreprise
*/
export async function clientApiEntrepriseBilans(siren: Siren) {
return await clientAPIEntreprise<
IAPIEntrepriseBanqueDeFranceBilans,
IBilansProtected
>(
`${
process.env.API_ENTREPRISE_URL
}${routes.apiEntreprise.banqueDeFrance.bilans(siren)}`,
mapToDomainObject
);
}
const mapToDomainObject = (
response: IAPIEntrepriseBanqueDeFranceBilans
): IBilansProtected => {
return response.data.map((item) => {
return {
annee: item.data.annee,
dateArreteExercice: item.data.date_arrete_exercice,
besoinEnFondsDeRoulement:
item.data.valeurs_calculees[0]?.besoin_en_fonds_de_roulement?.valeur ??
'',
capaciteAutofinancement:
item.data.valeurs_calculees[0]?.capacite_autofinancement?.valeur ?? '',
dettes4MaturiteAUnAnAuPlus:
item.data.valeurs_calculees[0]?.dettes4_maturite_a_un_an_au_plus
?.valeur ?? '',
disponibilites:
item.data.valeurs_calculees[0]?.disponibilites?.valeur ?? '',
excedentBrutExploitation:
item.data.valeurs_calculees[0]?.excedent_brut_exploitation?.valeur ??
'',
fondsRoulementNetGlobal:
item.data.valeurs_calculees[0]?.fonds_roulement_net_global?.valeur ??
'',
ratioFondsRoulementNetGlobalSurBesoinEnFondsDeRoulement:
item.data.valeurs_calculees[0]
?.ratio_fonds_roulement_net_global_sur_besoin_en_fonds_de_roulement
?.valeur ?? '',
totalDettesStables:
item.data.valeurs_calculees[0]?.total_dettes_stables?.valeur ?? '',
valeurAjouteeBdf:
item.data.valeurs_calculees[0]?.valeur_ajoutee_bdf?.valeur ?? '',
};
});
};
47 changes: 47 additions & 0 deletions clients/api-entreprise/bilans/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { IAPIEntrepriseResponse } from '../client';

export type IAPIEntrepriseBanqueDeFranceBilans = IAPIEntrepriseResponse<
{
data: DataItem;
links: Record<string, unknown>;
meta: Record<string, unknown>;
}[]
>;

type ValeursCalculees = {
disponibilites: Valeur;
total_dettes_stables: Valeur;
valeur_ajoutee_bdf: Valeur;
besoin_en_fonds_de_roulement: Valeur;
excedent_brut_exploitation: Valeur;
capacite_autofinancement: Valeur;
fonds_roulement_net_global: Valeur;
ratio_fonds_roulement_net_global_sur_besoin_en_fonds_de_roulement: Valeur;
dettes4_maturite_a_un_an_au_plus: Valeur;
};

type Valeur = {
valeur: string;
evolution: number | null;
};

type Donnees = {
code_nref: string;
valeurs: string[];
evolution: number | null;
code_absolu: string;
intitule: string;
code_EDI: string;
code: string;
code_type_donnee: string;
};

type DataItem = {
annee: string;
date_arrete_exercice: string;
declarations: {
numero_imprime: string;
donnees: Donnees[];
}[];
valeurs_calculees: ValeursCalculees[];
};
6 changes: 3 additions & 3 deletions clients/api-entreprise/chiffres-affaires/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { IChiffreAffairesProtected } from '#models/espace-agent/chiffre-affaires
import { Siret } from '#utils/helpers';
import { getFiscalYear } from '#utils/helpers/formatting/format-fiscal-year';
import clientAPIEntreprise from '../client';
import { IAPIEntrepriseDgfipChiffreAffaires } from './types';
import { IAPIEntrepriseChiffreAffaires } from './types';

/**
* GET CA from API Entreprise
*/
export async function clientApiEntrepriseChiffreAffaires(siret: Siret) {
return await clientAPIEntreprise<
IAPIEntrepriseDgfipChiffreAffaires,
IAPIEntrepriseChiffreAffaires,
IChiffreAffairesProtected
>(
`${
Expand All @@ -21,7 +21,7 @@ export async function clientApiEntrepriseChiffreAffaires(siret: Siret) {
}

const mapToDomainObject = (
response: IAPIEntrepriseDgfipChiffreAffaires
response: IAPIEntrepriseChiffreAffaires
): IChiffreAffairesProtected => {
return response.data
.map(({ data }) => ({
Expand Down
2 changes: 1 addition & 1 deletion clients/api-entreprise/chiffres-affaires/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IAPIEntrepriseResponse } from '../client';

export type IAPIEntrepriseDgfipChiffreAffaires = IAPIEntrepriseResponse<
export type IAPIEntrepriseChiffreAffaires = IAPIEntrepriseResponse<
{
data: FinancialData;
links: Record<string, unknown>;
Expand Down
4 changes: 4 additions & 0 deletions clients/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ const routes = {
chiffreAffaires: (siret: string) =>
`/v3/dgfip/etablissements/${siret}/chiffres_affaires`,
},
banqueDeFrance: {
bilans: (siren: string) =>
`/v3/banque_de_france/unites_legales/${siren}/bilans`,
},
mandatairesRCS: (siren: string) =>
`/v3/infogreffe/rcs/unites_legales/${siren}/mandataires_sociaux`,
effectifs: {
Expand Down
107 changes: 107 additions & 0 deletions components/finances-section/societe-bilans/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
'use client';

import FAQLink from '#components-ui/faq-link';
import { AsyncDataSectionClient } from '#components/section/data-section/client';
import { FullTable } from '#components/table/full';
import { EAdministration } from '#models/administrations/EAdministration';
import { IUniteLegale } from '#models/core/types';
import { ISession } from '#models/user/session';
import { formatCurrency, formatDate, getDateFromYYYYMM } from '#utils/helpers';
import { APIRoutesPaths } from 'app/api/data-fetching/routes-paths';
import { useAPIRouteData } from 'hooks/fetch/use-API-route-data';

export const FinancesSocieteBilansSection: React.FC<{
uniteLegale: IUniteLegale;
session: ISession | null;
}> = ({ uniteLegale, session }) => {
const banqueDeFranceBilansProtected = useAPIRouteData(
APIRoutesPaths.EspaceAgentBilansProtected,
uniteLegale.siren,
session
);

return (
<AsyncDataSectionClient
title="Bilans Banque de France"
id="bilans-banque-de-france"
sources={[EAdministration.BANQUE_DE_FRANCE]}
isProtected
data={banqueDeFranceBilansProtected}
notFoundInfo="Aucun bilan n’a été retrouvé pour cette structure."
>
{(bilans) => {
const body = [
[
'Date de clôture',
...bilans.map((item) =>
formatDate(getDateFromYYYYMM(item.dateArreteExercice || ''))
),
],
[
'Besoin en Fonds de Roulement',
...bilans.map((item) =>
formatCurrency(item.besoinEnFondsDeRoulement)
),
],
[
'Capacité d’Autofinancement',
...bilans.map((item) =>
formatCurrency(item.capaciteAutofinancement)
),
],
[
'Dettes 4 maturité à un an au plus',
...bilans.map((item) =>
formatCurrency(item.dettes4MaturiteAUnAnAuPlus)
),
],
[
'Disponibilités',
...bilans.map((item) => formatCurrency(item.disponibilites)),
],

[
'Excédent Brut d’Exploitation',
...bilans.map((item) =>
formatCurrency(item.excedentBrutExploitation)
),
],
[
'Fonds de Roulement Net Global',
...bilans.map((item) =>
formatCurrency(item.fondsRoulementNetGlobal)
),
],
[
'Ratio Fonds de Roulement Net Global sur Besoin en Fonds de Roulement',
...bilans.map((item) =>
formatCurrency(
item.ratioFondsRoulementNetGlobalSurBesoinEnFondsDeRoulement
)
),
],
[
'Total Dettes Stables',
...bilans.map((item) => formatCurrency(item.totalDettesStables)),
],
[
'Valeur ajoutée BDF',
...bilans.map((item) => formatCurrency(item.valeurAjouteeBdf)),
],
];

return (
<FullTable
head={[
<FAQLink tooltipLabel="Indicateurs" to="/faq/donnees-financieres">
Définition des indicateurs
</FAQLink>,
...bilans.map((item) => item.annee),
]}
body={body}
/>
);
}}
</AsyncDataSectionClient>
);
};
Loading
Loading