From bcf92487ab0162058ae00c1c4c9acc5f7485468f Mon Sep 17 00:00:00 2001 From: Youssef Date: Sun, 14 Jun 2026 01:53:16 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Export=20CSV=20des=20commandes=20=C3=A9?= =?UTF-8?q?quipements=20(Dashboard)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Ajout de la génération de CSV des équipements choisis et non fournis pour la saison active. - Création du DotationService et ajout de la route /admin/equipements/export-commande. - Ajout du bouton d'export sur le tableau de bord principal (index.html). --- .../core/repository/DotationRepository.java | 4 ++ .../core/service/DotationService.java | 63 +++++++++++++++++++ .../web/controller/DotationController.java | 31 ++++++++- .../src/main/resources/templates/index.html | 6 +- .../parametrage/equipements_list.html | 2 - 5 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 as-talange-core/src/main/java/com/astalange/core/service/DotationService.java diff --git a/as-talange-core/src/main/java/com/astalange/core/repository/DotationRepository.java b/as-talange-core/src/main/java/com/astalange/core/repository/DotationRepository.java index 0f6d83b..a2d7fb2 100644 --- a/as-talange-core/src/main/java/com/astalange/core/repository/DotationRepository.java +++ b/as-talange-core/src/main/java/com/astalange/core/repository/DotationRepository.java @@ -4,6 +4,10 @@ import com.astalange.core.entity.Dotation; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; +import com.astalange.core.entity.Saison; + @Repository public interface DotationRepository extends JpaRepository { + List findByLicence_SaisonAndChoisiTrueAndFourniFalse(Saison saison); } diff --git a/as-talange-core/src/main/java/com/astalange/core/service/DotationService.java b/as-talange-core/src/main/java/com/astalange/core/service/DotationService.java new file mode 100644 index 0000000..09c1852 --- /dev/null +++ b/as-talange-core/src/main/java/com/astalange/core/service/DotationService.java @@ -0,0 +1,63 @@ +package com.astalange.core.service; + +import com.astalange.core.entity.Dotation; +import com.astalange.core.entity.Saison; +import com.astalange.core.repository.DotationRepository; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class DotationService { + + private final DotationRepository dotationRepository; + + public DotationService(DotationRepository dotationRepository) { + this.dotationRepository = dotationRepository; + } + + public String genererCsvCommandeEquipement(Saison saisonActive) { + List dotations = dotationRepository.findByLicence_SaisonAndChoisiTrueAndFourniFalse(saisonActive); + + StringBuilder sb = new StringBuilder(); + // BOM for Excel to open UTF-8 correctly + sb.append('\ufeff'); + + // Header + sb.append("Catégorie;Nom;Prénom;Équipement;Taille;Flocage;Numéro\n"); + + for (Dotation d : dotations) { + String categorie = d.getLicence().getCategorie() != null ? d.getLicence().getCategorie().getNom() : ""; + String nom = d.getLicence().getAdherent().getNom(); + String prenom = d.getLicence().getAdherent().getPrenom(); + String equipement = d.getEquipement() != null ? d.getEquipement().getNom() : ""; + String taille = d.getTaille() != null ? d.getTaille() : ""; + String flocage = d.getFlocage() != null ? d.getFlocage() : ""; + String numero = d.getNumero() != null ? d.getNumero() : ""; + + sb.append(escapeCsv(categorie)).append(";") + .append(escapeCsv(nom)).append(";") + .append(escapeCsv(prenom)).append(";") + .append(escapeCsv(equipement)).append(";") + .append(escapeCsv(taille)).append(";") + .append(escapeCsv(flocage)).append(";") + .append(escapeCsv(numero)).append("\n"); + } + + return sb.toString(); + } + + private String escapeCsv(String value) { + if (value == null) { + return ""; + } + String result = value; + if (result.contains("\"")) { + result = result.replace("\"", "\"\""); + } + if (result.contains(";") || result.contains("\n") || result.contains("\"")) { + return "\"" + result + "\""; + } + return result; + } +} diff --git a/as-talange-web/src/main/java/com/astalange/web/controller/DotationController.java b/as-talange-web/src/main/java/com/astalange/web/controller/DotationController.java index 24bb2b2..53679be 100644 --- a/as-talange-web/src/main/java/com/astalange/web/controller/DotationController.java +++ b/as-talange-web/src/main/java/com/astalange/web/controller/DotationController.java @@ -11,13 +11,42 @@ import org.springframework.web.bind.annotation.RequestParam; import java.util.List; import jakarta.servlet.http.HttpServletRequest; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.http.ResponseEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import java.time.LocalDate; + +import com.astalange.core.service.DotationService; +import com.astalange.core.repository.SaisonRepository; +import com.astalange.core.entity.Saison; + @Controller public class DotationController { private final DotationRepository dotationRepository; + private final DotationService dotationService; + private final SaisonRepository saisonRepository; - public DotationController(DotationRepository dotationRepository) { + public DotationController(DotationRepository dotationRepository, DotationService dotationService, SaisonRepository saisonRepository) { this.dotationRepository = dotationRepository; + this.dotationService = dotationService; + this.saisonRepository = saisonRepository; + } + + @GetMapping("/admin/equipements/export-commande") + public ResponseEntity exportCommande() { + Saison saisonActive = saisonRepository.findByEstActiveTrue() + .orElseThrow(() -> new IllegalStateException("Aucune saison active")); + + String csvContent = dotationService.genererCsvCommandeEquipement(saisonActive); + byte[] csvBytes = csvContent.getBytes(java.nio.charset.StandardCharsets.UTF_8); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentDispositionFormData("attachment", "commande_equipements_" + LocalDate.now() + ".csv"); + headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8")); + + return new ResponseEntity<>(csvBytes, headers, org.springframework.http.HttpStatus.OK); } @PostMapping("/dotations/{id}") diff --git a/as-talange-web/src/main/resources/templates/index.html b/as-talange-web/src/main/resources/templates/index.html index ee5a768..226c43e 100644 --- a/as-talange-web/src/main/resources/templates/index.html +++ b/as-talange-web/src/main/resources/templates/index.html @@ -18,8 +18,12 @@
-
+

Tableau de bord

+ + + Export CSV Équipements +
diff --git a/as-talange-web/src/main/resources/templates/parametrage/equipements_list.html b/as-talange-web/src/main/resources/templates/parametrage/equipements_list.html index f037a0a..35e403b 100644 --- a/as-talange-web/src/main/resources/templates/parametrage/equipements_list.html +++ b/as-talange-web/src/main/resources/templates/parametrage/equipements_list.html @@ -23,8 +23,6 @@ + Nouvel Équipement - -