Skip to content

Commit 4129fb2

Browse files
committed
[OS-1729] Checklist > extract the personal data checklist status from the admission to the candidate
1 parent 73ef30c commit 4129fb2

File tree

73 files changed

+1027
-1028
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1027
-1028
lines changed

api/serializers/person.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# The core business involves the administration of students, teachers,
77
# courses, programs and so on.
88
#
9-
# Copyright (C) 2015-2023 Université catholique de Louvain (http://www.uclouvain.be)
9+
# Copyright (C) 2015-2026 Université catholique de Louvain (http://www.uclouvain.be)
1010
#
1111
# This program is free software: you can redistribute it and/or modify
1212
# it under the terms of the GNU General Public License as published by
@@ -101,5 +101,7 @@ def validate(self, data):
101101

102102

103103
class IdentificationDTOSerializer(DTOSerializer):
104+
statut_validation_donnees_personnelles = None
105+
104106
class Meta:
105107
source = IdentificationDTO

auth/predicates/common.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from admission.constants import CONTEXT_CONTINUING, CONTEXT_DOCTORATE, CONTEXT_GENERAL
3939
from admission.models import DoctorateAdmission, GeneralEducationAdmission
4040
from admission.models.base import BaseAdmission
41+
from base.models.enums.personal_data import ChoixStatutValidationDonneesPersonnelles
4142
from osis_role.errors import predicate_failed_msg
4243

4344

@@ -231,7 +232,7 @@ def past_experiences_checklist_tab_is_not_sufficient(
231232
message=_("The \"Personal data\" checklist tab must be in the \"Cleaned\" status in order to do this action.")
232233
)
233234
def personal_data_checklist_status_is_cleaned(self, user: User, obj: BaseAdmission):
234-
return obj.checklist.get('current', {}).get('donnees_personnelles', {}).get('statut') == 'GEST_EN_COURS'
235+
return obj.candidate.personal_data_validation_status == ChoixStatutValidationDonneesPersonnelles.TOILETTEES.name
235236

236237

237238
@predicate(bind=True)
@@ -241,12 +242,12 @@ def personal_data_checklist_status_is_cleaned(self, user: User, obj: BaseAdmissi
241242
)
242243
)
243244
def personal_data_checklist_status_is_to_be_processed(self, user: User, obj: BaseAdmission):
244-
return obj.checklist.get('current', {}).get('donnees_personnelles', {}).get('statut') == 'INITIAL_CANDIDAT'
245+
return obj.candidate.personal_data_validation_status == ChoixStatutValidationDonneesPersonnelles.A_TRAITER.name
245246

246247

247248
@predicate(bind=True)
248249
@predicate_failed_msg(
249250
message=_("The \"Personal data\" checklist tab must not be in the \"Validated\" status in order to do this action.")
250251
)
251252
def personal_data_checklist_status_is_not_validated(self, user: User, obj: BaseAdmission):
252-
return obj.checklist.get('current', {}).get('donnees_personnelles', {}).get('statut') != 'GEST_REUSSITE'
253+
return obj.candidate.personal_data_validation_status != ChoixStatutValidationDonneesPersonnelles.VALIDEES.name

ddd/admission/doctorat/preparation/domain/model/proposition.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# The core business involves the administration of students, teachers,
77
# courses, programs and so on.
88
#
9-
# Copyright (C) 2015-2025 Université catholique de Louvain (http://www.uclouvain.be)
9+
# Copyright (C) 2015-2026 Université catholique de Louvain (http://www.uclouvain.be)
1010
#
1111
# This program is free software: you can redistribute it and/or modify
1212
# it under the terms of the GNU General Public License as published by
@@ -111,11 +111,6 @@
111111
from admission.ddd.admission.shared_kernel.domain.model.complement_formation import (
112112
ComplementFormationIdentity,
113113
)
114-
from admission.ddd.admission.shared_kernel.domain.model.enums.equivalence import (
115-
EtatEquivalenceTitreAcces,
116-
StatutEquivalenceTitreAcces,
117-
TypeEquivalenceTitreAcces,
118-
)
119114
from admission.ddd.admission.shared_kernel.domain.model.enums.type_gestionnaire import (
120115
TypeGestionnaire,
121116
)
@@ -143,6 +138,7 @@
143138
from admission.ddd.admission.shared_kernel.domain.validator.exceptions import (
144139
ExperienceNonTrouveeException,
145140
)
141+
from admission.ddd.admission.shared_kernel.dtos import IdentificationDTO
146142
from admission.ddd.admission.shared_kernel.dtos.emplacement_document import (
147143
EmplacementDocumentDTO,
148144
)
@@ -1026,13 +1022,15 @@ def approuver_par_sic(
10261022
experience_parcours_interne_translator: IExperienceParcoursInterneTranslator,
10271023
grade_academique_formation_proposition: str,
10281024
annee_formation: AcademicYear,
1025+
identification_dto: IdentificationDTO,
10291026
):
10301027
if self.type_demande == TypeDemande.INSCRIPTION:
10311028
ApprouverInscriptionParSicValidatorList(
10321029
statut=self.statut,
10331030
checklist=self.checklist_actuelle,
10341031
besoin_de_derogation=self.besoin_de_derogation,
10351032
documents_dto=documents_dto,
1033+
statut_validation_donnees_personnelles=identification_dto.statut_validation_donnees_personnelles,
10361034
).validate()
10371035

