Skip to content

Commit

Permalink
[OS-636] Take the doctorate pre admission into account
Browse files Browse the repository at this point in the history
  • Loading branch information
jcougnaud committed Dec 3, 2024
1 parent a1e90ac commit 64636f2
Show file tree
Hide file tree
Showing 31 changed files with 700 additions and 199 deletions.
6 changes: 6 additions & 0 deletions auth/predicates/doctorate.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ def is_submitted(self, user: User, obj: DoctorateAdmission):
return isinstance(obj, DoctorateAdmission) and obj.status in STATUTS_PROPOSITION_DOCTORALE_SOUMISE


@predicate(bind=True)
@predicate_failed_msg(message=_("The proposition must be an admission to realize this action."))
def is_admission(self, user: User, obj: DoctorateAdmission):
return obj.type == ChoixTypeAdmission.ADMISSION.name


@predicate(bind=True)
@predicate_failed_msg(message=_('The proposition must not be cancelled to realize this action.'))
def not_cancelled(self, user: User, obj: DoctorateAdmission):
Expand Down
2 changes: 1 addition & 1 deletion auth/roles/admission_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def rule_set(cls):
'admission.view_admission_curriculum': is_part_of_education_group,
# Project
'admission.view_admission_project': is_part_of_education_group,
'admission.view_admission_cotutelle': is_part_of_education_group,
'admission.view_admission_cotutelle': is_part_of_education_group & doctorate.is_admission,
'admission.view_admission_training_choice': is_part_of_education_group,
'admission.view_admission_accounting': is_part_of_education_group,
'admission.view_admission_specific_questions': is_part_of_education_group,
Expand Down
5 changes: 3 additions & 2 deletions auth/roles/ca_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2023 Université catholique de Louvain (http://www.uclouvain.be)
# Copyright (C) 2015-2024 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -31,6 +31,7 @@
is_enrolled,
is_part_of_committee,
is_part_of_committee_and_invited,
is_admission,
)
from osis_role.contrib.models import RoleModel

