From 4933eff9426112e73e6b7183bc88b2f5f89ec630 Mon Sep 17 00:00:00 2001 From: scayac Date: Thu, 9 Oct 2025 21:28:15 +0200 Subject: [PATCH] =?UTF-8?q?Gestion=20bug=20affichage=20pr=C3=A9nom=20dans?= =?UTF-8?q?=20exports=20+=20affichage=20des=20groupements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/templates/course_detail.html | 24 +++++++++++++++++++++ main/views.py | 36 ++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/main/templates/course_detail.html b/main/templates/course_detail.html index 0c55cd8..b634a2d 100644 --- a/main/templates/course_detail.html +++ b/main/templates/course_detail.html @@ -195,9 +195,12 @@ $(document).ready(function() { // Keep the current ordering so we can restore it var storedOrder = table.order(); + // Expose grouping state to the global scope so exports can read it + window.courseGroupBy = groupBy; $('#btnGroup').on('click', function(){ groupBy = !groupBy; + window.courseGroupBy = groupBy; $(this).text(groupBy ? 'Désactiver le groupement' : 'Grouper par coureur'); if (groupBy) { // Sort by Nom (col 1) then Prénom (col 2) to make grouping contiguous @@ -213,6 +216,27 @@ $(document).ready(function() { function getVisibleRows() { var dt = $('#arriveesTable').DataTable(); var rows = dt.rows({search: 'applied'}).data().toArray(); + // If grouping is active, inject group-header marker rows into the exported data + try { + if (window.courseGroupBy) { + var output = []; + var lastKey = null; + for (var i = 0; i < rows.length; i++) { + var name = rows[i][1] || ''; + var prenom = rows[i][2] || ''; + var key = name + '|' + prenom; + if (key !== lastKey) { + // marker row: first cell '__GROUP__', second cell holds the group label + output.push(['__GROUP__', name + ' ' + prenom, '', '', '']); + lastKey = key; + } + output.push(rows[i]); + } + return JSON.stringify(output); + } + } catch (e) { + // fallback to default rows if anything goes wrong + } return JSON.stringify(rows); } diff --git a/main/views.py b/main/views.py index bfff531..3b3fddd 100644 --- a/main/views.py +++ b/main/views.py @@ -134,7 +134,7 @@ def export_csv(request, course_id): response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = f'attachment; filename="course_{course_id}_resultats.csv"' writer = csv.writer(response) - writer.writerow(['Rang', 'Nom', 'Classe', 'Temps']) + writer.writerow(['Rang', 'Nom', 'Prénom', 'Classe', 'Temps']) import json rows_json = request.POST.get('rows') @@ -172,13 +172,14 @@ def export_pdf(request, course_id): p.setFont("Helvetica-Bold", 16) p.drawString(50, y, f"Résultats - {course.nom} ({course.date})") - # En-tête du tableau + # En-tête du tableau (colonnes: premier, Nom, Prénom, Classe, Temps) y -= 40 p.setFont("Helvetica", 12) p.drawString(50, y, first_col_label) p.drawString(100, y, "Nom") - p.drawString(300, y, "Classe") - p.drawString(400, y, "Temps") + p.drawString(220, y, "Prénom") + p.drawString(340, y, "Classe") + p.drawString(460, y, "Temps") y -= 20 # Contenu : soit les lignes filtrées envoyées en POST, soit toutes les arrivées en base @@ -188,10 +189,24 @@ def export_pdf(request, course_id): try: rows = json.loads(rows_json) for row in rows: - p.drawString(50, y, str(row[0])) - p.drawString(100, y, str(row[1])) - p.drawString(300, y, str(row[2])) - p.drawString(400, y, str(row[3])) + # If we receive a group marker row (injected client-side when grouping), render it as a header + if isinstance(row, list) and len(row) > 0 and row[0] == '__GROUP__': + # Render group header spanning the table width + p.setFont("Helvetica-Bold", 12) + p.drawString(50, y, str(row[1])) + p.setFont("Helvetica", 12) + else: + # Standard row: expected format [first, nom, prenom, classe, temps] + first = row[0] if len(row) > 0 else '' + nom = row[1] if len(row) > 1 else '' + prenom = row[2] if len(row) > 2 else '' + classe = row[3] if len(row) > 3 else '' + temps_val = row[4] if len(row) > 4 else '' + p.drawString(50, y, str(first)) + p.drawString(100, y, str(nom)) + p.drawString(220, y, str(prenom)) + p.drawString(340, y, str(classe)) + p.drawString(460, y, str(temps_val)) y -= 20 # Nouvelle page si nécessaire if y < 50: @@ -206,8 +221,9 @@ def export_pdf(request, course_id): first_value = a.tour if course.type == 'multi' else a.rang p.drawString(50, y, str(first_value)) p.drawString(100, y, a.coureur.nom) - p.drawString(300, y, a.coureur.classe) - p.drawString(400, y, str(a.temps)) + p.drawString(220, y, a.coureur.prenom) + p.drawString(340, y, a.coureur.classe) + p.drawString(460, y, str(a.temps)) y -= 20 # Nouvelle page si nécessaire if y < 50: