feat(equipements): clean equipment search, fix category regression, and sync dotations on category change
This commit is contained in:
@@ -23,13 +23,15 @@ public class AdherentController {
|
||||
private final com.astalange.core.repository.LicenceRepository licenceRepository;
|
||||
private final com.astalange.core.repository.ModePaiementRepository modePaiementRepository;
|
||||
private final SaisonRepository saisonRepository;
|
||||
private final com.astalange.core.service.CategorieService categorieService;
|
||||
|
||||
public AdherentController(AdherentRepository adherentRepository, CategorieRepository categorieRepository, com.astalange.core.repository.LicenceRepository licenceRepository, com.astalange.core.repository.ModePaiementRepository modePaiementRepository, SaisonRepository saisonRepository) {
|
||||
public AdherentController(AdherentRepository adherentRepository, CategorieRepository categorieRepository, com.astalange.core.repository.LicenceRepository licenceRepository, com.astalange.core.repository.ModePaiementRepository modePaiementRepository, SaisonRepository saisonRepository, com.astalange.core.service.CategorieService categorieService) {
|
||||
this.adherentRepository = adherentRepository;
|
||||
this.categorieRepository = categorieRepository;
|
||||
this.licenceRepository = licenceRepository;
|
||||
this.modePaiementRepository = modePaiementRepository;
|
||||
this.saisonRepository = saisonRepository;
|
||||
this.categorieService = categorieService;
|
||||
}
|
||||
|
||||
@org.springframework.web.bind.annotation.ModelAttribute("equipes")
|
||||
@@ -187,7 +189,8 @@ public class AdherentController {
|
||||
.orElse(null);
|
||||
if (newCat != null) {
|
||||
licence.setCategorie(newCat);
|
||||
licenceRepository.save(licence);
|
||||
licence = licenceRepository.save(licence);
|
||||
categorieService.syncDotationsForLicence(licence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,13 @@ public class CategorieController {
|
||||
Categorie categorie = categorieRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Invalid category ID: " + id));
|
||||
model.addAttribute("categorie", categorie);
|
||||
Saison activeSaison = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||
model.addAttribute("allEquipements", activeSaison != null ? equipementRepository.findBySaison(activeSaison) : List.of());
|
||||
|
||||
Saison saison = categorie.getSaison();
|
||||
if (saison == null) {
|
||||
saison = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||
}
|
||||
|
||||
model.addAttribute("allEquipements", saison != null ? equipementRepository.findBySaison(saison) : List.of());
|
||||
return "parametrage/categories_form";
|
||||
}
|
||||
|
||||
|
||||
@@ -21,17 +21,95 @@ 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.ui.Model;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Controller
|
||||
public class DotationController {
|
||||
|
||||
private final DotationRepository dotationRepository;
|
||||
private final DotationService dotationService;
|
||||
private final SaisonRepository saisonRepository;
|
||||
private final EquipementRepository equipementRepository;
|
||||
private final CategorieRepository categorieRepository;
|
||||
|
||||
public DotationController(DotationRepository dotationRepository, DotationService dotationService, SaisonRepository saisonRepository) {
|
||||
public DotationController(DotationRepository dotationRepository, DotationService dotationService, SaisonRepository saisonRepository, EquipementRepository equipementRepository, CategorieRepository categorieRepository) {
|
||||
this.dotationRepository = dotationRepository;
|
||||
this.dotationService = dotationService;
|
||||
this.saisonRepository = saisonRepository;
|
||||
this.equipementRepository = equipementRepository;
|
||||
this.categorieRepository = categorieRepository;
|
||||
}
|
||||
|
||||
private Specification<Dotation> buildSpecification(Long equipementId, Long categorieId, Boolean fourni, Saison saisonActive) {
|
||||
return (root, query, cb) -> {
|
||||
if (Long.class != query.getResultType() && long.class != query.getResultType()) {
|
||||
root.fetch("equipement", jakarta.persistence.criteria.JoinType.LEFT);
|
||||
jakarta.persistence.criteria.Fetch<Object, Object> licenceFetch = root.fetch("licence", jakarta.persistence.criteria.JoinType.LEFT);
|
||||
licenceFetch.fetch("adherent", jakarta.persistence.criteria.JoinType.LEFT);
|
||||
licenceFetch.fetch("categorie", jakarta.persistence.criteria.JoinType.LEFT);
|
||||
}
|
||||
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
if (saisonActive != null) {
|
||||
predicates.add(cb.equal(root.get("licence").get("saison"), saisonActive));
|
||||
}
|
||||
if (equipementId != null) {
|
||||
predicates.add(cb.equal(root.get("equipement").get("id"), equipementId));
|
||||
}
|
||||
if (categorieId != null) {
|
||||
predicates.add(cb.equal(root.get("licence").get("categorie").get("id"), categorieId));
|
||||
}
|
||||
if (fourni != null) {
|
||||
predicates.add(cb.equal(root.get("fourni"), fourni));
|
||||
}
|
||||
return cb.and(predicates.toArray(new Predicate[0]));
|
||||
};
|
||||
}
|
||||
|
||||
@GetMapping("/admin/equipements/recherche")
|
||||
public String rechercheEquipements(
|
||||
@RequestParam(required = false) Long equipementId,
|
||||
@RequestParam(required = false) Long categorieId,
|
||||
@RequestParam(required = false) Boolean fourni,
|
||||
Model model) {
|
||||
|
||||
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||
Specification<Dotation> spec = buildSpecification(equipementId, categorieId, fourni, saisonActive);
|
||||
List<Dotation> dotations = dotationRepository.findAll(spec);
|
||||
|
||||
model.addAttribute("dotations", dotations);
|
||||
model.addAttribute("equipements", equipementRepository.findAll());
|
||||
model.addAttribute("categories", categorieRepository.findAll());
|
||||
model.addAttribute("equipementId", equipementId);
|
||||
model.addAttribute("categorieId", categorieId);
|
||||
model.addAttribute("fourni", fourni);
|
||||
|
||||
return "parametrage/equipements_recherche";
|
||||
}
|
||||
|
||||
@GetMapping("/admin/equipements/recherche/export")
|
||||
public ResponseEntity<byte[]> exportRechercheEquipements(
|
||||
@RequestParam(required = false) Long equipementId,
|
||||
@RequestParam(required = false) Long categorieId,
|
||||
@RequestParam(required = false) Boolean fourni) {
|
||||
|
||||
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||
Specification<Dotation> spec = buildSpecification(equipementId, categorieId, fourni, saisonActive);
|
||||
List<Dotation> dotations = dotationRepository.findAll(spec);
|
||||
|
||||
String csvContent = dotationService.genererCsvSearchEquipement(dotations);
|
||||
byte[] csvBytes = csvContent.getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDispositionFormData("attachment", "recherche_equipements_" + LocalDate.now() + ".csv");
|
||||
headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
|
||||
|
||||
return new ResponseEntity<>(csvBytes, headers, org.springframework.http.HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/admin/equipements/export-commande")
|
||||
|
||||
@@ -22,7 +22,12 @@ public class EquipementController {
|
||||
|
||||
@GetMapping
|
||||
public String listEquipements(Model model) {
|
||||
model.addAttribute("equipements", equipementRepository.findAll());
|
||||
Saison activeSaison = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||
if (activeSaison != null) {
|
||||
model.addAttribute("equipements", equipementRepository.findBySaison(activeSaison));
|
||||
} else {
|
||||
model.addAttribute("equipements", java.util.List.of());
|
||||
}
|
||||
return "parametrage/equipements_list";
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ public class LicenceController {
|
||||
private final DotationRepository dotationRepository;
|
||||
private final SaisonRepository saisonRepository;
|
||||
private final EquipeRepository equipeRepository;
|
||||
private final com.astalange.core.service.CategorieService categorieService;
|
||||
|
||||
public LicenceController(AdherentRepository adherentRepository,
|
||||
CategorieRepository categorieRepository,
|
||||
@@ -28,7 +29,8 @@ public class LicenceController {
|
||||
EquipementRepository equipementRepository,
|
||||
DotationRepository dotationRepository,
|
||||
SaisonRepository saisonRepository,
|
||||
EquipeRepository equipeRepository) {
|
||||
EquipeRepository equipeRepository,
|
||||
com.astalange.core.service.CategorieService categorieService) {
|
||||
this.adherentRepository = adherentRepository;
|
||||
this.categorieRepository = categorieRepository;
|
||||
this.licenceRepository = licenceRepository;
|
||||
@@ -36,6 +38,7 @@ public class LicenceController {
|
||||
this.dotationRepository = dotationRepository;
|
||||
this.saisonRepository = saisonRepository;
|
||||
this.equipeRepository = equipeRepository;
|
||||
this.categorieService = categorieService;
|
||||
}
|
||||
|
||||
@PostMapping("/adherents/{id}/licences")
|
||||
@@ -129,8 +132,125 @@ public class LicenceController {
|
||||
licence.setEquipe(null);
|
||||
}
|
||||
|
||||
licenceRepository.save(licence);
|
||||
licence = licenceRepository.save(licence);
|
||||
|
||||
// Sync dotations when category changes
|
||||
categorieService.syncDotationsForLicence(licence);
|
||||
|
||||
return "redirect:/adherents/" + adherentId + "/edit";
|
||||
}
|
||||
|
||||
@org.springframework.web.bind.annotation.GetMapping("/admin/licences/recherche")
|
||||
public String rechercheLicences(
|
||||
@RequestParam(required = false) String nom,
|
||||
@RequestParam(required = false) String prenom,
|
||||
@RequestParam(required = false) Long categorieId,
|
||||
@RequestParam(required = false) String numeroLicence,
|
||||
@RequestParam(required = false) String email,
|
||||
@RequestParam(required = false) String typeDemande,
|
||||
org.springframework.ui.Model model) {
|
||||
|
||||
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||
org.springframework.data.jpa.domain.Specification<Licence> spec = buildLicenceSpecification(nom, prenom, categorieId, numeroLicence, email, typeDemande, saisonActive);
|
||||
|
||||
List<Licence> licences = licenceRepository.findAll(spec);
|
||||
|
||||
model.addAttribute("licences", licences);
|
||||
model.addAttribute("categories", categorieRepository.findAll());
|
||||
model.addAttribute("nomFilter", nom);
|
||||
model.addAttribute("prenomFilter", prenom);
|
||||
model.addAttribute("categorieId", categorieId);
|
||||
model.addAttribute("numeroLicenceFilter", numeroLicence);
|
||||
model.addAttribute("emailFilter", email);
|
||||
model.addAttribute("typeDemandeFilter", typeDemande);
|
||||
|
||||
return "parametrage/licences_recherche";
|
||||
}
|
||||
|
||||
@org.springframework.web.bind.annotation.GetMapping("/admin/licences/recherche/export")
|
||||
public org.springframework.http.ResponseEntity<byte[]> exportRechercheLicences(
|
||||
@RequestParam(required = false) String nom,
|
||||
@RequestParam(required = false) String prenom,
|
||||
@RequestParam(required = false) Long categorieId,
|
||||
@RequestParam(required = false) String numeroLicence,
|
||||
@RequestParam(required = false) String email,
|
||||
@RequestParam(required = false) String typeDemande) {
|
||||
|
||||
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||
org.springframework.data.jpa.domain.Specification<Licence> spec = buildLicenceSpecification(nom, prenom, categorieId, numeroLicence, email, typeDemande, saisonActive);
|
||||
List<Licence> licences = licenceRepository.findAll(spec);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('\ufeff');
|
||||
sb.append("Nom;Prénom;Catégorie;N° Licence;Email;Type de Demande;Saison;Etat\n");
|
||||
|
||||
for (Licence l : licences) {
|
||||
String n = l.getAdherent() != null && l.getAdherent().getNom() != null ? l.getAdherent().getNom() : "";
|
||||
String p = l.getAdherent() != null && l.getAdherent().getPrenom() != null ? l.getAdherent().getPrenom() : "";
|
||||
String c = l.getCategorie() != null ? l.getCategorie().getNom() : "";
|
||||
String num = l.getNumeroLicence() != null ? l.getNumeroLicence() : "";
|
||||
String e = l.getAdherent() != null && l.getAdherent().getEmail() != null ? l.getAdherent().getEmail() : "";
|
||||
String td = l.getTypeDemande() != null ? l.getTypeDemande() : "";
|
||||
String s = l.getSaison() != null ? l.getSaison().getNom() : "";
|
||||
String etat = l.getEtat() != null ? l.getEtat() : "";
|
||||
|
||||
sb.append(escapeCsv(n)).append(";")
|
||||
.append(escapeCsv(p)).append(";")
|
||||
.append(escapeCsv(c)).append(";")
|
||||
.append(escapeCsv(num)).append(";")
|
||||
.append(escapeCsv(e)).append(";")
|
||||
.append(escapeCsv(td)).append(";")
|
||||
.append(escapeCsv(s)).append(";")
|
||||
.append(escapeCsv(etat)).append("\n");
|
||||
}
|
||||
|
||||
byte[] csvBytes = sb.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||
org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
|
||||
headers.setContentDispositionFormData("attachment", "recherche_licences_" + java.time.LocalDate.now() + ".csv");
|
||||
headers.setContentType(org.springframework.http.MediaType.parseMediaType("text/csv; charset=UTF-8"));
|
||||
|
||||
return new org.springframework.http.ResponseEntity<>(csvBytes, headers, org.springframework.http.HttpStatus.OK);
|
||||
}
|
||||
|
||||
private String escapeCsv(String value) {
|
||||
if (value == null) return "";
|
||||
if (value.contains("\"")) value = value.replace("\"", "\"\"");
|
||||
if (value.contains(";") || value.contains("\n") || value.contains("\"")) return "\"" + value + "\"";
|
||||
return value;
|
||||
}
|
||||
|
||||
private org.springframework.data.jpa.domain.Specification<Licence> buildLicenceSpecification(
|
||||
String nom, String prenom, Long categorieId, String numeroLicence, String email, String typeDemande, Saison saisonActive) {
|
||||
return (root, query, cb) -> {
|
||||
List<jakarta.persistence.criteria.Predicate> predicates = new java.util.ArrayList<>();
|
||||
|
||||
if (Long.class != query.getResultType() && long.class != query.getResultType()) {
|
||||
root.fetch("adherent", jakarta.persistence.criteria.JoinType.LEFT);
|
||||
root.fetch("categorie", jakarta.persistence.criteria.JoinType.LEFT);
|
||||
}
|
||||
|
||||
if (saisonActive != null) {
|
||||
predicates.add(cb.equal(root.get("saison"), saisonActive));
|
||||
}
|
||||
if (nom != null && !nom.trim().isEmpty()) {
|
||||
predicates.add(cb.like(cb.lower(root.get("adherent").get("nom")), "%" + nom.trim().toLowerCase() + "%"));
|
||||
}
|
||||
if (prenom != null && !prenom.trim().isEmpty()) {
|
||||
predicates.add(cb.like(cb.lower(root.get("adherent").get("prenom")), "%" + prenom.trim().toLowerCase() + "%"));
|
||||
}
|
||||
if (categorieId != null) {
|
||||
predicates.add(cb.equal(root.get("categorie").get("id"), categorieId));
|
||||
}
|
||||
if (numeroLicence != null && !numeroLicence.trim().isEmpty()) {
|
||||
predicates.add(cb.like(cb.lower(root.get("numeroLicence")), "%" + numeroLicence.trim().toLowerCase() + "%"));
|
||||
}
|
||||
if (email != null && !email.trim().isEmpty()) {
|
||||
predicates.add(cb.like(cb.lower(root.get("adherent").get("email")), "%" + email.trim().toLowerCase() + "%"));
|
||||
}
|
||||
if (typeDemande != null && !typeDemande.trim().isEmpty()) {
|
||||
predicates.add(cb.equal(root.get("typeDemande"), typeDemande.trim()));
|
||||
}
|
||||
return cb.and(predicates.toArray(new jakarta.persistence.criteria.Predicate[0]));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user