diff --git a/app/but/cursus_but.py b/app/but/cursus_but.py
index c72938a8fa5e7fb010566d441914e4316404b64a..b9a09f0b4759e602e7089e4b52e2e9a8dc5c94f1 100644
--- a/app/but/cursus_but.py
+++ b/app/but/cursus_but.py
@@ -29,7 +29,7 @@ from app.models.but_refcomp import (
     ApcReferentielCompetences,
 )
 from app.models.ues import UEParcours
-from app.models.but_validations import ApcValidationRCUE
+from app.models.but_validations import ApcValidationAnnee, ApcValidationRCUE
 from app.models.etudiants import Identite
 from app.models.formations import Formation
 from app.models.formsemestre import FormSemestre
@@ -42,7 +42,7 @@ from app.scodoc import sco_cursus_dut
 
 
 class SituationEtudCursusBUT(sco_cursus_dut.SituationEtudCursusClassic):
-    """Pour compat ScoDoc 7: à revoir pour le BUT"""
+    """Pour compat ScoDoc 7"""
 
     def __init__(self, etud: Identite, formsemestre_id: int, res: ResultatsSemestreBUT):
         super().__init__(etud, formsemestre_id, res)
@@ -54,8 +54,16 @@ class SituationEtudCursusBUT(sco_cursus_dut.SituationEtudCursusClassic):
         return False
 
     def parcours_validated(self):
-        "True si le parcours est validé"
-        return False  # XXX TODO
+        "True si le parcours (ici diplôme BUT) est validé"
+        # Si année 3 validée, ok
+        return any(
+            sco_codes.code_annee_validant(v.code)
+            for v in ApcValidationAnnee.query.filter_by(
+                etudid=self.etud.id,
+                ordre=3,
+                referentiel_competence_id=self.cur_sem.formation.referentiel_competence_id,
+            )
+        )
 
 
 class EtudCursusBUT:
@@ -287,81 +295,81 @@ class FormSemestreCursusBUT:
             )
         return niveaux_by_annee
 
