diff --git a/as-talange-core/src/main/java/com/astalange/core/repository/AdherentRepository.java b/as-talange-core/src/main/java/com/astalange/core/repository/AdherentRepository.java index a7b53d7..13101be 100644 --- a/as-talange-core/src/main/java/com/astalange/core/repository/AdherentRepository.java +++ b/as-talange-core/src/main/java/com/astalange/core/repository/AdherentRepository.java @@ -10,6 +10,9 @@ import java.util.List; public interface AdherentRepository extends JpaRepository { List findTop5ByOrderByIdDesc(); + @org.springframework.data.jpa.repository.Query("SELECT DISTINCT a FROM Adherent a LEFT JOIN FETCH a.licences l LEFT JOIN FETCH l.categorie c") + List findAllWithLicencesAndCategories(); + @org.springframework.data.jpa.repository.Query("SELECT DISTINCT a FROM Adherent a LEFT JOIN a.licences l WHERE LOWER(a.nom) LIKE LOWER(CONCAT('%', :query, '%')) OR LOWER(a.prenom) LIKE LOWER(CONCAT('%', :query, '%')) OR LOWER(l.numeroLicence) LIKE LOWER(CONCAT('%', :query, '%'))") List searchByQuery(@org.springframework.data.repository.query.Param("query") String query); } diff --git a/as-talange-web/src/main/java/com/astalange/web/controller/AdherentController.java b/as-talange-web/src/main/java/com/astalange/web/controller/AdherentController.java index 08deebd..6bdc840 100644 --- a/as-talange-web/src/main/java/com/astalange/web/controller/AdherentController.java +++ b/as-talange-web/src/main/java/com/astalange/web/controller/AdherentController.java @@ -1,6 +1,8 @@ package com.astalange.web.controller; import com.astalange.core.entity.Adherent; +import com.astalange.core.entity.Categorie; +import com.astalange.core.entity.Licence; import com.astalange.core.entity.Saison; import com.astalange.core.repository.AdherentRepository; import com.astalange.core.repository.CategorieRepository; @@ -31,15 +33,108 @@ public class AdherentController { } @GetMapping - public String listAdherents(@org.springframework.web.bind.annotation.RequestParam(required = false) String query, Model model) { - List adherents; + public String listAdherents( + @org.springframework.web.bind.annotation.RequestParam(required = false) String query, + @org.springframework.web.bind.annotation.RequestParam(required = false) String nom, + @org.springframework.web.bind.annotation.RequestParam(required = false) String prenom, + @org.springframework.web.bind.annotation.RequestParam(required = false) String categorie, + @org.springframework.web.bind.annotation.RequestParam(required = false) String licence, + @org.springframework.web.bind.annotation.RequestParam(required = false) String email, + @org.springframework.web.bind.annotation.RequestParam(required = false) String telephone, + @org.springframework.web.bind.annotation.RequestParam(required = false) String paiement, + @org.springframework.web.bind.annotation.RequestParam(defaultValue = "0") int page, + @org.springframework.web.bind.annotation.RequestParam(defaultValue = "20") int size, + Model model) { + + List adherents = adherentRepository.findAllWithLicencesAndCategories(); + + // 1. Filter by global query if (query != null && !query.trim().isEmpty()) { - adherents = adherentRepository.searchByQuery(query.trim()); + String q = query.trim().toLowerCase(); + adherents = adherents.stream().filter(a -> + (a.getNom() != null && a.getNom().toLowerCase().contains(q)) || + (a.getPrenom() != null && a.getPrenom().toLowerCase().contains(q)) || + (a.getLicenceActuelle() != null && a.getLicenceActuelle().getNumeroLicence() != null && a.getLicenceActuelle().getNumeroLicence().toLowerCase().contains(q)) + ).collect(java.util.stream.Collectors.toList()); model.addAttribute("searchQuery", query.trim()); - } else { - adherents = adherentRepository.findAll(); } - model.addAttribute("adherents", adherents); + + // 2. Filter by specific column filters + if (nom != null && !nom.trim().isEmpty()) { + String n = nom.trim().toLowerCase(); + adherents = adherents.stream().filter(a -> a.getNom() != null && a.getNom().toLowerCase().contains(n)).collect(java.util.stream.Collectors.toList()); + model.addAttribute("nomFilter", nom.trim()); + } + if (prenom != null && !prenom.trim().isEmpty()) { + String p = prenom.trim().toLowerCase(); + adherents = adherents.stream().filter(a -> a.getPrenom() != null && a.getPrenom().toLowerCase().contains(p)).collect(java.util.stream.Collectors.toList()); + model.addAttribute("prenomFilter", prenom.trim()); + } + if (categorie != null && !categorie.trim().isEmpty()) { + adherents = adherents.stream().filter(a -> + a.getLicenceActuelle() != null && + a.getLicenceActuelle().getCategorie() != null && + a.getLicenceActuelle().getCategorie().getNom().equalsIgnoreCase(categorie.trim()) + ).collect(java.util.stream.Collectors.toList()); + model.addAttribute("categorieFilter", categorie.trim()); + } + if (licence != null && !licence.trim().isEmpty()) { + String l = licence.trim().toLowerCase(); + adherents = adherents.stream().filter(a -> + a.getLicenceActuelle() != null && + a.getLicenceActuelle().getNumeroLicence() != null && + a.getLicenceActuelle().getNumeroLicence().toLowerCase().contains(l) + ).collect(java.util.stream.Collectors.toList()); + model.addAttribute("licenceFilter", licence.trim()); + } + if (email != null && !email.trim().isEmpty()) { + String e = email.trim().toLowerCase(); + adherents = adherents.stream().filter(a -> a.getEmail() != null && a.getEmail().toLowerCase().contains(e)).collect(java.util.stream.Collectors.toList()); + model.addAttribute("emailFilter", email.trim()); + } + if (telephone != null && !telephone.trim().isEmpty()) { + String t = telephone.trim().toLowerCase(); + adherents = adherents.stream().filter(a -> a.getTelephone() != null && a.getTelephone().toLowerCase().contains(t)).collect(java.util.stream.Collectors.toList()); + model.addAttribute("telephoneFilter", telephone.trim()); + } + if (paiement != null && !paiement.trim().isEmpty()) { + adherents = adherents.stream().filter(a -> { + String statut = a.getStatutPaiement(); + if ("A_JOUR".equalsIgnoreCase(paiement)) { + return "À jour".equalsIgnoreCase(statut); + } else if ("RESTE".equalsIgnoreCase(paiement)) { + return statut != null && statut.startsWith("Reste"); + } else if ("AUCUNE".equalsIgnoreCase(paiement)) { + return "Aucune licence".equalsIgnoreCase(statut); + } + return true; + }).collect(java.util.stream.Collectors.toList()); + model.addAttribute("paiementFilter", paiement.trim()); + } + + // 3. Paginate + int totalElements = adherents.size(); + int totalPages = (int) Math.ceil((double) totalElements / size); + if (page < 0) page = 0; + if (page >= totalPages && totalPages > 0) page = totalPages - 1; + + int start = page * size; + int end = Math.min(start + size, totalElements); + List pageContent = (start < totalElements) ? adherents.subList(start, end) : List.of(); + + model.addAttribute("adherents", pageContent); + model.addAttribute("currentPage", page); + model.addAttribute("totalPages", totalPages); + model.addAttribute("totalElements", totalElements); + model.addAttribute("pageSize", size); + + Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null); + if (saisonActive != null) { + model.addAttribute("categories", categorieRepository.findBySaison(saisonActive)); + } else { + model.addAttribute("categories", categorieRepository.findAll()); + } + return "adherents/list"; } @@ -56,10 +151,67 @@ public class AdherentController { Model model) { if (result.hasErrors()) { + if (adherent.getId() != null) { + Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null); + if (saisonActive != null) { + model.addAttribute("categories", categorieRepository.findBySaison(saisonActive)); + model.addAttribute("saisonActive", saisonActive); + } else { + model.addAttribute("categories", categorieRepository.findAll()); + } + model.addAttribute("licences", licenceRepository.findByAdherentId(adherent.getId())); + model.addAttribute("modesPaiement", modePaiementRepository.findAll()); + } else { + Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null); + if (saisonActive != null) { + model.addAttribute("categories", categorieRepository.findBySaison(saisonActive)); + } else { + model.addAttribute("categories", categorieRepository.findAll()); + } + } return "adherents/form"; } - adherentRepository.save(adherent); + if (adherent.getId() != null) { + Adherent existing = adherentRepository.findById(adherent.getId()).orElse(null); + if (existing != null) { + boolean dateChanged = !existing.getDateNaissance().equals(adherent.getDateNaissance()); + + if (dateChanged) { + int newBirthYear = adherent.getDateNaissance().getYear(); + List licences = licenceRepository.findByAdherentId(adherent.getId()); + for (Licence licence : licences) { + Saison saison = licence.getSaison(); + Categorie newCat = categorieRepository.findBySaison(saison).stream() + .filter(c -> newBirthYear >= c.getAnneeMin() && newBirthYear <= c.getAnneeMax()) + .findFirst() + .orElse(null); + if (newCat != null) { + licence.setCategorie(newCat); + licenceRepository.save(licence); + } + } + } + + existing.setNom(adherent.getNom()); + existing.setPrenom(adherent.getPrenom()); + existing.setDateNaissance(adherent.getDateNaissance()); + existing.setTelephone(adherent.getTelephone()); + existing.setEmail(adherent.getEmail()); + existing.setAdresse(adherent.getAdresse()); + existing.setRepresentantLegal(adherent.getRepresentantLegal()); + existing.setResidentTalange(adherent.isResidentTalange()); + existing.setSexe(adherent.getSexe()); + existing.setTypeMaillot(adherent.getTypeMaillot()); + + adherentRepository.save(existing); + } else { + adherentRepository.save(adherent); + } + } else { + adherentRepository.save(adherent); + } + return "redirect:/adherents"; } diff --git a/as-talange-web/src/main/resources/templates/adherents/list.html b/as-talange-web/src/main/resources/templates/adherents/list.html index 5d0ee99..c2e9c44 100644 --- a/as-talange-web/src/main/resources/templates/adherents/list.html +++ b/as-talange-web/src/main/resources/templates/adherents/list.html @@ -34,62 +34,159 @@ -
+
-
+ Effacer
- - - - - - - - - - - - - - - - - - - - - - - - - - -
NomPrénomN° LicenceEmailTéléphonePaiementActions
Aucun adhérent enregistré.
- Dupont -
- Masculin - | - Joueur -
-
Jean-jean@example.com0600000000 - À jour - - Voir / Modifier -
- -
-
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NomPrénomCatégorieN° LicenceEmailTéléphonePaiementActions
+ + + + + + + + + + + + + +
Aucun adhérent enregistré.
+ Dupont +
+ Masculin + | + Joueur +
+
Jean--jean@example.com0600000000 + À jour + + Voir / Modifier + + + +
+ + + +
+
+ Affichage de 1 à + 20 sur + 100 adhérents +
+
+ Aucun adhérent à afficher +
+
+ + + + Précédent + + + + + + + + + + + Suivant + +
+
-