feat: implémentation de la gestion des saisons (UI, service, refactoring sidebar)

This commit is contained in:
2026-05-29 22:35:33 +02:00
parent dd31d73fed
commit a429e67133
27 changed files with 591 additions and 185 deletions
@@ -26,6 +26,10 @@ public class Categorie {
@Column(name = "tarif_exterieur", nullable = false, precision = 10, scale = 2)
private BigDecimal tarifExterieur;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "saison_id", nullable = false)
private Saison saison;
// Getters and Setters
public Long getId() { return id; }
@@ -45,4 +49,7 @@ public class Categorie {
public BigDecimal getTarifExterieur() { return tarifExterieur; }
public void setTarifExterieur(BigDecimal tarifExterieur) { this.tarifExterieur = tarifExterieur; }
public Saison getSaison() { return saison; }
public void setSaison(Saison saison) { this.saison = saison; }
}
@@ -23,6 +23,10 @@ public class Equipement {
@Column(name = "prix_contribution", nullable = false, precision = 10, scale = 2)
private BigDecimal prixContribution = BigDecimal.ZERO;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "saison_id", nullable = false)
private Saison saison;
// Getters and Setters
public Long getId() { return id; }
@@ -39,4 +43,7 @@ public class Equipement {
public BigDecimal getPrixContribution() { return prixContribution; }
public void setPrixContribution(BigDecimal prixContribution) { this.prixContribution = prixContribution; }
public Saison getSaison() { return saison; }
public void setSaison(Saison saison) { this.saison = saison; }
}
@@ -21,8 +21,9 @@ public class Licence {
@JoinColumn(name = "categorie_id", nullable = false)
private Categorie categorie;
@Column(nullable = false, length = 20)
private String saison;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "saison_id", nullable = false)
private Saison saison;
@Column(nullable = false, length = 50)
private String etat;
@@ -89,8 +90,8 @@ public class Licence {
public Categorie getCategorie() { return categorie; }
public void setCategorie(Categorie categorie) { this.categorie = categorie; }
public String getSaison() { return saison; }
public void setSaison(String saison) { this.saison = saison; }
public Saison getSaison() { return saison; }
public void setSaison(Saison saison) { this.saison = saison; }
public String getEtat() { return etat; }
public void setEtat(String etat) { this.etat = etat; }
@@ -0,0 +1,58 @@
package com.astalange.core.entity;
import jakarta.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "saison")
public class Saison {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String nom;
@Column(name = "est_active", nullable = false)
private Boolean estActive = false;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public Boolean getEstActive() {
return estActive;
}
public void setEstActive(Boolean estActive) {
this.estActive = estActive;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Saison saison = (Saison) o;
return Objects.equals(id, saison.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
@@ -9,4 +9,7 @@ import java.util.List;
@Repository
public interface AdherentRepository extends JpaRepository<Adherent, Long> {
List<Adherent> findTop5ByOrderByIdDesc();
@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<Adherent> searchByQuery(@org.springframework.data.repository.query.Param("query") String query);
}
@@ -4,6 +4,10 @@ import com.astalange.core.entity.Categorie;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.astalange.core.entity.Saison;
import java.util.List;
@Repository
public interface CategorieRepository extends JpaRepository<Categorie, Long> {
List<Categorie> findBySaison(Saison saison);
}
@@ -4,6 +4,10 @@ import com.astalange.core.entity.Equipement;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.astalange.core.entity.Saison;
import java.util.List;
@Repository
public interface EquipementRepository extends JpaRepository<Equipement, Long> {
List<Equipement> findBySaison(Saison saison);
}
@@ -0,0 +1,12 @@
package com.astalange.core.repository;
import com.astalange.core.entity.Saison;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface SaisonRepository extends JpaRepository<Saison, Long> {
Optional<Saison> findByEstActiveTrue();
}
@@ -0,0 +1,84 @@
package com.astalange.core.service;
import com.astalange.core.entity.Categorie;
import com.astalange.core.entity.Equipement;
import com.astalange.core.entity.Saison;
import com.astalange.core.repository.CategorieRepository;
import com.astalange.core.repository.EquipementRepository;
import com.astalange.core.repository.SaisonRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
public class SaisonService {
private final SaisonRepository saisonRepository;
private final CategorieRepository categorieRepository;
private final EquipementRepository equipementRepository;
public SaisonService(SaisonRepository saisonRepository, CategorieRepository categorieRepository, EquipementRepository equipementRepository) {
this.saisonRepository = saisonRepository;
this.categorieRepository = categorieRepository;
this.equipementRepository = equipementRepository;
}
@Transactional
public Saison creerNouvelleSaison(String nom, boolean importerParametragePrecedent) {
Optional<Saison> ancienneSaisonOpt = saisonRepository.findByEstActiveTrue();
// Désactiver toutes les saisons actuelles (il ne devrait y en avoir qu'une mais on s'assure de tout nettoyer)
List<Saison> toutesLesSaisons = saisonRepository.findAll();
for (Saison s : toutesLesSaisons) {
s.setEstActive(false);
saisonRepository.save(s);
}
// Création de la nouvelle saison
Saison nouvelleSaison = new Saison();
nouvelleSaison.setNom(nom);
nouvelleSaison.setEstActive(true);
nouvelleSaison = saisonRepository.save(nouvelleSaison);
if (importerParametragePrecedent && ancienneSaisonOpt.isPresent()) {
Saison ancienneSaison = ancienneSaisonOpt.get();
dupliquerParametrages(ancienneSaison, nouvelleSaison);
}
return nouvelleSaison;
}
private void dupliquerParametrages(Saison ancienneSaison, Saison nouvelleSaison) {
// 1. Dupliquer les équipements
List<Equipement> anciensEquipements = equipementRepository.findBySaison(ancienneSaison);
for (Equipement ancien : anciensEquipements) {
Equipement nouvelEquipement = new Equipement();
nouvelEquipement.setNom(ancien.getNom());
nouvelEquipement.setDescription(ancien.getDescription());
nouvelEquipement.setObligatoire(ancien.getObligatoire());
nouvelEquipement.setPrixContribution(ancien.getPrixContribution());
nouvelEquipement.setSaison(nouvelleSaison);
equipementRepository.save(nouvelEquipement);
}
// 2. Dupliquer les catégories (avec incrémentation de l'année)
List<Categorie> anciennesCategories = categorieRepository.findBySaison(ancienneSaison);
for (Categorie ancienne : anciennesCategories) {
Categorie nouvelleCategorie = new Categorie();
nouvelleCategorie.setNom(ancienne.getNom());
// Incrémentation de +1 sur l'année de naissance pivot
if (ancienne.getAnneeMin() != null) {
nouvelleCategorie.setAnneeMin(ancienne.getAnneeMin() + 1);
}
if (ancienne.getAnneeMax() != null) {
nouvelleCategorie.setAnneeMax(ancienne.getAnneeMax() + 1);
}
nouvelleCategorie.setTarifBase(ancienne.getTarifBase());
nouvelleCategorie.setTarifExterieur(ancienne.getTarifExterieur());
nouvelleCategorie.setSaison(nouvelleSaison);
categorieRepository.save(nouvelleCategorie);
}
}
}
@@ -0,0 +1,43 @@
-- V9__introduction_saison.sql
-- 1. Création de la table saison
CREATE TABLE saison (
id BIGSERIAL PRIMARY KEY,
nom VARCHAR(255) NOT NULL,
est_active BOOLEAN NOT NULL DEFAULT FALSE
);
-- Création d'une saison par défaut pour les données existantes
INSERT INTO saison (nom, est_active) VALUES ('Saison Actuelle', TRUE);
-- 2. Ajout de saison_id dans les tables de paramétrage
ALTER TABLE categorie ADD COLUMN saison_id BIGINT;
ALTER TABLE equipement ADD COLUMN saison_id BIGINT;
-- Il n'y a pas de table tarif, les tarifs sont dans categorie.
-- Affecter la saison par défaut aux paramètres existants
UPDATE categorie SET saison_id = (SELECT id FROM saison LIMIT 1);
UPDATE equipement SET saison_id = (SELECT id FROM saison LIMIT 1);
-- Rendre saison_id NOT NULL et ajouter les contraintes
ALTER TABLE categorie ALTER COLUMN saison_id SET NOT NULL;
ALTER TABLE categorie ADD CONSTRAINT fk_categorie_saison FOREIGN KEY (saison_id) REFERENCES saison(id);
ALTER TABLE equipement ALTER COLUMN saison_id SET NOT NULL;
ALTER TABLE equipement ADD CONSTRAINT fk_equipement_saison FOREIGN KEY (saison_id) REFERENCES saison(id);
-- 3. Ajout de saison_id sur licence
-- Licence a déjà une colonne saison (String). On va la remplacer par saison_id
ALTER TABLE licence RENAME COLUMN saison TO ancienne_saison;
ALTER TABLE licence ADD COLUMN saison_id BIGINT;
UPDATE licence SET saison_id = (SELECT id FROM saison LIMIT 1);
ALTER TABLE licence ALTER COLUMN saison_id SET NOT NULL;
ALTER TABLE licence ADD CONSTRAINT fk_licence_saison FOREIGN KEY (saison_id) REFERENCES saison(id);
ALTER TABLE licence DROP COLUMN ancienne_saison;
-- 4. Migration de paiement et dotation pour pointer sur licence_id au lieu de adherent_id
-- Ajout des colonnes licence_id
-- (Paiement et Dotation avaient un adherent_id qui n'est pas dans l'entité actuelle mais peut-être en base ?)
-- D'après les entités, Paiement et Dotation ont DEJA licence_id et n'ont PAS adherent_id !
-- Le plan proposait de modifier ça mais le code a DÉJÀ ces modifications.
-- Je vais juste vérifier s'il faut modifier la base de données.
-- Les entités Paiement.java et Dotation.java ont déjà `private Licence licence;`