10381036
else:
@@ -1042,6 +1040,7 @@ def approuver_par_sic(
10421040
complements_formation=self.complements_formation,
10431041
checklist=self.checklist_actuelle,
10441042
documents_dto=documents_dto,
1043+
statut_validation_donnees_personnelles=identification_dto.statut_validation_donnees_personnelles,
10451044
).validate()
10461045

10471046
try:

ddd/admission/doctorat/preparation/domain/model/statut_checklist.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from admission.ddd.admission.shared_kernel.domain.model.enums.authentification import (
4141
EtatAuthentificationParcours,
4242
)
43+
from base.models.enums.personal_data import ChoixStatutValidationDonneesPersonnelles
4344
from osis_common.ddd import interface
4445

4546

@@ -71,7 +72,6 @@ def _serialize(cls, inst, field, value):
7172

7273
@attr.dataclass
7374
class StatutsChecklistDoctorale:
74-
donnees_personnelles: StatutChecklist
7575
assimilation: StatutChecklist
7676
parcours_anterieur: StatutChecklist
7777
financabilite: StatutChecklist
@@ -140,6 +140,12 @@ def merge_statuses(self, other_status):
140140
identifiant_parent=self.identifiant_parent,
141141
)
142142

143+
def to_dict(self):
144+
return {
145+
'extra': self.extra,
146+
'statut': self.statut.name,
147+
}
148+
143149

144150
@attr.dataclass
145151
class ConfigurationOngletChecklist(interface.ValueObject):
@@ -156,30 +162,30 @@ def get_status(self, status: str, extra: Optional[Dict[str, any]] = None) -> Opt
156162
identifiant=OngletsChecklist.donnees_personnelles,
157163
statuts=[
158164
ConfigurationStatutChecklist(
159-
identifiant='A_TRAITER',
160-
libelle=_('To be processed'),
165+
identifiant=ChoixStatutValidationDonneesPersonnelles.A_TRAITER.name,
166+
libelle=ChoixStatutValidationDonneesPersonnelles.A_TRAITER.value,
161167
statut=ChoixStatutChecklist.INITIAL_CANDIDAT,
162168
),
163169
ConfigurationStatutChecklist(
164-
identifiant='TOILETTEES',
165-
libelle=pgettext_lazy('plural', 'Cleaned'),
170+
identifiant=ChoixStatutValidationDonneesPersonnelles.TOILETTEES.name,
171+
libelle=ChoixStatutValidationDonneesPersonnelles.TOILETTEES.value,
166172
statut=ChoixStatutChecklist.GEST_EN_COURS,
167173
),
168174
ConfigurationStatutChecklist(
169-
identifiant='A_COMPLETER',
170-
libelle=_('To be completed'),
175+
identifiant=ChoixStatutValidationDonneesPersonnelles.A_COMPLETER.name,
176+
libelle=ChoixStatutValidationDonneesPersonnelles.A_COMPLETER.value,
171177
statut=ChoixStatutChecklist.GEST_BLOCAGE,
172178
extra={'fraud': '0'},
173179
),
174180
ConfigurationStatutChecklist(
175-
identifiant='FRAUDEUR',
176-
libelle=_('Fraudster'),
181+
identifiant=ChoixStatutValidationDonneesPersonnelles.FRAUDEUR.name,
182+
libelle=ChoixStatutValidationDonneesPersonnelles.FRAUDEUR.value,
177183
statut=ChoixStatutChecklist.GEST_BLOCAGE,
178184
extra={'fraud': '1'},
179185
),
180186
ConfigurationStatutChecklist(
181-
identifiant='VALIDEES',
182-
libelle=pgettext_lazy('plural', 'Validated'),
187+
identifiant=ChoixStatutValidationDonneesPersonnelles.VALIDEES.name,
188+
libelle=ChoixStatutValidationDonneesPersonnelles.VALIDEES.value,
183189
statut=ChoixStatutChecklist.GEST_REUSSITE,
184190
),
185191
],