-    def get_etud_validation_par_competence_et_annee(self, etud: Identite):
-        """{ competence_id : { 'BUT1' : validation_rcue (la "meilleure"), ... } }"""
-        validation_par_competence_et_annee = {}
-        for validation_rcue in ApcValidationRCUE.query.filter_by(etud=etud):
-            # On s'assurer qu'elle concerne notre cursus !
-            ue = validation_rcue.ue2
-            if ue.id not in self.ue_ids:
-                if (
-                    ue.formation.referentiel_competences_id
-                    == self.referentiel_competences_id
-                ):
-                    self.ue_ids = ue.id
-                else:
-                    continue  # skip this validation
-            niveau = validation_rcue.niveau()
-            if not niveau.competence.id in validation_par_competence_et_annee:
-                validation_par_competence_et_annee[niveau.competence.id] = {}
-            previous_validation = validation_par_competence_et_annee.get(
-                niveau.competence.id
-            ).get(validation_rcue.annee())
-            # prend la "meilleure" validation
-            if (not previous_validation) or (
-                sco_codes.BUT_CODES_ORDER[validation_rcue.code]
-                > sco_codes.BUT_CODES_ORDER[previous_validation["code"]]
-            ):
-                self.validation_par_competence_et_annee[niveau.competence.id][
-                    niveau.annee
-                ] = validation_rcue
-        return validation_par_competence_et_annee
-
-    def list_etud_inscriptions(self, etud: Identite):
-        "Le parcours à valider: celui du DERNIER semestre suivi (peut être None)"
-        self.niveaux_by_annee = {}
-        "{ annee : liste des niveaux à valider }"
-        self.niveaux: dict[int, ApcNiveau] = {}
-        "cache les niveaux"
-        for annee in (1, 2, 3):
-            niveaux_d = formation.referentiel_competence.get_niveaux_by_parcours(
-                annee, [self.parcour] if self.parcour else None  # XXX WIP
-            )[1]
-            # groupe les niveaux de tronc commun et ceux spécifiques au parcour
-            self.niveaux_by_annee[annee] = niveaux_d["TC"] + (
-                niveaux_d[self.parcour.id] if self.parcour else []
-            )
-            self.niveaux.update(
-                {niveau.id: niveau for niveau in self.niveaux_by_annee[annee]}
-            )
-
-        self.validation_par_competence_et_annee = {}
-        """{ competence_id : { 'BUT1' : validation_rcue (la "meilleure"), ... } }"""
-        for validation_rcue in ApcValidationRCUE.query.filter_by(etud=etud):
-            niveau = validation_rcue.niveau()
-            if not niveau.competence.id in self.validation_par_competence_et_annee:
-                self.validation_par_competence_et_annee[niveau.competence.id] = {}
-            previous_validation = self.validation_par_competence_et_annee.get(
-                niveau.competence.id
-            ).get(validation_rcue.annee())
-            # prend la "meilleure" validation
-            if (not previous_validation) or (
-                sco_codes.BUT_CODES_ORDER[validation_rcue.code]
-                > sco_codes.BUT_CODES_ORDER[previous_validation["code"]]
-            ):
-                self.validation_par_competence_et_annee[niveau.competence.id][
-                    niveau.annee
-                ] = validation_rcue
-
-        self.competences = {
-            competence.id: competence
-            for competence in (
-                self.parcour.query_competences()
-                if self.parcour
-                else self.formation.referentiel_competence.get_competences_tronc_commun()
-            )
-        }
-        "cache { competence_id : competence }"
+    # def get_etud_validation_par_competence_et_annee(self, etud: Identite):
+    #     """{ competence_id : { 'BUT1' : validation_rcue (la "meilleure"), ... } }"""
+    #     validation_par_competence_et_annee = {}
+    #     for validation_rcue in ApcValidationRCUE.query.filter_by(etud=etud):
+    #         # On s'assurer qu'elle concerne notre cursus !
+    #         ue = validation_rcue.ue2
+    #         if ue.id not in self.ue_ids:
+    #             if (
+    #                 ue.formation.referentiel_competences_id
+    #                 == self.referentiel_competences_id
+    #             ):
+    #                 self.ue_ids = ue.id
+    #             else:
+    #                 continue  # skip this validation
+    #         niveau = validation_rcue.niveau()
+    #         if not niveau.competence.id in validation_par_competence_et_annee:
+    #             validation_par_competence_et_annee[niveau.competence.id] = {}
+    #         previous_validation = validation_par_competence_et_annee.get(
+    #             niveau.competence.id
+    #         ).get(validation_rcue.annee())
+    #         # prend la "meilleure" validation
+    #         if (not previous_validation) or (
+    #             sco_codes.BUT_CODES_ORDER[validation_rcue.code]
+    #             > sco_codes.BUT_CODES_ORDER[previous_validation["code"]]
+    #         ):
+    #             self.validation_par_competence_et_annee[niveau.competence.id][
+    #                 niveau.annee
+    #             ] = validation_rcue
+    #     return validation_par_competence_et_annee
+
+    # def list_etud_inscriptions(self, etud: Identite):
+    #     "Le parcours à valider: celui du DERNIER semestre suivi (peut être None)"
+    #     self.niveaux_by_annee = {}
+    #     "{ annee : liste des niveaux à valider }"
+    #     self.niveaux: dict[int, ApcNiveau] = {}
+    #     "cache les niveaux"
+    #     for annee in (1, 2, 3):
+    #         niveaux_d = formation.referentiel_competence.get_niveaux_by_parcours(
+    #             annee, [self.parcour] if self.parcour else None  # XXX WIP
+    #         )[1]
+    #         # groupe les niveaux de tronc commun et ceux spécifiques au parcour
+    #         self.niveaux_by_annee[annee] = niveaux_d["TC"] + (
+    #             niveaux_d[self.parcour.id] if self.parcour else []
+    #         )
+    #         self.niveaux.update(
+    #             {niveau.id: niveau for niveau in self.niveaux_by_annee[annee]}
+    #         )
+
+    #     self.validation_par_competence_et_annee = {}
+    #     """{ competence_id : { 'BUT1' : validation_rcue (la "meilleure"), ... } }"""
+    #     for validation_rcue in ApcValidationRCUE.query.filter_by(etud=etud):
+    #         niveau = validation_rcue.niveau()
+    #         if not niveau.competence.id in self.validation_par_competence_et_annee:
+    #             self.validation_par_competence_et_annee[niveau.competence.id] = {}
+    #         previous_validation = self.validation_par_competence_et_annee.get(
+    #             niveau.competence.id
+    #         ).get(validation_rcue.annee())
+    #         # prend la "meilleure" validation
+    #         if (not previous_validation) or (
+    #             sco_codes.BUT_CODES_ORDER[validation_rcue.code]
+    #             > sco_codes.BUT_CODES_ORDER[previous_validation["code"]]
+    #         ):
+    #             self.validation_par_competence_et_annee[niveau.competence.id][
+    #                 niveau.annee
+    #             ] = validation_rcue
+
+    #     self.competences = {
+    #         competence.id: competence
+    #         for competence in (
+    #             self.parcour.query_competences()
+    #             if self.parcour
+    #             else self.formation.referentiel_competence.get_competences_tronc_commun()
+    #         )
+    #     }
+    #     "cache { competence_id : competence }"
 
 
 def but_ects_valides(etud: Identite, referentiel_competence_id: int) -> float:
