diff --git a/app/comp/res_common.py b/app/comp/res_common.py
index 839f631540fe3159a42bb09ee16f7cba7f96764c..30468da3d5fcbc54dc7c04166b430abdfc71dee9 100644
--- a/app/comp/res_common.py
+++ b/app/comp/res_common.py
@@ -397,7 +397,17 @@ class ResultatsSemestre(ResultatsCache):
         barre_valid_ue = self.formsemestre.formation.get_parcours().NOTES_BARRE_VALID_UE
         NO_NOTE = "-"  # contenu des cellules sans notes
         rows = []
-        titles = {"rang": "Rg"}  # column_id : title
+        # column_id : title
+        titles = {
+            "rang": "Rg",
+            # ordre des colonnes:
+            "_rang_col_order": 1,
+            "_civilite_str_col_order": 2,
+            "_nom_disp_col_order": 3,
+            "_prenom_col_order": 4,
+            "_nom_short_col_order": 5,
+            "_rang_col_order": 6,
+        }
         # les titres en footer: les mêmes, mais avec des bulles et liens:
         titles_bot = {}
 
@@ -436,7 +446,6 @@ class ResultatsSemestre(ResultatsCache):
             row["_nom_short_target_attrs"] = f'class="etudinfo" id="{etudid}"'
             row["_nom_disp_target"] = row["_nom_short_target"]
             row["_nom_disp_target_attrs"] = row["_nom_short_target_attrs"]
-            self._recap_etud_groups_infos(etudid, row, titles)
             # --- Moyenne générale
             moy_gen = self.etud_moy_gen.get(etudid, False)
             note_class = ""
@@ -523,7 +532,8 @@ class ResultatsSemestre(ResultatsCache):
                         modimpl_ids.add(modimpl.id)
 
             rows.append(row)
-
+        self._recap_add_partitions(rows, titles)
+        self._recap_add_admissions(rows, titles)
         # tri par rang croissant
         rows.sort(key=lambda e: e["_rang_order"])
 
@@ -547,12 +557,9 @@ class ResultatsSemestre(ResultatsCache):
             footer_rows.append(row)
         titles_bot.update(titles)
         footer_rows.append(titles_bot)
-        return (
-            rows,
-            footer_rows,
-            titles,
-            [title for title in titles if not title.startswith("_")],
-        )
+        column_ids = [title for title in titles if not title.startswith("_")]
+        column_ids.sort(key=lambda col_id: titles.get("_" + col_id + "_col_order", 100))
+        return (rows, footer_rows, titles, column_ids)
 
     def _recap_bottom_infos(self, ues, modimpl_ids: set, fmt_note) -> dict:
         """Les informations à mettre en bas de la table: min, max, moy, ECTS"""
@@ -631,3 +638,65 @@ class ResultatsSemestre(ResultatsCache):
         if row_class:
             row["_tr_class"] = " ".join([row.get("_tr_class", ""), row_class])
         titles["group"] = "Gr"
+
+    def _recap_add_admissions(self, rows: list[dict], titles: dict):
+        """Ajoute les colonnes "admission"
+        rows est une liste de dict avec un clé "etudid"
+        Les colonnes ont la classe css "admission"
+        """
+        fields = {
+            "bac": "Bac",
+            "specialite": "Spécialité",
+            "type_admission": "Type Adm.",
+            "classement": "Rg. Adm.",
+        }
+        titles.update(fields)
+        for row in rows:
+            etud = Identite.query.get(row["etudid"])
+            admission = etud.admission.first()
+            first = True
+            for cid in fields:
+                row[cid] = getattr(admission, cid) or ""
+                if first:
+                    row[f"_{cid}_class"] = "admission admission_first"
+                    first = False
+                else:
+                    row[f"_{cid}_class"] = "admission"
+                titles[f"_{cid}_class"] = row[f"_{cid}_class"]
+                titles[f"_{cid}_col_order"] = 1000  # à la fin
+
+    def _recap_add_partitions(self, rows: list[dict], titles: dict):
+        """Ajoute les colonnes indiquant les groupes
+        rows est une liste de dict avec un clé "etudid"
+        Les colonnes ont la classe css "partition"
+        """
+        partitions, partitions_etud_groups = sco_groups.get_formsemestre_groups(
+            self.formsemestre.id
+        )
+        first_partition = True
+        for partition in partitions:
+            cid = f"part_{partition['partition_id']}"
+            titles[cid] = partition["partition_name"]
+            if first_partition:
+                klass = "partition"
+            else:
+                klass = "partition partition_aux"
+            titles[f"_{cid}_class"] = klass
+            titles[f"_{cid}_col_order"] = 10
+            partition_etud_groups = partitions_etud_groups[partition["partition_id"]]
+            for row in rows:
+                # dans NotesTableCompat, à revoir
+                etud_etat = self.get_etud_etat(row["etudid"])
+                if etud_etat == "D":
+                    gr_name = "Dém."
+                    row["_tr_class"] = "dem"
+                elif etud_etat == DEF:
+                    gr_name = "Déf."
+                    row["_tr_class"] = "def"
+                else:
+                    group = partition_etud_groups.get(row["etudid"])
+                    gr_name = group["group_name"] if group else ""
+                if gr_name:
+                    row[f"{cid}"] = gr_name
+                    row[f"_{cid}_class"] = klass
+            first_partition = False
diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py
index 3b1c35d0b9faff5fde51bd9d9e7c0d564e4ce973..4ec90052b766ac887ef4b76eedfb305aa1a8c757 100644
--- a/app/models/formsemestre.py
+++ b/app/models/formsemestre.py
@@ -580,6 +580,9 @@ class FormSemestreInscription(db.Model):
     # etape apogee d'inscription (experimental 2020)
     etape = db.Column(db.String(APO_CODE_STR_LEN))
 
