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

✨ Impossible d'abandonner un projet achevé #2670

Merged
merged 7 commits into from
Feb 3, 2025
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const PorteurProjetActions = ({
familleId: project.familleId,
numeroCRE: project.numeroCRE,
}).formatter();
const peutDemanderAbandon = !abandonEnCours && !hasAttestationConformité;

return (
<div className="flex flex-col gap-3">
Expand Down Expand Up @@ -109,7 +110,7 @@ const PorteurProjetActions = ({
<span>Demander un changement de représentant légal</span>
</DropdownMenuSecondaryButton.DropdownItem>
)}
{!abandonEnCours && (
{peutDemanderAbandon && (
<>
<DropdownMenuSecondaryButton.DropdownItem
href={Routes.Abandon.demander(identifiantProjet)}
Expand Down
3 changes: 0 additions & 3 deletions packages/domain/lauréat/src/abandon/abandon.aggregate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import {
applyAbandonConfirmé,
confirmer,
} from './confirmer/confirmerAbandon.behavior';
import { annulerRejet } from './annulerRejet/annulerRejetAbandon.behavior';
import {
transmettrePreuveRecandidature,
PreuveRecandidatureTransmiseEvent,
Expand Down Expand Up @@ -89,7 +88,6 @@ export type AbandonAggregate = Aggregate<AbandonEvent> & {
};
annuléLe?: DateTime.ValueType;
readonly accorder: typeof accorder;
readonly annulerRejet: typeof annulerRejet;
readonly annuler: typeof annuler;
readonly confirmer: typeof confirmer;
readonly demander: typeof demander;
Expand All @@ -114,7 +112,6 @@ export const getDefaultAbandonAggregate: GetDefaultAggregateState<
},
accorder,
annuler,
annulerRejet,
confirmer,
demander,
demanderConfirmation,
Expand Down
4 changes: 0 additions & 4 deletions packages/domain/lauréat/src/abandon/abandon.register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { registerAccorderAbandonCommand } from './accorder/accorderAbandon.comma
import { registerAccorderAbandonUseCase } from './accorder/accorderAbandon.usecase';
import { registerAnnulerAbandonCommand } from './annuler/annulerAbandon.command';
import { registerAnnulerAbandonUseCase } from './annuler/annulerAbandon.usecase';
import { registerAnnulerRejetAbandonUseCase } from './annulerRejet/annulerRejetAbandon.usecase';
import { registerConfirmerAbandonCommand } from './confirmer/confirmerAbandon.command';
import { registerConfirmerAbandonUseCase } from './confirmer/confirmerAbandon.usecase';
import {
Expand All @@ -21,7 +20,6 @@ import {
} from './lister/listerAbandons.query';
import { registerRejeterAbandonCommand } from './rejeter/rejeterAbandon.command';
import { registerRejeterAbandonUseCase } from './rejeter/rejeterAbandon.usecase';
import { registerAnnulerRejetAbandonCommand } from './annulerRejet/annulerRejetAbandon.command';
import { registerTransmettrePreuveRecandidatureAbandonCommand } from './transmettre/transmettrePreuveRecandidatureAbandon.command';
import { registerTransmettrePreuveRecandidatureAbandonUseCase } from './transmettre/transmettrePreuveRecandidatureAbandon.usecase';
import { registerDemanderPreuveRecandidatureAbandonCommand } from './demanderPreuveRecandidature/demanderPreuveRecandidatureAbandon.command';
Expand All @@ -46,7 +44,6 @@ export const registerAbandonUseCases = ({ loadAggregate }: AbandonCommandDepende
registerDemanderConfirmationAbandonCommand(loadAggregate);
registerRejeterAbandonCommand(loadAggregate);
registerAnnulerAbandonCommand(loadAggregate);
registerAnnulerRejetAbandonCommand(loadAggregate);
registerTransmettrePreuveRecandidatureAbandonCommand(loadAggregate);
registerDemanderPreuveRecandidatureAbandonCommand(loadAggregate);

Expand All @@ -56,7 +53,6 @@ export const registerAbandonUseCases = ({ loadAggregate }: AbandonCommandDepende
registerDemanderConfirmationAbandonUseCase();
registerRejeterAbandonUseCase();
registerAnnulerAbandonUseCase();
registerAnnulerRejetAbandonUseCase();
registerTransmettrePreuveRecandidatureAbandonUseCase();
registerDemanderPreuveRecandidatureAbandonUseCase();
};
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export type DemanderOptions = {
identifiantProjet: IdentifiantProjet.ValueType;
pièceJustificative: DocumentProjet.ValueType;
raison: string;
estAchevé: boolean;
};

export async function demander(
Expand All @@ -56,9 +57,13 @@ export async function demander(
identifiantProjet,
pièceJustificative,
raison,
estAchevé,
}: DemanderOptions,
) {
this.statut.vérifierQueLeChangementDeStatutEstPossibleEn(StatutAbandon.demandé);
if (estAchevé) {
throw new ProjetAchevéError(identifiantProjet);
}

if (!pièceJustificative) {
throw new PièceJustificativeObligatoireError();
Expand Down Expand Up @@ -114,3 +119,9 @@ class PièceJustificativeObligatoireError extends InvalidOperationError {
super('La pièce justificative est obligatoire');
}
}

class ProjetAchevéError extends InvalidOperationError {
constructor(public identifiantProjet: IdentifiantProjet.ValueType) {
super("Impossible de demander l'abandon d'un projet achevé");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DocumentProjet } from '@potentiel-domain/document';
import { LoadAggregate } from '@potentiel-domain/core';

import { loadAbandonFactory } from '../abandon.aggregate';
import { loadAchèvementFactory } from '../../achèvement/achèvement.aggregate';

export type DemanderAbandonCommand = Message<
'Lauréat.Abandon.Command.DemanderAbandon',
Expand All @@ -20,6 +21,8 @@ export type DemanderAbandonCommand = Message<

export const registerDemanderAbandonCommand = (loadAggregate: LoadAggregate) => {
const loadAbandon = loadAbandonFactory(loadAggregate);
const loadAchèvement = loadAchèvementFactory(loadAggregate);

const handler: MessageHandler<DemanderAbandonCommand> = async ({
identifiantProjet,
pièceJustificative,
Expand All @@ -28,13 +31,15 @@ export const registerDemanderAbandonCommand = (loadAggregate: LoadAggregate) =>
dateDemande,
}) => {
const abandon = await loadAbandon(identifiantProjet, false);
const achèvement = await loadAchèvement(identifiantProjet, false);

await abandon.demander({
identifiantProjet,
pièceJustificative,
raison,
identifiantUtilisateur,
dateDemande,
estAchevé: achèvement.estAchevé(),
});
};
mediator.register('Lauréat.Abandon.Command.DemanderAbandon', handler);
Expand Down
3 changes: 0 additions & 3 deletions packages/domain/lauréat/src/abandon/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { AccorderAbandonUseCase } from './accorder/accorderAbandon.usecase';
import { AnnulerAbandonUseCase } from './annuler/annulerAbandon.usecase';
import { AnnulerRejetAbandonUseCase } from './annulerRejet/annulerRejetAbandon.usecase';
import { ConfirmerAbandonUseCase } from './confirmer/confirmerAbandon.usecase';
import {
ConsulterAbandonQuery,
Expand Down Expand Up @@ -33,7 +32,6 @@ export type { ConsulterAbandonReadModel, ListerAbandonReadModel };
export type AbandonUseCase =
| AccorderAbandonUseCase
| AnnulerAbandonUseCase
| AnnulerRejetAbandonUseCase
| ConfirmerAbandonUseCase
| DemanderAbandonUseCase
| DemanderConfirmationAbandonUseCase
Expand All @@ -44,7 +42,6 @@ export type AbandonUseCase =
export type {
AccorderAbandonUseCase,
AnnulerAbandonUseCase,
AnnulerRejetAbandonUseCase,
ConfirmerAbandonUseCase,
DemanderAbandonUseCase,
DemanderConfirmationAbandonUseCase,
Expand Down
9 changes: 0 additions & 9 deletions packages/domain/utilisateur/src/role.valueType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ const référencielPermissions = {
transmettrePreuveRecandidature:
'Lauréat.Abandon.UseCase.TransmettrePreuveRecandidatureAbandon',
accorder: 'Lauréat.Abandon.UseCase.AccorderAbandon',
annulerRejet: 'Lauréat.Abandon.UseCase.AnnulerRejetAbandon',
demanderConfirmation: 'Lauréat.Abandon.UseCase.DemanderConfirmationAbandon',
rejeter: 'Lauréat.Abandon.UseCase.RejeterAbandon',
},
Expand All @@ -111,7 +110,6 @@ const référencielPermissions = {
transmettrePreuveRecandidature:
'Lauréat.Abandon.Command.TransmettrePreuveRecandidatureAbandon',
accorder: 'Lauréat.Abandon.Command.AccorderAbandon',
annulerRejet: 'Lauréat.Abandon.Command.AnnulerRejetAbandon',
demanderConfirmation: 'Lauréat.Abandon.Command.DemanderConfirmationAbandon',
rejeter: 'Lauréat.Abandon.Command.RejeterAbandon',
},
Expand Down Expand Up @@ -510,12 +508,6 @@ const policies = {
référencielPermissions.lauréat.abandon.command.accorder,
],
},
'annuler-rejet': [
référencielPermissions.candidature.query.consulterProjet,
référencielPermissions.lauréat.abandon.query.consulter,
référencielPermissions.lauréat.abandon.usecase.annulerRejet,
référencielPermissions.lauréat.abandon.command.annulerRejet,
],
},
recours: {
consulter: {
Expand Down Expand Up @@ -1010,7 +1002,6 @@ const adminPolicies: ReadonlyArray<Policy> = [
'abandon.accorder',
'abandon.rejeter',
'abandon.demander-confirmation',
'abandon.annuler-rejet',

// Recours
'recours.consulter.liste',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { DemanderAbandonFixture } from './fixtures/demanderAbandon.fixture';
import { DemanderConfirmationAbandonFixture } from './fixtures/demanderConfirmationAbandon.fixture';
import { TransmettrePreuveRecandidatureAbandonFixture } from './fixtures/transmettrePreuveRecandidatureAbandon.fixture';
import { RejetAbandonFixture } from './fixtures/rejeterAbandonFixture';
import { AnnulerRejetAbandonFixture } from './fixtures/annulerRejetAbandon.fixture';
import { DemanderPreuveRecandidatureAbandonFixture } from './fixtures/demanderPreuveRecandidature.fixture';

export class AbandonWord {
Expand All @@ -25,12 +24,6 @@ export class AbandonWord {
return this.#annulerAbandonFixture;
}

#annulerRejetAbandonFixture: AnnulerRejetAbandonFixture;

get annulerRejetAbandonFixture() {
return this.#annulerRejetAbandonFixture;
}

#confirmerAbandonFixture: ConfirmerAbandonFixture;

get confirmerAbandonFixture() {
Expand Down Expand Up @@ -70,7 +63,6 @@ export class AbandonWord {
constructor() {
this.#accorderAbandonFixture = new AccorderAbandonFixture();
this.#annulerAbandonFixture = new AnnulerAbandonFixture();
this.#annulerRejetAbandonFixture = new AnnulerRejetAbandonFixture();
this.#confirmerAbandonFixture = new ConfirmerAbandonFixture();
this.#demanderAbandonFixture = new DemanderAbandonFixture();
this.#demanderConfirmationAbandonFixture = new DemanderConfirmationAbandonFixture();
Expand All @@ -83,7 +75,6 @@ export class AbandonWord {
reinitialiserEnDemande() {
this.#accorderAbandonFixture = new AccorderAbandonFixture();
this.#annulerAbandonFixture = new AnnulerAbandonFixture();
this.#annulerRejetAbandonFixture = new AnnulerRejetAbandonFixture();
this.#confirmerAbandonFixture = new ConfirmerAbandonFixture();
this.#demanderConfirmationAbandonFixture = new DemanderConfirmationAbandonFixture();
this.#demanderPreuveCandidatureAbandonFixture = new DemanderPreuveRecandidatureAbandonFixture();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Fonctionnalité: Demander l'abandon d'un projet lauréat
Quand le porteur demande l'abandon pour le projet lauréat
Alors le porteur devrait être informé que "L'abandon a déjà été accordé"

@NotImplemented
Scénario: Impossible de demander l'abandon d'un projet si celui-ci est achevé (car l'attestation de conformité et la preuve de transmission au co-contractant ont été transmise)

Scénario: Impossible de demander l'abandon d'un projet achevé
Etant donné une attestation de conformité transmise pour le projet lauréat
Quand le porteur demande l'abandon pour le projet lauréat
Alors le porteur devrait être informé que "Impossible de demander l'abandon d'un projet achevé"
Loading