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: add commune deleguee to voie #487

Closed
wants to merge 7 commits into from
Closed
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
3 changes: 3 additions & 0 deletions apps/api/src/lib/utils/csv.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ function extractData(rows: Row[]): {
nomAlt: toponymeRows[0].localizedValues.voie_nom
? beautifyNomAlt(toponymeRows[0].localizedValues.voie_nom)
: null,
communeDeleguee:
toponymeRows[0].rawValues.commune_deleguee_insee || null,
positions: extractPositions(toponymeRows),
createdAt: date,
updatedAt: date,
Expand All @@ -115,6 +117,7 @@ function extractData(rows: Row[]): {
nomAlt: voieRows[0].localizedValues.voie_nom
? beautifyNomAlt(voieRows[0].localizedValues.voie_nom)
: null,
communeDeleguee: voieRows[0].rawValues.commune_deleguee_insee || null,
createdAt: dates.length > 0 ? new Date(min(dates)) : new Date(),
updatedAt: dates.length > 0 ? new Date(max(dates)) : new Date(),
};
Expand Down
5 changes: 5 additions & 0 deletions apps/api/src/modules/toponyme/dto/create_toponyme.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

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

export class CreateToponymeDTO {
@Validate(ValidatorBal, ['nom'])
Expand All @@ -21,6 +22,10 @@ export class CreateToponymeDTO {
@ApiProperty({ required: false, nullable: true })
nomAlt: Record<string, string>;

@Validate(ValidatorCogCommune, ['commune_deleguee'])
@ApiProperty({ required: false, nullable: true })
communeDeleguee?: string;

@IsOptional()
@Validate(ValidatorBal, ['cad_parcelles'])
@ApiProperty({ required: false, nullable: true })
Expand Down
5 changes: 5 additions & 0 deletions apps/api/src/modules/toponyme/dto/update_toponyme.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

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

export class UpdateToponymeDTO {
@IsOptional()
Expand All @@ -22,6 +23,10 @@ export class UpdateToponymeDTO {
@ApiProperty({ required: false, nullable: true })
nomAlt: Record<string, string>;

@Validate(ValidatorCogCommune, ['commune_deleguee'])
@ApiProperty({ required: false, nullable: true })
communeDeleguee?: string;

@IsOptional()
@Validate(ValidatorBal, ['cad_parcelles'])
@ApiProperty({ required: false, nullable: true })
Expand Down
2 changes: 2 additions & 0 deletions apps/api/src/modules/toponyme/toponyme.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ export class ToponymeService {
nomAlt: createToponymeDto.nomAlt
? cleanNomAlt(createToponymeDto.nomAlt)
: null,
communeDeleguee: createToponymeDto.communeDeleguee || null,
positions: createToponymeDto.positions || [],
parcelles: createToponymeDto.parcelles || [],
};
Expand Down Expand Up @@ -226,6 +227,7 @@ export class ToponymeService {
balId: baseLocale.id,
banId: rawToponyme.banId || uuid(),
nom: cleanNom(rawToponyme.nom),
communeDeleguee: rawToponyme.communeDeleguee,
parcelles: rawToponyme.parcelles || [],
nomAlt: getNomAltDefault(rawToponyme.nomAlt),
...(rawToponyme.updatedAt && { updatedAt: rawToponyme.updatedAt }),
Expand Down
5 changes: 5 additions & 0 deletions apps/api/src/modules/voie/dto/create_voie.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
IsEnum,
} from 'class-validator';

import { ValidatorCogCommune } from '@/shared/validators/cog.validator';
import { TypeNumerotationEnum } from '@/shared/entities/voie.entity';
import { LineString } from './line_string';

Expand All @@ -23,6 +24,10 @@ export class CreateVoieDTO {
@ApiProperty({ required: false, nullable: true })
nomAlt: Record<string, string>;

@Validate(ValidatorCogCommune, ['commune_deleguee'])
@ApiProperty({ required: false, nullable: true })
communeDeleguee?: string;

@IsOptional()
@IsEnum(TypeNumerotationEnum)
@ApiProperty({ required: false, nullable: false, enum: TypeNumerotationEnum })
Expand Down
5 changes: 5 additions & 0 deletions apps/api/src/modules/voie/dto/update_voie.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {

import { TypeNumerotationEnum } from '@/shared/entities/voie.entity';
import { LineString } from './line_string';
import { ValidatorCogCommune } from '@/shared/validators/cog.validator';

export class UpdateVoieDTO {
@IsOptional()
Expand All @@ -24,6 +25,10 @@ export class UpdateVoieDTO {
@ApiProperty({ required: false, nullable: true })
nomAlt: Record<string, string>;

@Validate(ValidatorCogCommune, ['commune_deleguee'], {})
@ApiProperty({ required: false, nullable: true })
communeDeleguee?: string;

@IsOptional()
@IsEnum(TypeNumerotationEnum)
@ApiProperty({ required: false, nullable: false, enum: TypeNumerotationEnum })
Expand Down
2 changes: 2 additions & 0 deletions apps/api/src/modules/voie/voie.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export class VoieService {
balId: bal.id,
banId: uuid(),
nom: createVoieDto.nom,
communeDeleguee: createVoieDto.communeDeleguee || null,
typeNumerotation:
createVoieDto.typeNumerotation || TypeNumerotationEnum.NUMERIQUE,
trace: createVoieDto.trace || null,
Expand Down Expand Up @@ -168,6 +169,7 @@ export class VoieService {
banId: rawVoie.banId || uuid(),
nom: cleanNom(rawVoie.nom),
nomAlt: getNomAltDefault(rawVoie.nomAlt),
communeDeleguee: rawVoie.communeDeleguee,
typeNumerotation: rawVoie.typeNumerotation,
trace: rawVoie.trace || null,
...(rawVoie.updatedAt && { updatedAt: rawVoie.updatedAt }),
Expand Down
13 changes: 8 additions & 5 deletions apps/api/test/base_locale.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,24 +521,27 @@ describe('BASE LOCAL MODULE', () => {

describe('GET /bases-locales/csv', () => {
it('GET CSV 200', async () => {
const balId = await createBal({ nom: 'bal', commune: '91534' });
const balId = await createBal({ nom: 'bal', commune: '08053' });
const { banId: communeUuid } = await balRepository.findOneBy({
id: balId,
});
const voieId1 = await createVoie(balId, {
nom: 'rue de la paix',
communeDeleguee: '08294',
});
const { banId: voieUuid1 } = await voieRepository.findOneBy({
id: voieId1,
});
const voieId2 = await createVoie(balId, {
nom: 'rue de paris',
communeDeleguee: '08053',
});
const { banId: voieUuid2 } = await voieRepository.findOneBy({
id: voieId2,
});
const toponymeId1 = await createToponyme(balId, {
nom: 'allée',
communeDeleguee: '08294',
});
const { banId: toponymeUuid1 } = await toponymeRepository.findOneBy({
id: toponymeId1,
Expand Down Expand Up @@ -577,10 +580,10 @@ describe('BASE LOCAL MODULE', () => {
expect(response.headers['content-type']).toEqual(
'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;position;long;lat;x;y;cad_parcelles;source;date_der_maj
91534_xxxx_00001_bis;${communeUuid};${voieUuid1};${numeroUuid1};rue de la paix;allée;1;bis;1;91534;Saclay;inconnue;8;42;1114835.92;6113076.85;;ban;2000-01-02
91534_xxxx_00001_ter;${communeUuid};${voieUuid2};${numeroUuid2};rue de paris;allée;1;ter;0;91534;Saclay;inconnue;8;42;1114835.92;6113076.85;;ban;2000-01-02
91534_xxxx_99999;${communeUuid};${toponymeUuid1};;allée;;99999;;;91534;Saclay;;;;;;;commune;2000-01-02`;
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;08294;La Moncelle;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;08053;Bazeilles;inconnue;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
13 changes: 7 additions & 6 deletions apps/api/test/publication.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ describe('PUBLICATION MODULE', () => {

describe('POST /bases-locales/sync/exec', () => {
it('Publish 200 DRAFT', async () => {
const commune = '91534';
const commune = '08053';
const habilitationId = new ObjectId().toHexString();
const balId = await createBal({
nom: 'bal',
Expand All @@ -181,6 +181,7 @@ describe('PUBLICATION MODULE', () => {
});
const voieId = await createVoie(balId, {
nom: 'rue de la paix',
communeDeleguee: '08294',
});
const { banId: voieUuid } = await voieRepository.findOneBy({
id: voieId,
Expand Down Expand Up @@ -224,8 +225,8 @@ 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;position;long;lat;x;y;cad_parcelles;source;date_der_maj
91534_xxxx_00001_bis;${communeUuid};${voieUuid};${numeroUuid};rue de la paix;;1;bis;1;91534;Saclay;inconnue;8;42;1114835.92;6113076.85;;ban;2000-01-01`;
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`;
axiosMock
.onPut(`/revisions/${revisionId}/files/bal`)
.reply(({ data }) => {
Expand Down Expand Up @@ -345,8 +346,8 @@ 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;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`;
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`;
axiosMock
.onPut(`/revisions/${revisionId}/files/bal`)
.reply(({ data }) => {
Expand Down Expand Up @@ -409,7 +410,7 @@ describe('PUBLICATION MODULE', () => {
files: [
{
type: 'bal',
hash: '0c5d808a7e5612c9467607c574cb2317a76fe04d493efbd61b55a31bbd194227',
hash: 'a512238a358a47446e4eb6b89dbfbecc03b81fcb2492eed54e277699d1c49c62',
},
],
};
Expand Down
22 changes: 22 additions & 0 deletions apps/api/test/toponyme.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ describe('TOPONYME MODULE', () => {
const changes: UpdateToponymeDTO = {
nom: 'coucou',
nomAlt: null,
communeDeleguee: '08294',
parcelles: ['12345000AA0002', '12345000AA0005'],
positions: [createPositions()],
};
Expand All @@ -245,6 +246,7 @@ describe('TOPONYME MODULE', () => {
expect(response.body.id).toEqual(toponymeId);
expect(response.body.balId).toEqual(balId);
expect(response.body.nom).toEqual('coucou');
expect(response.body.communeDeleguee).toEqual('08294');
expect(response.body.parcelles).toEqual([
'12345000AA0002',
'12345000AA0005',
Expand All @@ -255,6 +257,26 @@ describe('TOPONYME MODULE', () => {
expect(bal.updatedAt.toISOString()).not.toEqual(updatedAt.toISOString());
});

it('Return 400 bad communeDeleguee', async () => {
const balId = await createBal({ nom: 'bal', commune: '08053' });
const toponymeId = await createToponyme(balId, {
nom: 'rue de la paix',
});
const changes: UpdateToponymeDTO = {
nom: 'coucou',
nomAlt: null,
communeDeleguee: '91400',
parcelles: ['12345000AA0002', '12345000AA0005'],
positions: [createPositions()],
};

await request(app.getHttpServer())
.put(`/toponymes/${toponymeId}`)
.send(changes)
.set('authorization', `Bearer ${token}`)
.expect(400);
});

it('Return 403', async () => {
const balId = await createBal({ nom: 'bal', commune: '91400' });
const toponymeId = await createToponyme(balId, {
Expand Down
30 changes: 29 additions & 1 deletion apps/api/test/voie.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -502,14 +502,15 @@ describe('VOIE MODULE', () => {

describe('PUT /voies', () => {
it('Return 200', async () => {
const balId = await createBal({ nom: 'bal', commune: '91400' });
const balId = await createBal({ nom: 'bal', commune: '08053' });
const voieId = await createVoie(balId, {
nom: 'rue de la paix',
});
const changes: UpdateVoieDTO = {
nom: 'coucou',
nomAlt: null,
typeNumerotation: TypeNumerotationEnum.NUMERIQUE,
communeDeleguee: '08294',
trace: {
type: 'LineString',
coordinates: [
Expand All @@ -527,6 +528,7 @@ describe('VOIE MODULE', () => {
expect(response.body.id).toEqual(voieId);
expect(response.body.balId).toEqual(balId);
expect(response.body.nom).toEqual('coucou');
expect(response.body.communeDeleguee).toEqual('08294');
expect(response.body.typeNumerotation).toEqual(
TypeNumerotationEnum.NUMERIQUE,
);
Expand All @@ -536,6 +538,32 @@ describe('VOIE MODULE', () => {
expect(bal.updatedAt.toISOString()).not.toEqual(updatedAt.toISOString());
});

it('Return 400 bad commune déléguée', async () => {
const balId = await createBal({ nom: 'bal', commune: '08053' });
const voieId = await createVoie(balId, {
nom: 'rue de la paix',
});
const changes: UpdateVoieDTO = {
nom: 'coucou',
nomAlt: null,
typeNumerotation: TypeNumerotationEnum.NUMERIQUE,
communeDeleguee: '91400',
trace: {
type: 'LineString',
coordinates: [
[48, 2],
[49, 1],
],
},
};

await request(app.getHttpServer())
.put(`/voies/${voieId}`)
.send(changes)
.set('authorization', `Bearer ${token}`)
.expect(400);
});

it('Return 200 trace empty', async () => {
const balId = await createBal({ nom: 'bal', commune: '91400' });
const voieId = await createVoie(balId, {
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 @@ -306,7 +306,7 @@ describe('TASK MODULE', () => {
const revision: Revision = {
_id: revisionId,
codeCommune: commune,
status: StatusRevision.PENDING,
status: StatusRevision.PUBLISHED,
ready: false,
createdAt: new Date(),
updatedAt: new Date(),
Expand Down Expand Up @@ -369,8 +369,8 @@ 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;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`;
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`;
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 @@ -425,7 +425,7 @@ describe('TASK MODULE', () => {
files: [
{
type: 'bal',
hash: 'a62492c9dbd6c74e7cfb2b67b3a9e49be89da7b8fa4dff3c061b0f82805b65c9',
hash: 'e80613f07843ede61ef9d3b396c2878fab65c165af9eac8b75c5aa12419907b8',
},
],
};
Expand Down
9 changes: 9 additions & 0 deletions libs/shared/src/entities/toponyme.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ export class Toponyme extends GlobalEntity {
@Column('json', { name: 'nom_alt', nullable: true })
nomAlt: Record<string, string> | null;

@ApiProperty()
@Column('varchar', {
name: 'commune_deleguee',
default: null,
nullable: true,
length: 5,
})
communeDeleguee: string | null;

@ApiProperty()
@Column('text', { nullable: true, array: true })
parcelles?: string[] | null;
Expand Down
9 changes: 9 additions & 0 deletions libs/shared/src/entities/voie.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ export class Voie extends GlobalEntity {
@Column('json', { name: 'nom_alt', nullable: true })
nomAlt: Record<string, string> | null;

@ApiProperty()
@Column('varchar', {
name: 'commune_deleguee',
default: null,
nullable: true,
length: 5,
})
communeDeleguee: string | null;

@ApiProperty({ enum: TypeNumerotationEnum })
@Column('enum', {
name: 'type_numerotation',
Expand Down
Loading