+    def __repr__(self):
+        return f"<{self.__class__.__name__} {self.id} etudid={self.etudid} sem={self.formsemestre_id} etat={self.etat}>"
+
 
 class NotesSemSet(db.Model):
     """semsets: ensemble de formsemestres pour exports Apogée"""
diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css
index 2196b4da32d20aaac6c6561ca293935488de0a82..85c6574da802a51f3e11847092d8b28bf5b41246 100644
--- a/app/static/css/scodoc.css
+++ b/app/static/css/scodoc.css
@@ -3178,7 +3178,13 @@ table.table_recap .group {
   border-left: 1px dashed rgb(160, 160, 160);
   white-space:nowrap;
 }
-
+table.table_recap .admission  {
+  white-space:nowrap;
+  color:rgb(6, 73, 6);
+}
+table.table_recap .admission_first {
+  border-left: 1px solid blue;
+}
 table.table_recap tbody tr td a:hover {
   color: red;
   text-decoration: underline;
@@ -3215,4 +3221,12 @@ table.table_recap tr.max td, table.table_recap tr.moy td {
   font-size: 80%;
   padding-top: 3px;
   padding-bottom: 3px;
+}
+table.table_recap tr.dem td {
+  color: rgb(100,100,100);
+  font-style: italic; 
+}
+table.table_recap tr.def td {
+  color: rgb(121, 74, 74);
+  font-style: italic; 
 }
\ No newline at end of file
diff --git a/app/static/js/table_recap.js b/app/static/js/table_recap.js
index 2b41cf5ac915cd25caacd091afae910fa2e76209..04acb30ef82868a489807355b25b0798dde33fac 100644
--- a/app/static/js/table_recap.js
+++ b/app/static/js/table_recap.js
@@ -13,6 +13,15 @@ $(function () {
                     dt.buttons('toggle_ident:name').text(visible ? "Civ/Nom/Prénom" : "Nom");
                 }
             },
+            {
+                name: "toggle_partitions",
+                text: "Toutes les partitions",
+                action: function (e, dt, node, config) {
+                    let visible = dt.columns(".partition_aux").visible()[0];
+                    dt.columns(".partition_aux").visible(!visible);
+                    dt.buttons('toggle_partitions:name').text(visible ? "Toutes les partitions" : "Cacher les partitions");
+                }
+            },
             $('table.table_recap').hasClass("apc") ?
                 {
                     name: "toggle_res",
@@ -44,6 +53,15 @@ $(function () {
             })
 
         }
+        buttons.push({
+            name: "toggle_admission",
+            text: "Montrer infos admission",
+            action: function (e, dt, node, config) {
+                let visible = dt.columns(".admission").visible()[0];
+                dt.columns(".admission").visible(!visible);
+                dt.buttons('toggle_admission:name').text(visible ? "Montrer infos admission" : "Cacher infos admission");
+            }
+        })
         $('table.table_recap').DataTable(
             {
                 paging: false,
@@ -59,8 +77,8 @@ $(function () {
                 colReorder: true,
                 "columnDefs": [
                     {
-                        // cache le détail de l'identité (pas réussi à le faire avec le sélecteur css)
-                        "targets": [1, 2, 3], // ".identite_detail",
+                        // cache le détail de l'identité et les colonnes admission
+                        "targets": ["identite_detail", "partition_aux", "admission"],
                         "visible": false,
                     },
                 ],
@@ -68,10 +86,10 @@ $(function () {
                 buttons: ['copy', 'excel', 'pdf',
                     {
                         extend: 'collection',
-                        text: 'Réglages affichage',
+                        text: 'Colonnes affichées',
                         autoClose: true,
                         buttons: buttons,
-                    }
+                    },
                 ]
             }
         );