Skip to content

Commit 382efd6

Browse files
arthurlbrjcMzem
authored andcommitted
feat: ajoute engagement offre postulée (#1698)
1 parent db76f21 commit 382efd6

14 files changed

+386
-160
lines changed

src/application/commands/add-candidature-offre-emploi.command.handler.ts

+30-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Inject, Injectable } from '@nestjs/common'
2+
import { Evenement, EvenementService } from 'src/domain/evenement'
23
import { DateService } from 'src/utils/date-service'
34
import { Command } from '../../building-blocks/types/command'
45
import { CommandHandler } from '../../building-blocks/types/command-handler'
@@ -21,32 +22,41 @@ export interface AddCandidatureOffreEmploiCommand extends Command {
2122
@Injectable()
2223
export class AddCandidatureOffreEmploiCommandHandler extends CommandHandler<
2324
AddCandidatureOffreEmploiCommand,
24-
void
25+
void,
26+
Offre.Favori<Offre.Favori.Emploi> | undefined
2527
> {
2628
constructor(
2729
@Inject(FavorisOffresEmploiRepositoryToken)
28-
private offresEmploiRepository: Offre.Favori.Emploi.Repository,
29-
private jeuneAuthorizer: JeuneAuthorizer,
30-
private readonly dateService: DateService
30+
private readonly offresEmploiRepository: Offre.Favori.Emploi.Repository,
31+
private readonly jeuneAuthorizer: JeuneAuthorizer,
32+
private readonly dateService: DateService,
33+
private readonly evenementService: EvenementService
3134
) {
3235
super('AddCandidatureOffreEmploiCommandHandler')
3336
}
3437

35-
async handle(command: AddCandidatureOffreEmploiCommand): Promise<Result> {
36-
const favori = await this.offresEmploiRepository.get(
38+
async getAggregate(
39+
command: AddCandidatureOffreEmploiCommand
40+
): Promise<Offre.Favori<Offre.Favori.Emploi> | undefined> {
41+
return this.offresEmploiRepository.get(
3742
command.idBeneficiaire,
3843
command.idOffre
3944
)
45+
}
46+
47+
async handle(
48+
command: AddCandidatureOffreEmploiCommand,
49+
_utilisateur: Authentification.Utilisateur,
50+
favori: Offre.Favori<Offre.Favori.Emploi> | undefined
51+
): Promise<Result> {
4052
if (!favori) {
4153
return failure(
4254
new NonTrouveError('Favori', 'pour l’offre d’emploi ' + command.idOffre)
4355
)
4456
}
4557

46-
const favoriAvecCandidature = Offre.Favori.postuler(
47-
favori,
48-
this.dateService.now()
49-
)
58+
const dateCandidature = this.dateService.now()
59+
const favoriAvecCandidature = Offre.Favori.postuler(favori, dateCandidature)
5060

5161
await this.offresEmploiRepository.save(favoriAvecCandidature)
5262
return emptySuccess()
@@ -62,7 +72,15 @@ export class AddCandidatureOffreEmploiCommandHandler extends CommandHandler<
6272
)
6373
}
6474

65-
async monitor(): Promise<void> {
66-
// TODO ?
75+
async monitor(
76+
utilisateur: Authentification.Utilisateur,
77+
_command: AddCandidatureOffreEmploiCommand,
78+
favori: Offre.Favori<Offre.Favori.Emploi>
79+
): Promise<void> {
80+
const codeEvenement = favori.offre.alternance
81+
? Evenement.Code.OFFRE_ALTERNANCE_CANDIDATURE_CONFIRMEE
82+
: Evenement.Code.OFFRE_EMPLOI_CANDIDATURE_CONFIRMEE
83+
84+
await this.evenementService.creer(codeEvenement, utilisateur)
6785
}
6886
}

src/application/commands/add-candidature-offre-immersion.command.handler.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Inject, Injectable } from '@nestjs/common'
2+
import { Evenement, EvenementService } from 'src/domain/evenement'
23
import { DateService } from 'src/utils/date-service'
34
import { Command } from '../../building-blocks/types/command'
45
import { CommandHandler } from '../../building-blocks/types/command-handler'
@@ -25,9 +26,10 @@ export class AddCandidatureOffreImmersionCommandHandler extends CommandHandler<
2526
> {
2627
constructor(
2728
@Inject(FavorisOffresImmersionRepositoryToken)
28-
private offresImmersionRepository: Offre.Favori.Immersion.Repository,
29-
private jeuneAuthorizer: JeuneAuthorizer,
30-
private readonly dateService: DateService
29+
private readonly offresImmersionRepository: Offre.Favori.Immersion.Repository,
30+
private readonly jeuneAuthorizer: JeuneAuthorizer,
31+
private readonly dateService: DateService,
32+
private readonly evenementService: EvenementService
3133
) {
3234
super('AddCandidatureOffreImmersionCommandHandler')
3335
}
@@ -65,7 +67,10 @@ export class AddCandidatureOffreImmersionCommandHandler extends CommandHandler<
6567
)
6668
}
6769

68-
async monitor(): Promise<void> {
69-
// TODO ?
70+
async monitor(utilisateur: Authentification.Utilisateur): Promise<void> {
71+
await this.evenementService.creer(
72+
Evenement.Code.OFFRE_IMMERSION_CANDIDATURE_CONFIRMEE,
73+
utilisateur
74+
)
7075
}
7176
}

src/application/commands/add-candidature-offre-service-civique.command.handler.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Inject, Injectable } from '@nestjs/common'
2+
import { Evenement, EvenementService } from 'src/domain/evenement'
23
import { DateService } from 'src/utils/date-service'
34
import { Command } from '../../building-blocks/types/command'
45
import { CommandHandler } from '../../building-blocks/types/command-handler'
@@ -25,9 +26,10 @@ export class AddCandidatureOffreServiceCiviqueCommandHandler extends CommandHand
2526
> {
2627
constructor(
2728
@Inject(FavorisOffresServiceCiviqueRepositoryToken)
28-
private offresServiceCiviqueRepository: Offre.Favori.ServiceCivique.Repository,
29-
private jeuneAuthorizer: JeuneAuthorizer,
30-
private readonly dateService: DateService
29+
private readonly offresServiceCiviqueRepository: Offre.Favori.ServiceCivique.Repository,
30+
private readonly jeuneAuthorizer: JeuneAuthorizer,
31+
private readonly dateService: DateService,
32+
private readonly evenementService: EvenementService
3133
) {
3234
super('AddCandidatureOffreServiceCiviqueCommandHandler')
3335
}
@@ -67,7 +69,10 @@ export class AddCandidatureOffreServiceCiviqueCommandHandler extends CommandHand
6769
)
6870
}
6971

