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

[WIP] [feature/OS-596 => DEV] En tant que gestionnaire CDD, je souhaite avoir une entrée de checklist _Finançabilité_, afin de me permettre d_analyser le dossier du candidat doctorant #2057

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
4 changes: 3 additions & 1 deletion auth/roles/program_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@ def rule_set(cls):
& (general.in_fac_status | doctorate.in_fac_status)
& ~is_sent_to_epc,
'admission.checklist_change_fac_comment': is_part_of_education_group & ~is_sent_to_epc,
'admission.checklist_financability_dispensation_fac': is_part_of_education_group & ~is_sent_to_epc,
'admission.checklist_financability_dispensation_fac': general.in_fac_status
& is_part_of_education_group
& ~is_sent_to_epc,
'admission.continuing_checklist_change_fac_comment': is_part_of_education_group & ~is_sent_to_epc,
'admission.checklist_change_comment': is_part_of_education_group
& continuing.is_continuing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,6 @@ def historiser_derogation_financabilite(
cls,
proposition: Proposition,
gestionnaire: str,
message: Optional[EmailMessage],
message: Optional[EmailMessage] = None,
):
raise NotImplementedError
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
)
from admission.ddd.admission.doctorat.preparation.domain.model.enums.checklist import DerogationFinancement
from admission.ddd.admission.doctorat.preparation.domain.model.proposition import PropositionIdentity
from admission.ddd.admission.doctorat.preparation.domain.service.i_historique import IHistorique
from admission.ddd.admission.doctorat.preparation.repository.i_proposition import IPropositionRepository


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,6 @@ def historiser_derogation_financabilite(
cls,
proposition: Proposition,
gestionnaire: str,
message: Optional[EmailMessage],
message: Optional[EmailMessage] = None,
):
raise NotImplementedError
10 changes: 9 additions & 1 deletion forms/admission/checklist.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,22 @@ def __init__(self, form_url, comment=None, label=None, permission=None, *args, *
'authentication': _('Comment about the authentication'),
}

labels_from_prefix = {
'financabilite__derogation': _('Faculty comment about financability dispensation'),
'decision_sic__derogation': _('Comment about dispensation'),
}

permissions = {
COMMENT_TAG_SIC: 'admission.checklist_change_sic_comment',
COMMENT_TAG_FAC: 'admission.checklist_change_fac_comment',
COMMENT_TAG_IUFC_FOR_FAC: 'admission.continuing_checklist_change_iufc_comment',
COMMENT_TAG_FAC_FOR_IUFC: 'admission.continuing_checklist_change_fac_comment',
}

self.fields['comment'].label = labels.get(comment_type, label or _('Comment'))
if self.prefix in labels_from_prefix:
self.fields['comment'].label = labels_from_prefix[self.prefix]
else:
self.fields['comment'].label = labels.get(comment_type, label or _('Comment'))

if permission is not None:
self.permission = permission
Expand Down
50 changes: 50 additions & 0 deletions migrations/0225_doctorate_financeabilite_email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Generated by Django 3.2.25 on 2024-05-22 14:49

from django.db import migrations
from osis_mail_template import MailTemplateMigration

from admission.mail_templates import (
ADMISSION_EMAIL_FINANCABILITY_DISPENSATION_NOTIFICATION_DOCTORATE,
)


class Migration(migrations.Migration):

dependencies = [
('admission', '0224_add_doctorate_checklist_emails'),
]

