feat: Export CSV des commandes équipements (Dashboard)
- 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).
This commit is contained in:
@@ -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<Dotation, Long> {
|
||||
List<Dotation> findByLicence_SaisonAndChoisiTrueAndFourniFalse(Saison saison);
|
||||
}
|
||||
|
||||
@@ -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<Dotation> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<byte[]> 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}")
|
||||
|
||||
@@ -18,8 +18,12 @@
|
||||
<!-- Main Content -->
|
||||
<main class="flex-1 flex flex-col h-screen overflow-hidden">
|
||||
<!-- Header -->
|
||||
<header class="h-16 bg-white border-b border-gray-200 flex items-center px-6">
|
||||
<header class="h-16 bg-white border-b border-gray-200 flex items-center justify-between px-6">
|
||||
<h2 class="text-lg font-semibold text-gray-800">Tableau de bord</h2>
|
||||
<a href="/admin/equipements/export-commande" class="bg-indigo-50 text-indigo-600 border border-indigo-200 px-4 py-2 rounded-lg text-sm font-medium hover:bg-indigo-100 transition-colors flex items-center">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>
|
||||
Export CSV Équipements
|
||||
</a>
|
||||
</header>
|
||||
|
||||
<!-- Main section -->
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
+ Nouvel Équipement
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200">
|
||||
|
||||
Reference in New Issue
Block a user