diff --git a/app/api/jury.py b/app/api/jury.py
index 190c9aff6d583fb55d6714a533decfed5986385f..528faa435c00f75dd9069194f8e2e114fc838a7e 100644
--- a/app/api/jury.py
+++ b/app/api/jury.py
@@ -54,25 +54,22 @@ from app.scodoc.sco_utils import json_error
 @as_json
 def decisions_jury(formsemestre_id: int):
     """Décisions du jury des étudiants du formsemestre.
-    (fonction disponible uniquement en BUT actuellement).
 
     SAMPLES
     -------
     /formsemestre/1/decisions_jury
     """
     # APC, pair:
-    formsemestre: FormSemestre = db.session.get(FormSemestre, formsemestre_id)
+    formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
     if formsemestre is None:
         return json_error(
             404,
             message="formsemestre inconnu",
         )
-    if formsemestre.formation.is_apc():
-        app.set_sco_dept(formsemestre.departement.acronym)
-        rows = jury_but_results.get_jury_but_results(formsemestre)
-        return rows
-    else:
-        raise ScoException("non implemente")
+
+    app.set_sco_dept(formsemestre.departement.acronym)
+    rows = jury_but_results.get_jury_but_results(formsemestre)
+    return rows
 
 
 def _news_delete_jury_etud(etud: Identite, detail: str = ""):
diff --git a/app/but/jury_but_results.py b/app/but/jury_but_results.py
index 044c966694b3426a286210ed623426a901ed8d25..d55ea1576fe0f96e9931cdbfbc88cab7f7d933b1 100644
--- a/app/but/jury_but_results.py
+++ b/app/but/jury_but_results.py
@@ -16,8 +16,11 @@ from app.scodoc import sco_pv_dict
 
 
 def get_jury_but_results(formsemestre: FormSemestre) -> list[dict]:
-    """Liste des résultats jury BUT sous forme de dict, pour API"""
-    if formsemestre.formation.referentiel_competence is None:
+    """Liste des résultats jury BUT ou classique sous forme de dict, pour API"""
+    if (
+        formsemestre.formation.is_apc()
+        and formsemestre.formation.referentiel_competence is None
+    ):
         # pas de ref. comp., donc pas de decisions de jury (ne lance pas d'exception)
         return []
     dpv = sco_pv_dict.dict_pvjury(formsemestre.id)
@@ -30,7 +33,7 @@ def get_jury_but_results(formsemestre: FormSemestre) -> list[dict]:
 def _get_jury_but_etud_result(
     formsemestre: FormSemestre, dpv: dict, etudid: int
 ) -> dict:
-    """Résultats de jury d'un étudiant sur un semestre pair de BUT"""
+    """Résultats de jury d'un étudiant sur un semestre, sous forme de dict"""
     etud = Identite.get_etud(etudid)
     dec_etud = dpv["decisions_dict"][etudid]
     if formsemestre.formation.is_apc():
diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py
index 990eea672aa88a97de114f8cb4f5dc04ba2daf4a..4afd6a3f34af7895d7a2c1ad58ba8ae17b351c44 100644
--- a/app/models/formsemestre.py
+++ b/app/models/formsemestre.py
@@ -202,22 +202,33 @@ class FormSemestre(models.ScoDocModel):
 
     @classmethod
     def get_formsemestre(
-        cls, formsemestre_id: int | str, dept_id: int = None
-    ) -> "FormSemestre":
-        """FormSemestre ou 404, cherche uniquement dans le département spécifié
-        ou le courant (g.scodoc_dept)"""
+        cls, formsemestre_id: int | str, dept_id: int = None, accept_none=False
+    ) -> "FormSemestre | None":
+        """FormSemestre ou 404 (ou None si accept_none), cherche uniquement dans
+        le département spécifié ou le courant (g.scodoc_dept).
+        Si accept_none, return None si l'id est invalide ou ne correspond
+        pas à un formsemestre.
+        """
         if not isinstance(formsemestre_id, int):
             try:
                 formsemestre_id = int(formsemestre_id)
             except (TypeError, ValueError):