70-
async monitor(): Promise<void> {
71-
// TODO ?
72+
async monitor(utilisateur: Authentification.Utilisateur): Promise<void> {
73+
await this.evenementService.creer(
74+
Evenement.Code.OFFRE_SERVICE_CIVIQUE_CANDIDATURE_CONFIRMEE,
75+
utilisateur
76+
)
7277
}
7378
}

src/application/commands/add-favori-offre-emploi.command.handler.ts

+16-6
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,22 @@ export class AddFavoriOffreEmploiCommandHandler extends CommandHandler<
6767

6868
async monitor(
6969
utilisateur: Authentification.Utilisateur,
70-
command: AddFavoriOffreEmploiCommand
70+
{ offreEmploi: { alternance }, aPostule }: AddFavoriOffreEmploiCommand
7171
): Promise<void> {
72-
const evenementType =
73-
command.offreEmploi.alternance === true
74-
? Evenement.Code.OFFRE_ALTERNANCE_SAUVEGARDEE
75-
: Evenement.Code.OFFRE_EMPLOI_SAUVEGARDEE
76-
await this.evenementService.creer(evenementType, utilisateur)
72+
const codeEvenement = ((): Evenement.Code => {
73+
switch (alternance) {
74+
case true:
75+
return aPostule
76+
? Evenement.Code.OFFRE_ALTERNANCE_CANDIDATURE_CONFIRMEE
77+
: Evenement.Code.OFFRE_ALTERNANCE_SAUVEGARDEE
78+
case false:
79+
default:
80+
return aPostule
81+
? Evenement.Code.OFFRE_EMPLOI_CANDIDATURE_CONFIRMEE
82+
: Evenement.Code.OFFRE_EMPLOI_SAUVEGARDEE
83+
}
84+
})()
85+
86+
await this.evenementService.creer(codeEvenement, utilisateur)
7787
}
7888
}

