fix: improve adherent size matching and conditional visibility in dotations
This commit is contained in:
@@ -64,4 +64,93 @@ public class Dotation {
|
||||
|
||||
public Boolean getChoisi() { return choisi; }
|
||||
public void setChoisi(Boolean choisi) { this.choisi = choisi; }
|
||||
|
||||
public static boolean isSizeMatch(String option, String adherentSize) {
|
||||
if (option == null || adherentSize == null) return false;
|
||||
String opt = option.trim();
|
||||
String adh = adherentSize.trim();
|
||||
if (opt.isEmpty() || adh.isEmpty()) return false;
|
||||
|
||||
if (opt.equalsIgnoreCase(adh)) return true;
|
||||
|
||||
String optLower = opt.toLowerCase();
|
||||
String adhLower = adh.toLowerCase();
|
||||
|
||||
// Extract height numbers (116, 128, 140, 152, 164)
|
||||
java.util.regex.Pattern numPattern = java.util.regex.Pattern.compile("\\b(116|128|140|152|164)\\b");
|
||||
java.util.regex.Matcher adhNumMatcher = numPattern.matcher(adhLower);
|
||||
java.util.regex.Matcher optNumMatcher = numPattern.matcher(optLower);
|
||||
if (adhNumMatcher.find()) {
|
||||
String num = adhNumMatcher.group(1);
|
||||
if (optLower.contains(num)) {
|
||||
return true;
|
||||
}
|
||||
} else if (optNumMatcher.find()) {
|
||||
String num = optNumMatcher.group(1);
|
||||
if (adhLower.contains(num)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract age patterns (5/6, 7/8, 9/10, 11/12, 13/14) or (5-6, 7-8, 9-10, 11-12, 13-14)
|
||||
java.util.regex.Pattern agePattern = java.util.regex.Pattern.compile("\\b(5[/\\-]6|7[/\\-]8|9[/\\-]10|11[/\\-]12|13[/\\-]14)\\b");
|
||||
java.util.regex.Matcher adhAge = agePattern.matcher(adhLower);
|
||||
if (adhAge.find()) {
|
||||
String ageKey = adhAge.group(1).replace("-", "/");
|
||||
String altAgeKey = ageKey.replace("/", "-");
|
||||
if (optLower.contains(ageKey) || optLower.contains(altAgeKey)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract shoe sizes / pointures (27/30, 31/34, 35/38, 39/42, 43/46)
|
||||
java.util.regex.Pattern ptPattern = java.util.regex.Pattern.compile("\\b(27[/\\-]30|31[/\\-]34|35[/\\-]38|39[/\\-]42|43[/\\-]46)\\b");
|
||||
java.util.regex.Matcher adhPt = ptPattern.matcher(adhLower);
|
||||
if (adhPt.find()) {
|
||||
String ptKey = adhPt.group(1).replace("-", "/");
|
||||
String altPtKey = ptKey.replace("/", "-");
|
||||
if (optLower.contains(ptKey) || optLower.contains(altPtKey)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract "Taille X"
|
||||
java.util.regex.Pattern tNumPattern = java.util.regex.Pattern.compile("taille\\s*([0-4])");
|
||||
java.util.regex.Matcher adhTNum = tNumPattern.matcher(adhLower);
|
||||
if (adhTNum.find()) {
|
||||
String tNum = adhTNum.group(1);
|
||||
if (optLower.contains("taille " + tNum) || optLower.contains("taille" + tNum) || optLower.equals(tNum)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Standalone letter sizes (XXL, XL, L, M, S, XS)
|
||||
java.util.regex.Pattern letterPattern = java.util.regex.Pattern.compile("\\b(xxl|xl|l|m|s|xs)\\b");
|
||||
java.util.regex.Matcher adhLetter = letterPattern.matcher(adhLower);
|
||||
java.util.regex.Matcher optLetter = letterPattern.matcher(optLower);
|
||||
if (adhLetter.find() && optLetter.find()) {
|
||||
if (adhLetter.group(1).equals(optLetter.group(1))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.length() >= 2 && adhLower.contains(optLower)) return true;
|
||||
if (adh.length() >= 2 && optLower.contains(adhLower)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isTailleOptionSelected(String option) {
|
||||
if (option == null) return false;
|
||||
String trimmedOpt = option.trim();
|
||||
if (this.taille != null && !this.taille.trim().isEmpty()) {
|
||||
return this.taille.trim().equalsIgnoreCase(trimmedOpt);
|
||||
}
|
||||
if (this.licence == null || this.licence.getAdherent() == null) {
|
||||
return false;
|
||||
}
|
||||
Adherent adherent = this.licence.getAdherent();
|
||||
return isSizeMatch(trimmedOpt, adherent.getTailleVetement()) || isSizeMatch(trimmedOpt, adherent.getPointure());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -132,11 +132,8 @@ public class CategorieService {
|
||||
String pt = licence.getAdherent().getPointure();
|
||||
for (String t : dispos) {
|
||||
String trimmed = t.trim();
|
||||
if (tv != null && !tv.trim().isEmpty() && trimmed.equalsIgnoreCase(tv.trim())) {
|
||||
matchedTaille = tv.trim();
|
||||
break;
|
||||
} else if (pt != null && !pt.trim().isEmpty() && trimmed.equalsIgnoreCase(pt.trim())) {
|
||||
matchedTaille = pt.trim();
|
||||
if (Dotation.isSizeMatch(trimmed, tv) || Dotation.isSizeMatch(trimmed, pt)) {
|
||||
matchedTaille = trimmed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,12 +234,20 @@ public class AdherentController {
|
||||
existing.setLieuNaissancePays(adherent.getLieuNaissancePays());
|
||||
existing.setNationalite(adherent.getNationalite());
|
||||
existing.setEmail(adherent.getEmail());
|
||||
existing.setTelephone(adherent.getTelephone());
|
||||
existing.setRepresentantLegal(adherent.getRepresentantLegal());
|
||||
existing.setResidentTalange(adherent.isResidentTalange());
|
||||
existing.setSexe(adherent.getSexe());
|
||||
existing.setTypeMaillot(adherent.getTypeMaillot());
|
||||
existing.setTailleVetement(adherent.getTailleVetement());
|
||||
existing.setPointure(adherent.getPointure());
|
||||
|
||||
adherentRepository.save(existing);
|
||||
|
||||
List<Licence> licences = licenceRepository.findByAdherentId(existing.getId());
|
||||
for (Licence licence : licences) {
|
||||
categorieService.syncDotationsForLicence(licence);
|
||||
}
|
||||
} else {
|
||||
adherentRepository.save(adherent);
|
||||
}
|
||||
|
||||
@@ -413,22 +413,17 @@
|
||||
<div th:if="${dot.equipement.taillesDisponibles != null and !dot.equipement.taillesDisponibles.trim().isEmpty()}">
|
||||
<label class="block text-[9px] uppercase font-bold text-gray-400">Taille</label>
|
||||
<select th:name="'taille_' + ${dot.id}" class="w-full text-xs border border-gray-300 rounded px-1 py-0.5 focus:ring-1 focus:ring-blue-500 outline-none">
|
||||
<option value="" th:selected="${dot.taille == null or dot.taille.isEmpty()}">Choisir...</option>
|
||||
<option th:if="${dot.taille != null and !dot.taille.isEmpty()}"
|
||||
<option value="">Choisir...</option>
|
||||
<option th:if="${dot.taille != null and !dot.taille.isEmpty() and !#strings.contains(dot.equipement.taillesDisponibles, dot.taille)}"
|
||||
th:value="${dot.taille}"
|
||||
th:text="${dot.taille} + ' (Actuelle)'"
|
||||
selected></option>
|
||||
<option th:each="t : ${#strings.arraySplit(dot.equipement.taillesDisponibles, ',')}"
|
||||
th:if="${dot.taille == null or dot.taille != #strings.trim(t)}"
|
||||
th:value="${#strings.trim(t)}"
|
||||
th:text="${#strings.trim(t)}"
|
||||
th:selected="${dot.taille == null and (#strings.trim(t) == adherent.tailleVetement or #strings.trim(t) == adherent.pointure)}"></option>
|
||||
th:selected="${dot.isTailleOptionSelected(#strings.trim(t))}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div th:if="${(dot.equipement.taillesDisponibles == null or dot.equipement.taillesDisponibles.trim().isEmpty())}">
|
||||
<label class="block text-[9px] uppercase font-bold text-gray-400">Taille</label>
|
||||
<input type="text" th:name="'taille_' + ${dot.id}" th:value="${dot.taille != null and !dot.taille.isEmpty() ? dot.taille : (adherent.tailleVetement != null ? adherent.tailleVetement : '')}" class="w-full text-xs border border-gray-300 rounded px-1 py-0.5 focus:ring-1 focus:ring-blue-500 outline-none" placeholder="Taille/Pointure">
|
||||
</div>
|
||||
|
||||
<div th:if="${dot.equipement.couleursDisponibles != null and !dot.equipement.couleursDisponibles.trim().isEmpty()}">
|
||||
<label class="block text-[9px] uppercase font-bold text-gray-400">Couleur</label>
|
||||
|
||||
Reference in New Issue
Block a user