Skip to content

Commit

Permalink
[OS-1330] Add in-creation statuses and don't assign the student role …
Browse files Browse the repository at this point in the history
…at doctorate creation
  • Loading branch information
jcougnaud committed Dec 6, 2024
1 parent 66d61d6 commit 1195cb3
Show file tree
Hide file tree
Showing 36 changed files with 341 additions and 178 deletions.
11 changes: 8 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ repos:
rev: 5.13.2
hooks:
- id: isort
args: ["--profile", "black", "--filter-files"]
args: ["--profile", "black", "--filter-files", "--src", "..", "--virtual-env", "../venv"]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
Expand All @@ -32,7 +38,7 @@ repos:
- id: diff-quality
name: pycodestyle
language: system
entry: diff-quality --violations=pycodestyle --compare-branch=origin/dev --fail-under=100 --options="--ignore=E501"
entry: diff-quality --violations=pycodestyle --compare-branch=origin/dev --fail-under=100 --options="--ignore=E501,W503"
types: [ python ]
pass_filenames: false

Expand All @@ -50,7 +56,6 @@ repos:
always_run: true
pass_filenames: false


- id: check_app_messages
name: Check messages
language: system
Expand Down
56 changes: 38 additions & 18 deletions auth/predicates/parcours_doctoral.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
# ##############################################################################
from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _
from osis_role.cache import predicate_cache
from osis_role.errors import predicate_failed_msg
from rules import predicate

from osis_role.cache import predicate_cache
from osis_role.errors import predicate_failed_msg
from parcours_doctoral.ddd.domain.model.enums import (
STATUTS_DOCTORAT_EPREUVE_CONFIRMATION_EN_COURS,
ChoixStatutParcoursDoctoral,
Expand All @@ -49,21 +49,27 @@ def _build_queryset_cache_key_from_role_qs(role_qs, suffix):


@predicate(bind=True)
@predicate_failed_msg(message=_("You must be the request author to access this admission"))
@predicate_failed_msg(message=_("You must be the request author to access this doctoral training"))
def is_parcours_doctoral_student(self, user: User, obj: ParcoursDoctoral):
return obj.student == user.person
return obj.student == user.person and obj.is_initialized


@predicate(bind=True)
@predicate_failed_msg(message=_("The doctorate is not initialized"))
def is_initialized(self, user: User, obj: ParcoursDoctoral):
return obj.is_initialized


@predicate(bind=True)
@predicate_failed_msg(message=_("The jury is not in progress"))
def is_jury_in_progress(self, user: User, obj: ParcoursDoctoral):
return obj.status == ChoixStatutParcoursDoctoral.PASSED_CONFIRMATION.name
return obj.status == ChoixStatutParcoursDoctoral.CONFIRMATION_REUSSIE.name


@predicate(bind=True)
@predicate_failed_msg(message=_("The confirmation paper is not in progress"))
def submitted_confirmation_paper(self, user: User, obj: ParcoursDoctoral):
return obj.status == ChoixStatutParcoursDoctoral.SUBMITTED_CONFIRMATION.name
return obj.status == ChoixStatutParcoursDoctoral.CONFIRMATION_SOUMISE.name


@predicate(bind=True)
Expand Down Expand Up @@ -94,28 +100,42 @@ def is_part_of_doctoral_commission(self, user: User, obj: ParcoursDoctoral):
@predicate(bind=True)
@predicate_failed_msg(message=_("You must be the request promoter to access this doctoral training"))
def is_parcours_doctoral_promoter(self, user: User, obj: ParcoursDoctoral):
return obj.supervision_group and user.person.pk in [
actor.person_id
for actor in obj.supervision_group.actors.all()
if actor.parcoursdoctoralsupervisionactor.type == ActorType.PROMOTER.name
]
return (
obj.is_initialized
and obj.supervision_group
and user.person.pk
in [
actor.person_id
for actor in obj.supervision_group.actors.all()
if actor.parcoursdoctoralsupervisionactor.type == ActorType.PROMOTER.name
]
)


@predicate(bind=True)
@predicate_failed_msg(message=_("You must be the reference promoter to access this doctoral training"))
def is_parcours_doctoral_reference_promoter(self, user: User, obj: ParcoursDoctoral):
return obj.supervision_group and user.person.pk in [
actor.person_id
for actor in obj.supervision_group.actors.all()
if actor.parcoursdoctoralsupervisionactor.type == ActorType.PROMOTER.name
and actor.parcoursdoctoralsupervisionactor.is_reference_promoter
]
return (
obj.is_initialized
and obj.supervision_group
and user.person.pk
in [
actor.person_id
for actor in obj.supervision_group.actors.all()
if actor.parcoursdoctoralsupervisionactor.type == ActorType.PROMOTER.name
and actor.parcoursdoctoralsupervisionactor.is_reference_promoter
]
)


@predicate(bind=True)
@predicate_failed_msg(message=_("You must be a member of the committee to access this doctoral training"))
def is_part_of_committee(self, user: User, obj: ParcoursDoctoral):
return obj.supervision_group and user.person.pk in [actor.person_id for actor in obj.supervision_group.actors.all()]
return (
obj.is_initialized
and obj.supervision_group
and user.person.pk in [actor.person_id for actor in obj.supervision_group.actors.all()]
)


@predicate(bind=True)
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 @@ -23,10 +23,11 @@
# see http://www.gnu.org/licenses/.
#
# ##############################################################################
from django.db.models import UniqueConstraint
from django.utils.translation import gettext_lazy as _
from osis_role.contrib.models import RoleModel
from rules import RuleSet, always_allow

from osis_role.contrib.models import RoleModel
from parcours_doctoral.auth.predicates.parcours_doctoral import is_part_of_committee


Expand All @@ -42,6 +43,7 @@ class Meta:
verbose_name = _("Role: Committee member")
verbose_name_plural = _("Role: Committee members")
group_name = "committee_members"
constraints = [UniqueConstraint(fields=['person'], name='unique_committee_member_person')]

@classmethod
def rule_set(cls):
Expand All @@ -56,6 +58,5 @@ def rule_set(cls):
'parcours_doctoral.view_confirmation': is_part_of_committee,
'parcours_doctoral.view_jury': is_part_of_committee,
'parcours_doctoral.approve_jury': is_part_of_committee,
'parcours_doctoral.view_supervision': is_part_of_committee,
}
return RuleSet(ruleset)
7 changes: 5 additions & 2 deletions auth/roles/promoter.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
# see http://www.gnu.org/licenses/.
#
# ##############################################################################
from django.db.models import UniqueConstraint
from django.utils.translation import gettext_lazy as _
from osis_role.contrib.models import RoleModel
from rules import RuleSet, always_allow