src/application/commands/add-favori-offre-immersion.command.handler.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,14 @@ export class AddFavoriOffreImmersionCommandHandler extends CommandHandler<
6565
return this.jeuneAuthorizer.autoriserLeJeune(command.idJeune, utilisateur)
6666
}
6767

68-
async monitor(utilisateur: Authentification.Utilisateur): Promise<void> {
69-
await this.evenementService.creer(
70-
Evenement.Code.OFFRE_IMMERSION_SAUVEGARDEE,
71-
utilisateur
72-
)
68+
async monitor(
69+
utilisateur: Authentification.Utilisateur,
70+
{ aPostule }: AddFavoriOffreImmersionCommand
71+
): Promise<void> {
72+
const codeEvenement = aPostule
73+
? Evenement.Code.OFFRE_IMMERSION_CANDIDATURE_CONFIRMEE
74+
: Evenement.Code.OFFRE_IMMERSION_SAUVEGARDEE
75+
76+
await this.evenementService.creer(codeEvenement, utilisateur)
7377
}
7478
}

src/application/commands/add-favori-offre-service-civique.command.handler.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,14 @@ export class AddFavoriOffreServiceCiviqueCommandHandler extends CommandHandler<
6565
return this.jeuneAuthorizer.autoriserLeJeune(command.idJeune, utilisateur)
6666
}
6767

68-
async monitor(utilisateur: Authentification.Utilisateur): Promise<void> {
69-
await this.evenementService.creer(
70-
Evenement.Code.OFFRE_SERVICE_CIVIQUE_SAUVEGARDEE,
71-
utilisateur
72-
)
68+
async monitor(
69+
utilisateur: Authentification.Utilisateur,
70+
{ aPostule }: AddFavoriServiceCiviqueCommand
71+
): Promise<void> {
72+
const codeEvenement = aPostule
73+
? Evenement.Code.OFFRE_SERVICE_CIVIQUE_CANDIDATURE_CONFIRMEE
74+
: Evenement.Code.OFFRE_SERVICE_CIVIQUE_SAUVEGARDEE
75+
76+
await this.evenementService.creer(codeEvenement, utilisateur)
7377
}
7478
}