ddd/admission/doctorat/preparation/domain/service/checklist.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# The core business involves the administration of students, teachers,
77
# courses, programs and so on.
88
#
9-
# Copyright (C) 2015-2024 Université catholique de Louvain (http://www.uclouvain.be)
9+
# Copyright (C) 2015-2026 Université catholique de Louvain (http://www.uclouvain.be)
1010
#
1111
# This program is free software: you can redistribute it and/or modify
1212
# it under the terms of the GNU General Public License as published by
@@ -32,8 +32,8 @@
3232
from admission.ddd.admission.doctorat.preparation.domain.model.enums.checklist import ChoixStatutChecklist
3333
from admission.ddd.admission.doctorat.preparation.domain.model.proposition import Proposition
3434
from admission.ddd.admission.doctorat.preparation.domain.model.statut_checklist import (
35-
StatutsChecklistDoctorale,
3635
StatutChecklist,
36+
StatutsChecklistDoctorale,
3737
)
3838
from admission.ddd.admission.shared_kernel.domain.model.enums.authentification import EtatAuthentificationParcours
3939
from admission.ddd.admission.shared_kernel.domain.service.i_profil_candidat import IProfilCandidatTranslator
@@ -73,10 +73,6 @@ def recuperer_checklist_initiale(
7373
)
7474