operations = [
MailTemplateMigration(
ADMISSION_EMAIL_FINANCABILITY_DISPENSATION_NOTIFICATION_DOCTORATE,
{
'en': '{academic_year} enrolment application ineligible for funding: exemption required',
'fr-be': "Demande d'inscription {academic_year} non finançable : Dérogation nécessaire",
},
{
'en': '''<p>Your file number: {admission_reference}</p>
<p>Dear {candidate_first_name} {candidate_last_name},</p>
<p>Thank you for applying to enrol in the course {training_title} [{training_acronym}] ({training_campus}).</p>
<p>After reviewing your academic curriculum and in accordance with the decree of 11 April 2014 adapting the funding of higher education institutions to the latest restructuring of higher education, it appears from the information you have provided and/or at our disposal that, per the meaning of the aforementioned decree, you are ineligible for funding.</p>
<p>However, if you have specific arguments to put forward, you can apply for a faculty exemption with a view to enrolment. To do so, please contact your faculty (<a href="{contact_link}">{contact_link}</a>) as soon as possible to learn how to apply for an exemption.</p>
<p>For your information, and as a general rule, an exemption application must be made in writing and accompanied by a curriculum vitae, a letter of motivation and a copy of the detailed results of all previous years of higher education (transcripts).</p>
<p>The faculty will inform the Enrolment Office of its decision. If the faculty’s decision is favourable, the Enrolment Office will validate your application for (re)enrolment as soon as it is received. If the decision is not favourable, you will receive as soon as possible an official letter denying enrolment.</p>
<p>We are aware of the disappointment that this letter may cause. Please do consult your faculty to determine whether an exemption is possible.</p>
<p>Sincerely,</p>
<p>The UCLouvain Enrolment Office</p>
<p><a href="https://uclouvain.be/en/study/inscriptions">https://uclouvain.be/en/study/inscriptions</a></p>
''',
'fr-be': '''<p>Votre numéro de dossier : {admission_reference}</p>
<p>{greetings} {candidate_first_name} {candidate_last_name},</p>
<p>Votre demande d'inscription au programme {training_title} [{training_acronym}] ({training_campus}) nous est bien parvenue et nous vous en remercions.</p>
<p>Après analyse de votre curriculum académique et conformément au décret du 11 avril 2014 adaptant le financement des établissements d'enseignement supérieur à la nouvelle organisation des études, il ressort des informations que vous nous avez fournies et/ou dont nous disposons que vous n’êtes pas finançable au sens du décret précité.</p>
<p>Toutefois, si vous disposez d’arguments particuliers à faire valoir, vous pouvez introduire une demande de dérogation facultaire en vue d’une inscription. Pour ce faire, veuillez contacter votre faculté (<a href="{contact_link}">{contact_link}</a>) dans les plus brefs délais afin de connaître les modalités en vue d'introduire une demande de dérogation.</p>
<p>Pour votre information et de manière générale, une demande de dérogation doit être introduite par écrit et être accompagnée d'un curriculum vitae, d’une lettre de motivation et d'une copie des résultats détaillés de toutes les années d'études supérieures antérieures (relevés de notes).</p>
<p>La faculté communiquera sa décision au Service des inscriptions. En cas de décision favorable de la faculté et dès sa réception, le Service des inscriptions validera votre demande de (ré)inscription. Dans le cas contraire, un courrier officiel de refus d’inscription vous parviendra dans les meilleurs délais.</p>
<p>Consciente de la déception que ce courrier pourrait susciter, nous vous prions néanmoins d’agréer, {greetings_end}, l'expression de nos salutations distinguées.</p>
<p>Le Service des inscriptions de l'UCLouvain.</p>
<p><a href="https://uclouvain.be/fr/etudier/inscriptions">https://uclouvain.be/fr/etudier/inscriptions</a>.</p>
''',
},
),
]
9 changes: 5 additions & 4 deletions templates/admission/doctorate/checklist.html
Original file line number Diff line number Diff line change
Expand Up @@ -958,10 +958,11 @@
});

// Pass the ckeditor data to the form data if necessary
$(document).on('click', '.ckeditor-form [type="submit"]', function(event) {
$(this).closest('form').find("textarea[data-type=ckeditortype]").each(function() {
CKEDITOR.instances[$(this).attr('id')].updateElement();
})
$(document).on('click', '.ckeditor-form [type="submit"], .ckeditor-form [name="save"]', function(event) {
$(this).closest('form').find("textarea").each(function() {
const editor = CKEDITOR.instances[$(this).attr('id')];
if (editor) editor.updateElement();
});
});

})(jQuery)
Expand Down
1 change: 0 additions & 1 deletion templates/admission/general_education/checklist.html
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,6 @@
$('#list-group-link-financabilite').on('show.bs.tab', function() {
htmx.trigger('#financabilite-computed-rule', 'financabiliteComputeRule');
});

})(jQuery)

