Skip to content

Commit

Permalink
♻️ Modifier date de mise en service
Browse files Browse the repository at this point in the history
  • Loading branch information
benjlevesque committed Nov 13, 2024
1 parent 4da0e44 commit 3f9ec8e
Show file tree
Hide file tree
Showing 21 changed files with 331 additions and 140 deletions.
1 change: 1 addition & 0 deletions packages/applications/bootstrap/src/setupRéseau.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const setupRéseau = async () => {
'RebuildTriggered',
'AccuséRéceptionDemandeComplèteRaccordementTransmis-V1',
'DateMiseEnServiceTransmise-V1',
'DateMiseEnServiceModifiée-V1',
'DemandeComplèteDeRaccordementTransmise-V1',
'DemandeComplèteDeRaccordementTransmise-V2',
'DemandeComplèteRaccordementModifiée-V1',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ export const register = () => {
misÀJourLe: event.created_at,
};
case 'DateMiseEnServiceTransmise-V1':
case 'DateMiseEnServiceModifiée-V1':
return {
...dossier,
miseEnService: {
Expand Down
3 changes: 3 additions & 0 deletions packages/domain/réseau/src/raccordement/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { ModifierDemandeComplèteRaccordementUseCase } from './modifier/modifier
import { ModifierGestionnaireRéseauRaccordementUseCase } from './modifier/modifierGestionnaireRéseauRaccordement.usecase';
import { ModifierPropositiontechniqueEtFinancièreUseCase } from './modifier/modifierPropositiontechniqueEtFinancière.usecase';
import { ModifierRéférenceDossierRaccordementUseCase } from './modifier/modifierRéférenceDossierRaccordement.usecase';
import { ModifierDateMiseEnServiceUseCase } from './modifier/modifierDateMiseEnService.usecase';
import {
RechercherDossierRaccordementQuery,
RechercherDossierRaccordementReadModel,
Expand Down Expand Up @@ -80,6 +81,7 @@ export type RaccordementUseCase =
| ModifierGestionnaireRéseauRaccordementUseCase
| ModifierPropositiontechniqueEtFinancièreUseCase
| ModifierRéférenceDossierRaccordementUseCase
| ModifierDateMiseEnServiceUseCase
| TransmettreDateMiseEnServiceUseCase
| TransmettreDemandeComplèteRaccordementUseCase
| TransmettrePropositionTechniqueEtFinancièreUseCase
Expand All @@ -88,6 +90,7 @@ export type RaccordementUseCase =

export type {
ModifierDemandeComplèteRaccordementUseCase,
ModifierDateMiseEnServiceUseCase,
ModifierGestionnaireRéseauRaccordementUseCase,
ModifierPropositiontechniqueEtFinancièreUseCase,
ModifierRéférenceDossierRaccordementUseCase,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { DateTime, IdentifiantProjet } from '@potentiel-domain/common';
import { DomainEvent, InvalidOperationError } from '@potentiel-domain/core';
import { Option } from '@potentiel-libraries/monads';

import * as RéférenceDossierRaccordement from '../référenceDossierRaccordement.valueType';
import { RaccordementAggregate } from '../raccordement.aggregate';
import { DateDansLeFuturError } from '../dateDansLeFutur.error';

export type DateMiseEnServiceModifiéeEvent = DomainEvent<
'DateMiseEnServiceModifiée-V1',
{
dateMiseEnService: DateTime.RawType;
référenceDossierRaccordement: RéférenceDossierRaccordement.RawType;
identifiantProjet: IdentifiantProjet.RawType;
}
>;

type ModifierDateMiseEnServiceOptions = {
dateMiseEnService: DateTime.ValueType;
dateDésignation: DateTime.ValueType;
identifiantProjet: IdentifiantProjet.ValueType;
référenceDossier: RéférenceDossierRaccordement.ValueType;
};

export async function modifierDateMiseEnService(
this: RaccordementAggregate,
{
dateMiseEnService,
dateDésignation,
identifiantProjet,
référenceDossier,
}: ModifierDateMiseEnServiceOptions,
) {
if (dateMiseEnService.estDansLeFutur()) {
throw new DateDansLeFuturError();
}

if (dateMiseEnService.estAntérieurÀ(dateDésignation)) {
throw new DateMiseEnServiceAntérieureDateDésignationProjetError();
}

const dossier = this.récupérerDossier(référenceDossier.formatter());
if (Option.isNone(dossier.miseEnService.dateMiseEnService)) {
throw new AucuneDateDeMiseEnServiceTransmiseError();
}

if (!this.dateModifiée(référenceDossier, dateMiseEnService)) {
throw new DateDeMiseEnServiceInchangéeError();
}

const dateMiseEnServiceModifiée: DateMiseEnServiceModifiéeEvent = {
type: 'DateMiseEnServiceModifiée-V1',
payload: {
dateMiseEnService: dateMiseEnService.formatter(),
identifiantProjet: identifiantProjet.formatter(),
référenceDossierRaccordement: référenceDossier.formatter(),
},
};

await this.publish(dateMiseEnServiceModifiée);
}

export function applyDateMiseEnServiceModifiéeEventV1(
this: RaccordementAggregate,
{ payload: { dateMiseEnService, référenceDossierRaccordement } }: DateMiseEnServiceModifiéeEvent,
) {
const dossier = this.récupérerDossier(référenceDossierRaccordement);
dossier.miseEnService.dateMiseEnService = DateTime.convertirEnValueType(dateMiseEnService);
}

export class DateMiseEnServiceAntérieureDateDésignationProjetError extends InvalidOperationError {
constructor() {
super(
`La date de mise en service ne peut pas être antérieure à la date de désignation du projet`,
);
}
}

class AucuneDateDeMiseEnServiceTransmiseError extends InvalidOperationError {
constructor() {
super(`Aucune date de mise en service n'a encore été transmise`);
}
}

class DateDeMiseEnServiceInchangéeError extends InvalidOperationError {
constructor() {
super(`La date de mise en service est inchangée`);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Message, MessageHandler, mediator } from 'mediateur';

import { DateTime, IdentifiantProjet } from '@potentiel-domain/common';
import { LoadAggregate } from '@potentiel-domain/core';
import { Lauréat } from '@potentiel-domain/laureat';

import * as RéférenceDossierRaccordement from '../référenceDossierRaccordement.valueType';
import { loadRaccordementAggregateFactory } from '../raccordement.aggregate';

export type ModifierDateMiseEnServiceCommand = Message<
'Réseau.Raccordement.Command.ModifierDateMiseEnService',
{
dateMiseEnService: DateTime.ValueType;
référenceDossier: RéférenceDossierRaccordement.ValueType;
identifiantProjet: IdentifiantProjet.ValueType;
}
>;

export const registerModifierDateMiseEnServiceCommand = (loadAggregate: LoadAggregate) => {
const loadRaccordementAggregate = loadRaccordementAggregateFactory(loadAggregate);
const loadLauréatAggregate = Lauréat.loadLauréatFactory(loadAggregate);

const handler: MessageHandler<ModifierDateMiseEnServiceCommand> = async ({
dateMiseEnService,
référenceDossier,
identifiantProjet,
}) => {
const raccordement = await loadRaccordementAggregate(identifiantProjet);
const laureát = await loadLauréatAggregate(identifiantProjet);

await raccordement.modifierDateMiseEnService({
dateDésignation: laureát.notifiéLe,
dateMiseEnService,
identifiantProjet,
référenceDossier,
});
};

mediator.register('Réseau.Raccordement.Command.ModifierDateMiseEnService', handler);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Message, MessageHandler, mediator } from 'mediateur';

import { DateTime, IdentifiantProjet } from '@potentiel-domain/common';

import * as RéférenceDossierRaccordement from '../référenceDossierRaccordement.valueType';

import { ModifierDateMiseEnServiceCommand } from './modifierDateMiseEnService.command';

export type ModifierDateMiseEnServiceUseCase = Message<
'Réseau.Raccordement.UseCase.ModifierDateMiseEnService',
{
dateMiseEnServiceValue: string;
référenceDossierValue: string;
identifiantProjetValue: string;
}
>;

export const registerModifierDateMiseEnServiceUseCase = () => {
const runner: MessageHandler<ModifierDateMiseEnServiceUseCase> = async ({
dateMiseEnServiceValue,
référenceDossierValue,
identifiantProjetValue,
}) => {
const dateMiseEnService = DateTime.convertirEnValueType(dateMiseEnServiceValue);
const identifiantProjet = IdentifiantProjet.convertirEnValueType(identifiantProjetValue);
const référenceDossier =
RéférenceDossierRaccordement.convertirEnValueType(référenceDossierValue);

await mediator.send<ModifierDateMiseEnServiceCommand>({
type: 'Réseau.Raccordement.Command.ModifierDateMiseEnService',
data: {
dateMiseEnService,
identifiantProjet,
référenceDossier,
},
});
};

mediator.register('Réseau.Raccordement.UseCase.ModifierDateMiseEnService', runner);
};
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ import {
RaccordementSuppriméEvent,
supprimerRaccordement,
} from './supprimer/supprimerRaccordement.behavior';
import {
applyDateMiseEnServiceModifiéeEventV1,
DateMiseEnServiceModifiéeEvent,
modifierDateMiseEnService,
} from './modifier/modifierDateMiseEnService.behavior';

export type DeprecateEvent =
| DemandeComplèteRaccordementTransmiseEventV1
Expand All @@ -92,6 +97,7 @@ export type RaccordementEvent =
| DemandeComplèteRaccordementTransmiseEvent
| PropositionTechniqueEtFinancièreTransmiseEvent
| DateMiseEnServiceTransmiseEvent
| DateMiseEnServiceModifiéeEvent
| DemandeComplèteRaccordementModifiéeEvent
| RéférenceDossierRacordementModifiéeEvent
| PropositionTechniqueEtFinancièreModifiéeEvent
Expand Down Expand Up @@ -123,13 +129,14 @@ export type RaccordementAggregate = Aggregate<RaccordementEvent> & {
readonly transmettreDemande: typeof transmettreDemande;
readonly transmettreDateMiseEnService: typeof transmettreDateMiseEnService;
readonly transmettrePropositionTechniqueEtFinancière: typeof transmettrePropositionTechniqueEtFinancière;
readonly modifierDateMiseEnService: typeof modifierDateMiseEnService;
readonly modifierDemandeComplèteRaccordement: typeof modifierDemandeComplèteRaccordement;
readonly modifierRéférenceDossierRacordement: typeof modifierRéférenceDossierRacordement;
readonly modifierPropositionTechniqueEtFinancière: typeof modifierPropositionTechniqueEtFinancière;
readonly modifierGestionnaireRéseau: typeof modifierGestionnaireRéseau;
readonly contientLeDossier: (référence: RéférenceDossierRaccordement.ValueType) => boolean;
readonly récupérerDossier: (référence: string) => DossierRaccordement;
readonly aUneDateDeMiseEnService: () => boolean;
readonly aUneDateDeMiseEnService: (référence?: RéférenceDossierRaccordement.ValueType) => boolean;
readonly attribuerGestionnaireRéseau: typeof attribuerGestionnaireRéseau;
readonly supprimerDossier: typeof supprimerDossier;
readonly supprimerRaccordement: typeof supprimerRaccordement;
Expand All @@ -150,6 +157,7 @@ export const getDefaultRaccordementAggregate: GetDefaultAggregateState<
transmettreDemande,
transmettreDateMiseEnService,
transmettrePropositionTechniqueEtFinancière,
modifierDateMiseEnService,
modifierDemandeComplèteRaccordement,
modifierRéférenceDossierRacordement,
modifierPropositionTechniqueEtFinancière,
Expand Down Expand Up @@ -230,6 +238,9 @@ function apply(this: RaccordementAggregate, event: RaccordementEvent) {
case 'DateMiseEnServiceTransmise-V1':
applyDateMiseEnServiceTransmiseEventV1.bind(this)(event);
break;
case 'DateMiseEnServiceModifiée-V1':
applyDateMiseEnServiceModifiéeEventV1.bind(this)(event);
break;
case 'GestionnaireRéseauRaccordementModifié-V1':
applyGestionnaireRéseauRaccordementModifiéEventV1.bind(this)(event);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import { registerSupprimerDossierDuRaccordementCommand } from './dossier/supprim
import { registerSupprimerRaccordementCommand } from './supprimer/supprimerRaccordement.command';
import { registerListerDossierRaccordementEnAttenteMiseEnServiceQuery } from './lister/listerDossierRaccordementEnAttenteMiseEnService.query';
import { registerListerDossierRaccordementQuery } from './lister/listerDossierRaccordement.query';
import { registerModifierDateMiseEnServiceCommand } from './modifier/modifierDateMiseEnService.command';
import { registerModifierDateMiseEnServiceUseCase } from './modifier/modifierDateMiseEnService.usecase';

export type RaccordementQueryDependencies = ConsulterDossierRaccordementDependencies &
ConsulterGestionnaireRéseauRaccordementDependencies &
Expand All @@ -71,6 +73,7 @@ export const registerRaccordementQueries = (dependencies: RaccordementQueryDepen
export const registerRaccordementUseCases = ({
loadAggregate,
}: RaccordementCommandDependencies) => {
registerModifierDateMiseEnServiceCommand(loadAggregate);
registerModifierDemandeComplèteRaccordementCommand(loadAggregate);
registerModifierGestionnaireRéseauProjetCommand(loadAggregate);
registerModifierPropositionTechniqueEtFinancièreCommand(loadAggregate);
Expand All @@ -82,6 +85,7 @@ export const registerRaccordementUseCases = ({
registerSupprimerDossierDuRaccordementCommand(loadAggregate);
registerSupprimerRaccordementCommand(loadAggregate);

registerModifierDateMiseEnServiceUseCase();
registerModifierDemandeComplèteRaccordementUseCase();
registerModifierGestionnaireRéseauRaccordementUseCase();
registerModifierPropositiontechniqueEtFinancièreUseCase();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { DateTime, IdentifiantProjet } from '@potentiel-domain/common';
import { DomainEvent, InvalidOperationError } from '@potentiel-domain/core';
import { Option } from '@potentiel-libraries/monads';

import * as RéférenceDossierRaccordement from '../référenceDossierRaccordement.valueType';
import { RaccordementAggregate } from '../raccordement.aggregate';
import { DateDansLeFuturError } from '../dateDansLeFutur.error';
import { DossierNonRéférencéPourLeRaccordementDuProjetError } from '../dossierNonRéférencéPourLeRaccordementDuProjet.error';

export type DateMiseEnServiceTransmiseEvent = DomainEvent<
'DateMiseEnServiceTransmise-V1',
Expand Down Expand Up @@ -38,13 +38,10 @@ export async function transmettreDateMiseEnService(
if (dateMiseEnService.estAntérieurÀ(dateDésignation)) {
throw new DateMiseEnServiceAntérieureDateDésignationProjetError();
}
const dossier = this.récupérerDossier(référenceDossier.référence);

if (!this.contientLeDossier(référenceDossier)) {
throw new DossierNonRéférencéPourLeRaccordementDuProjetError();
}

if (!this.dateModifiée(référenceDossier, dateMiseEnService)) {
throw new DateIdentiqueDeMiseEnServiceDéjàTransmiseError();
if (Option.isSome(dossier.miseEnService.dateMiseEnService)) {
throw new DateMiseEnServiceDéjàTransmiseError();
}

const dateMiseEnServiceTransmise: DateMiseEnServiceTransmiseEvent = {
Expand Down Expand Up @@ -75,7 +72,7 @@ export class DateMiseEnServiceAntérieureDateDésignationProjetError extends Inv
}
}

class DateIdentiqueDeMiseEnServiceDéjàTransmiseError extends InvalidOperationError {
class DateMiseEnServiceDéjàTransmiseError extends InvalidOperationError {
constructor() {
super(`La date de mise en service est déjà transmise pour ce dossier de raccordement`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function vérifierEmailEnvoyé(this: PotentielWorld, email: string, data: DataTa
if (key === 'sujet') {
expect(notif.messageSubject).to.equal(value);
} else {
expect(notif.variables[key]).to.equal(value);
expect(notif.variables[key]).to.match(new RegExp(value));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface DemanderAbandon {
readonly demandéPar: string;
readonly raison: string;
readonly recandidature: boolean;
readonly identifiantProjet: string;
}

export class DemanderAbandonFixture
Expand Down Expand Up @@ -53,7 +54,15 @@ export class DemanderAbandonFixture
return this.#recandidature;
}

créer(partialFixture?: Partial<Readonly<DemanderAbandon>>): Readonly<DemanderAbandon> {
#identifiantProjet!: string;

get identifiantProjet(): string {
return this.#identifiantProjet;
}

créer(
partialFixture: Partial<Readonly<DemanderAbandon>> & { identifiantProjet: string },
): Readonly<DemanderAbandon> {
const recandidature = faker.datatype.boolean();

const fixture = {
Expand All @@ -68,6 +77,7 @@ export class DemanderAbandonFixture
this.#demandéPar = fixture.demandéPar;
this.#raison = fixture.raison;
this.#recandidature = fixture.recandidature;
this.#identifiantProjet = fixture.identifiantProjet;

if (!fixture.recandidature) {
const content = faker.word.words();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ async function créerDemandeAbandon(this: PotentielWorld, etat: string) {

const { raison, demandéLe, demandéPar, pièceJustificative, recandidature } =
this.lauréatWorld.abandonWorld.demanderAbandonFixture.créer({
identifiantProjet,
recandidature: etat.includes('avec recandidature'),
demandéPar: this.utilisateurWorld.porteurFixture.email,
});
Expand Down
Loading

0 comments on commit 3f9ec8e

Please sign in to comment.