src/building-blocks/types/command-handler.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
* @see https://martinfowler.com/bliki/CommandQuerySeparation.html
2020
* @see https://udidahan.com/2009/12/09/clarified-cqrs/
2121
*/
22-
export abstract class CommandHandler<C, R, A = void> {
22+
export abstract class CommandHandler<Command, Data, Aggregat = void> {
2323
protected logger: Logger
2424
protected apmService: APM.Agent
2525
private commandName: string
@@ -31,9 +31,9 @@ export abstract class CommandHandler<C, R, A = void> {
3131
}
3232

3333
async execute(
34-
command?: C,
34+
command?: Command,
3535
utilisateur?: Authentification.Utilisateur
36-
): Promise<Result<R>> {
36+
): Promise<Result<Data>> {
3737
try {
3838
const aggregate = await this.getAggregate(command, utilisateur)
3939

@@ -65,33 +65,33 @@ export abstract class CommandHandler<C, R, A = void> {
6565

6666
// FIXME return Result
6767
async getAggregate(
68-
_command?: C,
68+
_command?: Command,
6969
_utilisateur?: Authentification.Utilisateur
70-
): Promise<A | undefined> {
70+
): Promise<Aggregat | undefined> {
7171
return undefined
7272
}
7373

7474
abstract authorize(
75-
command?: C,
75+
command?: Command,
7676
utilisateur?: Authentification.Utilisateur,
77-
aggregate?: A
77+
aggregate?: Aggregat
7878
): Promise<Result>
7979

8080
abstract handle(
81-
command?: C,
81+
command?: Command,
8282
utilisateur?: Authentification.Utilisateur,
83-
aggregate?: A
84-
): Promise<Result<R>>
83+
aggregate?: Aggregat
84+
): Promise<Result<Data>>
8585

8686
abstract monitor(
8787
utilisateur?: Authentification.Utilisateur,
88-
command?: C,
89-
aggregate?: A
88+
command?: Command,
89+
aggregate?: Aggregat
9090
): Promise<void>
9191

9292
protected logAfter(
93-
result: Result<R>,
94-
command?: C,
93+
result: Result<Data>,
94+
command?: Command,
9595
utilisateur?: Authentification.Utilisateur
9696
): void {
9797
const resultPourLog = construireResultPourLog(result)

src/domain/evenement.ts

+24
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,13 @@ export namespace Evenement {
8282
OFFRE_ALTERNANCE_AFFICHEE = 'OFFRE_ALTERNANCE_AFFICHEE',
8383
OFFRE_ALTERNANCE_PARTAGEE = 'OFFRE_ALTERNANCE_PARTAGEE',
8484
OFFRE_ALTERNANCE_POSTULEE = 'OFFRE_ALTERNANCE_POSTULEE',
85+
OFFRE_ALTERNANCE_CANDIDATURE_CONFIRMEE = 'OFFRE_ALTERNANCE_CANDIDATURE_CONFIRMEE',
8586
OFFRE_ALTERNANCE_RECHERCHEE = 'OFFRE_ALTERNANCE_RECHERCHEE',
8687
OFFRE_ALTERNANCE_SAUVEGARDEE = 'OFFRE_ALTERNANCE_SAUVEGARDEE',
8788
OFFRE_EMPLOI_AFFICHEE = 'OFFRE_EMPLOI_AFFICHEE',
8889
OFFRE_EMPLOI_PARTAGEE = 'OFFRE_EMPLOI_PARTAGEE',
8990
OFFRE_EMPLOI_POSTULEE = 'OFFRE_EMPLOI_POSTULEE',
91+
OFFRE_EMPLOI_CANDIDATURE_CONFIRMEE = 'OFFRE_EMPLOI_CANDIDATURE_CONFIRMEE',
9092
OFFRE_EMPLOI_RECHERCHEE = 'OFFRE_EMPLOI_RECHERCHEE',
9193
OFFRE_EMPLOI_SAUVEGARDEE = 'OFFRE_EMPLOI_SAUVEGARDEE',
9294
OFFRE_IMMERSION_AFFICHEE = 'OFFRE_IMMERSION_AFFICHEE',
@@ -97,13 +99,15 @@ export namespace Evenement {
9799
OFFRE_IMMERSION_LOCALISATION = 'OFFRE_IMMERSION_LOCALISATION',
98100
OFFRE_IMMERSION_RECHERCHEE = 'OFFRE_IMMERSION_RECHERCHEE',
99101
OFFRE_IMMERSION_SAUVEGARDEE = 'OFFRE_IMMERSION_SAUVEGARDEE',
102+
OFFRE_IMMERSION_CANDIDATURE_CONFIRMEE = 'OFFRE_IMMERSION_CANDIDATURE_CONFIRMEE',
100103
OFFRE_IMMERSION_CONTACT_AFFICHEE = 'OFFRE_IMMERSION_CONTACT_AFFICHEE',
101104
OFFRE_PARTAGEE = 'OFFRE_PARTAGEE',
102105
OFFRE_POSTULEE = 'OFFRE_POSTULEE',
103106
OFFRE_SERVICE_CIVIQUE_AFFICHE = 'OFFRE_SERVICE_CIVIQUE_AFFICHE',
104107
OFFRE_SERVICE_CIVIQUE_AFFICHEE = 'OFFRE_SERVICE_CIVIQUE_AFFICHEE',
105108
OFFRE_SERVICE_CIVIQUE_PARTAGEE = 'OFFRE_SERVICE_CIVIQUE_PARTAGEE',
106109
OFFRE_SERVICE_CIVIQUE_POSTULEE = 'OFFRE_SERVICE_CIVIQUE_POSTULEE',
110+
OFFRE_SERVICE_CIVIQUE_CANDIDATURE_CONFIRMEE = 'OFFRE_SERVICE_CIVIQUE_CANDIDATURE_CONFIRMEE',
107111
OFFRE_SERVICE_CIVIQUE_SAUVEGARDEE = 'OFFRE_SERVICE_CIVIQUE_SAUVEGARDEE',
108112
OFFRE_SERVICE_CIVIQUE_RECHERCHEE = 'OFFRE_SERVICE_CIVIQUE_RECHERCHEE',
109113
PIECE_JOINTE_CONSEILLER_TELECHARGEE = 'PIECE_JOINTE_CONSEILLER_TELECHARGEE',
@@ -385,6 +389,11 @@ const evenements: {
385389
action: 'Postuler',
386390
nom: 'Emploi'
387391
},
392+
[Evenement.Code.OFFRE_EMPLOI_CANDIDATURE_CONFIRMEE]: {
393+
categorie: 'Offre',
394+
action: 'Candidature confirmée',
395+
nom: 'Emploi'
396+
},
388397
[Evenement.Code.OFFRE_EMPLOI_PARTAGEE]: {
389398
categorie: 'Offre',
390399
action: 'Partage',
@@ -410,6 +419,11 @@ const evenements: {
410419
action: 'Favori',
411420
nom: 'Immersion'
412421
},
422+
[Evenement.Code.OFFRE_IMMERSION_CANDIDATURE_CONFIRMEE]: {
423+
categorie: 'Offre',
424+
action: 'Candidature confirmée',
425+
nom: 'Immersion'
426+
},
413427
[Evenement.Code.OFFRE_IMMERSION_APPEL]: {
414428
categorie: 'Offre',
415429
action: 'Appel',
@@ -455,6 +469,11 @@ const evenements: {
455469
action: 'Postuler',
456470
nom: 'Alternance'
457471
},
472+
[Evenement.Code.OFFRE_ALTERNANCE_CANDIDATURE_CONFIRMEE]: {
473+
categorie: 'Offre',
474+
action: 'Candidature confirmée',
475+
nom: 'Alternance'
476+
},
458477
[Evenement.Code.OFFRE_ALTERNANCE_PARTAGEE]: {
459478
categorie: 'Offre',
460479
action: 'Partage',
@@ -584,6 +603,11 @@ const evenements: {
584603
action: 'Postuler',
585604
nom: 'Service Civique'
586605
},
606+
[Evenement.Code.OFFRE_SERVICE_CIVIQUE_CANDIDATURE_CONFIRMEE]: {
607+
categorie: 'Offre',
608+
action: 'Candidature confirmée',
609+
nom: 'Service Civique'
610+
},
587611
[Evenement.Code.OFFRE_SERVICE_CIVIQUE_PARTAGEE]: {
588612
categorie: 'Offre',
589613
action: 'Partage',

0 commit comments

Comments
 (0)