159 lines
7.1 KiB
Java
159 lines
7.1 KiB
Java
package com.astalange.web.controller;
|
|
|
|
import com.astalange.core.entity.*;
|
|
import com.astalange.core.repository.CategorieRepository;
|
|
import com.astalange.core.repository.CreneauEntrainementRepository;
|
|
import com.astalange.core.repository.SaisonRepository;
|
|
import com.astalange.core.repository.TerrainRepository;
|
|
import org.springframework.stereotype.Controller;
|
|
import org.springframework.ui.Model;
|
|
import org.springframework.validation.BindingResult;
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
|
|
|
import java.util.*;
|
|
|
|
@Controller
|
|
@RequestMapping("/planning")
|
|
public class PlanningController {
|
|
|
|
private final CreneauEntrainementRepository creneauRepository;
|
|
private final TerrainRepository terrainRepository;
|
|
private final CategorieRepository categorieRepository;
|
|
private final SaisonRepository saisonRepository;
|
|
|
|
public PlanningController(CreneauEntrainementRepository creneauRepository,
|
|
TerrainRepository terrainRepository,
|
|
CategorieRepository categorieRepository,
|
|
SaisonRepository saisonRepository) {
|
|
this.creneauRepository = creneauRepository;
|
|
this.terrainRepository = terrainRepository;
|
|
this.categorieRepository = categorieRepository;
|
|
this.saisonRepository = saisonRepository;
|
|
}
|
|
|
|
@GetMapping
|
|
public String showPlanning(@RequestParam(required = false) JourSemaine jour, Model model) {
|
|
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
|
if (saisonActive == null) {
|
|
model.addAttribute("noActiveSeason", true);
|
|
return "planning/planning";
|
|
}
|
|
|
|
JourSemaine selectedDay = (jour != null) ? jour : JourSemaine.LUNDI;
|
|
List<Terrain> terrains = terrainRepository.findAll();
|
|
|
|
// Sort terrains to ensure consistent order (Terrain Vert then Terrain Synthétique)
|
|
terrains.sort(Comparator.comparing(Terrain::getId));
|
|
|
|
Map<Long, Integer> terrainIndices = new HashMap<>();
|
|
for (int i = 0; i < terrains.size(); i++) {
|
|
terrainIndices.put(terrains.get(i).getId(), i);
|
|
}
|
|
|
|
List<CreneauEntrainement> creneaux = creneauRepository.findBySaisonAndJourSemaineFetch(saisonActive, selectedDay);
|
|
|
|
// Detect conflicts
|
|
for (int i = 0; i < creneaux.size(); i++) {
|
|
CreneauEntrainement c1 = creneaux.get(i);
|
|
for (int j = 0; j < creneaux.size(); j++) {
|
|
if (i == j) continue;
|
|
CreneauEntrainement c2 = creneaux.get(j);
|
|
if (c1.overlapsWith(c2)) {
|
|
c1.setEnConflit(true);
|
|
c1.getCategoriesEnConflit().add(c2.getCategorie().getNom());
|
|
}
|
|
}
|
|
}
|
|
|
|
model.addAttribute("saisonActive", saisonActive);
|
|
model.addAttribute("selectedDay", selectedDay);
|
|
model.addAttribute("jours", JourSemaine.values());
|
|
model.addAttribute("terrains", terrains);
|
|
model.addAttribute("terrainIndices", terrainIndices);
|
|
model.addAttribute("creneaux", creneaux);
|
|
|
|
return "planning/planning";
|
|
}
|
|
|
|
@GetMapping("/new")
|
|
public String showCreateForm(Model model, RedirectAttributes redirectAttributes) {
|
|
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
|
if (saisonActive == null) {
|
|
redirectAttributes.addFlashAttribute("error", "Veuillez activer une saison avant de planifier un créneau.");
|
|
return "redirect:/saisons";
|
|
}
|
|
|
|
CreneauEntrainement creneau = new CreneauEntrainement();
|
|
creneau.setSaison(saisonActive);
|
|
|
|
model.addAttribute("creneau", creneau);
|
|
model.addAttribute("categories", categorieRepository.findBySaison(saisonActive));
|
|
model.addAttribute("terrains", terrainRepository.findAll());
|
|
model.addAttribute("zones", ZoneTerrain.values());
|
|
model.addAttribute("jours", JourSemaine.values());
|
|
|
|
return "planning/form";
|
|
}
|
|
|
|
@GetMapping("/{id}/edit")
|
|
public String showEditForm(@PathVariable Long id, Model model, RedirectAttributes redirectAttributes) {
|
|
CreneauEntrainement creneau = creneauRepository.findById(id)
|
|
.orElseThrow(() -> new IllegalArgumentException("Créneau introuvable : " + id));
|
|
|
|
model.addAttribute("creneau", creneau);
|
|
model.addAttribute("categories", categorieRepository.findBySaison(creneau.getSaison()));
|
|
model.addAttribute("terrains", terrainRepository.findAll());
|
|
model.addAttribute("zones", ZoneTerrain.values());
|
|
model.addAttribute("jours", JourSemaine.values());
|
|
|
|
return "planning/form";
|
|
}
|
|
|
|
@PostMapping
|
|
public String saveCreneau(@ModelAttribute("creneau") CreneauEntrainement creneau, BindingResult result, Model model, RedirectAttributes redirectAttributes) {
|
|
// Validation
|
|
if (creneau.getHeureDebut() != null && creneau.getHeureFin() != null) {
|
|
if (!creneau.getHeureDebut().isBefore(creneau.getHeureFin())) {
|
|
result.rejectValue("heureDebut", "error.heureDebut", "L'heure de début doit être antérieure à l'heure de fin.");
|
|
}
|
|
if (creneau.getHeureDebut().isBefore(java.time.LocalTime.of(8, 0)) || creneau.getHeureFin().isAfter(java.time.LocalTime.of(22, 0))) {
|
|
result.rejectValue("heureDebut", "error.heureDebut", "Les entraînements doivent se dérouler entre 08:00 et 22:00.");
|
|
}
|
|
}
|
|
|
|
if (result.hasErrors()) {
|
|
Saison saison = creneau.getSaison();
|
|
if (saison == null) {
|
|
saison = saisonRepository.findByEstActiveTrue().orElseThrow();
|
|
creneau.setSaison(saison);
|
|
}
|
|
model.addAttribute("categories", categorieRepository.findBySaison(saison));
|
|
model.addAttribute("terrains", terrainRepository.findAll());
|
|
model.addAttribute("zones", ZoneTerrain.values());
|
|
model.addAttribute("jours", JourSemaine.values());
|
|
return "planning/form";
|
|
}
|
|
|
|
// Set active season if not set (for new items)
|
|
if (creneau.getSaison() == null) {
|
|
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElseThrow();
|
|
creneau.setSaison(saisonActive);
|
|
}
|
|
|
|
creneauRepository.save(creneau);
|
|
redirectAttributes.addFlashAttribute("success", "Créneau d'entraînement enregistré avec succès.");
|
|
return "redirect:/planning?jour=" + creneau.getJourSemaine().name();
|
|
}
|
|
|
|
@PostMapping("/{id}/delete")
|
|
public String deleteCreneau(@PathVariable Long id, RedirectAttributes redirectAttributes) {
|
|
CreneauEntrainement creneau = creneauRepository.findById(id)
|
|
.orElseThrow(() -> new IllegalArgumentException("Créneau introuvable : " + id));
|
|
JourSemaine jour = creneau.getJourSemaine();
|
|
creneauRepository.delete(creneau);
|
|
redirectAttributes.addFlashAttribute("success", "Créneau d'entraînement supprimé avec succès.");
|
|
return "redirect:/planning?jour=" + jour.name();
|
|
}
|
|
}
|