+                if accept_none:
+                    return None
                 abort(404, "formsemestre_id invalide")
-        if g.scodoc_dept:
-            dept_id = dept_id if dept_id is not None else g.scodoc_dept_id
-        if dept_id is not None:
-            return cls.query.filter_by(
-                id=formsemestre_id, dept_id=dept_id
-            ).first_or_404()
-        return cls.query.filter_by(id=formsemestre_id).first_or_404()
+
+        dept_id = (
+            dept_id
+            if dept_id is not None
+            else (g.scodoc_dept_id if g.scodoc_dept else None)
+        )
+
+        query = (
+            cls.query.filter_by(id=formsemestre_id)
+            if dept_id is None
+            else cls.query.filter_by(id=formsemestre_id, dept_id=dept_id)
+        )
+        return query.first() if accept_none else query.first_or_404()
 
     @classmethod
     def create_formsemestre(cls, args: dict, silent=False) -> "FormSemestre":
diff --git a/app/scodoc/sco_dump_db.py b/app/scodoc/sco_dump_db.py
index b7a5f8aba41b26bba3e11ae3c9d43e0bb10396ee..f1f8b1522cbce1c8ae4e60a5eab54f53905b5f82 100644
--- a/app/scodoc/sco_dump_db.py
+++ b/app/scodoc/sco_dump_db.py
@@ -53,7 +53,7 @@ import subprocess
 
 import requests
 
-from flask import g, request
+from flask import current_app, g, request
 from flask_login import current_user
 
 import app.scodoc.notesdb as ndb
@@ -184,6 +184,7 @@ def _send_db(
                 "serial": _get_scodoc_serial(),
                 "sco_user": str(current_user),
                 "sent_by": f'"{current_user.get_nomcomplet()}" <{current_user.email}>',
+                "admin_mail": current_app.config.get("SCODOC_ADMIN_MAIL"),
                 "sco_version": sco_version.SCOVERSION,
                 "sco_fullversion": scu.get_scodoc_version(),
                 "traceback_str": traceback_str,
diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py
index 5dc218e9cce42d7c762fc1b92c4ae2e22a63f91d..c47cca531886fc8cfbb40e034a80978a587d04c6 100644
--- a/app/scodoc/sco_edit_ue.py
+++ b/app/scodoc/sco_edit_ue.py
@@ -683,9 +683,7 @@ def ue_table(formation_id=None, semestre_idx=1, msg=""):  # was ue_list
     """
     from app.scodoc import sco_formsemestre_validation
 
-    formation: Formation = db.session.get(Formation, formation_id)
-    if not formation:
-        raise ScoValueError("invalid formation_id")
+    formation = Formation.get_formation(formation_id)
     parcours = formation.get_cursus()
     is_apc = parcours.APC_SAE
     if semestre_idx == "all" or semestre_idx == "":
diff --git a/app/scodoc/sco_formations.py b/app/scodoc/sco_formations.py
index 2fc63a347839e078f1a999b9509eeb9e4c34fe68..e86b371dc1966647bc3097f5c7932a012953cb4c 100644
--- a/app/scodoc/sco_formations.py
+++ b/app/scodoc/sco_formations.py
@@ -218,7 +218,7 @@ def formation_export(
     export_external_ues=False,
     export_codes_apo=True,
     fmt=None,
-) -> flask.Response:
+) -> flask.Response | dict:
     """Get a formation, with UE, matieres, modules
     in desired format
     """
@@ -233,6 +233,9 @@ def formation_export(
         export_codes_apo=export_codes_apo,
         ac_as_list=fmt == "xml",
     )
+    if fmt is None:
+        return f_dict
+
     filename = f"scodoc_formation_{formation.departement.acronym}_{formation.acronyme or ''}_v{formation.version}"
     return scu.sendResult(
         f_dict,