refactor: introduit des types du domain pour découpler notre code de celui de l'API Fabrique Social
parent
a4d237a79f
commit
6648bd6f29
|
@ -1,9 +1,49 @@
|
|||
import { Company } from '@/store/reducers/companySituationReducer'
|
||||
import { codeActivité } from '@/domain/CodeActivite'
|
||||
import { codeCatégorieJuridique } from '@/domain/CodeCatégorieJuridique'
|
||||
import { Entreprise } from '@/domain/Entreprise'
|
||||
import { Établissement } from '@/domain/Établissement'
|
||||
import { siren, siret } from '@/domain/Siren'
|
||||
|
||||
export async function searchDenominationOrSiren(value: string) {
|
||||
return searchFullText(value)
|
||||
export async function searchDenominationOrSiren(
|
||||
searchTerm: string
|
||||
): Promise<Array<Entreprise> | null> {
|
||||
return searchFullText(searchTerm).then(
|
||||
(entreprises) => entreprises?.map(fabriqueSocialEntrepriseAdapter) || null
|
||||
)
|
||||
}
|
||||
|
||||
export const fabriqueSocialEntrepriseAdapter = (
|
||||
entreprise: FabriqueSocialEntreprise
|
||||
): Entreprise => {
|
||||
const siège = entreprise && getSiege(entreprise)
|
||||
|
||||
return {
|
||||
nom: entreprise.label,
|
||||
siren: siren(entreprise.siren),
|
||||
dateDeCréation: new Date(entreprise.dateCreationUniteLegale),
|
||||
codeCatégorieJuridique: codeCatégorieJuridique(
|
||||
entreprise.categorieJuridiqueUniteLegale
|
||||
),
|
||||
activitéPrincipale: codeActivité(entreprise.activitePrincipale),
|
||||
siège: siège && établissementAdapter(siège),
|
||||
établissement: établissementAdapter(entreprise.firstMatchingEtablissement),
|
||||
}
|
||||
}
|
||||
|
||||
const établissementAdapter = (
|
||||
fabriqueSocialEtablissement: FabriqueSocialEtablissement
|
||||
): Établissement => ({
|
||||
siret: siret(fabriqueSocialEtablissement.siret),
|
||||
activitéPrincipale: codeActivité(
|
||||
fabriqueSocialEtablissement.activitePrincipaleEtablissement
|
||||
),
|
||||
adresse: {
|
||||
complète: fabriqueSocialEtablissement.address,
|
||||
codePostal: fabriqueSocialEtablissement.codePostalEtablissement,
|
||||
codeCommune: fabriqueSocialEtablissement.codeCommuneEtablissement,
|
||||
},
|
||||
})
|
||||
|
||||
/*
|
||||
* Fields are documented in https://www.sirene.fr/static-resources/doc/Description%20fichier%20StockUniteLegaleHistorique.pdf?version=1.33.1
|
||||
*/
|
||||
|
@ -67,10 +107,10 @@ async function searchFullText(
|
|||
return json.entreprises
|
||||
}
|
||||
|
||||
export function getSiegeOrFirstEtablissement(
|
||||
entreprise: FabriqueSocialEntreprise | Company
|
||||
): FabriqueSocialEtablissement {
|
||||
return (entreprise.allMatchingEtablissements.find(
|
||||
function getSiege(
|
||||
entreprise: FabriqueSocialEntreprise
|
||||
): FabriqueSocialEtablissement | undefined {
|
||||
return entreprise.allMatchingEtablissements.find(
|
||||
(etablissement) => etablissement.etablissementSiege
|
||||
) || entreprise.firstMatchingEtablissement)!
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
import { Fragment, useMemo } from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { styled } from 'styled-components'
|
||||
|
||||
import {
|
||||
FabriqueSocialEntreprise,
|
||||
getSiegeOrFirstEtablissement,
|
||||
} from '@/api/fabrique-social'
|
||||
import { Spacing } from '@/design-system/layout'
|
||||
import { Strong } from '@/design-system/typography'
|
||||
import { H4 } from '@/design-system/typography/heading'
|
||||
import {
|
||||
Entreprise,
|
||||
établissementEstDifférentDuSiège,
|
||||
} from '@/domain/Entreprise'
|
||||
|
||||
export default function CompanySearchDetails({
|
||||
export default function EntrepriseSearchDetails({
|
||||
entreprise,
|
||||
}: {
|
||||
entreprise: FabriqueSocialEntreprise
|
||||
entreprise: Entreprise
|
||||
}) {
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
const { siren, label, dateCreationUniteLegale } = entreprise
|
||||
const { nom, siren, siège, établissement, dateDeCréation } = entreprise
|
||||
|
||||
const DateFormatter = useMemo(
|
||||
() =>
|
||||
|
@ -29,8 +29,6 @@ export default function CompanySearchDetails({
|
|||
[i18n.language]
|
||||
)
|
||||
|
||||
const siegeOrFirstEtablissement = getSiegeOrFirstEtablissement(entreprise)
|
||||
|
||||
return (
|
||||
<CompanyContainer>
|
||||
<H4
|
||||
|
@ -40,49 +38,25 @@ export default function CompanySearchDetails({
|
|||
}}
|
||||
>
|
||||
<>
|
||||
{'highlightLabel' in entreprise
|
||||
? highlightLabelToJSX(entreprise.highlightLabel)
|
||||
: label}{' '}
|
||||
<small>({siren})</small>
|
||||
{nom} <small>({siren})</small>
|
||||
</>
|
||||
</H4>
|
||||
<Spacing sm />
|
||||
<Trans>Crée le :</Trans>{' '}
|
||||
<Strong>{DateFormatter.format(new Date(dateCreationUniteLegale))}</Strong>
|
||||
<Strong>{DateFormatter.format(dateDeCréation)}</Strong>
|
||||
{établissementEstDifférentDuSiège(entreprise) && (
|
||||
<>
|
||||
<br />
|
||||
<Trans>Siège :</Trans> <Strong>{siège?.adresse.complète}</Strong>
|
||||
</>
|
||||
)}
|
||||
<br />
|
||||
<Trans>Domiciliée à l'adresse :</Trans>{' '}
|
||||
<Strong>{siegeOrFirstEtablissement.address}</Strong>
|
||||
<Trans>Établissement recherché:</Trans>{' '}
|
||||
<Strong>{établissement?.adresse.complète}</Strong>
|
||||
</CompanyContainer>
|
||||
)
|
||||
}
|
||||
|
||||
function highlightLabelToJSX(highlightLabel: string) {
|
||||
const highlightRE = /(.*?)<b><u>(.+?)<\/u><\/b>/gm
|
||||
let parsedLength = 0
|
||||
const result = []
|
||||
let matches: RegExpExecArray | null = null
|
||||
while ((matches = highlightRE.exec(highlightLabel)) !== null) {
|
||||
parsedLength += matches[0].length
|
||||
result.push(
|
||||
<Fragment key={matches[2]}>
|
||||
{matches[1]}
|
||||
<Highlight>{matches[2]}</Highlight>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
result.push(highlightLabel.slice(parsedLength))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
const Highlight = styled.strong`
|
||||
background-color: ${({ theme }) =>
|
||||
theme.darkMode
|
||||
? theme.colors.bases.secondary[600]
|
||||
: theme.colors.bases.secondary[100]};
|
||||
color: inherit;
|
||||
`
|
||||
|
||||
const CompanyContainer = styled.div`
|
||||
text-align: left;
|
||||
`
|
||||
|
|
|
@ -3,7 +3,6 @@ import { ReactNode, useEffect, useRef } from 'react'
|
|||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { styled } from 'styled-components'
|
||||
|
||||
import { FabriqueSocialEntreprise } from '@/api/fabrique-social'
|
||||
import { ForceThemeProvider } from '@/components/utils/DarkModeContext'
|
||||
import { Message } from '@/design-system'
|
||||
import { Card } from '@/design-system/card'
|
||||
|
@ -15,10 +14,11 @@ import { Strong } from '@/design-system/typography'
|
|||
import { StyledLink } from '@/design-system/typography/link'
|
||||
import { Li, Ul } from '@/design-system/typography/list'
|
||||
import { Body } from '@/design-system/typography/paragraphs'
|
||||
import { Entreprise } from '@/domain/Entreprise'
|
||||
import useSearchCompany from '@/hooks/useSearchCompany'
|
||||
|
||||
import { Appear, FromTop } from '../ui/animate'
|
||||
import CompanySearchDetails from './SearchDetails'
|
||||
import EntrepriseSearchDetails from './SearchDetails'
|
||||
|
||||
const StyledCard = styled(Card)`
|
||||
flex-direction: row; // for Safari <= 13
|
||||
|
@ -28,14 +28,14 @@ const StyledCard = styled(Card)`
|
|||
}
|
||||
`
|
||||
|
||||
export function CompanySearchField(props: {
|
||||
export function EntrepriseSearchField(props: {
|
||||
label?: ReactNode
|
||||
onValue?: () => void
|
||||
onClear?: () => void
|
||||
onSubmit?: (search: FabriqueSocialEntreprise | null) => void
|
||||
onSubmit?: (search: Entreprise | null) => void
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const refResults = useRef<FabriqueSocialEntreprise[] | null>(null)
|
||||
const refResults = useRef<Entreprise[] | null>(null)
|
||||
|
||||
const searchFieldProps = {
|
||||
...props,
|
||||
|
@ -102,8 +102,8 @@ function Results({
|
|||
results,
|
||||
onSubmit,
|
||||
}: {
|
||||
results: Array<FabriqueSocialEntreprise>
|
||||
onSubmit?: (établissement: FabriqueSocialEntreprise) => void
|
||||
results: Array<Entreprise>
|
||||
onSubmit?: (entreprise: Entreprise) => void
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
|
@ -152,14 +152,14 @@ function Results({
|
|||
<FromTop>
|
||||
<ForceThemeProvider>
|
||||
<Ul noMarker data-test-id="company-search-results">
|
||||
{results.map((etablissement) => (
|
||||
<Li key={etablissement.siren}>
|
||||
{results.map((entreprise) => (
|
||||
<Li key={entreprise.siren}>
|
||||
<StyledCard
|
||||
onPress={() => onSubmit?.(etablissement)}
|
||||
onClick={() => onSubmit?.(etablissement)}
|
||||
onPress={() => onSubmit?.(entreprise)}
|
||||
onClick={() => onSubmit?.(entreprise)}
|
||||
compact
|
||||
bodyAs="div"
|
||||
aria-label={`${etablissement.label}, Selectionner cette entreprise`}
|
||||
aria-label={`${entreprise.nom}, Selectionner cette entreprise`}
|
||||
ctaLabel={
|
||||
<ChevronIcon
|
||||
style={{
|
||||
|
@ -170,7 +170,7 @@ function Results({
|
|||
/>
|
||||
}
|
||||
>
|
||||
<CompanySearchDetails entreprise={etablissement} />
|
||||
<EntrepriseSearchDetails entreprise={entreprise} />
|
||||
</StyledCard>
|
||||
</Li>
|
||||
))}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
export interface Adresse {
|
||||
complète?: string
|
||||
codePostal: string
|
||||
codeCommune: string
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export type Brand<T, U extends string> = T & { __tag: U }
|
|
@ -0,0 +1,6 @@
|
|||
import { Brand } from '@/domain/Brand'
|
||||
|
||||
export type CodeActivite = Brand<string, 'CodeActivite'>
|
||||
// Pourrait être inféré des données de fetchBénéfice
|
||||
|
||||
export const codeActivité = (code: string) => code as CodeActivite
|
|
@ -0,0 +1,6 @@
|
|||
import { Brand } from '@/domain/Brand'
|
||||
|
||||
export type CodeCatégorieJuridique = Brand<string, 'CodeCatégorieJuridique'>
|
||||
|
||||
export const codeCatégorieJuridique = (code: string) =>
|
||||
code as CodeCatégorieJuridique
|
|
@ -0,0 +1,17 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { formatDate, parsePublicodesDateString } from '@/domain/Date'
|
||||
|
||||
describe('parsePublicodesDateString', () => {
|
||||
it('comprend 24-12-2024 comme le 24 décembre 2024', () => {
|
||||
expect(parsePublicodesDateString('24/12/2024')).toEqual(
|
||||
new Date(2024, 11, 24)
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatDate', () => {
|
||||
it("écrit le 15 août 1980 comme '15/08/1980' (format Publicodes)", () => {
|
||||
expect(formatDate(new Date('1980-08-15'))).toEqual('15/08/1980')
|
||||
})
|
||||
})
|
|
@ -0,0 +1,10 @@
|
|||
import { format, parse } from 'date-fns/fp'
|
||||
|
||||
export const publicodesStandardDateFormat = 'dd/MM/yyyy'
|
||||
|
||||
export const formatDate = format(publicodesStandardDateFormat)
|
||||
|
||||
export const parsePublicodesDateString = parse(
|
||||
new Date(),
|
||||
publicodesStandardDateFormat
|
||||
)
|
|
@ -0,0 +1,24 @@
|
|||
import { CodeActivite } from '@/domain/CodeActivite'
|
||||
import { CodeCatégorieJuridique } from '@/domain/CodeCatégorieJuridique'
|
||||
import { Établissement } from '@/domain/Établissement'
|
||||
import { Siren } from '@/domain/Siren'
|
||||
|
||||
export interface Entreprise {
|
||||
nom: string
|
||||
siren: Siren
|
||||
dateDeCréation: Date
|
||||
codeCatégorieJuridique: CodeCatégorieJuridique
|
||||
activitéPrincipale: CodeActivite
|
||||
siège?: Établissement
|
||||
établissement: Établissement
|
||||
}
|
||||
|
||||
export const établissementEstLeSiège = (entreprise: Entreprise): boolean =>
|
||||
!!entreprise.siège &&
|
||||
!!entreprise.siège.adresse.complète &&
|
||||
entreprise.siège.adresse.complète ===
|
||||
entreprise.établissement.adresse.complète
|
||||
|
||||
export const établissementEstDifférentDuSiège = (
|
||||
entreprise: Entreprise
|
||||
): boolean => !établissementEstLeSiège(entreprise)
|
|
@ -0,0 +1,7 @@
|
|||
import { Brand } from '@/domain/Brand'
|
||||
|
||||
export type Siren = Brand<string, 'Siren'>
|
||||
export const siren = (value: string): Siren => value as Siren
|
||||
|
||||
export type Siret = Brand<string, 'Siret'>
|
||||
export const siret = (value: string): Siret => value as Siret
|
|
@ -0,0 +1,9 @@
|
|||
import { Adresse } from '@/domain/Adresse'
|
||||
import { CodeActivite } from '@/domain/CodeActivite'
|
||||
import { Siret } from '@/domain/Siren'
|
||||
|
||||
export interface Établissement {
|
||||
siret: Siret
|
||||
adresse: Adresse
|
||||
activitéPrincipale: CodeActivite
|
||||
}
|
|
@ -1,22 +1,19 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
|
||||
import {
|
||||
FabriqueSocialEntreprise,
|
||||
searchDenominationOrSiren,
|
||||
} from '@/api/fabrique-social'
|
||||
import { searchDenominationOrSiren } from '@/api/fabrique-social'
|
||||
import { Entreprise } from '@/domain/Entreprise'
|
||||
|
||||
import { useDebounce } from './useDebounce'
|
||||
|
||||
export default function useSearchCompany(
|
||||
value: string
|
||||
): [boolean, Array<FabriqueSocialEntreprise>] {
|
||||
const [result, setResult] = useState<Array<FabriqueSocialEntreprise>>([])
|
||||
): [boolean, Array<Entreprise>] {
|
||||
const [result, setResult] = useState<Array<Entreprise>>([])
|
||||
const [searchPending, setSearchPending] = useState(Boolean(value))
|
||||
const debouncedValue = useDebounce(value, 300)
|
||||
|
||||
useEffect(() => {
|
||||
setSearchPending(Boolean(value))
|
||||
|
||||
if (!value) {
|
||||
setResult([])
|
||||
}
|
||||
|
@ -28,7 +25,7 @@ export default function useSearchCompany(
|
|||
}
|
||||
|
||||
searchDenominationOrSiren(debouncedValue)
|
||||
.then((entreprise: Array<FabriqueSocialEntreprise> | null) => {
|
||||
.then((entreprise: Array<Entreprise> | null) => {
|
||||
setResult(entreprise || [])
|
||||
setSearchPending(false)
|
||||
})
|
||||
|
|
|
@ -2,10 +2,7 @@ import { useDispatch } from 'react-redux'
|
|||
|
||||
import fetchBénéfice from '@/api/activité-vers-bénéfice'
|
||||
import { fetchCommuneDetails } from '@/api/commune'
|
||||
import {
|
||||
FabriqueSocialEntreprise,
|
||||
getSiegeOrFirstEtablissement,
|
||||
} from '@/api/fabrique-social'
|
||||
import { Entreprise } from '@/domain/Entreprise'
|
||||
import {
|
||||
addCommuneDetails,
|
||||
setBénéficeType,
|
||||
|
@ -15,24 +12,20 @@ import {
|
|||
export function useSetEntreprise() {
|
||||
const dispatch = useDispatch()
|
||||
|
||||
return (entreprise: FabriqueSocialEntreprise | null) => {
|
||||
if (entreprise === null) {
|
||||
return (entreprise: Entreprise | null) => {
|
||||
if (entreprise === null || !entreprise.établissement.adresse) {
|
||||
return
|
||||
}
|
||||
|
||||
dispatch(setCompany(entreprise))
|
||||
|
||||
const siegeOrFirstEtablissement = getSiegeOrFirstEtablissement(entreprise)
|
||||
|
||||
void fetchCommuneDetails(
|
||||
siegeOrFirstEtablissement.codeCommuneEtablissement
|
||||
).then(
|
||||
void fetchCommuneDetails(entreprise.établissement.adresse.codeCommune).then(
|
||||
(communeDetails) =>
|
||||
communeDetails && dispatch(addCommuneDetails(communeDetails))
|
||||
)
|
||||
|
||||
void fetchBénéfice(
|
||||
siegeOrFirstEtablissement.activitePrincipaleEtablissement
|
||||
).then((bénéfice) => bénéfice && dispatch(setBénéficeType(bénéfice)))
|
||||
void fetchBénéfice(entreprise.établissement.activitéPrincipale).then(
|
||||
(bénéfice) => bénéfice && dispatch(setBénéficeType(bénéfice))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,9 @@ import { Trans, useTranslation } from 'react-i18next'
|
|||
import { useDispatch } from 'react-redux'
|
||||
import { generatePath, useNavigate } from 'react-router-dom'
|
||||
|
||||
import {
|
||||
FabriqueSocialEntreprise,
|
||||
searchDenominationOrSiren,
|
||||
} from '@/api/fabrique-social'
|
||||
import { searchDenominationOrSiren } from '@/api/fabrique-social'
|
||||
import { CompanyDetails } from '@/components/company/Details'
|
||||
import { CompanySearchField } from '@/components/company/SearchField'
|
||||
import { EntrepriseSearchField } from '@/components/company/SearchField'
|
||||
import { useEngine } from '@/components/utils/EngineContext'
|
||||
import AnswerGroup from '@/design-system/answer-group'
|
||||
import { Button } from '@/design-system/buttons'
|
||||
|
@ -16,6 +13,7 @@ import { Grid, Spacing } from '@/design-system/layout'
|
|||
import PopoverConfirm from '@/design-system/popover/PopoverConfirm'
|
||||
import { H3 } from '@/design-system/typography/heading'
|
||||
import { Body } from '@/design-system/typography/paragraphs'
|
||||
import { Entreprise } from '@/domain/Entreprise'
|
||||
import { useSetEntreprise } from '@/hooks/useSetEntreprise'
|
||||
import { useSitePaths } from '@/sitePaths'
|
||||
import { getCookieValue } from '@/storage/readCookie'
|
||||
|
@ -85,7 +83,7 @@ export default function SearchOrCreate() {
|
|||
activité
|
||||
</Body>
|
||||
</Trans>
|
||||
<CompanySearchField onSubmit={handleCompanySubmit} />
|
||||
<EntrepriseSearchField onSubmit={handleCompanySubmit} />
|
||||
<Spacing md />
|
||||
</>
|
||||
)}
|
||||
|
@ -100,7 +98,7 @@ function useHandleCompanySubmit() {
|
|||
const setEntreprise = useSetEntreprise()
|
||||
|
||||
const handleCompanySubmit = useCallback(
|
||||
(établissement: FabriqueSocialEntreprise | null) => {
|
||||
(établissement: Entreprise | null) => {
|
||||
if (!établissement) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -14,10 +14,7 @@ import {
|
|||
} from 'react-router-dom'
|
||||
import { styled } from 'styled-components'
|
||||
|
||||
import {
|
||||
FabriqueSocialEntreprise,
|
||||
searchDenominationOrSiren,
|
||||
} from '@/api/fabrique-social'
|
||||
import { searchDenominationOrSiren } from '@/api/fabrique-social'
|
||||
import { TrackPage } from '@/components/ATInternetTracking'
|
||||
import { CompanyDetails } from '@/components/company/Details'
|
||||
import RuleInput from '@/components/conversation/RuleInput'
|
||||
|
@ -36,6 +33,7 @@ import { Container, Grid, Spacing } from '@/design-system/layout'
|
|||
import { Strong } from '@/design-system/typography'
|
||||
import { H2, H3 } from '@/design-system/typography/heading'
|
||||
import { Body, Intro } from '@/design-system/typography/paragraphs'
|
||||
import { Entreprise } from '@/domain/Entreprise'
|
||||
import { useQuestionList } from '@/hooks/useQuestionList'
|
||||
import { useSetEntreprise } from '@/hooks/useSetEntreprise'
|
||||
import useSimulationConfig from '@/hooks/useSimulationConfig'
|
||||
|
@ -399,9 +397,7 @@ const usePourMonEntreprisePath = () => {
|
|||
|
||||
const useSirenFromParams = (overwrite: boolean) => {
|
||||
const { entreprise: param } = useParams<{ entreprise?: string }>()
|
||||
const [entreprise, setEntreprise] = useState<FabriqueSocialEntreprise | null>(
|
||||
null
|
||||
)
|
||||
const [entreprise, setEntreprise] = useState<Entreprise | null>(null)
|
||||
|
||||
const [entreprisePending, setEntreprisePending] = useState(false)
|
||||
const [entrepriseNotFound, setEntrepriseNotFound] = useState(false)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Bénéfice } from '@/api/activité-vers-bénéfice'
|
||||
import { Commune } from '@/api/commune'
|
||||
import { FabriqueSocialEntreprise } from '@/api/fabrique-social'
|
||||
import { Entreprise } from '@/domain/Entreprise'
|
||||
|
||||
export type CompanyActions = ReturnType<
|
||||
| typeof resetCompany
|
||||
|
@ -26,7 +26,7 @@ export const setBénéficeType = (bénéfice: NonNullable<Bénéfice>) =>
|
|||
bénéfice,
|
||||
}) as const
|
||||
|
||||
export const setCompany = (entreprise: FabriqueSocialEntreprise) => {
|
||||
export const setCompany = (entreprise: Entreprise) => {
|
||||
return {
|
||||
type: 'COMPANY::SET_EXISTING_COMPANY',
|
||||
entreprise,
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { DottedName } from 'modele-social'
|
||||
|
||||
import {
|
||||
FabriqueSocialEntreprise,
|
||||
getSiegeOrFirstEtablissement,
|
||||
} from '@/api/fabrique-social'
|
||||
import { CodeCatégorieJuridique } from '@/domain/CodeCatégorieJuridique'
|
||||
import { formatDate } from '@/domain/Date'
|
||||
import { Entreprise } from '@/domain/Entreprise'
|
||||
import { Action } from '@/store/actions/actions'
|
||||
import { buildSituationFromObject, omit } from '@/utils'
|
||||
|
||||
|
@ -38,8 +37,6 @@ export function isCompanyDottedName(dottedName: DottedName) {
|
|||
return SAVED_NAMESPACES.some((namespace) => dottedName.startsWith(namespace))
|
||||
}
|
||||
|
||||
export type Company = Omit<FabriqueSocialEntreprise, 'highlightLabel'>
|
||||
|
||||
export function companySituation(state: Situation = {}, action: Action) {
|
||||
switch (action.type) {
|
||||
case 'UPDATE_SITUATION':
|
||||
|
@ -86,27 +83,24 @@ export function companySituation(state: Situation = {}, action: Action) {
|
|||
return state
|
||||
}
|
||||
|
||||
export function getCompanySituation(company: Company): Situation {
|
||||
const siegeOrFirstEtablissement = getSiegeOrFirstEtablissement(company)
|
||||
|
||||
export function getCompanySituation(entreprise: Entreprise): Situation {
|
||||
return {
|
||||
'entreprise . date de création': company.dateCreationUniteLegale.replace(
|
||||
/(.*)-(.*)-(.*)/,
|
||||
'$3/$2/$1'
|
||||
),
|
||||
'entreprise . date de création': formatDate(entreprise.dateDeCréation),
|
||||
'entreprise . catégorie juridique': `'${getCatégorieFromCode(
|
||||
company.categorieJuridiqueUniteLegale
|
||||
entreprise.codeCatégorieJuridique
|
||||
)}'`,
|
||||
'entreprise . SIREN': `'${company.siren}'`,
|
||||
'entreprise . nom': `'${company.label}'`,
|
||||
'établissement . SIRET': `'${siegeOrFirstEtablissement.siret}'`,
|
||||
'entreprise . activité': `'${company.activitePrincipale}'`,
|
||||
'entreprise . SIREN': `'${entreprise.siren}'`,
|
||||
'entreprise . nom': `'${entreprise.nom}'`,
|
||||
'établissement . SIRET': `'${entreprise.établissement.siret}'`,
|
||||
'entreprise . activité': `'${entreprise.activitéPrincipale}'`,
|
||||
}
|
||||
}
|
||||
|
||||
type CatégorieJuridique = 'EI' | 'SARL' | 'SAS' | 'SELARL' | 'SELAS' | 'autre'
|
||||
|
||||
const getCatégorieFromCode = (code: string): CatégorieJuridique => {
|
||||
const getCatégorieFromCode = (
|
||||
code: CodeCatégorieJuridique
|
||||
): CatégorieJuridique => {
|
||||
/*
|
||||
Nous utilisons le code entreprise pour connaitre le statut juridique
|
||||
(voir https://www.insee.fr/fr/information/2028129)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { getSiegeOrFirstEtablissement } from '@/api/fabrique-social'
|
||||
import { fabriqueSocialEntrepriseAdapter } from '@/api/fabrique-social'
|
||||
|
||||
import {
|
||||
fabriqueSocialWithoutSiege,
|
||||
|
@ -8,14 +8,40 @@ import {
|
|||
} from './fabrique-social.fixtures'
|
||||
|
||||
describe('Fabrique Social', () => {
|
||||
describe('getSiegeOrFirstEtablissement Function', () => {
|
||||
it('should return siege', () => {
|
||||
const siege = getSiegeOrFirstEtablissement(fabriqueSocialWithSiege)
|
||||
expect(siege.address).toBe('23 RUE DE MOGADOR 75009 PARIS 9')
|
||||
describe('fabriqueSocialEntrepriseAdapter', () => {
|
||||
describe('Si l’entreprise est retournée avec un siège différent de la recherche', () => {
|
||||
const entreprise = fabriqueSocialEntrepriseAdapter(
|
||||
fabriqueSocialWithSiege
|
||||
)
|
||||
|
||||
it('retourne le siren', () => {
|
||||
expect(entreprise.siren).to.equal('849074190')
|
||||
})
|
||||
|
||||
it("a l'établissement demandé dans 'établissement'", () => {
|
||||
expect(entreprise.siège?.adresse.complète).to.equal(
|
||||
'23 RUE DE MOGADOR 75009 PARIS 9'
|
||||
)
|
||||
})
|
||||
it("a le siège dans 'siège'", () => {
|
||||
expect(entreprise.établissement.adresse.complète).to.equal(
|
||||
'4 RUE VOLTAIRE 44000 NANTES'
|
||||
)
|
||||
})
|
||||
})
|
||||
it('should return FirstEtablissement', () => {
|
||||
const siege = getSiegeOrFirstEtablissement(fabriqueSocialWithoutSiege)
|
||||
expect(siege.address).toBe('4 RUE VOLTAIRE 44000 NANTES')
|
||||
describe("Si l'entreprise est retournée sans siège", () => {
|
||||
const entreprise = fabriqueSocialEntrepriseAdapter(
|
||||
fabriqueSocialWithoutSiege
|
||||
)
|
||||
|
||||
it("n'a pas de siège", () => {
|
||||
expect(entreprise.siège?.adresse.complète).to.equal(undefined)
|
||||
})
|
||||
it('a l’établissement demandé', () => {
|
||||
expect(entreprise.établissement.adresse.complète).to.equal(
|
||||
'4 RUE VOLTAIRE 44000 NANTES'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue