fix(licence): corriger l'évaluation SpEL Thymeleaf et finaliser la réduction éducateur
This commit is contained in:
@@ -50,15 +50,21 @@ public class Licence {
|
|||||||
@Column(name = "sport_easy_email_sent_at")
|
@Column(name = "sport_easy_email_sent_at")
|
||||||
private java.time.LocalDateTime sportEasyEmailSentAt;
|
private java.time.LocalDateTime sportEasyEmailSentAt;
|
||||||
|
|
||||||
|
@Column(name = "reduction_educateur", nullable = false)
|
||||||
|
private Boolean reductionEducateur = false;
|
||||||
|
|
||||||
|
@Column(name = "pourcentage_reduction_educateur")
|
||||||
|
private Integer pourcentageReductionEducateur = 100;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "licence", cascade = CascadeType.ALL, orphanRemoval = true)
|
@OneToMany(mappedBy = "licence", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
private List<Paiement> paiements = new ArrayList<>();
|
private List<Paiement> paiements = new ArrayList<>();
|
||||||
|
|
||||||
@OneToMany(mappedBy = "licence", cascade = CascadeType.ALL, orphanRemoval = true)
|
@OneToMany(mappedBy = "licence", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
private List<Dotation> dotations = new ArrayList<>();
|
private List<Dotation> dotations = new ArrayList<>();
|
||||||
|
|
||||||
// Logic for Global Total Price
|
// Logic for Raw Price (before reduction)
|
||||||
@Transient
|
@Transient
|
||||||
public BigDecimal getPrixTotal() {
|
public BigDecimal getPrixBrut() {
|
||||||
if (categorie == null) return BigDecimal.ZERO;
|
if (categorie == null) return BigDecimal.ZERO;
|
||||||
|
|
||||||
BigDecimal prixTotal = (adherent != null && adherent.isResidentTalange())
|
BigDecimal prixTotal = (adherent != null && adherent.isResidentTalange())
|
||||||
@@ -69,7 +75,7 @@ public class Licence {
|
|||||||
|
|
||||||
if (dotations != null) {
|
if (dotations != null) {
|
||||||
for (Dotation dot : dotations) {
|
for (Dotation dot : dotations) {
|
||||||
if (dot.getChoisi() && dot.getEquipement() != null) {
|
if (dot != null && Boolean.TRUE.equals(dot.getChoisi()) && dot.getEquipement() != null) {
|
||||||
BigDecimal price = categorie.getEquipementPrix(dot.getEquipement().getId());
|
BigDecimal price = categorie.getEquipementPrix(dot.getEquipement().getId());
|
||||||
if (price != null) {
|
if (price != null) {
|
||||||
prixTotal = prixTotal.add(price);
|
prixTotal = prixTotal.add(price);
|
||||||
@@ -81,6 +87,50 @@ public class Licence {
|
|||||||
return prixTotal;
|
return prixTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
public BigDecimal getEquipementsContrib() {
|
||||||
|
if (categorie == null) return BigDecimal.ZERO;
|
||||||
|
BigDecimal tarifCategorie = (adherent != null && adherent.isResidentTalange())
|
||||||
|
? categorie.getTarifBase()
|
||||||
|
: categorie.getTarifExterieur();
|
||||||
|
if (tarifCategorie == null) tarifCategorie = BigDecimal.ZERO;
|
||||||
|
BigDecimal prixBrut = getPrixBrut();
|
||||||
|
BigDecimal contrib = prixBrut.subtract(tarifCategorie);
|
||||||
|
return contrib.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : contrib;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logic for Global Total Price (after discount if applicable)
|
||||||
|
@Transient
|
||||||
|
public BigDecimal getPrixTotal() {
|
||||||
|
BigDecimal prixBrut = getPrixBrut();
|
||||||
|
|
||||||
|
if (Boolean.TRUE.equals(reductionEducateur)) {
|
||||||
|
int pct = (pourcentageReductionEducateur != null && pourcentageReductionEducateur >= 1 && pourcentageReductionEducateur <= 100)
|
||||||
|
? pourcentageReductionEducateur
|
||||||
|
: 100;
|
||||||
|
|
||||||
|
if (pct >= 100) {
|
||||||
|
return BigDecimal.ZERO.setScale(2, java.math.RoundingMode.HALF_UP);
|
||||||
|
} else {
|
||||||
|
BigDecimal multiplier = BigDecimal.valueOf(100 - pct)
|
||||||
|
.divide(BigDecimal.valueOf(100), 4, java.math.RoundingMode.HALF_UP);
|
||||||
|
return prixBrut.multiply(multiplier).setScale(2, java.math.RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prixBrut.setScale(2, java.math.RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
public BigDecimal getMontantReduction() {
|
||||||
|
if (!Boolean.TRUE.equals(reductionEducateur)) {
|
||||||
|
return BigDecimal.ZERO.setScale(2, java.math.RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
BigDecimal prixBrut = getPrixBrut();
|
||||||
|
BigDecimal prixTotal = getPrixTotal();
|
||||||
|
return prixBrut.subtract(prixTotal).setScale(2, java.math.RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
|
||||||
// Logic for Reste A Payer
|
// Logic for Reste A Payer
|
||||||
@Transient
|
@Transient
|
||||||
public BigDecimal getResteAPayer() {
|
public BigDecimal getResteAPayer() {
|
||||||
@@ -146,6 +196,12 @@ public class Licence {
|
|||||||
public java.time.LocalDateTime getSportEasyEmailSentAt() { return sportEasyEmailSentAt; }
|
public java.time.LocalDateTime getSportEasyEmailSentAt() { return sportEasyEmailSentAt; }
|
||||||
public void setSportEasyEmailSentAt(java.time.LocalDateTime sportEasyEmailSentAt) { this.sportEasyEmailSentAt = sportEasyEmailSentAt; }
|
public void setSportEasyEmailSentAt(java.time.LocalDateTime sportEasyEmailSentAt) { this.sportEasyEmailSentAt = sportEasyEmailSentAt; }
|
||||||
|
|
||||||
|
public Boolean getReductionEducateur() { return reductionEducateur != null ? reductionEducateur : false; }
|
||||||
|
public void setReductionEducateur(Boolean reductionEducateur) { this.reductionEducateur = reductionEducateur; }
|
||||||
|
|
||||||
|
public Integer getPourcentageReductionEducateur() { return pourcentageReductionEducateur != null ? pourcentageReductionEducateur : 100; }
|
||||||
|
public void setPourcentageReductionEducateur(Integer pourcentageReductionEducateur) { this.pourcentageReductionEducateur = pourcentageReductionEducateur; }
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
public boolean isRenouvellement() {
|
public boolean isRenouvellement() {
|
||||||
return typeDemande != null && (
|
return typeDemande != null && (
|
||||||
|
|||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE licence ADD COLUMN reduction_educateur BOOLEAN NOT NULL DEFAULT FALSE;
|
||||||
|
ALTER TABLE licence ADD COLUMN pourcentage_reduction_educateur INT DEFAULT 100;
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package com.astalange.core;
|
||||||
|
|
||||||
|
import com.astalange.core.entity.Adherent;
|
||||||
|
import com.astalange.core.entity.Categorie;
|
||||||
|
import com.astalange.core.entity.Licence;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class LicenceReductionTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Devrait calculer le prix normal sans réduction")
|
||||||
|
void testPrixSansReduction() {
|
||||||
|
Categorie cat = new Categorie();
|
||||||
|
cat.setTarifBase(new BigDecimal("100.00"));
|
||||||
|
cat.setTarifExterieur(new BigDecimal("120.00"));
|
||||||
|
|
||||||
|
Adherent adh = new Adherent();
|
||||||
|
adh.setResidentTalange(true);
|
||||||
|
|
||||||
|
Licence licence = new Licence();
|
||||||
|
licence.setCategorie(cat);
|
||||||
|
licence.setAdherent(adh);
|
||||||
|
licence.setReductionEducateur(false);
|
||||||
|
|
||||||
|
assertEquals(new BigDecimal("100.00"), licence.getPrixBrut());
|
||||||
|
assertEquals(new BigDecimal("100.00"), licence.getPrixTotal());
|
||||||
|
assertEquals(new BigDecimal("0.00"), licence.getMontantReduction());
|
||||||
|
assertEquals(new BigDecimal("100.00"), licence.getResteAPayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Devrait calculer une réduction de 100% (gratuit)")
|
||||||
|
void testReduction100Pourcent() {
|
||||||
|
Categorie cat = new Categorie();
|
||||||
|
cat.setTarifBase(new BigDecimal("140.00"));
|
||||||
|
|
||||||
|
Adherent adh = new Adherent();
|
||||||
|
adh.setResidentTalange(true);
|
||||||
|
|
||||||
|
Licence licence = new Licence();
|
||||||
|
licence.setCategorie(cat);
|
||||||
|
licence.setAdherent(adh);
|
||||||
|
licence.setReductionEducateur(true);
|
||||||
|
licence.setPourcentageReductionEducateur(100);
|
||||||
|
|
||||||
|
assertEquals(new BigDecimal("140.00"), licence.getPrixBrut());
|
||||||
|
assertEquals(new BigDecimal("0.00"), licence.getPrixTotal());
|
||||||
|
assertEquals(new BigDecimal("140.00"), licence.getMontantReduction());
|
||||||
|
assertEquals(new BigDecimal("0.00"), licence.getResteAPayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Devrait calculer une réduction partielle (ex: 50%)")
|
||||||
|
void testReductionPartielle50Pourcent() {
|
||||||
|
Categorie cat = new Categorie();
|
||||||
|
cat.setTarifBase(new BigDecimal("150.00"));
|
||||||
|
|
||||||
|
Adherent adh = new Adherent();
|
||||||
|
adh.setResidentTalange(true);
|
||||||
|
|
||||||
|
Licence licence = new Licence();
|
||||||
|
licence.setCategorie(cat);
|
||||||
|
licence.setAdherent(adh);
|
||||||
|
licence.setReductionEducateur(true);
|
||||||
|
licence.setPourcentageReductionEducateur(50);
|
||||||
|
|
||||||
|
assertEquals(new BigDecimal("150.00"), licence.getPrixBrut());
|
||||||
|
assertEquals(new BigDecimal("75.00"), licence.getPrixTotal());
|
||||||
|
assertEquals(new BigDecimal("75.00"), licence.getMontantReduction());
|
||||||
|
assertEquals(new BigDecimal("75.00"), licence.getResteAPayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Devrait calculer une réduction partielle de 20%")
|
||||||
|
void testReductionPartielle20Pourcent() {
|
||||||
|
Categorie cat = new Categorie();
|
||||||
|
cat.setTarifBase(new BigDecimal("200.00"));
|
||||||
|
|
||||||
|
Adherent adh = new Adherent();
|
||||||
|
adh.setResidentTalange(true);
|
||||||
|
|
||||||
|
Licence licence = new Licence();
|
||||||
|
licence.setCategorie(cat);
|
||||||
|
licence.setAdherent(adh);
|
||||||
|
licence.setReductionEducateur(true);
|
||||||
|
licence.setPourcentageReductionEducateur(20);
|
||||||
|
|
||||||
|
assertEquals(new BigDecimal("200.00"), licence.getPrixBrut());
|
||||||
|
assertEquals(new BigDecimal("160.00"), licence.getPrixTotal());
|
||||||
|
assertEquals(new BigDecimal("40.00"), licence.getMontantReduction());
|
||||||
|
assertEquals(new BigDecimal("160.00"), licence.getResteAPayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,7 +50,9 @@ public class LicenceController {
|
|||||||
@RequestParam(required = false) String typeDemande,
|
@RequestParam(required = false) String typeDemande,
|
||||||
@RequestParam(required = false) String typeLicence,
|
@RequestParam(required = false) String typeLicence,
|
||||||
@RequestParam(required = false) String commentaire,
|
@RequestParam(required = false) String commentaire,
|
||||||
@RequestParam(required = false) Long equipeId) {
|
@RequestParam(required = false) Long equipeId,
|
||||||
|
@RequestParam(required = false, defaultValue = "false") Boolean reductionEducateur,
|
||||||
|
@RequestParam(required = false, defaultValue = "100") Integer pourcentageReductionEducateur) {
|
||||||
|
|
||||||
Adherent adherent = adherentRepository.findById(id)
|
Adherent adherent = adherentRepository.findById(id)
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Invalid Adherent ID"));
|
.orElseThrow(() -> new IllegalArgumentException("Invalid Adherent ID"));
|
||||||
@@ -75,6 +77,8 @@ public class LicenceController {
|
|||||||
licence.setTypeDemande(typeDemande);
|
licence.setTypeDemande(typeDemande);
|
||||||
licence.setTypeLicence(typeLicence);
|
licence.setTypeLicence(typeLicence);
|
||||||
licence.setCommentaire(commentaire);
|
licence.setCommentaire(commentaire);
|
||||||
|
licence.setReductionEducateur(Boolean.TRUE.equals(reductionEducateur));
|
||||||
|
licence.setPourcentageReductionEducateur(pourcentageReductionEducateur != null ? pourcentageReductionEducateur : 100);
|
||||||
|
|
||||||
if (equipeId != null) {
|
if (equipeId != null) {
|
||||||
Equipe equipe = equipeRepository.findById(equipeId)
|
Equipe equipe = equipeRepository.findById(equipeId)
|
||||||
@@ -100,7 +104,9 @@ public class LicenceController {
|
|||||||
@RequestParam(required = false) String typeDemande,
|
@RequestParam(required = false) String typeDemande,
|
||||||
@RequestParam(required = false) String typeLicence,
|
@RequestParam(required = false) String typeLicence,
|
||||||
@RequestParam(required = false) String commentaire,
|
@RequestParam(required = false) String commentaire,
|
||||||
@RequestParam(required = false) Long equipeId) {
|
@RequestParam(required = false) Long equipeId,
|
||||||
|
@RequestParam(required = false, defaultValue = "false") Boolean reductionEducateur,
|
||||||
|
@RequestParam(required = false, defaultValue = "100") Integer pourcentageReductionEducateur) {
|
||||||
|
|
||||||
Licence licence = licenceRepository.findById(licenceId)
|
Licence licence = licenceRepository.findById(licenceId)
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Invalid Licence ID"));
|
.orElseThrow(() -> new IllegalArgumentException("Invalid Licence ID"));
|
||||||
@@ -114,6 +120,8 @@ public class LicenceController {
|
|||||||
licence.setTypeDemande(typeDemande);
|
licence.setTypeDemande(typeDemande);
|
||||||
licence.setTypeLicence(typeLicence);
|
licence.setTypeLicence(typeLicence);
|
||||||
licence.setCommentaire(commentaire);
|
licence.setCommentaire(commentaire);
|
||||||
|
licence.setReductionEducateur(Boolean.TRUE.equals(reductionEducateur));
|
||||||
|
licence.setPourcentageReductionEducateur(pourcentageReductionEducateur != null ? pourcentageReductionEducateur : 100);
|
||||||
|
|
||||||
if (equipeId != null) {
|
if (equipeId != null) {
|
||||||
Equipe equipe = equipeRepository.findById(equipeId)
|
Equipe equipe = equipeRepository.findById(equipeId)
|
||||||
@@ -189,7 +197,7 @@ public class LicenceController {
|
|||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append('\ufeff');
|
sb.append('\ufeff');
|
||||||
sb.append("Nom;Prénom;Catégorie;N° Licence;Email;Type de Demande;Saison;Etat\n");
|
sb.append("Nom;Prénom;Catégorie;N° Licence;Email;Type de Demande;Réduction Éducateur;Saison;Etat\n");
|
||||||
|
|
||||||
for (Licence l : licences) {
|
for (Licence l : licences) {
|
||||||
String n = l.getAdherent() != null && l.getAdherent().getNom() != null ? l.getAdherent().getNom() : "";
|
String n = l.getAdherent() != null && l.getAdherent().getNom() != null ? l.getAdherent().getNom() : "";
|
||||||
@@ -198,6 +206,7 @@ public class LicenceController {
|
|||||||
String num = l.getNumeroLicence() != null ? l.getNumeroLicence() : "";
|
String num = l.getNumeroLicence() != null ? l.getNumeroLicence() : "";
|
||||||
String e = l.getAdherent() != null && l.getAdherent().getEmail() != null ? l.getAdherent().getEmail() : "";
|
String e = l.getAdherent() != null && l.getAdherent().getEmail() != null ? l.getAdherent().getEmail() : "";
|
||||||
String td = l.getTypeDemande() != null ? l.getTypeDemande() : "";
|
String td = l.getTypeDemande() != null ? l.getTypeDemande() : "";
|
||||||
|
String red = Boolean.TRUE.equals(l.getReductionEducateur()) ? ("-" + l.getPourcentageReductionEducateur() + "%") : "Non";
|
||||||
String s = l.getSaison() != null ? l.getSaison().getNom() : "";
|
String s = l.getSaison() != null ? l.getSaison().getNom() : "";
|
||||||
String etat = l.getEtat() != null ? l.getEtat() : "";
|
String etat = l.getEtat() != null ? l.getEtat() : "";
|
||||||
|
|
||||||
@@ -207,6 +216,7 @@ public class LicenceController {
|
|||||||
.append(escapeCsv(num)).append(";")
|
.append(escapeCsv(num)).append(";")
|
||||||
.append(escapeCsv(e)).append(";")
|
.append(escapeCsv(e)).append(";")
|
||||||
.append(escapeCsv(td)).append(";")
|
.append(escapeCsv(td)).append(";")
|
||||||
|
.append(escapeCsv(red)).append(";")
|
||||||
.append(escapeCsv(s)).append(";")
|
.append(escapeCsv(s)).append(";")
|
||||||
.append(escapeCsv(etat)).append("\n");
|
.append(escapeCsv(etat)).append("\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,7 +226,7 @@
|
|||||||
<div th:if="${adherent.id != null}" class="max-w-6xl mx-auto bg-white rounded-xl shadow-sm border border-gray-100 p-8 mt-6">
|
<div th:if="${adherent.id != null}" class="max-w-6xl mx-auto bg-white rounded-xl shadow-sm border border-gray-100 p-8 mt-6">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h3 class="text-xl font-bold text-gray-900">Licences de l'adhérent</h3>
|
<h3 class="text-xl font-bold text-gray-900">Licences de l'adhérent</h3>
|
||||||
<button th:if="${#lists.isEmpty(licences)}" onclick="openLicenceModal()" class="bg-green-600 text-white px-4 py-2 rounded-lg text-sm font-medium hover:bg-green-700 transition-colors">
|
<button onclick="openLicenceModal()" class="bg-green-600 text-white px-4 py-2 rounded-lg text-sm font-medium hover:bg-green-700 transition-colors">
|
||||||
+ Ajouter une Licence
|
+ Ajouter une Licence
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -251,14 +251,14 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<th:block th:each="lic : ${licences}">
|
<th:block th:each="lic : ${licences}">
|
||||||
<tr class="hover:bg-gray-50 border-b border-gray-100 licence-row"
|
<tr class="hover:bg-gray-50 border-b border-gray-100 licence-row"
|
||||||
th:data-tarif-base="${lic.categorie.tarifBase}"
|
th:data-tarif-base="${lic.categorie != null ? lic.categorie.tarifBase : 0}"
|
||||||
th:data-tarif-exterieur="${lic.categorie.tarifExterieur}"
|
th:data-tarif-exterieur="${lic.categorie != null ? lic.categorie.tarifExterieur : 0}"
|
||||||
th:data-equipements-contrib="${lic.getPrixTotal().subtract(adherent.residentTalange ? lic.categorie.tarifBase : lic.categorie.tarifExterieur)}"
|
th:data-equipements-contrib="${lic.getEquipementsContrib()}"
|
||||||
th:data-total-paye="${lic.getPrixTotal().subtract(lic.getResteAPayer())}">
|
th:data-total-paye="${lic.getSommePayee()}">
|
||||||
<td class="py-4 px-4 font-medium text-gray-900" th:text="${lic.saison.nom}">2024-2025</td>
|
<td class="py-4 px-4 font-medium text-gray-900" th:text="${lic.saison != null ? lic.saison.nom : '-'}">2024-2025</td>
|
||||||
<td class="py-4 px-4 text-gray-600">
|
<td class="py-4 px-4 text-gray-600">
|
||||||
<span th:text="${lic.categorie.nom + (lic.equipe != null ? ' (' + lic.equipe.nom + ')' : '')}">U15</span>
|
<span th:text="${lic.categorie != null ? (lic.categorie.nom + (lic.equipe != null ? ' (' + lic.equipe.nom + ')' : '')) : '-'}">U15</span>
|
||||||
<span class="text-[10px] text-gray-400 block cell-tarif-categorie" th:text="${(lic.adherent != null && lic.adherent.residentTalange ? lic.categorie.tarifBase : lic.categorie.tarifExterieur) + ' € (Catégorie)'}">100.00 € (Catégorie)</span>
|
<span class="text-[10px] text-gray-400 block cell-tarif-categorie" th:text="${lic.categorie != null ? ((lic.adherent != null && lic.adherent.residentTalange ? lic.categorie.tarifBase : lic.categorie.tarifExterieur) + ' € (Catégorie)') : '-'}">100.00 € (Catégorie)</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="py-4 px-4 text-gray-600 text-xs">
|
<td class="py-4 px-4 text-gray-600 text-xs">
|
||||||
<div th:text="${lic.typeDemande != null ? lic.typeDemande : '-'}">Nouvelle</div>
|
<div th:text="${lic.typeDemande != null ? lic.typeDemande : '-'}">Nouvelle</div>
|
||||||
@@ -270,23 +270,37 @@
|
|||||||
th:classappend="${lic.etat == 'Validée' ? 'bg-blue-100 text-blue-800' : (lic.etat == 'Payée' ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800')}"
|
th:classappend="${lic.etat == 'Validée' ? 'bg-blue-100 text-blue-800' : (lic.etat == 'Payée' ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800')}"
|
||||||
th:text="${lic.etat}">Brouillon</span>
|
th:text="${lic.etat}">Brouillon</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="py-4 px-4 text-gray-900 font-medium cell-tarif-global" th:text="${lic.getPrixTotal() + ' €'}">130.00 €</td>
|
<td class="py-4 px-4 font-medium cell-tarif-global">
|
||||||
|
<div th:if="${lic.reductionEducateur}" class="flex flex-col">
|
||||||
|
<span class="text-[10px] font-bold text-amber-700 bg-amber-50 border border-amber-200 px-2 py-0.5 rounded-full inline-block w-max mb-0.5"
|
||||||
|
th:text="'Éducateur (-' + ${lic.pourcentageReductionEducateur != null ? lic.pourcentageReductionEducateur : 100} + '%)'">Éducateur (-100%)</span>
|
||||||
|
<div class="flex items-center space-x-1 text-xs">
|
||||||
|
<span th:if="${lic.getPrixBrut().compareTo(lic.getPrixTotal()) != 0}" class="line-through text-gray-400" th:text="${lic.getPrixBrut() + ' €'}">150.00 €</span>
|
||||||
|
<span class="text-gray-900 font-bold" th:text="${lic.getPrixTotal() + ' €'}">0.00 €</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:if="${!lic.reductionEducateur}">
|
||||||
|
<span class="text-gray-900" th:text="${lic.getPrixTotal() + ' €'}">130.00 €</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
<td class="py-4 px-4 font-semibold cell-reste-payer"
|
<td class="py-4 px-4 font-semibold cell-reste-payer"
|
||||||
th:classappend="${lic.getResteAPayer() == 0 ? 'text-green-600' : 'text-red-600'}"
|
th:classappend="${lic.getResteAPayer().compareTo(T(java.math.BigDecimal).ZERO) == 0 ? 'text-green-600' : 'text-red-600'}"
|
||||||
th:text="${lic.getResteAPayer() + ' €'}">30.00 €</td>
|
th:text="${lic.getResteAPayer() + ' €'}">30.00 €</td>
|
||||||
<td class="py-4 px-4 text-right flex justify-end space-x-2">
|
<td class="py-4 px-4 text-right flex justify-end space-x-2">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
th:data-licence-id="${lic.id}"
|
th:data-licence-id="${lic.id}"
|
||||||
th:data-categorie-id="${lic.categorie.id}"
|
th:data-categorie-id="${lic.categorie != null ? lic.categorie.id : ''}"
|
||||||
th:data-numero-licence="${lic.numeroLicence}"
|
th:data-numero-licence="${lic.numeroLicence != null ? lic.numeroLicence : ''}"
|
||||||
th:data-etat="${lic.etat}"
|
th:data-etat="${lic.etat != null ? lic.etat : 'Brouillon'}"
|
||||||
th:data-type-demande="${lic.typeDemande}"
|
th:data-type-demande="${lic.typeDemande != null ? lic.typeDemande : ''}"
|
||||||
th:data-type-licence="${lic.typeLicence}"
|
th:data-type-licence="${lic.typeLicence != null ? lic.typeLicence : ''}"
|
||||||
th:data-equipe-id="${lic.equipe != null ? lic.equipe.id : ''}"
|
th:data-equipe-id="${lic.equipe != null ? lic.equipe.id : ''}"
|
||||||
th:data-commentaire="${lic.commentaire}"
|
th:data-commentaire="${lic.commentaire != null ? lic.commentaire : ''}"
|
||||||
onclick="openLicenceModal(this.getAttribute('data-licence-id'), this.getAttribute('data-categorie-id'), this.getAttribute('data-numero-licence'), this.getAttribute('data-etat'), this.getAttribute('data-type-demande'), this.getAttribute('data-type-licence'), this.getAttribute('data-equipe-id'), this.getAttribute('data-commentaire'))"
|
th:data-reduction-educateur="${lic.reductionEducateur}"
|
||||||
|
th:data-pourcentage-reduction="${lic.pourcentageReductionEducateur != null ? lic.pourcentageReductionEducateur : 100}"
|
||||||
|
onclick="openLicenceModal(this.getAttribute('data-licence-id'), this.getAttribute('data-categorie-id'), this.getAttribute('data-numero-licence'), this.getAttribute('data-etat'), this.getAttribute('data-type-demande'), this.getAttribute('data-type-licence'), this.getAttribute('data-equipe-id'), this.getAttribute('data-commentaire'), this.getAttribute('data-reduction-educateur'), this.getAttribute('data-pourcentage-reduction'))"
|
||||||
class="text-blue-600 hover:text-blue-800 font-medium bg-blue-50 px-3 py-1 rounded-lg">Modifier</button>
|
class="text-blue-600 hover:text-blue-800 font-medium bg-blue-50 px-3 py-1 rounded-lg">Modifier</button>
|
||||||
<button th:if="${lic.getResteAPayer() > 0}"
|
<button th:if="${lic.getResteAPayer().compareTo(T(java.math.BigDecimal).ZERO) > 0}"
|
||||||
type="button"
|
type="button"
|
||||||
th:data-licence-id="${lic.id}"
|
th:data-licence-id="${lic.id}"
|
||||||
th:data-reste-a-payer="${lic.getResteAPayer()}"
|
th:data-reste-a-payer="${lic.getResteAPayer()}"
|
||||||
@@ -554,6 +568,19 @@
|
|||||||
<label class="block text-sm font-medium text-gray-700 mb-1">Commentaire</label>
|
<label class="block text-sm font-medium text-gray-700 mb-1">Commentaire</label>
|
||||||
<textarea id="licenceCommentaireInput" name="commentaire" rows="3" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none" placeholder="Commentaire optionnel..."></textarea>
|
<textarea id="licenceCommentaireInput" name="commentaire" rows="3" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none" placeholder="Commentaire optionnel..."></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="bg-amber-50 p-3 rounded-lg border border-amber-200">
|
||||||
|
<label class="flex items-center space-x-2 cursor-pointer select-none">
|
||||||
|
<input type="checkbox" id="reductionEducateurInput" name="reductionEducateur" value="true" onchange="toggleReductionPourcentageVisibility()" class="w-4 h-4 text-amber-600 border-gray-300 rounded focus:ring-amber-500">
|
||||||
|
<span class="text-sm font-semibold text-amber-900">Enfant d'éducateur / Réduction</span>
|
||||||
|
</label>
|
||||||
|
<div id="pourcentageReductionBlock" class="hidden mt-2 pt-2 border-t border-amber-200/60">
|
||||||
|
<label class="block text-xs font-medium text-amber-800 mb-1">Taux de réduction (%)</label>
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<input type="number" id="pourcentageReductionInput" name="pourcentageReductionEducateur" min="1" max="100" value="100" class="w-full border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:ring-2 focus:ring-amber-500 outline-none">
|
||||||
|
<span class="text-xs font-bold text-amber-800">%</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="items-center px-4 py-3 flex justify-end space-x-2">
|
<div class="items-center px-4 py-3 flex justify-end space-x-2">
|
||||||
<button type="button" onclick="closeLicenceModal()" class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">Annuler</button>
|
<button type="button" onclick="closeLicenceModal()" class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">Annuler</button>
|
||||||
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700">Enregistrer</button>
|
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700">Enregistrer</button>
|
||||||
@@ -644,7 +671,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
function openLicenceModal(licenceId = null, categorieId = '', numeroLicence = '', etat = 'Brouillon', typeDemande = '', typeLicence = '', equipeId = '', commentaire = '') {
|
function toggleReductionPourcentageVisibility() {
|
||||||
|
const chk = document.getElementById('reductionEducateurInput');
|
||||||
|
const block = document.getElementById('pourcentageReductionBlock');
|
||||||
|
if (chk && chk.checked) {
|
||||||
|
block.classList.remove('hidden');
|
||||||
|
} else if (block) {
|
||||||
|
block.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openLicenceModal(licenceId = null, categorieId = '', numeroLicence = '', etat = 'Brouillon', typeDemande = '', typeLicence = '', equipeId = '', commentaire = '', reductionEducateur = false, pourcentageReductionEducateur = 100) {
|
||||||
document.getElementById('licenceModal').classList.remove('hidden');
|
document.getElementById('licenceModal').classList.remove('hidden');
|
||||||
const form = document.getElementById('licenceForm');
|
const form = document.getElementById('licenceForm');
|
||||||
const title = document.getElementById('licenceModalTitle');
|
const title = document.getElementById('licenceModalTitle');
|
||||||
@@ -655,6 +692,16 @@
|
|||||||
// Clean up team options first
|
// Clean up team options first
|
||||||
equipeSelect.innerHTML = '<option value="">Aucune équipe</option>';
|
equipeSelect.innerHTML = '<option value="">Aucune équipe</option>';
|
||||||
|
|
||||||
|
const redChk = document.getElementById('reductionEducateurInput');
|
||||||
|
const pctInput = document.getElementById('pourcentageReductionInput');
|
||||||
|
if (redChk) {
|
||||||
|
redChk.checked = (reductionEducateur === true || reductionEducateur === 'true');
|
||||||
|
}
|
||||||
|
if (pctInput) {
|
||||||
|
pctInput.value = (pourcentageReductionEducateur !== null && pourcentageReductionEducateur !== undefined && pourcentageReductionEducateur !== '') ? pourcentageReductionEducateur : 100;
|
||||||
|
}
|
||||||
|
toggleReductionPourcentageVisibility();
|
||||||
|
|
||||||
if (licenceId) {
|
if (licenceId) {
|
||||||
title.textContent = 'Modifier la Licence';
|
title.textContent = 'Modifier la Licence';
|
||||||
form.action = '/adherents/' + adherentId + '/licences/' + licenceId + '/update';
|
form.action = '/adherents/' + adherentId + '/licences/' + licenceId + '/update';
|
||||||
|
|||||||
@@ -86,7 +86,10 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="py-3 px-4 text-gray-600" th:text="${licence.categorie != null ? licence.categorie.nom : '-'}">Catégorie</td>
|
<td class="py-3 px-4 text-gray-600" th:text="${licence.categorie != null ? licence.categorie.nom : '-'}">Catégorie</td>
|
||||||
<td class="py-3 px-4 text-gray-600 font-mono" th:text="${licence.numeroLicence != null ? licence.numeroLicence : '-'}">N°</td>
|
<td class="py-3 px-4 text-gray-600 font-mono" th:text="${licence.numeroLicence != null ? licence.numeroLicence : '-'}">N°</td>
|
||||||
<td class="py-3 px-4 text-gray-600" th:text="${licence.typeDemande != null ? licence.typeDemande : '-'}">Type</td>
|
<td class="py-3 px-4 text-gray-600">
|
||||||
|
<div th:text="${licence.typeDemande != null ? licence.typeDemande : '-'}">Type</div>
|
||||||
|
<span th:if="${licence.reductionEducateur}" class="text-[10px] font-bold text-amber-700 bg-amber-50 border border-amber-200 px-1.5 py-0.5 rounded-full inline-block mt-0.5" th:text="'Éducateur (-' + ${licence.pourcentageReductionEducateur} + '%)'">Éducateur (-100%)</span>
|
||||||
|
</td>
|
||||||
<td class="py-3 px-4 text-gray-600" th:text="${licence.adherent.email != null ? licence.adherent.email : '-'}">Email</td>
|
<td class="py-3 px-4 text-gray-600" th:text="${licence.adherent.email != null ? licence.adherent.email : '-'}">Email</td>
|
||||||
<td class="py-3 px-4 text-gray-600" th:text="${licence.etat != null ? licence.etat : '-'}">Etat</td>
|
<td class="py-3 px-4 text-gray-600" th:text="${licence.etat != null ? licence.etat : '-'}">Etat</td>
|
||||||
<td class="py-3 px-4 text-right">
|
<td class="py-3 px-4 text-right">
|
||||||
|
|||||||
Reference in New Issue
Block a user