Skip to content

Commit

Permalink
Merge branch 'master' into fufeck_feat_add-commune-deleguee-to-numero
Browse files Browse the repository at this point in the history
  • Loading branch information
fufeck committed Jan 27, 2025
2 parents 19d5362 + f502087 commit ffdcdda
Show file tree
Hide file tree
Showing 17 changed files with 158 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Procfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
clock: yarn start:cron
postdeploy: yarn typeorm:migration:run
postdeploy: bash scripts/postdeploy.sh
12 changes: 9 additions & 3 deletions apps/api/src/lib/utils/csv.utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { validate } from '@ban-team/validateur-bal';
import { normalize } from '@ban-team/adresses-util/lib/voies';
import { chain, compact, keyBy, min, max } from 'lodash';
import { v4 as uuid } from 'uuid';

import { beautifyUppercased, beautifyNomAlt } from './string.utils';

Expand All @@ -17,6 +18,7 @@ export type FromCsvType = {
validationError?: string;
accepted?: number;
rejected?: number;
communeNomsAlt?: Record<string, string>;
voies?: Partial<Voie>[];
numeros?: Partial<Numero>[];
toponymes?: Partial<Toponyme>[];
Expand Down Expand Up @@ -56,7 +58,7 @@ export function extractCodeCommune({
function extractPosition(row: any) {
return {
source: row.parsedValues.source || null,
type: row.parsedValues.position || PositionTypeEnum.INCONNUE,
type: row.parsedValues.position || PositionTypeEnum.ENTREE,
point: {
type: 'Point',
coordinates: [row.parsedValues.long, row.parsedValues.lat],
Expand Down Expand Up @@ -109,7 +111,6 @@ function extractData(rows: Row[]): {
.groupBy((r) => normalize(r.parsedValues.voie_nom))
.map((voieRows) => {
const dates = compact(voieRows.map((r) => r.parsedValues.date_der_maj));

return {
id: new ObjectId().toHexString(),
banId: extractIdBanToponyme(voieRows[0]),
Expand Down Expand Up @@ -147,7 +148,7 @@ function extractData(rows: Row[]): {
if (toponymeString && !(toponymeString in toponymesIndex)) {
const toponyme: Partial<Toponyme> = {
id: new ObjectId().toHexString(),
banId: extractIdBanToponyme(numeroRows[0]),
banId: uuid(),
nom: beautifyUppercased(
numeroRows[0].parsedValues.lieudit_complement_nom,
),
Expand Down Expand Up @@ -208,10 +209,15 @@ export async function extractFromCsv(
accepted.filter((r) => extractCodeCommune(r) === codeCommune),
);

const communeNomsAlt =
rows.find((row) => row.localizedValues?.commune_nom)?.localizedValues
?.commune_nom || null;

return {
isValid: true,
accepted: accepted.length,
rejected: rejected.length,
communeNomsAlt,
voies: communesData.voies,
numeros: communesData.numeros,
toponymes: communesData.toponymes,
Expand Down
15 changes: 13 additions & 2 deletions apps/api/src/modules/base_locale/base_locale.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ export class BaseLocaleService {
voies,
numeros,
toponymes,
communeNomsAlt,
isValid,
accepted,
rejected,
Expand All @@ -222,7 +223,12 @@ export class BaseLocaleService {
);
}
// On populate la Bal avec les infos du fichier
await this.populate(baseLocale, { voies, numeros, toponymes });
await this.populate(baseLocale, {
voies,
numeros,
toponymes,
communeNomsAlt,
});
// On met a jour le updatedAt de la Bal
await this.touch(baseLocale.id);

Expand Down Expand Up @@ -389,8 +395,13 @@ export class BaseLocaleService {

async populate(
baseLocale: BaseLocale,
{ voies, toponymes, numeros }: FromCsvType,
{ voies, toponymes, numeros, communeNomsAlt }: FromCsvType,
): Promise<BaseLocale> {
if (communeNomsAlt) {
this.basesLocalesRepository.update(baseLocale.id, {
communeNomsAlt,
});
}
// On supprime les numeros, vois et toponymes si il y en a
await this.numeroService.deleteMany({ balId: baseLocale.id });
await this.voieService.deleteMany({ balId: baseLocale.id });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { ValidatorBal } from '@/shared/validators/validator_bal.validator';
import { ApiProperty } from '@nestjs/swagger';
import {
ArrayMaxSize,
ArrayNotEmpty,
IsEmail,
IsNotEmpty,
IsNotEmptyObject,
IsOptional,
Validate,
} from 'class-validator';

export class UpdateBaseLocaleDTO {
Expand All @@ -13,6 +16,12 @@ export class UpdateBaseLocaleDTO {
@IsNotEmpty()
nom?: string;

@IsOptional()
@IsNotEmptyObject()
@Validate(ValidatorBal, ['langAlt'])
@ApiProperty({ required: false, nullable: true })
communeNomsAlt: Record<string, string>;

@IsOptional()
@ApiProperty({ required: false, nullable: false })
@ArrayNotEmpty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {

import { PositionTypeEnum } from '@/shared/entities/position.entity';
import { ValidatorCogCommune } from '@/shared/validators/cog.validator';
import { ValidatorBal } from '@/shared/validators/validator_bal.validator';

export class UpdateBatchNumeroChangeDTO {
@IsOptional()
Expand All @@ -33,6 +34,7 @@ export class UpdateBatchNumeroChangeDTO {
@IsOptional()
@IsNotEmpty()
@IsEnum(PositionTypeEnum)
@Validate(ValidatorBal, ['position'])
@ApiProperty({ required: false, nullable: false })
positionType?: PositionTypeEnum;

Expand Down
7 changes: 4 additions & 3 deletions apps/api/test/base_locale.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const baseLocalePublicProperties = [
'id',
'banId',
'nom',
'communeNomsAlt',
'commune',
'nbNumeros',
'nbNumerosCertifies',
Expand Down Expand Up @@ -186,7 +187,7 @@ describe('BASE LOCAL MODULE', () => {
};
return {
id,
type: PositionTypeEnum.INCONNUE,
type: PositionTypeEnum.ENTREE,
source: 'ban',
point,
} as Position;
Expand Down Expand Up @@ -587,8 +588,8 @@ describe('BASE LOCAL MODULE', () => {
'text/csv; charset=utf-8',
);
const csvFile = `cle_interop;id_ban_commune;id_ban_toponyme;id_ban_adresse;voie_nom;lieudit_complement_nom;numero;suffixe;certification_commune;commune_insee;commune_nom;commune_deleguee_insee;commune_deleguee_nom;position;long;lat;x;y;cad_parcelles;source;date_der_maj
08053_xxxx_00001_bis;${communeUuid};${voieUuid1};${numeroUuid1};rue de la paix;allée;1;bis;1;08053;Bazeilles;08053;Bazeilles;inconnue;8;42;1114835.92;6113076.85;;ban;2000-01-02
08053_xxxx_00001_ter;${communeUuid};${voieUuid2};${numeroUuid2};rue de paris;allée;1;ter;0;08053;Bazeilles;08294;La Moncelle;inconnue;8;42;1114835.92;6113076.85;;ban;2000-01-02
08053_xxxx_00001_bis;${communeUuid};${voieUuid1};${numeroUuid1};rue de la paix;allée;1;bis;1;08053;Bazeilles;08053;Bazeilles;entrée;8;42;1114835.92;6113076.85;;ban;2000-01-02
08053_xxxx_00001_ter;${communeUuid};${voieUuid2};${numeroUuid2};rue de paris;allée;1;ter;0;08053;Bazeilles;08294;La Moncelle;entrée;8;42;1114835.92;6113076.85;;ban;2000-01-02
08053_xxxx_99999;${communeUuid};${toponymeUuid1};;allée;;99999;;;08053;Bazeilles;08294;La Moncelle;;;;;;;commune;2000-01-02`;
expect(response.text.replace(/\s/g, '')).toEqual(
csvFile.replace(/\s/g, ''),
Expand Down
2 changes: 1 addition & 1 deletion apps/api/test/numero.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ describe('NUMERO', () => {
positions: [
{
id: new ObjectId().toHexString(),
type: PositionTypeEnum.INCONNUE,
type: PositionTypeEnum.ENTREE,
source: 'ban',
point: {
type: 'Point',
Expand Down
9 changes: 4 additions & 5 deletions apps/api/test/publication.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ describe('PUBLICATION MODULE', () => {
};
return {
id,
type: PositionTypeEnum.INCONNUE,
type: PositionTypeEnum.ENTREE,
source: 'ban',
point,
} as Position;
Expand Down Expand Up @@ -226,7 +226,7 @@ describe('PUBLICATION MODULE', () => {
axiosMock.onPost(`/revisions/${revisionId}/compute`).reply(200, revision);

const csvFile = `cle_interop;id_ban_commune;id_ban_toponyme;id_ban_adresse;voie_nom;lieudit_complement_nom;numero;suffixe;certification_commune;commune_insee;commune_nom;commune_deleguee_insee;commune_deleguee_nom;position;long;lat;x;y;cad_parcelles;source;date_der_maj
08053_xxxx_00001_bis;${communeUuid};${voieUuid};${numeroUuid};rue de la paix;;1;bis;1;08053;Bazeilles;08294;La Moncelle;inconnue;8;42;1114835.92;6113076.85;;ban;2000-01-01`;
08053_xxxx_00001_bis;${communeUuid};${voieUuid};${numeroUuid};rue de la paix;;1;bis;1;08053;Bazeilles;08294;La Moncelle;entrée;8;42;1114835.92;6113076.85;;ban;2000-01-01`;
axiosMock
.onPut(`/revisions/${revisionId}/files/bal`)
.reply(({ data }) => {
Expand Down Expand Up @@ -347,7 +347,7 @@ describe('PUBLICATION MODULE', () => {
axiosMock.onPost(`/revisions/${revisionId}/compute`).reply(200, revision);

const csvFile = `cle_interop;id_ban_commune;id_ban_toponyme;id_ban_adresse;voie_nom;lieudit_complement_nom;numero;suffixe;certification_commune;commune_insee;commune_nom;commune_deleguee_insee;commune_deleguee_nom;position;long;lat;x;y;cad_parcelles;source;date_der_maj
91534_xxxx_00001_bis;${communeUuid};${toponymeUuid};${numeroUuid};rue de la paix;;1;bis;1;91534;Saclay;;;inconnue;8;42;1114835.92;6113076.85;;ban;2000-01-01`;
91534_xxxx_00001_bis;${communeUuid};${toponymeUuid};${numeroUuid};rue de la paix;;1;bis;1;91534;Saclay;;;entrée;8;42;1114835.92;6113076.85;;ban;2000-01-01`;
axiosMock
.onPut(`/revisions/${revisionId}/files/bal`)
.reply(({ data }) => {
Expand Down Expand Up @@ -410,7 +410,7 @@ describe('PUBLICATION MODULE', () => {
files: [
{
type: 'bal',
hash: 'a512238a358a47446e4eb6b89dbfbecc03b81fcb2492eed54e277699d1c49c62',
hash: '37925d84890a965635aa5f119efade4fb2dc02331039a80c57497a9bb21ea82b',
},
],
};
Expand Down Expand Up @@ -456,7 +456,6 @@ describe('PUBLICATION MODULE', () => {
axiosMock
.onGet(`habilitations/${habilitationId}`)
.reply(200, habilitation);

// SEND REQUEST
const response = await request(app.getHttpServer())
.post(`/bases-locales/${balId}/sync/exec`)
Expand Down
2 changes: 1 addition & 1 deletion apps/api/test/toponyme.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ describe('TOPONYME MODULE', () => {
};
return {
id,
type: PositionTypeEnum.INCONNUE,
type: PositionTypeEnum.ENTREE,
source: 'ban',
point,
} as Position;
Expand Down
8 changes: 4 additions & 4 deletions apps/cron/test/task.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ describe('TASK MODULE', () => {
};
return {
id,
type: PositionTypeEnum.INCONNUE,
type: PositionTypeEnum.ENTREE,
source: 'ban',
point,
} as Position;
Expand Down Expand Up @@ -370,7 +370,7 @@ describe('TASK MODULE', () => {
axiosMock.onPost(`/revisions/${revisionId}/compute`).reply(200, revision);

const csvFile = `cle_interop;id_ban_commune;id_ban_toponyme;id_ban_adresse;voie_nom;lieudit_complement_nom;numero;suffixe;certification_commune;commune_insee;commune_nom;commune_deleguee_insee;commune_deleguee_nom;position;long;lat;x;y;cad_parcelles;source;date_der_maj
91534_xxxx_00001_bis;52c4de09-6b82-45eb-8ed7-b212607282f7;26734c2d-2a14-4eeb-ac5b-1be055c0a5ae;2da3bb47-1a10-495a-8c29-6b8d0e79f9af;rue de la paix;;1;bis;1;91534;Saclay;;;inconnue;8;42;1114835.92;6113076.85;;ban;2000-01-01`;
91534_xxxx_00001_bis;52c4de09-6b82-45eb-8ed7-b212607282f7;26734c2d-2a14-4eeb-ac5b-1be055c0a5ae;2da3bb47-1a10-495a-8c29-6b8d0e79f9af;rue de la paix;;1;bis;1;91534;Saclay;;;entrée;8;42;1114835.92;6113076.85;;ban;2000-01-01`;
axiosMock.onPut(`/revisions/${revisionId}/files/bal`).reply(({ data }) => {
expect(data.replace(/\s/g, '')).toEqual(csvFile.replace(/\s/g, ''));
return [200, null];
Expand Down Expand Up @@ -414,7 +414,7 @@ describe('TASK MODULE', () => {
const revision: Revision = {
_id: revisionId.toString(),
codeCommune: commune,
status: StatusRevision.PENDING,
status: StatusRevision.PUBLISHED,
ready: false,
createdAt: new Date(),
updatedAt: new Date(),
Expand All @@ -425,7 +425,7 @@ describe('TASK MODULE', () => {
files: [
{
type: 'bal',
hash: 'e80613f07843ede61ef9d3b396c2878fab65c165af9eac8b75c5aa12419907b8',
hash: '5387136992a3d0ca40c53dc14c21fda9a4ca566b18bd6c45df7aa852774b4c8a',
},
],
};
Expand Down
4 changes: 4 additions & 0 deletions libs/shared/src/entities/base_locale.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export class BaseLocale extends GlobalEntity {
@Column('text', { nullable: false })
nom: string;

@ApiProperty()
@Column('json', { name: 'commune_noms_alt', nullable: true })
communeNomsAlt: Record<string, string> | null;

@ApiProperty()
@Column('varchar', { nullable: false, length: 5 })
commune: string;
Expand Down
3 changes: 2 additions & 1 deletion libs/shared/src/entities/position.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Toponyme } from './toponyme.entity';
import { ObjectId } from 'mongodb';
import { Validate } from 'class-validator';
import { PointValidator } from '../validators/coord.validator';
import { ValidatorBal } from '../validators/validator_bal.validator';

export enum PositionTypeEnum {
ENTREE = 'entrée',
Expand All @@ -24,7 +25,6 @@ export enum PositionTypeEnum {
DELIVRANCE_POSTALE = 'délivrance postale',
PARCELLE = 'parcelle',
SEGMENT = 'segment',
INCONNUE = 'inconnue',
}

@Entity({ name: 'positions' })
Expand All @@ -49,6 +49,7 @@ export class Position {
numeroId?: string;

@ApiProperty({ enum: PositionTypeEnum })
@Validate(ValidatorBal, ['position'])
@Column('enum', {
enum: PositionTypeEnum,
default: PositionTypeEnum.ENTREE,
Expand Down
10 changes: 10 additions & 0 deletions libs/shared/src/modules/export_csv/utils/export_csv_bal.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type RowType = {
banIds: BanIdsType;
codeCommune: string;
communeDeleguee?: string;
communeNomsAlt: Record<string, string>;
codeVoie: string;
numero: number;
suffixe?: string;
Expand Down Expand Up @@ -143,6 +144,12 @@ function createRow(obj: RowType, withComment: boolean): CsvRowType {
row.commentaire_voie = obj.commentVoie;
}

if (obj.communeNomsAlt) {
Object.keys(obj.communeNomsAlt).forEach((o) => {
row['commune_nom_' + o] = obj.communeNomsAlt[o];
});
}

if (obj.nomVoieAlt) {
Object.keys(obj.nomVoieAlt).forEach((o) => {
row['voie_nom_' + o] = obj.nomVoieAlt[o];
Expand Down Expand Up @@ -204,6 +211,7 @@ export async function exportBalToCsv(
toponyme: v.banId,
adresse: n.banId,
},
communeNomsAlt: baseLocale.communeNomsAlt,
codeVoie: DEFAULT_CODE_VOIE,
numero: n.numero,
suffixe: n.suffixe,
Expand Down Expand Up @@ -232,6 +240,7 @@ export async function exportBalToCsv(
commune: baseLocale.banId,
toponyme: t.banId,
},
communeNomsAlt: baseLocale.communeNomsAlt,
codeVoie: DEFAULT_CODE_VOIE,
numero: DEFAULT_NUMERO_TOPONYME,
updatedAt: t.updatedAt,
Expand All @@ -249,6 +258,7 @@ export async function exportBalToCsv(
},
codeCommune: baseLocale.commune,
communeDeleguee: t.communeDeleguee,
communeNomsAlt: baseLocale.communeNomsAlt,
codeVoie: DEFAULT_CODE_VOIE,
numero: DEFAULT_NUMERO_TOPONYME,
updatedAt: t.updatedAt,
Expand Down
11 changes: 7 additions & 4 deletions libs/shared/src/validators/validator_bal.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ export class ValidatorBal implements ValidatorConstraintInterface {
if (supportedNomAlt.has(codeISO)) {
const nomVoie = value[codeISO];
const { errors } = await validateurBAL(nomVoie, 'voie_nom');
return errors.length === 0;
if (errors.length > 0) {
return false;
}
} else {
return false;
}
}
return true;
}
} catch {
return false;
Expand All @@ -50,8 +53,8 @@ export class ValidatorBal implements ValidatorConstraintInterface {

defaultMessage(args: ValidationArguments) {
const field = args.constraints[0];
const value =
field === 'langAlt' ? Object.values(args.value)[0] : args.value;
return 'Le champ ' + field + ' : ' + value + " n'est pas valide";
return field === 'langAlt'
? "Le champ de langue régionale n'est pas valide"
: `Le champ ${field} : ${args.value} n'est pas valide`;
}
}
Loading

0 comments on commit ffdcdda

Please sign in to comment.