diff --git a/app/api/formations.py b/app/api/formations.py
index 7c6bd4930c3c0417df4a7653fe57c491f8896f26..ac5c10e2ac138a7736240dde9b153ac9182045c7 100644
--- a/app/api/formations.py
+++ b/app/api/formations.py
@@ -368,6 +368,8 @@ def get_module(module_id: int):
return module.to_dict(convert_objects=True)
+@bp.route("/ue/set_code_apogee", methods=["POST"])
+@api_web_bp.route("/ue/set_code_apogee", methods=["POST"])
@bp.route("/ue/<int:ue_id>/set_code_apogee/<string:code_apogee>", methods=["POST"])
@api_web_bp.route(
"/ue/<int:ue_id>/set_code_apogee/<string:code_apogee>", methods=["POST"]
@@ -381,17 +383,22 @@ def get_module(module_id: int):
@login_required
@scodoc
@permission_required(Permission.EditFormation)
-def ue_set_code_apogee(ue_id: int, code_apogee: str = ""):
+def ue_set_code_apogee(ue_id: int | None = None, code_apogee: str = ""):
"""Change le code Apogée de l'UE.
Le code est une chaîne, avec éventuellement plusieurs valeurs séparées
par des virgules.
(Ce changement peut être fait sur formation verrouillée)
+ Si ue_id n'est pas spécifié, utilise l'argument oid du POST.
Si code_apogee n'est pas spécifié ou vide,
- utilise l'argument value du POST (utilisé par jinplace.js)
+ utilise l'argument value du POST
Le retour est une chaîne (le code enregistré), pas json.
"""
+ if ue_id is None:
+ ue_id = request.form.get("oid")
+ if ue_id is None:
+ return json_error(404, "argument oid manquant")
if not code_apogee:
code_apogee = request.form.get("value", "")
query = UniteEns.query.filter_by(id=ue_id)
@@ -454,6 +461,8 @@ def ue_set_code_apogee_rcue(ue_id: int, code_apogee: str = ""):
return code_apogee or ""
+@bp.route("/module/set_code_apogee", methods=["POST"])
+@api_web_bp.route("/module/set_code_apogee", methods=["POST"])
@bp.route(
"/module/<int:module_id>/set_code_apogee/<string:code_apogee>",
methods=["POST"],
@@ -475,17 +484,22 @@ def ue_set_code_apogee_rcue(ue_id: int, code_apogee: str = ""):
@login_required
@scodoc
@permission_required(Permission.EditFormation)
-def module_set_code_apogee(module_id: int, code_apogee: str = ""):
+def module_set_code_apogee(module_id: int | None = None, code_apogee: str = ""):
"""Change le code Apogée du module.
Le code est une chaîne, avec éventuellement plusieurs valeurs séparées
par des virgules.
(Ce changement peut être fait sur formation verrouillée)
+ Si module_id n'est pas spécifié, utilise l'argument oid du POST.
Si code_apogee n'est pas spécifié ou vide,
utilise l'argument value du POST (utilisé par jinplace.js)
Le retour est une chaîne (le code enregistré), pas json.
"""
+ if module_id is None:
+ module_id = request.form.get("oid")
+ if module_id is None:
+ return json_error(404, "argument oid manquant")
if not code_apogee:
code_apogee = request.form.get("value", "")
query = Module.query.filter_by(id=module_id)
diff --git a/app/api/formsemestres.py b/app/api/formsemestres.py
index 7d91516dd92cc9ce57b3a3da7667fef944f02a58..6239c127836a9a8ae6cc4a5e12884981cb70a75c 100644
--- a/app/api/formsemestres.py
+++ b/app/api/formsemestres.py
@@ -14,7 +14,7 @@ from flask_json import as_json
from flask_login import current_user, login_required
import sqlalchemy as sa
import app
-from app import db
+from app import db, log
from app.api import api_bp as bp, api_web_bp, API_CLIENT_ERROR
from app.decorators import scodoc, permission_required
from app.scodoc.sco_utils import json_error
@@ -64,6 +64,7 @@ def formsemestre_infos(formsemestre_id: int):
"date_fin": "31/08/2022",
"dept_id": 1,
"elt_annee_apo": null,
+ "elt_passage_apo" : null,
"elt_sem_apo": null,
"ens_can_edit_eval": false,
"etat": true,
@@ -220,6 +221,127 @@ def formsemestre_edit(formsemestre_id: int):
return formsemestre.to_dict_api()
+@bp.route("/formsemestre/apo/set_etapes", methods=["POST"])
+@api_web_bp.route("/formsemestre/apo/set_etapes", methods=["POST"])
+@scodoc
+@permission_required(Permission.EditApogee)
+def formsemestre_set_apo_etapes():
+ """Change les codes étapes du semestre indiqué.
+ Le code est une chaîne, avec éventuellement plusieurs valeurs séparées
+ par des virgules.
+ (Ce changement peut être fait sur un semestre verrouillé)
+
+ Args:
+ oid=int, le formsemestre_id
+ value=chaine "V1RT, V1RT2", codes séparés par des virgules
+ """
+ formsemestre_id = int(request.form.get("oid"))
+ etapes_apo_str = request.form.get("value")
+ formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
+
+ current_etapes = {e.etape_apo for e in formsemestre.etapes}
+ new_etapes = {s.strip() for s in etapes_apo_str.split(",")}
+
+ if new_etapes != current_etapes:
+ formsemestre.etapes = []
+ for etape_apo in new_etapes:
+ etape = FormSemestreEtape(
+ formsemestre_id=formsemestre_id, etape_apo=etape_apo
+ )
+ formsemestre.etapes.append(etape)
+ db.session.add(formsemestre)
+ db.session.commit()
+ log(
+ f"""API formsemestre_set_apo_etapes: formsemestre_id={
+ formsemestre.id} code_apogee={etapes_apo_str}"""
+ )
+ return ("", 204)
+
+
+@bp.route("/formsemestre/apo/set_elt_sem", methods=["POST"])
+@api_web_bp.route("/formsemestre/apo/set_elt_sem", methods=["POST"])
+@scodoc
+@permission_required(Permission.EditApogee)
+def formsemestre_set_elt_sem_apo():
+ """Change les codes étapes du semestre indiqué.
+ Le code est une chaîne, avec éventuellement plusieurs valeurs séparées
+ par des virgules.
+ (Ce changement peut être fait sur un semestre verrouillé)
+
+ Args:
+ oid=int, le formsemestre_id
+ value=chaine "V3ONM, V3ONM1, V3ONM2", codes séparés par des virgules
+ """
+ oid = int(request.form.get("oid"))
+ value = (request.form.get("value") or "").strip()
+ formsemestre = FormSemestre.get_formsemestre(oid)
+ if value != formsemestre.elt_sem_apo:
+ formsemestre.elt_sem_apo = value
+ db.session.add(formsemestre)
+ db.session.commit()
+ log(
+ f"""API formsemestre_set_elt_sem_apo: formsemestre_id={
+ formsemestre.id} code_apogee={value}"""
+ )
+ return ("", 204)
+
+
+@bp.route("/formsemestre/apo/set_elt_annee", methods=["POST"])
+@api_web_bp.route("/formsemestre/apo/set_elt_annee", methods=["POST"])
+@scodoc
+@permission_required(Permission.EditApogee)
+def formsemestre_set_elt_annee_apo():
+ """Change les codes étapes du semestre indiqué (par le champ oid).
+ Le code est une chaîne, avec éventuellement plusieurs valeurs séparées
+ par des virgules.
+ (Ce changement peut être fait sur un semestre verrouillé)
+
+ Args:
+ oid=int, le formsemestre_id
+ value=chaine "V3ONM, V3ONM1, V3ONM2", codes séparés par des virgules
+ """
+ oid = int(request.form.get("oid"))
+ value = (request.form.get("value") or "").strip()
+ formsemestre = FormSemestre.get_formsemestre(oid)
+ if value != formsemestre.elt_annee_apo:
+ formsemestre.elt_annee_apo = value
+ db.session.add(formsemestre)
+ db.session.commit()
+ log(
+ f"""API formsemestre_set_elt_annee_apo: formsemestre_id={
+ formsemestre.id} code_apogee={value}"""
+ )
+ return ("", 204)
+
+
+@bp.route("/formsemestre/apo/set_elt_passage", methods=["POST"])
+@api_web_bp.route("/formsemestre/apo/set_elt_passage", methods=["POST"])
+@scodoc
+@permission_required(Permission.EditApogee)
+def formsemestre_set_elt_passage_apo():
+ """Change les codes apogée de passage du semestre indiqué (par le champ oid).
+ Le code est une chaîne, avec éventuellement plusieurs valeurs séparées
+ par des virgules.
+ (Ce changement peut être fait sur un semestre verrouillé)
+
+ Args:
+ oid=int, le formsemestre_id
+ value=chaine "V3ONM, V3ONM1, V3ONM2", codes séparés par des virgules
+ """
+ oid = int(request.form.get("oid"))
+ value = (request.form.get("value") or "").strip()
+ formsemestre = FormSemestre.get_formsemestre(oid)
+ if value != formsemestre.elt_annee_apo:
+ formsemestre.elt_passage_apo = value
+ db.session.add(formsemestre)
+ db.session.commit()
+ log(
+ f"""API formsemestre_set_elt_passage_apo: formsemestre_id={
+ formsemestre.id} code_apogee={value}"""
+ )
+ return ("", 204)
+
+
@bp.route("/formsemestre/<int:formsemestre_id>/bulletins")
@bp.route("/formsemestre/<int:formsemestre_id>/bulletins/<string:version>")
@api_web_bp.route("/formsemestre/<int:formsemestre_id>/bulletins")
diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py
index eb10f57b7444b6879e785d3fe84f75e9b8dcac99..b0a77139cc2fa0d55b1338623cb4c2e1ed5f626a 100644
--- a/app/models/formsemestre.py
+++ b/app/models/formsemestre.py
@@ -123,9 +123,11 @@ class FormSemestre(models.ScoDocModel):
)
"autorise les enseignants à créer des évals dans leurs modimpls"
elt_sem_apo = db.Column(db.Text()) # peut être fort long !
- "code element semestre Apogee, eg 'VRTW1' ou 'V2INCS4,V2INLS4,...'"
+ "code element semestre Apogée, eg 'VRTW1' ou 'V2INCS4,V2INLS4,...'"
elt_annee_apo = db.Column(db.Text())
"code element annee Apogee, eg 'VRT1A' ou 'V2INLA,V2INCA,...'"
+ elt_passage_apo = db.Column(db.Text())
+ "code element passage Apogée"
# Data pour groups_auto_assignment
# (ce champ est utilisé uniquement via l'API par le front js)
@@ -993,7 +995,12 @@ class FormSemestre(models.ScoDocModel):
def get_codes_apogee(self, category=None) -> set[str]:
"""Les codes Apogée (codés en base comme "VRT1,VRT2")
- category: None: tous, "etapes": étapes associées, "sem: code semestre", "annee": code annuel
+ category:
+ None: tous,
+ "etapes": étapes associées,
+ "sem: code semestre"
+ "annee": code annuel
+ "passage": code passage
"""
codes = set()
if category is None or category == "etapes":
@@ -1002,6 +1009,8 @@ class FormSemestre(models.ScoDocModel):
codes |= {x.strip() for x in self.elt_sem_apo.split(",") if x}
if (category is None or category == "annee") and self.elt_annee_apo:
codes |= {x.strip() for x in self.elt_annee_apo.split(",") if x}
+ if (category is None or category == "passage") and self.elt_passage_apo:
+ codes |= {x.strip() for x in self.elt_passage_apo.split(",") if x}
return codes
def get_inscrits(self, include_demdef=False, order=False) -> list[Identite]:
diff --git a/app/scodoc/sco_dept.py b/app/scodoc/sco_dept.py
index 6a0ee01460e3e2ff142a5efccf6ebfb8466eb3fe..e033a89a54f60144e1a375ccd1012dd27cbd010f 100644
--- a/app/scodoc/sco_dept.py
+++ b/app/scodoc/sco_dept.py
@@ -137,6 +137,7 @@ def _convert_formsemestres_to_dicts(
"bul_hide_xml": formsemestre.bul_hide_xml,
"dateord": formsemestre.date_debut,
"elt_annee_apo": formsemestre.elt_annee_apo,
+ "elt_passage_apo": formsemestre.elt_passage_apo,
"elt_sem_apo": formsemestre.elt_sem_apo,
"etapes_apo_str": formsemestre.etapes_apo_str(),
"formation": f"{formation.acronyme} v{formation.version}",
@@ -189,6 +190,7 @@ def _sem_table_gt(formsemestres: Query, showcodes=False, fmt="html") -> GenTable
"formation",
"etapes_apo_str",
"elt_annee_apo",
+ "elt_passage_apo",
"elt_sem_apo",
]
if showcodes:
@@ -203,9 +205,18 @@ def _sem_table_gt(formsemestres: Query, showcodes=False, fmt="html") -> GenTable
html_class=html_class,
html_sortable=True,
html_table_attrs=f"""
- data-apo_save_url="{url_for('notes.formsemestre_set_apo_etapes', scodoc_dept=g.scodoc_dept)}"
- data-elt_annee_apo_save_url="{url_for('notes.formsemestre_set_elt_annee_apo', scodoc_dept=g.scodoc_dept)}"
- data-elt_sem_apo_save_url="{url_for('notes.formsemestre_set_elt_sem_apo', scodoc_dept=g.scodoc_dept)}"
+ data-apo_save_url="{
+ url_for('apiweb.formsemestre_set_apo_etapes', scodoc_dept=g.scodoc_dept)
+ }"
+ data-elt_annee_apo_save_url="{
+ url_for('apiweb.formsemestre_set_elt_annee_apo', scodoc_dept=g.scodoc_dept)
+ }"
+ data-elt_sem_apo_save_url="{
+ url_for('apiweb.formsemestre_set_elt_sem_apo', scodoc_dept=g.scodoc_dept)
+ }"
+ data-elt_passage_apo_save_url="{
+ url_for('apiweb.formsemestre_set_elt_passage_apo', scodoc_dept=g.scodoc_dept)
+ }"
""",
html_with_td_classes=True,
preferences=sco_preferences.SemPreferences(),
@@ -221,6 +232,7 @@ def _sem_table_gt(formsemestres: Query, showcodes=False, fmt="html") -> GenTable
"etapes_apo_str": "Étape Apo.",
"elt_annee_apo": "Elt. année Apo.",
"elt_sem_apo": "Elt. sem. Apo.",
+ "elt_passage_apo": "Elt. pass. Apo.",
"formation": "Formation",
},
table_id="semlist",
@@ -282,6 +294,9 @@ def _style_sems(sems: list[dict], fmt="html") -> list[dict]:
sem["_elt_sem_apo_td_attrs"] = (
f""" data-oid="{sem['formsemestre_id']}" data-value="{sem['elt_sem_apo']}" """
)
+ sem["_elt_passage_apo_td_attrs"] = (
+ f""" data-oid="{sem['formsemestre_id']}" data-value="{sem['elt_passage_apo']}" """
+ )
return sems
diff --git a/app/scodoc/sco_formation_recap.py b/app/scodoc/sco_formation_recap.py
index 3b5a923e9ee78ed28e33df858b319b1dc77317e3..f0074e4eb1cab69d8afe16b8eb2dd72c6fd7c84e 100644
--- a/app/scodoc/sco_formation_recap.py
+++ b/app/scodoc/sco_formation_recap.py
@@ -60,13 +60,15 @@ def formation_table_recap(formation_id, fmt="html") -> Response:
"_sem_order": f"{li:04d}",
"code": ue.acronyme,
"titre": ue.titre or "",
- "_titre_target": url_for(
- "notes.ue_edit",
- scodoc_dept=g.scodoc_dept,
- ue_id=ue.id,
- )
- if can_edit
- else None,
+ "_titre_target": (
+ url_for(
+ "notes.ue_edit",
+ scodoc_dept=g.scodoc_dept,
+ ue_id=ue.id,
+ )
+ if can_edit
+ else None
+ ),
"apo": ue.code_apogee or "",
"_apo_td_attrs": f""" data-oid="{ue.id}" data-value="{ue.code_apogee or ''}" """,
"coef": ue.coefficient or "",
@@ -83,19 +85,23 @@ def formation_table_recap(formation_id, fmt="html") -> Response:
# le module (ou ressource ou sae)
T.append(
{
- "sem": f"S{mod.semestre_id}"
- if mod.semestre_id is not None
- else "-",
+ "sem": (
+ f"S{mod.semestre_id}"
+ if mod.semestre_id is not None
+ else "-"
+ ),
"_sem_order": f"{li:04d}",
"code": mod.code,
"titre": mod.abbrev or mod.titre,
- "_titre_target": url_for(
- "notes.module_edit",
- scodoc_dept=g.scodoc_dept,
- module_id=mod.id,
- )
- if can_edit
- else None,
+ "_titre_target": (
+ url_for(
+ "notes.module_edit",
+ scodoc_dept=g.scodoc_dept,
+ module_id=mod.id,
+ )
+ if can_edit
+ else None
+ ),
"apo": mod.code_apogee,
"_apo_td_attrs": f""" data-oid="{mod.id}" data-value="{mod.code_apogee or ''}" """,
"coef": mod.coefficient,
@@ -154,8 +160,12 @@ def formation_table_recap(formation_id, fmt="html") -> Response:
html_class=html_class,
html_class_ignore_default=True,
html_table_attrs=f"""
- data-apo_ue_save_url="{url_for('notes.ue_set_apo', scodoc_dept=g.scodoc_dept)}"
- data-apo_mod_save_url="{url_for('notes.module_set_apo', scodoc_dept=g.scodoc_dept)}"
+ data-apo_ue_save_url="{
+ url_for('apiweb.ue_set_code_apogee', scodoc_dept=g.scodoc_dept)
+ }"
+ data-apo_mod_save_url="{
+ url_for('apiweb.module_set_code_apogee', scodoc_dept=g.scodoc_dept)
+ }"
""",
html_with_td_classes=True,
base_url=f"{request.base_url}?formation_id={formation_id}",
diff --git a/app/scodoc/sco_formsemestre.py b/app/scodoc/sco_formsemestre.py
index 16daef1a7bd1ace2a05602d85db666f2393efc6d..00ea831e374c4ffc40867ec3cf32a38d8ed421a5 100644
--- a/app/scodoc/sco_formsemestre.py
+++ b/app/scodoc/sco_formsemestre.py
@@ -39,7 +39,7 @@ import app.scodoc.sco_utils as scu
from app import log
from app.models import Departement
from app.models import Formation, FormSemestre
-from app.scodoc import sco_cache, codes_cursus, sco_formations, sco_preferences
+from app.scodoc import sco_cache, codes_cursus, sco_preferences
from app.scodoc.gen_tables import GenTable
from app.scodoc.codes_cursus import NO_SEMESTRE_ID
from app.scodoc.sco_exceptions import ScoInvalidIdType, ScoValueError
@@ -68,6 +68,7 @@ _formsemestreEditor = ndb.EditableTable(
"ens_can_edit_eval",
"elt_sem_apo",
"elt_annee_apo",
+ "elt_passage_apo",
"edt_id",
),
filter_dept=True,
diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py
index 70237d20bcc622c60a5d47624c8d4cab450d1473..d7e6349a7a676b21bcc77a05f3f638c5b50038d2 100644
--- a/app/scodoc/sco_formsemestre_edit.py
+++ b/app/scodoc/sco_formsemestre_edit.py
@@ -464,6 +464,17 @@ def do_formsemestre_createwithmodules(edit=False, formsemestre: FormSemestre = N
},
)
)
+ modform.append(
+ (
+ "elt_passage_apo",
+ {
+ "size": 32,
+ "title": "Element(s) Apogée passage:",
+ "explanation": "associé(s) au passage. Séparés par des virgules.",
+ "allow_null": True, # toujours optionnel car rarement utilisé
+ },
+ )
+ )
if ScoDocSiteConfig.get("edt_ics_path"):
modform.append(
(
diff --git a/app/static/js/scolar_index.js b/app/static/js/scolar_index.js
index 9b75eb0df0b5b173e6d0845c7f43e886f426d9a0..c2d09670bc8ab08896be020172db233d173e0d34 100644
--- a/app/static/js/scolar_index.js
+++ b/app/static/js/scolar_index.js
@@ -34,5 +34,9 @@ $(document).ready(function () {
save_url = document.querySelector("table#semlist.apo_editable").dataset
.elt_sem_apo_save_url;
elt_sem_apo_editor = new ScoFieldEditor(".elt_sem_apo", save_url, false);
+
+ save_url = document.querySelector("table#semlist.apo_editable").dataset
+ .elt_passage_apo_save_url;
+ elt_passage_apo_editor = new ScoFieldEditor(".elt_passage_apo", save_url, false);
}
});
diff --git a/app/views/notes.py b/app/views/notes.py
index da115d62dd3e27b222752cef906d557d2bca1312..d82f0de38fac596b9a5d7be33f3b15875c49f582 100644
--- a/app/views/notes.py
+++ b/app/views/notes.py
@@ -3123,123 +3123,6 @@ sco_publish(
)
-@bp.route("/formsemestre_set_apo_etapes", methods=["POST"])
-@scodoc
-@permission_required(Permission.EditApogee)
-def formsemestre_set_apo_etapes():
- """Change les codes étapes du semestre indiqué.
- Args: oid=formsemestre_id, value=chaine "V1RT, V1RT2", codes séparés par des virgules
- """
- formsemestre_id = int(request.form.get("oid"))
- etapes_apo_str = request.form.get("value")
- formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
- current_etapes = {e.etape_apo for e in formsemestre.etapes}
- new_etapes = {s.strip() for s in etapes_apo_str.split(",")}
-
- if new_etapes != current_etapes:
- formsemestre.etapes = []
- for etape_apo in new_etapes:
- etape = models.FormSemestreEtape(
- formsemestre_id=formsemestre_id, etape_apo=etape_apo
- )
- formsemestre.etapes.append(etape)
- db.session.add(formsemestre)
- db.session.commit()
- ScolarNews.add(
- typ=ScolarNews.NEWS_APO,
- text=f"Modification code Apogée du semestre {formsemestre.titre_annee()})",
- )
- return ("", 204)
-
-
-@bp.route("/formsemestre_set_elt_annee_apo", methods=["POST"])
-@scodoc
-@permission_required(Permission.EditApogee)
-def formsemestre_set_elt_annee_apo():
- """Change les codes étapes du semestre indiqué.
- Args: oid=formsemestre_id, value=chaine "V3ONM, V3ONM1, V3ONM2", codes séparés par des virgules
- """
- oid = int(request.form.get("oid"))
- value = (request.form.get("value") or "").strip()
- formsemestre: FormSemestre = FormSemestre.query.get_or_404(oid)
- if value != formsemestre.elt_annee_apo:
- formsemestre.elt_annee_apo = value
- db.session.add(formsemestre)
- db.session.commit()
- ScolarNews.add(
- typ=ScolarNews.NEWS_APO,
- text=f"Modification code Apogée du semestre {formsemestre.titre_annee()})",
- )
- return ("", 204)
-
-
-@bp.route("/formsemestre_set_elt_sem_apo", methods=["POST"])
-@scodoc
-@permission_required(Permission.EditApogee)
-def formsemestre_set_elt_sem_apo():
- """Change les codes étapes du semestre indiqué.
- Args: oid=formsemestre_id, value=chaine "V3ONM, V3ONM1, V3ONM2", codes séparés par des virgules
- """
- try:
- oid = int(request.form.get("oid"))
- except (TypeError, ValueError) as exc:
- raise ScoValueError("paramètre invalide") from exc
- value = (request.form.get("value") or "").strip()
- formsemestre: FormSemestre = FormSemestre.query.get_or_404(oid)
- if value != formsemestre.elt_sem_apo:
- formsemestre.elt_sem_apo = value
- db.session.add(formsemestre)
- db.session.commit()
- ScolarNews.add(
- typ=ScolarNews.NEWS_APO,
- text=f"Modification code Apogée du semestre {formsemestre.titre_annee()})",
- )
- return ("", 204)
-
-
-@bp.route("/ue_set_apo", methods=["POST"])
-@scodoc
-@permission_required(Permission.EditApogee)
-def ue_set_apo():
- """Change le code APO de l'UE
- Args: oid=ue_id, value=chaine "VRTU12" (1 seul code / UE)
- """
- ue_id = int(request.form.get("oid"))
- code_apo = (request.form.get("value") or "").strip()
- ue = UniteEns.query.get_or_404(ue_id)
- if code_apo != ue.code_apogee:
- ue.code_apogee = code_apo
- db.session.add(ue)
- db.session.commit()
- ScolarNews.add(
- typ=ScolarNews.NEWS_FORM,
- text=f"Modification code Apogée d'UE dans la formation {ue.formation.titre} ({ue.formation.acronyme})",
- )
- return ("", 204)
-
-
-@bp.route("/module_set_apo", methods=["POST"])
-@scodoc
-@permission_required(Permission.EditApogee)
-def module_set_apo():
- """Change le code APO du module
- Args: oid=ue_id, value=chaine "VRTU12" (1 seul code / UE)
- """
- oid = int(request.form.get("oid"))
- code_apo = (request.form.get("value") or "").strip()
- mod = Module.query.get_or_404(oid)
- if code_apo != mod.code_apogee:
- mod.code_apogee = code_apo
- db.session.add(mod)
- db.session.commit()
- ScolarNews.add(
- typ=ScolarNews.NEWS_FORM,
- text=f"""Modification code Apogée d'UE dans la formation {
- mod.formation.titre} ({mod.formation.acronyme})""",
- )
- return ("", 204)
-
-
# sco_semset
sco_publish("/semset_page", sco_semset.semset_page, Permission.EditApogee)
sco_publish(
diff --git a/migrations/versions/07f37334727b_code_passage_apo.py b/migrations/versions/07f37334727b_code_passage_apo.py
new file mode 100644
index 0000000000000000000000000000000000000000..7f7a4147d533451c4d25929ec90e851a55aaf4f2
--- /dev/null
+++ b/migrations/versions/07f37334727b_code_passage_apo.py
@@ -0,0 +1,27 @@
+"""code_passage_apo
+
+Revision ID: 07f37334727b
+Revises: 809faa9d89ec
+Create Date: 2024-06-24 02:15:54.019156
+
+"""
+
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = "07f37334727b"
+down_revision = "809faa9d89ec"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ with op.batch_alter_table("notes_formsemestre", schema=None) as batch_op:
+ batch_op.add_column(sa.Column("elt_passage_apo", sa.Text(), nullable=True))
+
+
+def downgrade():
+ with op.batch_alter_table("notes_formsemestre", schema=None) as batch_op:
+ batch_op.drop_column("elt_passage_apo")