From ec35ee0ab93bfd11ac6df37eb54535e53f0403e9 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet <emmanuel.viennet@gmail.com>
Date: Sat, 17 Dec 2022 23:14:13 -0300
Subject: [PATCH] Pas d'UEs externes en BUT. Voir #542

---
 app/models/formsemestre.py     |  2 +-
 app/scodoc/sco_bulletins.py    |  3 ++-
 app/scodoc/sco_saisie_notes.py |  8 ++++----
 app/scodoc/sco_ue_external.py  | 37 +++++++++++++++++++---------------
 4 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py
index 1c00d633a..1da6feffb 100644
--- a/app/models/formsemestre.py
+++ b/app/models/formsemestre.py
@@ -349,7 +349,7 @@ class FormSemestre(db.Model):
         return [ModuleImpl.query.get(modimpl_id) for modimpl_id in cursor]
 
     def can_be_edited_by(self, user):
-        """Vrai si user peut modifier ce semestre"""
+        """Vrai si user peut modifier ce semestre (est chef ou l'un des responsables)"""
         if not user.has_permission(Permission.ScoImplement):  # pas chef
             if not self.resp_can_edit or user.id not in [
                 resp.id for resp in self.responsables
diff --git a/app/scodoc/sco_bulletins.py b/app/scodoc/sco_bulletins.py
index 9a98d6fe6..410b3972a 100644
--- a/app/scodoc/sco_bulletins.py
+++ b/app/scodoc/sco_bulletins.py
@@ -1217,7 +1217,8 @@ def make_menu_autres_operations(
                 "formsemestre_id": formsemestre.id,
                 "etudid": etud.id,
             },
-            "enabled": sco_permissions_check.can_validate_sem(formsemestre.id),
+            "enabled": sco_permissions_check.can_validate_sem(formsemestre.id)
+            and not formsemestre.formation.is_apc(),
         },
         {
             "title": "Entrer décisions jury",
diff --git a/app/scodoc/sco_saisie_notes.py b/app/scodoc/sco_saisie_notes.py
index c4b89b09e..81e92d517 100644
--- a/app/scodoc/sco_saisie_notes.py
+++ b/app/scodoc/sco_saisie_notes.py
@@ -77,10 +77,10 @@ def convert_note_from_string(
     note,
     note_max,
     note_min=scu.NOTES_MIN,
-    etudid=None,
-    absents=None,
-    tosuppress=None,
-    invalids=None,
+    etudid: int = None,
+    absents: list[int] = None,
+    tosuppress: list[int] = None,
+    invalids: list[int] = None,
 ):
     """converti une valeur (chaine saisie) vers une note numérique (float)
     Les listes absents, tosuppress et invalids sont modifiées
diff --git a/app/scodoc/sco_ue_external.py b/app/scodoc/sco_ue_external.py
index 0e17492c9..8a8cff2b1 100644
--- a/app/scodoc/sco_ue_external.py
+++ b/app/scodoc/sco_ue_external.py
@@ -54,7 +54,7 @@ Solution proposée (nov 2014):
 
 """
 import flask
-from flask import flash, request
+from flask import flash, g, request, url_for
 from flask_login import current_user
 from app.models.formsemestre import FormSemestre
 
@@ -68,8 +68,6 @@ from app.scodoc import sco_edit_matiere
 from app.scodoc import sco_edit_module
 from app.scodoc import sco_edit_ue
 from app.scodoc import sco_evaluation_db
-from app.scodoc import sco_formations
-from app.scodoc import sco_formsemestre
 from app.scodoc import sco_moduleimpl
 from app.scodoc import sco_saisie_notes
 from app.scodoc import sco_etud
@@ -217,7 +215,7 @@ def get_external_moduleimpl_id(formsemestre_id: int, ue_id: int) -> int:
         )
 
 
-# Web function
+# Web view
 def external_ue_create_form(formsemestre_id: int, etudid: int):
     """Formulaire création UE externe + inscription étudiant et saisie note
     - Demande UE: peut-être existante (liste les UE externes de cette formation),
@@ -226,15 +224,18 @@ def external_ue_create_form(formsemestre_id: int, etudid: int):
 
     Note: pour l'édition éventuelle de ces informations, on utilisera les
     fonctions standards sur les UE/modules/notes
+
+    En BUT, pas d'UEs externes. Voir https://scodoc.org/git/ScoDoc/ScoDoc/issues/542
     """
-    sem = sco_formsemestre.get_formsemestre(formsemestre_id)
+    formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
     # Contrôle d'accès:
-    if not current_user.has_permission(Permission.ScoImplement):
-        if not sem["resp_can_edit"] or (current_user.id not in sem["responsables"]):
-            raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
+    if not formsemestre.can_be_edited_by(current_user):
+        raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
+    if formsemestre.formation.is_apc():
+        raise ScoValueError("Impossible d'ajouter une UE externe en BUT")
 
     etud = sco_etud.get_etud_info(filled=True, etudid=etudid)[0]
-    formation_id = sem["formation_id"]
+    formation_id = formsemestre.formation.id
     existing_external_ue = get_existing_external_ue(formation_id)
 
     H = [
@@ -251,8 +252,7 @@ def external_ue_create_form(formsemestre_id: int, etudid: int):
     """,
     ]
     html_footer = html_sco_header.sco_footer()
-    Fo = sco_formations.formation_list(args={"formation_id": sem["formation_id"]})[0]
-    parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"])
+    parcours = formsemestre.formation.get_parcours()
     ue_types = [
         typ for typ in parcours.ALLOWED_UE_TYPES if typ != sco_codes_parcours.UE_SPORT
     ]
@@ -341,9 +341,11 @@ def external_ue_create_form(formsemestre_id: int, etudid: int):
         cancelbutton="Annuler",
     )
 
-    bull_url = "formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" % (
-        formsemestre_id,
-        etudid,
+    bull_url = url_for(
+        "notes.formsemestre_bulletinetud",
+        scodoc_dept=g.scodoc_dept,
+        formsemestre_id=formsemestre_id,
+        etudid=etudid,
     )
     if tf[0] == 0:
         return "\n".join(H) + "\n" + tf[1] + html_footer
@@ -351,7 +353,9 @@ def external_ue_create_form(formsemestre_id: int, etudid: int):
         return flask.redirect(bull_url)
     else:
         note = tf[2]["note"].strip().upper()
-        note_value, invalid = sco_saisie_notes.convert_note_from_string(note, 20.0)
+        note_value, invalid = sco_saisie_notes.convert_note_from_string(
+            note, 20.0, etudid=etudid, absents=[], tosuppress=[], invalids=[]
+        )
         if invalid:
             return (
                 "\n".join(H)
@@ -386,4 +390,5 @@ def external_ue_create_form(formsemestre_id: int, etudid: int):
             formsemestre_id,
             {etudid: note_value},
         )
-        return flask.redirect(bull_url + "&head_message=Ajout%20effectué")
+        flash("Ajout effectué")
+        return flask.redirect(bull_url)