Expand Down Expand Up @@ -63,7 +64,7 @@ def rule_set(cls):
'admission.view_doctorateadmission': is_part_of_committee,
'admission.view_admission_training_choice': is_part_of_committee,
'admission.view_admission_project': is_part_of_committee,
'admission.view_admission_cotutelle': is_part_of_committee,
'admission.view_admission_cotutelle': is_admission & is_part_of_committee,
'admission.view_admission_supervision': is_part_of_committee,
# A ca member can approve as long as he is invited to the committee
'admission.approve_proposition': is_part_of_committee_and_invited,
Expand Down
6 changes: 4 additions & 2 deletions auth/roles/candidate.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
'view_admission_accounting': common.is_admission_request_author & doctorate.unconfirmed_proposition,
'view_admission_training_choice': common.is_admission_request_author & doctorate.unconfirmed_proposition,
'view_admission_project': common.is_admission_request_author & doctorate.unconfirmed_proposition,
'view_admission_cotutelle': common.is_admission_request_author & doctorate.unconfirmed_proposition,
'view_admission_cotutelle': common.is_admission_request_author
& doctorate.unconfirmed_proposition
& doctorate.is_admission,
'view_admission_supervision': common.is_admission_request_author & doctorate.unconfirmed_proposition,
# Can edit while not confirmed proposition
'delete_doctorateadmission': common.is_admission_request_author & doctorate.unconfirmed_proposition,
Expand All @@ -64,7 +66,7 @@
# Project tabs and supervision group edition are accessible as long as signing has not begun
'change_admission_training_choice': common.is_admission_request_author & doctorate.in_progress,
'change_admission_project': common.is_admission_request_author & doctorate.in_progress,
'change_admission_cotutelle': common.is_admission_request_author & doctorate.in_progress,
'change_admission_cotutelle': common.is_admission_request_author & doctorate.in_progress & doctorate.is_admission,
'change_admission_supervision': common.is_admission_request_author & doctorate.in_progress,
'request_signatures': common.is_admission_request_author & doctorate.in_progress,
'add_supervision_member': common.is_admission_request_author & doctorate.in_progress,
Expand Down
22 changes: 17 additions & 5 deletions auth/roles/central_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,26 @@ def rule_set(cls):
'admission.appose_sic_notice': is_entity_manager,
'admission.view_admission_person': is_entity_manager,
'admission.change_admission_person': is_entity_manager
& (general.in_sic_status | continuing.in_manager_status | doctorate.in_sic_status
| general.in_progress | continuing.in_progress | doctorate.in_progress)
& (
general.in_sic_status
| continuing.in_manager_status
| doctorate.in_sic_status
| general.in_progress
| continuing.in_progress
| doctorate.in_progress
)
& ~is_sent_to_epc
& ~pending_digit_ticket_response,
'admission.view_admission_coordinates': is_entity_manager,
'admission.change_admission_coordinates': is_entity_manager
& (general.in_sic_status | continuing.in_manager_status | doctorate.in_sic_status
| general.in_progress | continuing.in_progress | doctorate.in_progress)
& (
general.in_sic_status
| continuing.in_manager_status
| doctorate.in_sic_status
| general.in_progress
| continuing.in_progress
| doctorate.in_progress
)
& ~is_sent_to_epc
& ~pending_digit_ticket_response,
'admission.view_admission_training_choice': is_entity_manager,
Expand All @@ -103,7 +115,7 @@ def rule_set(cls):
& (general.in_sic_status | continuing.in_manager_status | doctorate.in_sic_status)
& ~is_sent_to_epc,
'admission.view_admission_project': is_entity_manager,
'admission.view_admission_cotutelle': is_entity_manager,
'admission.view_admission_cotutelle': doctorate.is_admission & is_entity_manager,
'admission.view_admission_supervision': is_entity_manager,
'admission.view_admission_accounting': is_entity_manager,
'admission.change_admission_accounting': is_entity_manager
Expand Down
7 changes: 4 additions & 3 deletions auth/roles/doctorate_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2023 Université catholique de Louvain (http://www.uclouvain.be)
# Copyright (C) 2015-2024 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -24,10 +24,11 @@
#
# ##############################################################################

from django.utils.translation import gettext_lazy as _
from rules import RuleSet, always_allow

from admission.auth.predicates import doctorate
from osis_role.contrib.models import RoleModel
from django.utils.translation import gettext_lazy as _


class DoctorateReader(RoleModel):
Expand All @@ -46,7 +47,7 @@ def rule_set(cls):
'admission.view_admission_languages': always_allow,
'admission.view_admission_curriculum': always_allow,
'admission.view_admission_project': always_allow,
'admission.view_admission_cotutelle': always_allow,
'admission.view_admission_cotutelle': doctorate.is_admission,
'admission.view_admission_supervision': always_allow,
'admission.view_dossiers': always_allow,
'admission.view_internalnote': always_allow,
Expand Down
8 changes: 5 additions & 3 deletions auth/roles/program_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from django.db import models
from django.utils.translation import gettext_lazy as _

from admission.auth.predicates import general, continuing, doctorate
from admission.auth.predicates.common import (
has_education_group_of_types,
is_part_of_education_group,
Expand All @@ -36,7 +37,6 @@
pending_digit_ticket_response,
past_experiences_checklist_tab_is_not_sufficient,
)
from admission.auth.predicates import general, continuing, doctorate
from admission.infrastructure.admission.domain.service.annee_inscription_formation import (
AnneeInscriptionFormationTranslator,
)
Expand Down Expand Up @@ -110,8 +110,10 @@ def rule_set(cls):
# Project
'admission.view_admission_project': is_part_of_education_group,
'admission.change_admission_project': is_part_of_education_group & ~is_sent_to_epc,
'admission.view_admission_cotutelle': is_part_of_education_group,
'admission.change_admission_cotutelle': is_part_of_education_group & ~is_sent_to_epc,
'admission.view_admission_cotutelle': doctorate.is_admission & is_part_of_education_group,
'admission.change_admission_cotutelle': doctorate.is_admission
& is_part_of_education_group
& ~is_sent_to_epc,
'admission.view_admission_training_choice': is_part_of_education_group,
'admission.change_admission_training_choice': is_part_of_education_group
& (continuing.in_manager_status | doctorate.in_fac_status)
Expand Down
8 changes: 3 additions & 5 deletions auth/roles/promoter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2023 Université catholique de Louvain (http://www.uclouvain.be)
# Copyright (C) 2015-2024 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -27,12 +27,10 @@
from rules import RuleSet

from admission.auth.predicates.doctorate import (
is_admission_reference_promoter,
is_admission_request_promoter,
is_being_enrolled,
is_enrolled,
is_part_of_committee_and_invited,
is_pre_admission,
is_admission,
)
from osis_role.contrib.models import RoleModel

Expand Down Expand Up @@ -70,7 +68,7 @@ def rule_set(cls):
# A promoter can view as long as he is one of the admission promoters
'admission.view_admission_project': is_admission_request_promoter,
'admission.view_admission_training_choice': is_admission_request_promoter,
'admission.view_admission_cotutelle': is_admission_request_promoter,
'admission.view_admission_cotutelle': is_admission & is_admission_request_promoter,
'admission.view_admission_supervision': is_admission_request_promoter,
'admission.view_admission_jury': is_admission_request_promoter,
# A promoter can approve as long as he is invited to the admission committee
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from admission.ddd.admission.doctorat.preparation.domain.model.enums import (
ChoixEtatSignature,
ChoixStatutSignatureGroupeDeSupervision,
ChoixTypeAdmission,
)
from admission.ddd.admission.doctorat.preparation.domain.model.proposition import PropositionIdentity
from admission.ddd.admission.doctorat.preparation.domain.validator import ShouldSignaturesPasEtreEnvoyees
Expand All @@ -57,6 +58,7 @@
SignatairesValidatorList,
SupprimerMembreCAValidatorList,
SupprimerPromoteurValidatorList,
SignatairesPreAdmissionValidatorList,
)
from osis_common.ddd import interface

Expand Down Expand Up @@ -262,6 +264,9 @@ def verifier_signatures_non_envoyees(self):
def verifier_signataires(self):
SignatairesValidatorList(groupe_de_supervision=self).validate()

def verifier_signataires_pre_admission(self):
SignatairesPreAdmissionValidatorList(groupe_de_supervision=self).validate()

def verifier_promoteur_reference_renseigne_institut_these(
self,
signataire: SignataireIdentity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2022 Université catholique de Louvain (http://www.uclouvain.be)
# Copyright (C) 2015-2024 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -26,6 +26,7 @@
from functools import partial
from typing import List

from admission.ddd.admission.doctorat.preparation.domain.model.enums import ChoixTypeAdmission
from admission.ddd.admission.doctorat.preparation.domain.model.groupe_de_supervision import GroupeDeSupervision
from admission.ddd.admission.doctorat.preparation.domain.model.proposition import Proposition
from admission.ddd.admission.doctorat.preparation.domain.service.i_promoteur import IPromoteurTranslator
Expand All @@ -50,15 +51,27 @@ def verifier(
questions_specifiques: List[QuestionSpecifique],
promoteur_translator: IPromoteurTranslator,
) -> None:
if proposition_candidat.type_admission == ChoixTypeAdmission.PRE_ADMISSION:
fonctions_personnalisees = [
# Vérification différente de la composition du groupe de supervision
groupe_de_supervision.verifier_signataires_pre_admission,
]
else:
fonctions_personnalisees = [
# Vérification différente de la composition du groupe de supervision
groupe_de_supervision.verifier_signataires,
# Vérification de la cotutelle, absente en pré-admission
groupe_de_supervision.verifier_cotutelle,
partial(CotutellePossedePromoteurExterne.verifier, groupe_de_supervision, promoteur_translator),
]

execute_functions_and_aggregate_exceptions(
proposition_candidat.verifier_projet_doctoral,
groupe_de_supervision.verifier_cotutelle,
partial(GroupeDeSupervisionPossedeUnPromoteurMinimum.verifier, groupe_de_supervision, promoteur_translator),
partial(CotutellePossedePromoteurExterne.verifier, groupe_de_supervision, promoteur_translator),
groupe_de_supervision.verifier_signataires,
partial(
VerifierQuestionsSpecifiques.verifier_onglet_choix_formation,
proposition_candidat,
questions_specifiques,
),
*fonctions_personnalisees,
)
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,18 @@ class ShouldProjetEtreComplet(BusinessValidator):
experience_precedente_recherche: 'ExperiencePrecedenteRecherche'

def validate(self, *args, **kwargs):
if self.type_admission == ChoixTypeAdmission.PRE_ADMISSION:
if not self.projet.titre:
raise DetailProjetNonCompleteException
return

champs_obligatoires = [
"titre",
"resume",
"langue_redaction_these",
"documents",
"proposition_programme_doctoral",
]
if self.type_admission == ChoixTypeAdmission.ADMISSION:
champs_obligatoires.append("proposition_programme_doctoral")

champs_financements_obligatoires = [
"duree_prevue",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
# see http://www.gnu.org/licenses/.
#
# ##############################################################################
from datetime import datetime, date
from datetime import date
from typing import List, Optional, Union, Dict

import attr
Expand Down Expand Up @@ -55,12 +55,11 @@
StatutChecklist,
)
from admission.ddd.admission.doctorat.preparation.domain.validator import *
from admission.ddd.admission.domain.model.complement_formation import ComplementFormationIdentity
from admission.ddd.admission.domain.model.titre_acces_selectionnable import TitreAccesSelectionnable
from admission.ddd.admission.doctorat.preparation.domain.validator import *
from admission.ddd.admission.doctorat.preparation.domain.validator._should_statut_etre_en_attente_de_signature import (
ShouldStatutEtreEnAttenteDeSignature,
)
from admission.ddd.admission.domain.model.complement_formation import ComplementFormationIdentity
from admission.ddd.admission.domain.model.titre_acces_selectionnable import TitreAccesSelectionnable
from admission.ddd.admission.domain.validator import (
ShouldAnneesCVRequisesCompletees,
ShouldExperiencesAcademiquesEtreCompletees,
Expand Down Expand Up @@ -431,6 +430,19 @@ def get_invariants_validators(self) -> List[BusinessValidator]:
]


@attr.dataclass(frozen=True, slots=True)
class SignatairesPreAdmissionValidatorList(TwoStepsMultipleBusinessExceptionListValidator):
groupe_de_supervision: 'GroupeDeSupervision'

def get_data_contract_validators(self) -> List[BusinessValidator]:
return []

def get_invariants_validators(self) -> List[BusinessValidator]:
return [
ShouldGroupeDeSupervisionAvoirUnPromoteurDeReference(self.groupe_de_supervision),
]


@attr.dataclass(frozen=True, slots=True)
class ApprobationValidatorList(TwoStepsMultipleBusinessExceptionListValidator):
groupe_de_supervision: 'GroupeDeSupervision'
Expand Down
10 changes: 9 additions & 1 deletion ddd/admission/doctorat/preparation/dtos/proposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from osis_profile import PLUS_5_ISO_CODES
from .motif_refus import MotifRefusDTO
from .doctorat_formation import DoctoratFormationDTO
from ..domain.model.enums import STATUTS_PROPOSITION_DOCTORALE_NON_SOUMISE
from ..domain.model.enums import STATUTS_PROPOSITION_DOCTORALE_NON_SOUMISE, ChoixTypeAdmission
from ..domain.model.enums.checklist import DroitsInscriptionMontant


Expand Down Expand Up @@ -150,6 +150,14 @@ def est_inscription(self):
def est_admission(self):
return self.type == TypeDemande.ADMISSION.name

@property
def est_pre_admission_doctorat(self):
return self.type_admission == ChoixTypeAdmission.PRE_ADMISSION.name

@property
def est_admission_doctorat(self):
return self.type_admission == ChoixTypeAdmission.ADMISSION.name


@attr.dataclass(frozen=True, slots=True)
class PropositionGestionnaireDTO(PropositionDTO):
Expand Down
Loading

0 comments on commit 64636f2

Please sign in to comment.