-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TRA-15707] Ajout des informations d'adresses splittées à l'objet Com…
…pany (#3944)
- Loading branch information
1 parent
43975cf
commit fda221a
Showing
19 changed files
with
823 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
back/src/companies/__tests__/companyUtils.integration.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
import { CompanyType } from "@prisma/client"; | ||
import { resetDatabase } from "../../../integration-tests/helper"; | ||
import { userWithCompanyFactory } from "../../__tests__/factories"; | ||
import { getCompanySplittedAddress } from "../companyUtils"; | ||
|
||
describe("getCompanySplittedAddress", () => { | ||
afterEach(async () => { | ||
await resetDatabase(); | ||
}); | ||
|
||
it("should return company's splitted address (FR)", async () => { | ||
// Given | ||
const { company } = await userWithCompanyFactory("ADMIN", { | ||
name: "Acme FR", | ||
address: "4 boulevard Pasteur 44100 Nantes" | ||
}); | ||
|
||
const companySearch = { | ||
orgId: company.orgId, | ||
siret: company.orgId, | ||
etatAdministratif: "A", | ||
addressVoie: "72 rue du Barbâtre", | ||
addressPostalCode: "37100", | ||
addressCity: "Reims", | ||
codePaysEtrangerEtablissement: "" | ||
}; | ||
|
||
// When | ||
const splittedAddress = getCompanySplittedAddress(companySearch, company); | ||
|
||
// Then | ||
expect(splittedAddress?.street).toBe("72 rue du Barbâtre"); | ||
expect(splittedAddress?.postalCode).toBe("37100"); | ||
expect(splittedAddress?.city).toBe("Reims"); | ||
expect(splittedAddress?.country).toBe("FR"); | ||
}); | ||
|
||
it("should return company's splitted address (foreign)", async () => { | ||
// Given | ||
const { company } = await userWithCompanyFactory("ADMIN", { | ||
vatNumber: "BE0894129667", | ||
orgId: "BE0894129667", | ||
name: "Acme BE", | ||
address: "Rue Bois de Goesnes 4 4570 Marchin", | ||
companyTypes: [CompanyType.TRANSPORTER] | ||
}); | ||
|
||
const companySearch = { | ||
orgId: "BE0894129667", | ||
vatNumber: "BE0894129667", | ||
etatAdministratif: "A", | ||
addressVoie: "", | ||
addressPostalCode: "", | ||
addressCity: "", | ||
codePaysEtrangerEtablissement: "BE" | ||
}; | ||
|
||
// When | ||
const splittedAddress = getCompanySplittedAddress(companySearch, company); | ||
|
||
// Then | ||
expect(splittedAddress?.street).toBe("Rue Bois de Goesnes 4"); | ||
expect(splittedAddress?.postalCode).toBe("4570"); | ||
expect(splittedAddress?.city).toBe("Marchin"); | ||
expect(splittedAddress?.country).toBe("BE"); | ||
}); | ||
|
||
it("companySearch is empty > should update with company's address manual split", async () => { | ||
// Given | ||
const { company } = await userWithCompanyFactory("ADMIN", { | ||
name: "Acme FR", | ||
vatNumber: null, | ||
address: "4 boulevard Pasteur 44100 Nantes" | ||
}); | ||
|
||
const companySearch = { | ||
orgId: company.orgId, | ||
siret: company.orgId, | ||
etatAdministratif: "A", | ||
codePaysEtrangerEtablissement: "" | ||
}; | ||
|
||
// When | ||
const splittedAddress = getCompanySplittedAddress(companySearch, company); | ||
|
||
// Then | ||
expect(splittedAddress?.street).toBe("4 boulevard Pasteur"); | ||
expect(splittedAddress?.postalCode).toBe("44100"); | ||
expect(splittedAddress?.city).toBe("Nantes"); | ||
expect(splittedAddress?.country).toBe("FR"); | ||
}); | ||
|
||
it("aberrant address > should return null", async () => { | ||
// Given | ||
const { company } = await userWithCompanyFactory("ADMIN", { | ||
name: "Acme FR", | ||
vatNumber: null, | ||
address: "Adresse test" | ||
}); | ||
|
||
const companySearch = { | ||
orgId: company.orgId, | ||
siret: company.orgId, | ||
etatAdministratif: "A", | ||
codePaysEtrangerEtablissement: "" | ||
}; | ||
|
||
// When | ||
const splittedAddress = getCompanySplittedAddress(companySearch, company); | ||
|
||
// Then | ||
expect(splittedAddress?.street).toBe(null); | ||
expect(splittedAddress?.postalCode).toBe(null); | ||
expect(splittedAddress?.city).toBe(null); | ||
expect(splittedAddress?.country).toBe(null); | ||
}); | ||
|
||
it.each([null, undefined, {}])( | ||
"companySearch is %p > should do manual split", | ||
async companySearch => { | ||
// Given | ||
const { company } = await userWithCompanyFactory("ADMIN", { | ||
name: "Acme FR", | ||
vatNumber: null, | ||
address: "4 boulevard pasteur 44100 Nantes" | ||
}); | ||
|
||
// When | ||
const splittedAddress = getCompanySplittedAddress(companySearch, company); | ||
|
||
// Then | ||
expect(splittedAddress?.street).toBe("4 boulevard pasteur"); | ||
expect(splittedAddress?.postalCode).toBe("44100"); | ||
expect(splittedAddress?.city).toBe("Nantes"); | ||
expect(splittedAddress?.country).toBe("FR"); | ||
} | ||
); | ||
|
||
it("partial addresses with no street > should return postalCode and city (API split)", async () => { | ||
// Given | ||
const { company } = await userWithCompanyFactory("ADMIN", { | ||
name: "Acme FR", | ||
vatNumber: null, | ||
address: "48170 CHAUDEYRAC" | ||
}); | ||
|
||
const companySearch = { | ||
orgId: company.orgId, | ||
siret: company.orgId, | ||
etatAdministratif: "A", | ||
addressVoie: "", | ||
addressPostalCode: "48170", | ||
addressCity: "CHAUDEYRAC", | ||
codePaysEtrangerEtablissement: "" | ||
}; | ||
|
||
// When | ||
const splittedAddress = getCompanySplittedAddress(companySearch, company); | ||
|
||
// Then | ||
expect(splittedAddress?.street).toBe(""); | ||
expect(splittedAddress?.postalCode).toBe("48170"); | ||
expect(splittedAddress?.city).toBe("CHAUDEYRAC"); | ||
expect(splittedAddress?.country).toBe("FR"); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { splitAddress } from "../common/addresses"; | ||
import { Company } from "@prisma/client"; | ||
import { isDefinedStrict } from "../common/helpers"; | ||
import type { CompanySearchResult } from "@td/codegen-back"; | ||
|
||
export type AddressCompanySearchResult = Pick< | ||
CompanySearchResult, | ||
| "addressVoie" | ||
| "addressPostalCode" | ||
| "addressCity" | ||
| "codePaysEtrangerEtablissement" | ||
>; | ||
|
||
interface SplittedAddress { | ||
street: string | null; | ||
postalCode: string | null; | ||
city: string | null; | ||
country: string | null; | ||
} | ||
|
||
export type CompanyToSplit = Pick<Company, "vatNumber" | "address">; | ||
|
||
/** | ||
* Retourne l'adresse splittée d'une entreprise ('street', 'postalCode', 'city', 'country'). | ||
* | ||
* Pour éviter de multiplier les appels aux APIs externes, cette fonction fait pas d'appel | ||
* elle-même et prend en entrée un companySearchResult (partiel). | ||
* | ||
* Si le companySearchResult est valide, retourne les champs splittés. | ||
* | ||
* Si le companySearchResult mais l'adresse complète de l'entreprise est exploitable, retourne | ||
* un split manuel. | ||
* | ||
* Si le split n'a pas fonctionné, retourne tous les champs à null. | ||
* | ||
* Attention: certaines entreprises ont des addresses du genre "codePostal ville", | ||
* auquel cas on retourne "" pour la rue. | ||
*/ | ||
export const getCompanySplittedAddress = ( | ||
companySearchResult: AddressCompanySearchResult | null | undefined, | ||
company?: CompanyToSplit | null | undefined | ||
): SplittedAddress => { | ||
let res; | ||
|
||
// Split manuel... | ||
if ( | ||
// ...si pas de retour des APIs | ||
!companySearchResult || | ||
// ...si entreprise étrangère | ||
isDefinedStrict(companySearchResult.codePaysEtrangerEtablissement) || | ||
// ...si le retour des APIs ne comprend pas d'adresse fiable | ||
!isDefinedStrict(companySearchResult?.addressPostalCode?.trim()) | ||
) { | ||
res = splitAddress(company?.address, company?.vatNumber); | ||
} | ||
// Sinon, split avec les données retournées par les APIs | ||
else { | ||
res = { | ||
street: companySearchResult.addressVoie, | ||
postalCode: companySearchResult.addressPostalCode, | ||
city: companySearchResult.addressCity, | ||
country: "FR" | ||
}; | ||
} | ||
|
||
// Un certain nombre d'entreprises ont des addresses du genre "codePostal ville" | ||
// (donc on tolère l'absence de libellé de voie) | ||
// Mais s'il manque le code postal ou la ville, on considère l'adresse comme invalide. | ||
// On retourne null plutôt qu'une adresse semi-complète. | ||
if ( | ||
!isDefinedStrict(res.postalCode?.trim()) || | ||
!isDefinedStrict(res.city?.trim()) | ||
) { | ||
return { | ||
street: null, | ||
postalCode: null, | ||
city: null, | ||
country: null | ||
}; | ||
} | ||
|
||
return res; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.