from osis_role.contrib.models import RoleModel
from parcours_doctoral.auth.predicates.parcours_doctoral import (
complementary_training_enabled,
confirmation_paper_in_progress,
is_jury_in_progress,
is_parcours_doctoral_promoter,
is_parcours_doctoral_reference_promoter,
Expand All @@ -49,6 +49,9 @@ class Meta:
verbose_name = _("Role: Promoter")
verbose_name_plural = _("Role: Promoters")
group_name = "promoters"
constraints = [
UniqueConstraint(fields=['person'], name='unique_promoter_person'),
]

@classmethod
def rule_set(cls):
Expand Down
32 changes: 21 additions & 11 deletions ddd/domain/model/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,25 @@
# ##############################################################################
import itertools

from base.models.utils.utils import ChoiceEnum
from django.utils.translation import gettext_lazy as _
from django.utils.translation import pgettext_lazy

from base.models.utils.utils import ChoiceEnum


class ChoixStatutParcoursDoctoral(ChoiceEnum):
# After enrolment
ADMITTED = _('ADMITTED')
# En cours de création
EN_ATTENTE_INJECTION_EPC = _('EN_ATTENTE_INJECTION_EPC')
EN_COURS_DE_CREATION_PAR_GESTIONNAIRE = _('EN_COURS_DE_CREATION_PAR_GESTIONNAIRE')
# Après création
ADMIS = _('ADMIS')
# Groupe de supervision
EN_ATTENTE_DE_SIGNATURE = _('Waiting for signature')
EN_ATTENTE_DE_SIGNATURE = _('EN_ATTENTE_DE_SIGNATURE')
# Confirmation exam
SUBMITTED_CONFIRMATION = _('SUBMITTED_CONFIRMATION')
PASSED_CONFIRMATION = _('PASSED_CONFIRMATION')
NOT_ALLOWED_TO_CONTINUE = _('NOT_ALLOWED_TO_CONTINUE')
CONFIRMATION_TO_BE_REPEATED = _('CONFIRMATION_TO_BE_REPEATED')
CONFIRMATION_SOUMISE = _('CONFIRMATION_SOUMISE')
CONFIRMATION_REUSSIE = _('CONFIRMATION_REUSSIE')
NON_AUTORISE_A_POURSUIVRE = _('NON_AUTORISE_A_POURSUIVRE')
CONFIRMATION_A_REPRESENTER = _('CONFIRMATION_A_REPRESENTER')
# Jury
JURY_SOUMIS = _('JURY_SOUMIS')
JURY_APPROUVE_CA = _('JURY_APPROUVE_CA')
Expand All @@ -49,10 +53,16 @@ class ChoixStatutParcoursDoctoral(ChoiceEnum):
JURY_REFUSE_ADRE = _('JURY_REFUSE_ADRE')


STATUTS_DOCTORAT_EN_COURS_DE_CREATION = {
ChoixStatutParcoursDoctoral.EN_ATTENTE_INJECTION_EPC.name,
ChoixStatutParcoursDoctoral.EN_COURS_DE_CREATION_PAR_GESTIONNAIRE.name,
}


STATUTS_DOCTORAT_EPREUVE_CONFIRMATION_EN_COURS = {
ChoixStatutParcoursDoctoral.ADMITTED.name,
ChoixStatutParcoursDoctoral.SUBMITTED_CONFIRMATION.name,
ChoixStatutParcoursDoctoral.CONFIRMATION_TO_BE_REPEATED.name,
ChoixStatutParcoursDoctoral.ADMIS.name,
ChoixStatutParcoursDoctoral.CONFIRMATION_SOUMISE.name,
ChoixStatutParcoursDoctoral.CONFIRMATION_A_REPRESENTER.name,
}


Expand Down
10 changes: 5 additions & 5 deletions ddd/domain/model/parcours_doctoral.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
from typing import List, Optional

import attr
from osis_common.ddd import interface

from osis_common.ddd import interface
from parcours_doctoral.ddd.domain.model._cotutelle import Cotutelle
from parcours_doctoral.ddd.domain.model._experience_precedente_recherche import (
ExperiencePrecedenteRecherche,
Expand Down Expand Up @@ -100,16 +100,16 @@ def verifier_projet_doctoral(self):
).validate()

def soumettre_epreuve_confirmation(self):
self.statut = ChoixStatutParcoursDoctoral.SUBMITTED_CONFIRMATION
self.statut = ChoixStatutParcoursDoctoral.CONFIRMATION_SOUMISE

def encoder_decision_reussite_epreuve_confirmation(self):
self.statut = ChoixStatutParcoursDoctoral.PASSED_CONFIRMATION
self.statut = ChoixStatutParcoursDoctoral.CONFIRMATION_REUSSIE

def encoder_decision_echec_epreuve_confirmation(self):
self.statut = ChoixStatutParcoursDoctoral.NOT_ALLOWED_TO_CONTINUE
self.statut = ChoixStatutParcoursDoctoral.NON_AUTORISE_A_POURSUIVRE

def encoder_decision_repassage_epreuve_confirmation(self):
self.statut = ChoixStatutParcoursDoctoral.CONFIRMATION_TO_BE_REPEATED
self.statut = ChoixStatutParcoursDoctoral.CONFIRMATION_A_REPRESENTER

def _modifier_projet(
self,
Expand Down
1 change: 1 addition & 0 deletions ddd/domain/validator/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

from django.utils.translation import gettext_lazy as _
from django.utils.translation import pgettext_lazy

from osis_common.ddd.interface import BusinessException


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
# see http://www.gnu.org/licenses/.
#
# ##############################################################################
from base.ddd.utils.business_validator import MultipleBusinessExceptions
from django.test import TestCase

from base.ddd.utils.business_validator import MultipleBusinessExceptions
from parcours_doctoral.ddd.commands import RecupererParcoursDoctoralQuery
from parcours_doctoral.ddd.domain.model.enums import ChoixStatutParcoursDoctoral
from parcours_doctoral.ddd.epreuve_confirmation.commands import ConfirmerEchecCommand
Expand Down Expand Up @@ -69,4 +69,4 @@ def test_should_confirmer_echec_epreuve_confirmation_si_valide(self):
RecupererParcoursDoctoralQuery(parcours_doctoral_uuid=parcours_doctoral_id.uuid),
)

self.assertEqual(parcours_doctoral.statut, ChoixStatutParcoursDoctoral.NOT_ALLOWED_TO_CONTINUE.name)
self.assertEqual(parcours_doctoral.statut, ChoixStatutParcoursDoctoral.NON_AUTORISE_A_POURSUIVRE.name)
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
# ##############################################################################
import datetime

from base.ddd.utils.business_validator import MultipleBusinessExceptions
from django.test import TestCase

from base.ddd.utils.business_validator import MultipleBusinessExceptions
from parcours_doctoral.ddd.commands import RecupererParcoursDoctoralQuery
from parcours_doctoral.ddd.domain.model.enums import ChoixStatutParcoursDoctoral
from parcours_doctoral.ddd.epreuve_confirmation.commands import (
Expand Down Expand Up @@ -75,7 +75,7 @@ def test_should_confirmer_repassage_epreuve_confirmation_si_valide(self):
RecupererParcoursDoctoralQuery(parcours_doctoral_uuid=parcours_doctoral_id.uuid),
)

self.assertEqual(parcours_doctoral.statut, ChoixStatutParcoursDoctoral.CONFIRMATION_TO_BE_REPEATED.name)
self.assertEqual(parcours_doctoral.statut, ChoixStatutParcoursDoctoral.CONFIRMATION_A_REPRESENTER.name)

epreuve_confirmation_creee = next(
(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
# see http://www.gnu.org/licenses/.
#
# ##############################################################################
from base.ddd.utils.business_validator import MultipleBusinessExceptions
from django.test import TestCase

from base.ddd.utils.business_validator import MultipleBusinessExceptions
from parcours_doctoral.ddd.commands import RecupererParcoursDoctoralQuery
from parcours_doctoral.ddd.domain.model.enums import ChoixStatutParcoursDoctoral
from parcours_doctoral.ddd.epreuve_confirmation.commands import ConfirmerReussiteCommand
Expand Down Expand Up @@ -63,4 +63,4 @@ def test_should_confirmer_reussite_epreuve_confirmation_si_valide(self):
RecupererParcoursDoctoralQuery(parcours_doctoral_uuid=parcours_doctoral_id.uuid),
)

self.assertEqual(parcours_doctoral.statut, ChoixStatutParcoursDoctoral.PASSED_CONFIRMATION.name)
self.assertEqual(parcours_doctoral.statut, ChoixStatutParcoursDoctoral.CONFIRMATION_REUSSIE.name)
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
# ##############################################################################
import datetime

from base.ddd.utils.business_validator import MultipleBusinessExceptions
from django.test import TestCase

from base.ddd.utils.business_validator import MultipleBusinessExceptions
from parcours_doctoral.ddd.domain.model.enums import ChoixStatutParcoursDoctoral
from parcours_doctoral.ddd.epreuve_confirmation.builder.epreuve_confirmation_identity import (
EpreuveConfirmationIdentityBuilder,
Expand Down Expand Up @@ -121,4 +121,4 @@ def test_should_soumettre_epreuve_confirmation_si_valide(self):
self.assertEqual(epreuve_confirmation_mise_a_jour.proces_verbal_ca, ['mon_fichier_2'])
self.assertEqual(epreuve_confirmation_mise_a_jour.avis_renouvellement_mandat_recherche, ['mon_fichier_3'])

self.assertEqual(parcours_doctoral.statut, ChoixStatutParcoursDoctoral.SUBMITTED_CONFIRMATION)
self.assertEqual(parcours_doctoral.statut, ChoixStatutParcoursDoctoral.CONFIRMATION_SOUMISE)
4 changes: 2 additions & 2 deletions ddd/test/factory/parcours_doctoral.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
import uuid

import factory
from base.tests.factories.person import generate_global_id

from base.tests.factories.person import generate_global_id
from parcours_doctoral.ddd.domain.model._cotutelle import Cotutelle, pas_de_cotutelle
from parcours_doctoral.ddd.domain.model._experience_precedente_recherche import (
aucune_experience_precedente_recherche,
Expand Down Expand Up @@ -110,7 +110,7 @@ class Meta:
matricule_doctorant = factory.LazyFunction(generate_global_id)
reference = factory.Iterator(REFERENCE_MEMORY_ITERATOR)
formation_id = factory.SubFactory(_FormationIdentityFactory)
statut = ChoixStatutParcoursDoctoral.ADMITTED
statut = ChoixStatutParcoursDoctoral.ADMIS
projet = factory.SubFactory(_ProjetFactory)
financement = factory.SubFactory(_FinancementFactory)
experience_precedente_recherche = aucune_experience_precedente_recherche
Expand Down
2 changes: 1 addition & 1 deletion ddd/test/use_case/read/test_recuperer_doctorat.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def test_should_recuperer_parcours_doctoral_connu(self):
self.assertEqual(parcours_doctoral_dto.uuid, 'uuid-SC3DP-promoteurs-membres-deja-approuves')
self.assertEqual(parcours_doctoral_dto.reference, 'r4')

self.assertEqual(parcours_doctoral_dto.statut, ChoixStatutParcoursDoctoral.ADMITTED.name)
self.assertEqual(parcours_doctoral_dto.statut, ChoixStatutParcoursDoctoral.ADMIS.name)

self.assertEqual(parcours_doctoral_dto.formation.sigle, 'SC3DP')
self.assertEqual(parcours_doctoral_dto.formation.annee, 2022)
Expand Down
Loading

0 comments on commit 1195cb3

Please sign in to comment.