diff --git a/app/but/jury_but.py b/app/but/jury_but.py
index 5bd71c7ec93d63325f47f14a66b174c091b66e04..8c19239f91e110f6a231c0493921ccafee9687a2 100644
--- a/app/but/jury_but.py
+++ b/app/but/jury_but.py
@@ -1034,8 +1034,8 @@ class DecisionsProposeesAnnee(DecisionsProposees):
         return messages
 
     def valide_diplome(self) -> bool:
-        "Vrai si l'étudiant à validé son diplôme"
-        return False  # TODO XXX
+        "Vrai si l'étudiant a validé son diplôme (décision enregistrée)"
+        return self.annee_but == 3 and sco_codes.code_annee_validant(self.code_valide)
 
 
 def list_ue_parcour_etud(
diff --git a/app/but/jury_but_pv.py b/app/but/jury_but_pv.py
index 56e45d41254ee90f250e932f2feff9e425356b41..c20000fb490f6b8520b628d7afab02ab2f36b785 100644
--- a/app/but/jury_but_pv.py
+++ b/app/but/jury_but_pv.py
@@ -155,6 +155,7 @@ def pvjury_table_but(
             deca = None
 
         ects_but_valides = but_ects_valides(etud, referentiel_competence_id)
+        has_diplome = deca.valide_diplome()
         row = {
             "nom_pv": (
                 etud.code_ine or etud.code_nip or etud.id
@@ -181,10 +182,15 @@ def pvjury_table_but(
             ),
             "decision_but": deca.code_valide if deca else "",
             "devenir": (
-                ", ".join([f"S{i}" for i in deca.get_autorisations_passage()])
-                if deca
-                else ""
+                "Diplôme obtenu"
+                if has_diplome
+                else (
+                    ", ".join([f"S{i}" for i in deca.get_autorisations_passage()])
+                    if deca
+                    else ""
+                )
             ),
+            "diplome": "ADM" if has_diplome else "",
             # pour exports excel seulement:
             "civilite": etud.civilite_etat_civil_str,
             "nom": etud.nom,
diff --git a/app/models/but_validations.py b/app/models/but_validations.py
index adf0d203fbcf6fafb280587da15d42ede920afcc..8ec9a110700ce44ef8e106d8b724a68120066283 100644
--- a/app/models/but_validations.py
+++ b/app/models/but_validations.py
@@ -219,6 +219,7 @@ def dict_decision_jury(etud: Identite, formsemestre: FormSemestre) -> dict:
                         dec_rcue["code"]}"""
                 )
         decisions["descr_decisions_rcue"] = ", ".join(titres_rcues)
+        decisions["descr_decisions_rcue_list"] = titres_rcues
         decisions["descr_decisions_niveaux"] = (
             "Niveaux de compétences: " + decisions["descr_decisions_rcue"]
         )
diff --git a/app/scodoc/sco_pv_lettres_inviduelles.py b/app/scodoc/sco_pv_lettres_inviduelles.py
index c3d069e71596959cf7ee7969b32b299c7b8da63a..3517c9a6a94191e5f0d0451ec03a7a30add41f32 100644
--- a/app/scodoc/sco_pv_lettres_inviduelles.py
+++ b/app/scodoc/sco_pv_lettres_inviduelles.py
@@ -257,7 +257,9 @@ def pdf_lettre_individuelle(sem, decision, etud: Identite, params, signature=Non
     else:
         params["autorisations_txt"] = ""
 
-    if decision["decision_sem"] and situation_etud.parcours_validated():
+    if (
+        formsemestre.formation.is_apc() or decision["decision_sem"]
+    ) and situation_etud.parcours_validated():
         params["diplome_txt"] = (
             """Vous avez donc obtenu le diplôme : <b>%(titre_formation)s</b>""" % params
         )
@@ -357,5 +359,8 @@ def add_apc_infos(formsemestre: FormSemestre, params: dict, decision: dict):
         params[
             "decision_ue_txt"
         ] = f"""{params["decision_ue_txt"]}<br/>
-            <b>Niveaux de compétences:</b><br/> {decision.get("descr_decisions_rcue") or ""}
+            <b>Niveaux de compétences:</b>
+            <br/>&nbsp;&nbsp;&nbsp;&nbsp;- {
+                '<br/>&nbsp;&nbsp;&nbsp;&nbsp;- '.join( decision.get("descr_decisions_rcue_list", []) )
+            }
         """