7575
return StatutsChecklistDoctorale(
76-
donnees_personnelles=StatutChecklist(
77-
libelle=_("To be processed"),
78-
statut=ChoixStatutChecklist.INITIAL_CANDIDAT,
79-
),
8076
assimilation=StatutChecklist(
8177
libelle=_("Not concerned")
8278
if identification_dto.pays_nationalite_europeen

ddd/admission/doctorat/preparation/domain/validator/_should_informations_checklist_etre_completees.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# The core business involves the administration of students, teachers,
77
# courses, programs and so on.
88
#
9-
# Copyright (C) 2015-2025 Université catholique de Louvain (http://www.uclouvain.be)
9+
# Copyright (C) 2015-2026 Université catholique de Louvain (http://www.uclouvain.be)
1010
#
1111
# This program is free software: you can redistribute it and/or modify
1212
# it under the terms of the GNU General Public License as published by
@@ -82,6 +82,7 @@
8282
)
8383
from admission.ddd.admission.shared_kernel.enums.type_demande import TypeDemande
8484
from base.ddd.utils.business_validator import BusinessValidator
85+
from base.models.enums.personal_data import ChoixStatutValidationDonneesPersonnelles
8586
from epc.models.enums.condition_acces import ConditionAcces
8687

8788

@@ -309,10 +310,10 @@ def validate(self, *args, **kwargs):
309310

310311
@attr.dataclass(frozen=True, slots=True)
311312
class ShouldDonneesPersonnellesEtreDansEtatCorrectPourApprouverDemande(BusinessValidator):
312-
checklist_actuelle: StatutsChecklistDoctorale
313+
statut_validation_donnees_personnelles: str
313314

314315
def validate(self, *args, **kwargs):
315-
if self.checklist_actuelle.donnees_personnelles.statut != ChoixStatutChecklist.GEST_REUSSITE:
316+
if self.statut_validation_donnees_personnelles != ChoixStatutValidationDonneesPersonnelles.VALIDEES.name:
316317
raise EtatChecklistDonneesPersonnellesNonValidePourApprouverDemande
317318

318319

ddd/admission/doctorat/preparation/domain/validator/validator_by_business_action.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# The core business involves the administration of students, teachers,
77
# courses, programs and so on.
88
#
9-
# Copyright (C) 2015-2025 Université catholique de Louvain (http://www.uclouvain.be)
9+
# Copyright (C) 2015-2026 Université catholique de Louvain (http://www.uclouvain.be)
1010
#
1111
# This program is free software: you can redistribute it and/or modify
1212
# it under the terms of the GNU General Public License as published by
@@ -731,6 +731,8 @@ class ApprouverAdmissionParSicValidatorList(TwoStepsMultipleBusinessExceptionLis
731731
checklist: StatutsChecklistDoctorale
732732
documents_dto: List[EmplacementDocumentDTO]
733733

734+
statut_validation_donnees_personnelles: str
735+
734736
def get_data_contract_validators(self) -> List[BusinessValidator]:
735737
return []
736738

@@ -740,7 +742,7 @@ def get_invariants_validators(self) -> List[BusinessValidator]:
740742
statut=self.statut,
741743
),
742744
ShouldDonneesPersonnellesEtreDansEtatCorrectPourApprouverDemande(
743-
checklist_actuelle=self.checklist,
745+
statut_validation_donnees_personnelles=self.statut_validation_donnees_personnelles,
744746
),
745747
ShouldDecisionCddEtreDansEtatCorrectPourApprouverDemande(
746748
checklist_actuelle=self.checklist,
@@ -766,6 +768,8 @@ class ApprouverInscriptionParSicValidatorList(TwoStepsMultipleBusinessExceptionL
766768

767769
documents_dto: List[EmplacementDocumentDTO]
768770

771+
statut_validation_donnees_personnelles: str
772+
769773
def get_data_contract_validators(self) -> List[BusinessValidator]:
770774
return []
771775

@@ -775,7 +779,7 @@ def get_invariants_validators(self) -> List[BusinessValidator]:
775779
statut=self.statut,
776780
),
777781
ShouldDonneesPersonnellesEtreDansEtatCorrectPourApprouverDemande(
778-
checklist_actuelle=self.checklist,
782+
statut_validation_donnees_personnelles=self.statut_validation_donnees_personnelles,
779783
),
780784
ShouldDecisionCddEtreDansEtatCorrectPourApprouverDemande(
781785
checklist_actuelle=self.checklist,

ddd/admission/doctorat/preparation/test/factory/proposition.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# The core business involves the administration of students, teachers,
77
# courses, programs and so on.
88
#
9-
# Copyright (C) 2015-2025 Université catholique de Louvain (http://www.uclouvain.be)
9+
# Copyright (C) 2015-2026 Université catholique de Louvain (http://www.uclouvain.be)
1010
#
1111
# This program is free software: you can redistribute it and/or modify
1212
# it under the terms of the GNU General Public License as published by
@@ -213,7 +213,6 @@ class Meta:
213213
model = StatutsChecklistDoctorale
214214
abstract = False
215215

216-
donnees_personnelles = factory.SubFactory(StatutChecklistFactory)
217216
assimilation = factory.SubFactory(StatutChecklistFactory)
218217
choix_formation = factory.SubFactory(StatutChecklistFactory)
219218
parcours_anterieur = factory.SubFactory(StatutChecklistFactory)
@@ -341,7 +340,6 @@ class Params:
341340
StatutsChecklistDoctoraleFactory,
342341
financabilite__statut=ChoixStatutChecklist.GEST_REUSSITE,
343342
financabilite__extra={'reussite': 'financable'},
344-
donnees_personnelles__statut=ChoixStatutChecklist.GEST_REUSSITE,
345343
decision_cdd__statut=ChoixStatutChecklist.GEST_REUSSITE,
346344
),
347345
)

ddd/admission/doctorat/preparation/test/use_case/write/test_approuver_admission_par_sic_service.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# The core business involves the administration of students, teachers,
77
# courses, programs and so on.
88
#
9-
# Copyright (C) 2015-2025 Université catholique de Louvain (http://www.uclouvain.be)
9+
# Copyright (C) 2015-2026 Université catholique de Louvain (http://www.uclouvain.be)
1010
#
1111
# This program is free software: you can redistribute it and/or modify
1212
# it under the terms of the GNU General Public License as published by
@@ -41,8 +41,9 @@
4141
)
4242
from admission.ddd.admission.doctorat.preparation.domain.validator.exceptions import (
4343
DocumentAReclamerImmediatException,
44+
EtatChecklistDecisionCddNonValidePourApprouverDemande,
4445
EtatChecklistDonneesPersonnellesNonValidePourApprouverDemande,
45-
ParcoursAnterieurNonSuffisantException, EtatChecklistDecisionCddNonValidePourApprouverDemande,
46+
ParcoursAnterieurNonSuffisantException,
4647
)
4748
from admission.ddd.admission.doctorat.preparation.test.factory.groupe_de_supervision import (
4849
GroupeDeSupervisionSC3DPFactory,
@@ -79,6 +80,7 @@
7980
message_bus_in_memory_instance,
8081
)
8182
from base.ddd.utils.business_validator import MultipleBusinessExceptions
83+
from base.models.enums.personal_data import ChoixStatutValidationDonneesPersonnelles
8284
from base.models.person_merge_proposal import PersonMergeStatus
8385
from ddd.logic.shared_kernel.academic_year.domain.model.academic_year import (
8486
AcademicYear,
@@ -214,9 +216,15 @@ def test_should_lever_exception_si_parcours_anterieur_non_suffisant(self):
214216
self.assertIsInstance(context.exception.exceptions.pop(), ParcoursAnterieurNonSuffisantException)
215217

216218
def test_should_lever_exception_si_donnees_personnelles_non_validees(self):
217-
self.proposition.checklist_actuelle.donnees_personnelles.statut = ChoixStatutChecklist.INITIAL_CANDIDAT
218-
with self.assertRaises(MultipleBusinessExceptions) as context:
219-
self.message_bus.invoke(self.command(**self.parametres_commande_par_defaut))
219+
index = next(
220+
i for i, c in enumerate(ProfilCandidatInMemoryTranslator.profil_candidats) if c.matricule == '0123456789'
221+
)
222+
with patch.multiple(
223+
ProfilCandidatInMemoryTranslator.profil_candidats[index],
224+
statut_validation_donnees_personnelles=ChoixStatutValidationDonneesPersonnelles.A_COMPLETER.name,
225+
):
226+
with self.assertRaises(MultipleBusinessExceptions) as context:
227+
self.message_bus.invoke(self.command(**self.parametres_commande_par_defaut))
220228
self.assertIsInstance(
221229
context.exception.exceptions.pop(),
222230
EtatChecklistDonneesPersonnellesNonValidePourApprouverDemande,

ddd/admission/doctorat/preparation/test/use_case/write/test_approuver_inscription_par_sic_service.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# The core business involves the administration of students, teachers,
77
# courses, programs and so on.
88
#
9-
# Copyright (C) 2015-2025 Université catholique de Louvain (http://www.uclouvain.be)
9+
# Copyright (C) 2015-2026 Université catholique de Louvain (http://www.uclouvain.be)
1010
#
1111
# This program is free software: you can redistribute it and/or modify
1212
# it under the terms of the GNU General Public License as published by
@@ -46,9 +46,10 @@
4646
)
4747
from admission.ddd.admission.doctorat.preparation.domain.validator.exceptions import (
4848
DocumentAReclamerImmediatException,
49+
EtatChecklistDecisionCddNonValidePourApprouverDemande,
4950
EtatChecklistDecisionSicNonValidePourApprouverUneInscription,
5051
EtatChecklistDonneesPersonnellesNonValidePourApprouverDemande,
51-
ParcoursAnterieurNonSuffisantException, EtatChecklistDecisionCddNonValidePourApprouverDemande,
52+
ParcoursAnterieurNonSuffisantException,
5253
)
5354
from admission.ddd.admission.doctorat.preparation.test.factory.groupe_de_supervision import (
5455
GroupeDeSupervisionSC3DPFactory,
@@ -78,6 +79,7 @@
7879
message_bus_in_memory_instance,
7980
)
8081
from base.ddd.utils.business_validator import MultipleBusinessExceptions
82+
from base.models.enums.personal_data import ChoixStatutValidationDonneesPersonnelles
8183
from base.models.person_merge_proposal import PersonMergeStatus
8284
from ddd.logic.shared_kernel.academic_year.domain.model.academic_year import (
8385
AcademicYear,
@@ -211,9 +213,15 @@ def test_should_lever_exception_si_parcours_anterieur_non_suffisant(self):
211213
self.assertIsInstance(context.exception.exceptions.pop(), ParcoursAnterieurNonSuffisantException)
212214

213215
def test_should_lever_exception_si_donnees_personnelles_non_validees(self):
214-
self.proposition.checklist_actuelle.donnees_personnelles.statut = ChoixStatutChecklist.INITIAL_CANDIDAT
215-
with self.assertRaises(MultipleBusinessExceptions) as context:
216-
self.message_bus.invoke(self.command(**self.parametres_commande_par_defaut))
216+
index = next(
217+
i for i, c in enumerate(ProfilCandidatInMemoryTranslator.profil_candidats) if c.matricule == '0123456789'
218+
)
219+
with patch.multiple(
220+
ProfilCandidatInMemoryTranslator.profil_candidats[index],
221+
statut_validation_donnees_personnelles=ChoixStatutValidationDonneesPersonnelles.A_COMPLETER.name,
222+
):
223+
with self.assertRaises(MultipleBusinessExceptions) as context:
224+
self.message_bus.invoke(self.command(**self.parametres_commande_par_defaut))
217225
self.assertIsInstance(
218226
context.exception.exceptions.pop(),
219227
EtatChecklistDonneesPersonnellesNonValidePourApprouverDemande,

0 commit comments

Comments
 (0)