Files
as-talange/as-talange-web/src/main/java/com/astalange/web/controller/LicenceController.java
T
ucef 5f2bf61829
AS Talange CI/CD Pipeline / Build & Run Unit Tests (push) Successful in 3m8s
AS Talange CI/CD Pipeline / Deploy to Test Environment (push) Successful in 3m28s
feat: gestion type de demande, calcul dynamique du tarif et pre-selection equipement (maillot) pour inscription
2026-06-24 23:56:46 +02:00

244 lines
12 KiB
Java

package com.astalange.web.controller;
import com.astalange.core.entity.*;
import com.astalange.core.repository.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Controller
@Transactional
public class LicenceController {
private final AdherentRepository adherentRepository;
private final CategorieRepository categorieRepository;
private final LicenceRepository licenceRepository;
private final EquipementRepository equipementRepository;
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,
LicenceRepository licenceRepository,
EquipementRepository equipementRepository,
DotationRepository dotationRepository,
SaisonRepository saisonRepository,
EquipeRepository equipeRepository,
com.astalange.core.service.CategorieService categorieService) {
this.adherentRepository = adherentRepository;
this.categorieRepository = categorieRepository;
this.licenceRepository = licenceRepository;
this.equipementRepository = equipementRepository;
this.dotationRepository = dotationRepository;
this.saisonRepository = saisonRepository;
this.equipeRepository = equipeRepository;
this.categorieService = categorieService;
}
@PostMapping("/adherents/{id}/licences")
public String addLicence(
@PathVariable Long id,
@RequestParam Long categorieId,
@RequestParam String etat,
@RequestParam(required = false) String numeroLicence,
@RequestParam(required = false) String typeDemande,
@RequestParam(required = false) String typeLicence,
@RequestParam(required = false) Long equipeId) {
Adherent adherent = adherentRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Invalid Adherent ID"));
List<Licence> existingLicences = licenceRepository.findByAdherentId(id);
if (!existingLicences.isEmpty()) {
return "redirect:/adherents/" + id + "/edit";
}
Categorie categorie = categorieRepository.findById(categorieId)
.orElseThrow(() -> new IllegalArgumentException("Invalid Categorie ID"));
Saison saisonActive = saisonRepository.findByEstActiveTrue()
.orElseThrow(() -> new IllegalStateException("Aucune saison active trouvée"));
Licence licence = new Licence();
licence.setAdherent(adherent);
licence.setCategorie(categorie);
licence.setSaison(saisonActive);
licence.setEtat(etat);
licence.setNumeroLicence(numeroLicence);
licence.setTypeDemande(typeDemande);
licence.setTypeLicence(typeLicence);
if (equipeId != null) {
Equipe equipe = equipeRepository.findById(equipeId)
.orElseThrow(() -> new IllegalArgumentException("Invalid Equipe ID"));
licence.setEquipe(equipe);
}
licence = licenceRepository.save(licence);
// Auto-initialize dotations via CategorieService to ensure consistency
categorieService.syncDotationsForLicence(licence);
return "redirect:/adherents/" + id + "/edit";
}
@PostMapping("/adherents/{adherentId}/licences/{licenceId}/update")
public String updateLicence(
@PathVariable Long adherentId,
@PathVariable Long licenceId,
@RequestParam Long categorieId,
@RequestParam String etat,
@RequestParam(required = false) String numeroLicence,
@RequestParam(required = false) String typeDemande,
@RequestParam(required = false) String typeLicence,
@RequestParam(required = false) Long equipeId) {
Licence licence = licenceRepository.findById(licenceId)
.orElseThrow(() -> new IllegalArgumentException("Invalid Licence ID"));
Categorie categorie = categorieRepository.findById(categorieId)
.orElseThrow(() -> new IllegalArgumentException("Invalid Categorie ID"));
licence.setCategorie(categorie);
licence.setEtat(etat);
licence.setNumeroLicence(numeroLicence);
licence.setTypeDemande(typeDemande);
licence.setTypeLicence(typeLicence);
if (equipeId != null) {
Equipe equipe = equipeRepository.findById(equipeId)
.orElseThrow(() -> new IllegalArgumentException("Invalid Equipe ID"));
licence.setEquipe(equipe);
} else {
licence.setEquipe(null);
}
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]));
};
}
}