feat: ajout du filtre et de la fonction de relance des adherents avec tailles manquantes
This commit is contained in:
+157
-30
@@ -1,32 +1,34 @@
|
||||
package com.astalange.web.controller;
|
||||
|
||||
import com.astalange.core.entity.AppUser;
|
||||
import com.astalange.core.entity.Dotation;
|
||||
import com.astalange.core.entity.ExportHistory;
|
||||
import com.astalange.core.entity.Saison;
|
||||
import com.astalange.core.entity.TypeExport;
|
||||
import com.astalange.core.repository.AppUserRepository;
|
||||
import com.astalange.core.repository.CategorieRepository;
|
||||
import com.astalange.core.repository.DotationRepository;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
import com.astalange.core.repository.EquipementRepository;
|
||||
import com.astalange.core.repository.SaisonRepository;
|
||||
import com.astalange.core.security.CustomUserDetails;
|
||||
import com.astalange.core.service.DotationService;
|
||||
import com.astalange.core.service.ExportHistoryService;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
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;
|
||||
|
||||
import com.astalange.core.repository.EquipementRepository;
|
||||
import com.astalange.core.repository.CategorieRepository;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import java.util.ArrayList;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
|
||||
@Controller
|
||||
public class DotationController {
|
||||
@@ -36,16 +38,44 @@ public class DotationController {
|
||||
private final SaisonRepository saisonRepository;
|
||||
private final EquipementRepository equipementRepository;
|
||||
private final CategorieRepository categorieRepository;
|
||||
private final ExportHistoryService exportHistoryService;
|
||||
private final AppUserRepository appUserRepository;
|
||||
|
||||
public DotationController(DotationRepository dotationRepository, DotationService dotationService, SaisonRepository saisonRepository, EquipementRepository equipementRepository, CategorieRepository categorieRepository) {
|
||||
public DotationController(DotationRepository dotationRepository,
|
||||
DotationService dotationService,
|
||||
SaisonRepository saisonRepository,
|
||||
EquipementRepository equipementRepository,
|
||||
CategorieRepository categorieRepository,
|
||||
ExportHistoryService exportHistoryService,
|
||||
AppUserRepository appUserRepository) {
|
||||
this.dotationRepository = dotationRepository;
|
||||
this.dotationService = dotationService;
|
||||
this.saisonRepository = saisonRepository;
|
||||
this.equipementRepository = equipementRepository;
|
||||
this.categorieRepository = categorieRepository;
|
||||
this.exportHistoryService = exportHistoryService;
|
||||
this.appUserRepository = appUserRepository;
|
||||
}
|
||||
|
||||
private Specification<Dotation> buildSpecification(Long equipementId, Long categorieId, Boolean fourni, Boolean commandee, Saison saisonActive) {
|
||||
private AppUser getCurrentUser() {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (auth != null && auth.getPrincipal() instanceof CustomUserDetails userDetails) {
|
||||
return appUserRepository.findById(userDetails.getId()).orElse(null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int compterElementsCsv(String csvContent) {
|
||||
if (csvContent == null || csvContent.trim().isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
int lines = (int) Arrays.stream(csvContent.split("\n"))
|
||||
.filter(l -> !l.trim().isEmpty())
|
||||
.count();
|
||||
return Math.max(0, lines - 1);
|
||||
}
|
||||
|
||||
private Specification<Dotation> buildSpecification(Long equipementId, Long categorieId, Boolean fourni, Boolean commandee, Boolean tailleRenseignee, Saison saisonActive) {
|
||||
return (root, query, cb) -> {
|
||||
if (Long.class != query.getResultType() && long.class != query.getResultType()) {
|
||||
root.fetch("equipement", jakarta.persistence.criteria.JoinType.LEFT);
|
||||
@@ -70,6 +100,24 @@ public class DotationController {
|
||||
if (commandee != null) {
|
||||
predicates.add(cb.equal(root.get("commandee"), commandee));
|
||||
}
|
||||
if (tailleRenseignee != null) {
|
||||
if (tailleRenseignee) {
|
||||
predicates.add(cb.and(
|
||||
cb.isNotNull(root.get("taille")),
|
||||
cb.notEqual(cb.trim(root.get("taille")), "")
|
||||
));
|
||||
} else {
|
||||
// Uniquement les équipements proposant une grille de tailles mais dont la taille n'est pas encore saisie
|
||||
predicates.add(cb.and(
|
||||
cb.isNotNull(root.get("equipement").get("taillesDisponibles")),
|
||||
cb.notEqual(cb.trim(root.get("equipement").get("taillesDisponibles")), ""),
|
||||
cb.or(
|
||||
cb.isNull(root.get("taille")),
|
||||
cb.equal(cb.trim(root.get("taille")), "")
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
||||
return cb.and(predicates.toArray(new Predicate[0]));
|
||||
};
|
||||
}
|
||||
@@ -80,12 +128,13 @@ public class DotationController {
|
||||
@RequestParam(required = false) Long categorieId,
|
||||
@RequestParam(required = false) Boolean fourni,
|
||||
@RequestParam(required = false) Boolean commandee,
|
||||
@RequestParam(required = false) Boolean tailleRenseignee,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "20") int size,
|
||||
Model model) {
|
||||
|
||||
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||
Specification<Dotation> spec = buildSpecification(equipementId, categorieId, fourni, commandee, saisonActive);
|
||||
Specification<Dotation> spec = buildSpecification(equipementId, categorieId, fourni, commandee, tailleRenseignee, saisonActive);
|
||||
List<Dotation> allDotations = dotationRepository.findAll(spec);
|
||||
|
||||
int totalElements = allDotations.size();
|
||||
@@ -104,6 +153,7 @@ public class DotationController {
|
||||
model.addAttribute("categorieId", categorieId);
|
||||
model.addAttribute("fourni", fourni);
|
||||
model.addAttribute("commandee", commandee);
|
||||
model.addAttribute("tailleRenseignee", tailleRenseignee);
|
||||
|
||||
model.addAttribute("currentPage", page);
|
||||
model.addAttribute("totalPages", totalPages);
|
||||
@@ -118,17 +168,21 @@ public class DotationController {
|
||||
@RequestParam(required = false) Long equipementId,
|
||||
@RequestParam(required = false) Long categorieId,
|
||||
@RequestParam(required = false) Boolean fourni,
|
||||
@RequestParam(required = false) Boolean commandee) {
|
||||
@RequestParam(required = false) Boolean commandee,
|
||||
@RequestParam(required = false) Boolean tailleRenseignee) {
|
||||
|
||||
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||
Specification<Dotation> spec = buildSpecification(equipementId, categorieId, fourni, commandee, saisonActive);
|
||||
Specification<Dotation> spec = buildSpecification(equipementId, categorieId, fourni, commandee, tailleRenseignee, saisonActive);
|
||||
List<Dotation> dotations = dotationRepository.findAll(spec);
|
||||
|
||||
String csvContent = dotationService.genererCsvSearchEquipement(dotations);
|
||||
String filename = Boolean.FALSE.equals(tailleRenseignee) ? "relance_tailles_manquantes_" + LocalDate.now() + ".csv" : "recherche_equipements_" + LocalDate.now() + ".csv";
|
||||
exportHistoryService.enregistrerExport(TypeExport.RECHERCHE_EQUIPEMENTS, filename, csvContent, compterElementsCsv(csvContent), saisonActive, getCurrentUser());
|
||||
|
||||
byte[] csvBytes = csvContent.getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDispositionFormData("attachment", "recherche_equipements_" + LocalDate.now() + ".csv");
|
||||
headers.setContentDispositionFormData("attachment", filename);
|
||||
headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
|
||||
|
||||
return new ResponseEntity<>(csvBytes, headers, org.springframework.http.HttpStatus.OK);
|
||||
@@ -140,10 +194,13 @@ public class DotationController {
|
||||
.orElseThrow(() -> new IllegalStateException("Aucune saison active"));
|
||||
|
||||
String csvContent = dotationService.genererCsvCommandeEquipement(saisonActive);
|
||||
String filename = "commande_equipements_regroupee_" + LocalDate.now() + ".csv";
|
||||
exportHistoryService.enregistrerExport(TypeExport.COMMANDE_EQUIPEMENT, filename, csvContent, compterElementsCsv(csvContent), saisonActive, getCurrentUser());
|
||||
|
||||
byte[] csvBytes = csvContent.getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDispositionFormData("attachment", "commande_equipements_regroupee_" + LocalDate.now() + ".csv");
|
||||
headers.setContentDispositionFormData("attachment", filename);
|
||||
headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
|
||||
|
||||
return new ResponseEntity<>(csvBytes, headers, org.springframework.http.HttpStatus.OK);
|
||||
@@ -155,10 +212,13 @@ public class DotationController {
|
||||
.orElseThrow(() -> new IllegalStateException("Aucune saison active"));
|
||||
|
||||
String csvContent = dotationService.genererCsvFlocageInitiales(saisonActive);
|
||||
String filename = "flocage_initiales_" + LocalDate.now() + ".csv";
|
||||
exportHistoryService.enregistrerExport(TypeExport.FLOCAGE_INITIALES, filename, csvContent, compterElementsCsv(csvContent), saisonActive, getCurrentUser());
|
||||
|
||||
byte[] csvBytes = csvContent.getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDispositionFormData("attachment", "flocage_initiales_" + LocalDate.now() + ".csv");
|
||||
headers.setContentDispositionFormData("attachment", filename);
|
||||
headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
|
||||
|
||||
return new ResponseEntity<>(csvBytes, headers, org.springframework.http.HttpStatus.OK);
|
||||
@@ -170,15 +230,82 @@ public class DotationController {
|
||||
.orElseThrow(() -> new IllegalStateException("Aucune saison active"));
|
||||
|
||||
String csvContent = dotationService.genererCsvFlocagePrenomNumero(saisonActive);
|
||||
String filename = "flocage_prenom_numero_" + LocalDate.now() + ".csv";
|
||||
exportHistoryService.enregistrerExport(TypeExport.FLOCAGE_PRENOM_NUMERO, filename, csvContent, compterElementsCsv(csvContent), saisonActive, getCurrentUser());
|
||||
|
||||
byte[] csvBytes = csvContent.getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDispositionFormData("attachment", "flocage_prenom_numero_" + LocalDate.now() + ".csv");
|
||||
headers.setContentDispositionFormData("attachment", filename);
|
||||
headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
|
||||
|
||||
return new ResponseEntity<>(csvBytes, headers, org.springframework.http.HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/admin/exports/historique")
|
||||
public String historiqueExports(@RequestParam(required = false) Long saisonId, Model model) {
|
||||
List<Saison> saisons = saisonRepository.findAll();
|
||||
Saison saisonFiltre = null;
|
||||
if (saisonId != null) {
|
||||
saisonFiltre = saisonRepository.findById(saisonId).orElse(null);
|
||||
}
|
||||
List<ExportHistory> historique = exportHistoryService.obtenirHistoriqueParSaison(saisonFiltre);
|
||||
|
||||
model.addAttribute("historique", historique);
|
||||
model.addAttribute("saisons", saisons);
|
||||
model.addAttribute("saisonId", saisonId);
|
||||
return "parametrage/export_history";
|
||||
}
|
||||
|
||||
@GetMapping("/admin/exports/{id}/download")
|
||||
public ResponseEntity<byte[]> downloadExport(@PathVariable Long id) {
|
||||
ExportHistory history = exportHistoryService.trouverParId(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Export introuvable ID: " + id));
|
||||
|
||||
byte[] csvBytes = history.getContenu().getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDispositionFormData("attachment", history.getNomFichier());
|
||||
headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
|
||||
|
||||
return new ResponseEntity<>(csvBytes, headers, org.springframework.http.HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/admin/exports/{id}/apercu")
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, Object>> apercuExport(@PathVariable Long id) {
|
||||
ExportHistory history = exportHistoryService.trouverParId(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Export introuvable ID: " + id));
|
||||
|
||||
String content = history.getContenu();
|
||||
if (content.startsWith("\ufeff")) {
|
||||
content = content.substring(1);
|
||||
}
|
||||
|
||||
String[] lines = content.split("\n");
|
||||
List<String> headers = new ArrayList<>();
|
||||
List<List<String>> rows = new ArrayList<>();
|
||||
|
||||
if (lines.length > 0) {
|
||||
headers = Arrays.asList(lines[0].split(";"));
|
||||
for (int i = 1; i < lines.length; i++) {
|
||||
if (!lines[i].trim().isEmpty()) {
|
||||
rows.add(Arrays.asList(lines[i].split(";", -1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("id", history.getId());
|
||||
response.put("typeExport", history.getTypeExport().getLibelle());
|
||||
response.put("nomFichier", history.getNomFichier());
|
||||
response.put("dateExport", history.getDateExport().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm")));
|
||||
response.put("headers", headers);
|
||||
response.put("rows", rows);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/dotations/{id}")
|
||||
public String updateDotation(
|
||||
|
||||
Reference in New Issue
Block a user