feat: implement educator management and display educator initials on training schedule
AS Talange CI/CD Pipeline / Build & Run Unit Tests (push) Successful in 3m2s
AS Talange CI/CD Pipeline / Build & Run in Docker Container (push) Successful in 3m20s

This commit is contained in:
2026-06-01 21:44:02 +02:00
parent e39921f049
commit aba4ed0770
12 changed files with 349 additions and 4 deletions
@@ -0,0 +1,88 @@
package com.astalange.web.controller;
import com.astalange.core.entity.Educateur;
import com.astalange.core.entity.Categorie;
import com.astalange.core.entity.Equipe;
import com.astalange.core.entity.Saison;
import com.astalange.core.repository.EducateurRepository;
import com.astalange.core.repository.CategorieRepository;
import com.astalange.core.repository.EquipeRepository;
import com.astalange.core.repository.SaisonRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Controller
@RequestMapping("/educateurs")
public class EducateurController {
private final EducateurRepository educateurRepository;
private final CategorieRepository categorieRepository;
private final EquipeRepository equipeRepository;
private final SaisonRepository saisonRepository;
public EducateurController(EducateurRepository educateurRepository,
CategorieRepository categorieRepository,
EquipeRepository equipeRepository,
SaisonRepository saisonRepository) {
this.educateurRepository = educateurRepository;
this.categorieRepository = categorieRepository;
this.equipeRepository = equipeRepository;
this.saisonRepository = saisonRepository;
}
@GetMapping
public String listEducateurs(Model model) {
model.addAttribute("educateurs", educateurRepository.findAllWithCategorieAndEquipe());
return "parametrage/educateurs_list";
}
@GetMapping("/new")
public String showCreateForm(Model model) {
model.addAttribute("educateur", new Educateur());
populateModelAttributes(model);
return "parametrage/educateurs_form";
}
@GetMapping("/{id}/edit")
public String showEditForm(@PathVariable Long id, Model model) {
Educateur educateur = educateurRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Invalid educator ID: " + id));
model.addAttribute("educateur", educateur);
populateModelAttributes(model);
return "parametrage/educateurs_form";
}
@PostMapping
public String saveEducateur(@ModelAttribute("educateur") Educateur educateur) {
if (educateur.getCategorie() != null && educateur.getCategorie().getId() == null) {
educateur.setCategorie(null);
}
if (educateur.getEquipe() != null && educateur.getEquipe().getId() == null) {
educateur.setEquipe(null);
}
educateurRepository.save(educateur);
return "redirect:/educateurs";
}
@PostMapping("/{id}/delete")
public String deleteEducateur(@PathVariable Long id) {
Educateur educateur = educateurRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Invalid educator ID: " + id));
educateurRepository.delete(educateur);
return "redirect:/educateurs";
}
private void populateModelAttributes(Model model) {
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
if (saisonActive != null) {
model.addAttribute("categories", categorieRepository.findBySaison(saisonActive));
model.addAttribute("equipes", equipeRepository.findBySaison(saisonActive));
} else {
model.addAttribute("categories", categorieRepository.findAll());
model.addAttribute("equipes", equipeRepository.findAllWithCategorie());
}
}
}
@@ -3,6 +3,7 @@ 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.EducateurRepository;
import com.astalange.core.repository.EquipeRepository;
import com.astalange.core.repository.SaisonRepository;
import com.astalange.core.repository.TerrainRepository;
@@ -23,17 +24,20 @@ public class PlanningController {
private final CategorieRepository categorieRepository;
private final SaisonRepository saisonRepository;
private final EquipeRepository equipeRepository;
private final EducateurRepository educateurRepository;
public PlanningController(CreneauEntrainementRepository creneauRepository,
TerrainRepository terrainRepository,
CategorieRepository categorieRepository,
SaisonRepository saisonRepository,
EquipeRepository equipeRepository) {
EquipeRepository equipeRepository,
EducateurRepository educateurRepository) {
this.creneauRepository = creneauRepository;
this.terrainRepository = terrainRepository;
this.categorieRepository = categorieRepository;
this.saisonRepository = saisonRepository;
this.equipeRepository = equipeRepository;
this.educateurRepository = educateurRepository;
}
@GetMapping
@@ -56,10 +60,33 @@ public class PlanningController {
}
List<CreneauEntrainement> creneaux = creneauRepository.findBySaisonAndJourSemaineFetch(saisonActive, selectedDay);
List<Educateur> educateurs = educateurRepository.findAllWithCategorieAndEquipe();
// Detect conflicts
// Detect conflicts and populate educator initials
for (int i = 0; i < creneaux.size(); i++) {
CreneauEntrainement c1 = creneaux.get(i);
// Populate educator initials
List<String> initials = new ArrayList<>();
for (Educateur ed : educateurs) {
boolean match = false;
if (c1.getEquipe() != null) {
if (ed.getEquipe() != null && ed.getEquipe().getId().equals(c1.getEquipe().getId())) {
match = true;
}
} else if (c1.getCategorie() != null) {
if (ed.getCategorie() != null && ed.getCategorie().getId().equals(c1.getCategorie().getId())) {
match = true;
} else if (ed.getEquipe() != null && ed.getEquipe().getCategorie() != null && ed.getEquipe().getCategorie().getId().equals(c1.getCategorie().getId())) {
match = true;
}
}
if (match) {
initials.add(ed.getInitiales());
}
}
c1.setInitialesEducateurs(String.join(", ", initials));
for (int j = 0; j < creneaux.size(); j++) {
if (i == j) continue;
CreneauEntrainement c2 = creneaux.get(j);