$('#merge-experience-form').on('submit', (e) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
hx-swap="outerHTML"
style="overflow: auto;"
id="financability-derogation-notification-form"
class="ckeditor-form"
>
<div class="modal-body" style="overflow:auto;">

Expand Down
95 changes: 95 additions & 0 deletions tests/views/doctorate/checklist/test_financability.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,17 @@ def test_post(self):
self.assertEqual(self.admission.last_update_author, self.sic_manager_user.person)
self.assertEqual(self.admission.modified_at, datetime.datetime.today())

def test_post_with_faculty_manager(self):
self.client.force_login(user=self.fac_manager_user)

response = self.client.post(
self.url,
**self.default_headers,
)

# Check the response
self.assertEqual(response.status_code, 403)


@freezegun.freeze_time('2022-01-01')
class FinancabiliteNotFinanceableSetRuleViewTestCase(TestCase):
Expand Down Expand Up @@ -282,6 +293,17 @@ def test_post(self):
self.assertEqual(self.admission.last_update_author, self.sic_manager_user.person)
self.assertEqual(self.admission.modified_at, datetime.datetime.today())

def test_post_with_faculty_manager(self):
self.client.force_login(user=self.fac_manager_user)

response = self.client.post(
self.url,
**self.default_headers,
)

# Check the response
self.assertEqual(response.status_code, 403)


@freezegun.freeze_time('2022-01-01')
class FinancabiliteNotFinanceableViewTestCase(TestCase):
Expand Down Expand Up @@ -343,6 +365,17 @@ def test_post(self):
self.assertEqual(self.admission.last_update_author, self.sic_manager_user.person)
self.assertEqual(self.admission.modified_at, datetime.datetime.today())

def test_post_with_faculty_manager(self):
self.client.force_login(user=self.fac_manager_user)

response = self.client.post(
self.url,
**self.default_headers,
)

# Check the response
self.assertEqual(response.status_code, 403)


class FinancabiliteDerogationViewTestCase(TestCase):
@classmethod
Expand Down Expand Up @@ -390,6 +423,16 @@ def test_non_concerne_post(self):
)
self.assertEqual(self.admission.last_update_author, self.sic_manager_user.person)

self.client.force_login(user=self.fac_manager_user)

response = self.client.post(
url,
**self.default_headers,
)

# Check the response
self.assertEqual(response.status_code, 403)

def test_abandon_candidat_post(self):
self.client.force_login(user=self.sic_manager_user)

Expand All @@ -412,6 +455,16 @@ def test_abandon_candidat_post(self):
DerogationFinancement.ABANDON_DU_CANDIDAT.name,
)

self.client.force_login(user=self.fac_manager_user)

response = self.client.post(
url,
**self.default_headers,
)

# Check the response
self.assertEqual(response.status_code, 403)

def test_refus_post(self):
self.client.force_login(user=self.sic_manager_user)

Expand All @@ -435,6 +488,16 @@ def test_refus_post(self):
DerogationFinancement.REFUS_DE_DEROGATION_FACULTAIRE.name,
)

self.client.force_login(user=self.fac_manager_user)

response = self.client.post(
url,
**self.default_headers,
)

# Check the response
self.assertEqual(response.status_code, 403)

def test_refus_post_with_other_reasons(self):
self.client.force_login(user=self.sic_manager_user)

Expand Down Expand Up @@ -491,6 +554,16 @@ def test_accord_post(self):
DerogationFinancement.ACCORD_DE_DEROGATION_FACULTAIRE.name,
)

self.client.force_login(user=self.fac_manager_user)

response = self.client.post(
url,
**self.default_headers,
)

# Check the response
self.assertEqual(response.status_code, 403)

def test_notification_candidat(self):
self.client.force_login(user=self.sic_manager_user)

Expand All @@ -515,6 +588,16 @@ def test_notification_candidat(self):
self.assertEqual(self.admission.financability_dispensation_status, DerogationFinancement.CANDIDAT_NOTIFIE.name)
self.assertEqual(self.admission.financability_dispensation_first_notification_by, self.sic_manager_user.person)

self.client.force_login(user=self.fac_manager_user)

response = self.client.post(
url,
**self.default_headers,
)

# Check the response
self.assertEqual(response.status_code, 403)


@freezegun.freeze_time('2022-01-01')
class FinancabiliteNotConcernedViewTestCase(TestCase):
Expand All @@ -531,6 +614,7 @@ def setUpTestData(cls):
)

cls.sic_manager_user = SicManagementRoleFactory(entity=cls.first_doctoral_commission).person.user
cls.fac_manager_user = ProgramManagerRoleFactory(education_group=cls.training.education_group).person.user
cls.admission: DoctorateAdmission = DoctorateAdmissionFactory(
training=cls.training,
candidate=CompletePersonFactory(language=settings.LANGUAGE_CODE_FR),
Expand Down Expand Up @@ -571,3 +655,14 @@ def test_post(self):
)
self.assertEqual(self.admission.last_update_author, self.sic_manager_user.person)
self.assertEqual(self.admission.modified_at, datetime.datetime.today())

def test_post_with_faculty_manager(self):
self.client.force_login(user=self.fac_manager_user)

response = self.client.post(
self.url,
**self.default_headers,
)

# Check the response
self.assertEqual(response.status_code, 403)
8 changes: 0 additions & 8 deletions views/doctorate/details/checklist/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ def checklist_documents_by_tab(cls, specific_questions: List[QuestionSpecifiqueD
documents_by_tab = {
OngletsChecklist.assimilation.name: assimilation_documents,
OngletsChecklist.financabilite.name: {
'DIPLOME_EQUIVALENCE',
'DIPLOME_BELGE_CERTIFICAT_INSCRIPTION',
'DIPLOME_ETRANGER_CERTIFICAT_INSCRIPTION',
'DIPLOME_ETRANGER_TRADUCTION_CERTIFICAT_INSCRIPTION',
Expand All @@ -174,9 +173,7 @@ def checklist_documents_by_tab(cls, specific_questions: List[QuestionSpecifiqueD
OngletsChecklist.choix_formation.name: {},
OngletsChecklist.parcours_anterieur.name: {
'ATTESTATION_ABSENCE_DETTE_ETABLISSEMENT',
'DIPLOME_EQUIVALENCE',
'CURRICULUM',
'ADDITIONAL_DOCUMENTS',
*secondary_studies_attachments,
},
OngletsChecklist.donnees_personnelles.name: assimilation_documents,
Expand Down Expand Up @@ -265,10 +262,6 @@ def get_context_data(self, **kwargs):
tab_names.append('decision_sic__derogation')
tab_names.append('financabilite__derogation')

comments_labels = {
'decision_sic__derogation': _('Comment about dispensation'),
'financabilite__derogation': _('Faculty comment about financability dispensation'),
}
comments_permissions = {
'financabilite__derogation': 'admission.checklist_change_fac_comment',
}
Expand All @@ -284,7 +277,6 @@ def get_context_data(self, **kwargs):
comment=comments.get(tab_name, None),
form_url=resolve_url(f'{self.base_namespace}:save-comment', uuid=self.admission_uuid, tab=tab_name),
prefix=tab_name,
label=comments_labels.get(tab_name, None),
permission=comments_permissions.get(tab_name, None),
)
for tab_name in tab_names
Expand Down
22 changes: 12 additions & 10 deletions views/doctorate/details/checklist/financeability.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,17 @@ def get_context_data(self, **kwargs):
context['financability_dispensation_notification_form'] = self.financability_dispensation_notification_form

if self.request.htmx:
comment = CommentEntry.objects.filter(
object_uuid=self.admission_uuid, tags__contains=['financabilite']
).first()
comment_derogation = CommentEntry.objects.filter(
object_uuid=self.admission_uuid, tags__contains=['financabilite__derogation']
).first()
comments = {
('__'.join(c.tags)): c
for c in CommentEntry.objects.filter(
object_uuid=self.admission_uuid,
tags__contains=['financabilite'],
)
}

context['comment_forms'] = {
'financabilite': CommentForm(
comment=comment,
comment=comments.get('financabilite'),
form_url=resolve_url(
f'{self.base_namespace}:save-comment',
uuid=self.admission_uuid,
Expand All @@ -242,12 +243,13 @@ def get_context_data(self, **kwargs):
prefix='financabilite',
),
'financabilite__derogation': CommentForm(
comment=comment_derogation,
comment=comments.get('financabilite__derogation'),
form_url=resolve_url(
f'{self.base_namespace}:save-comment', uuid=self.admission_uuid, tab='financabilite__derogation'
f'{self.base_namespace}:save-comment',
uuid=self.admission_uuid,
tab='financabilite__derogation',
),
prefix='financabilite__derogation',
label=_('Faculty comment about financability dispensation'),
permission='admission.checklist_change_fac_comment',
),
}
Expand Down
Loading