feat: add team support to result

This commit is contained in:
Thibaut Valentin 2026-01-18 15:10:38 +01:00
parent e8d5d0fa0c
commit 1cbbde6506
5 changed files with 70 additions and 24 deletions

View File

@ -12,6 +12,8 @@ import lombok.Setter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
@Getter @Getter
@Setter @Setter
@ -71,6 +73,8 @@ public class CompetitionGuestModel implements CombModel {
@Override @Override
public String getName() { public String getName() {
if (this.isTeam())
return this.fname;
return this.fname + " " + this.lname; return this.fname + " " + this.lname;
} }
@ -78,4 +82,21 @@ public class CompetitionGuestModel implements CombModel {
public String getName(MembreModel model, ResultPrivacy privacy) { public String getName(MembreModel model, ResultPrivacy privacy) {
return getName(); return getName();
} }
public boolean isTeam() {
return "__team".equals(this.lname);
}
public boolean isInTeam(Object comb_) {
if (!this.isTeam())
return false;
if (comb_ instanceof Long id_) {
if (id_ >= 0)
return comb.stream().anyMatch(membre -> Objects.equals(membre.getId(), id_));
else
return guest.stream().anyMatch(guestModel -> Objects.equals(guestModel.getId(), -id_));
}
return Stream.concat(comb.stream(), guest.stream()).anyMatch(c -> Objects.equals(c, comb_));
}
} }

View File

@ -114,6 +114,9 @@ public class MatchModel {
} }
public boolean isC1(Object comb) { public boolean isC1(Object comb) {
if (this.c1_guest != null && this.c1_guest.isInTeam(comb))
return true;
if (comb instanceof Long id_) { if (comb instanceof Long id_) {
if (id_ >= 0) if (id_ >= 0)
return Objects.equals(this.c1_id != null ? this.c1_id.getId() : null, id_); return Objects.equals(this.c1_id != null ? this.c1_id.getId() : null, id_);
@ -124,6 +127,9 @@ public class MatchModel {
} }
public boolean isC2(Object comb) { public boolean isC2(Object comb) {
if (this.c2_guest != null && this.c2_guest.isInTeam(comb))
return true;
if (comb instanceof Long id_) { if (comb instanceof Long id_) {
if (id_ >= 0) if (id_ >= 0)
return Objects.equals(this.c2_id != null ? this.c2_id.getId() : null, id_); return Objects.equals(this.c2_id != null ? this.c2_id.getId() : null, id_);

View File

@ -291,7 +291,11 @@ public class ResultService {
builder.nb_insc(combs.size()); builder.nb_insc(combs.size());
builder.tt_match((int) matchModels.stream().filter(MatchModel::isEnd).count()); builder.tt_match((int) matchModels.stream().filter(MatchModel::isEnd).count());
builder.point(combs.stream().mapToInt(CombsArrayData.CombsData::pointMake).sum()); builder.point(matchModels.stream()
.filter(MatchModel::isEnd)
.flatMap(m -> m.getScores().stream())
.filter(s -> s.getS1() > -900 && s.getS2() > -900)
.mapToInt(s -> s.getS1() + s.getS2()).sum());
builder.combs(combs); builder.combs(combs);
return builder.build(); return builder.build();
@ -312,12 +316,12 @@ public class ResultService {
.map(models -> { .map(models -> {
HashMap<String, String> map = new HashMap<>(); HashMap<String, String> map = new HashMap<>();
models.forEach( models.forEach(
r -> map.put(Utils.getFullName(r.getMembre()), getCombTempId(r.getMembre().getId()))); r -> map.put(r.getMembre().getName(), getCombTempId(r.getMembre().getId())));
return map; return map;
}) })
.chain(map -> competitionGuestRepository.list("competition.uuid = ?1", uuid) .chain(map -> competitionGuestRepository.list("competition.uuid = ?1 AND lname != \"__team\"", uuid)
.map(models -> { .map(models -> {
models.forEach(guestModel -> map.put(Utils.getFullName(guestModel), models.forEach(guestModel -> map.put(guestModel.getName(),
getCombTempId(guestModel.getId() * -1))); getCombTempId(guestModel.getId() * -1)));
return map; return map;
}) })
@ -355,8 +359,10 @@ public class ResultService {
builder.cat((registerModel.getCategorie2() == null) ? "---" : builder.cat((registerModel.getCategorie2() == null) ? "---" :
registerModel.getCategorie2().getName(trad)); registerModel.getCategorie2().getName(trad));
return matchRepository.list("category.compet.uuid = ?1 AND (c1_id = ?2 OR c2_id = ?2)", uuid, return matchRepository.list(
registerModel.getMembre()); "SELECT DISTINCT m FROM MatchModel m LEFT JOIN m.c1_guest.comb c1g LEFT JOIN m.c2_guest.comb c2g " +
"WHERE m.category.compet.uuid = ?1 AND (m.c1_id = ?2 OR m.c2_id = ?2 OR c1g = ?2 OR c2g = ?2)",
uuid, registerModel.getMembre());
})); }));
} else { } else {
uni = competitionGuestRepository.find("id = ?1 AND competition.uuid = ?2", -id, uuid).firstResult() uni = competitionGuestRepository.find("id = ?1 AND competition.uuid = ?2", -id, uuid).firstResult()
@ -366,7 +372,9 @@ public class ResultService {
builder.cat( builder.cat(
(guestModel.getCategorie() == null) ? "---" : guestModel.getCategorie().getName(trad)); (guestModel.getCategorie() == null) ? "---" : guestModel.getCategorie().getName(trad));
return matchRepository.list("category.compet.uuid = ?1 AND (c1_guest = ?2 OR c2_guest = ?2)", return matchRepository.list(
"SELECT DISTINCT m FROM MatchModel m LEFT JOIN m.c1_guest.guest c1g LEFT JOIN m.c2_guest.guest c2g " +
"WHERE m.category.compet.uuid = ?1 AND (m.c1_guest = ?2 OR m.c2_guest = ?2 OR c1g = ?2 OR c2g = ?2)",
uuid, guestModel); uuid, guestModel);
}); });
} }
@ -389,12 +397,13 @@ public class ResultService {
builder2.date(matchModel.getDate()); builder2.date(matchModel.getDate());
builder2.poule(pouleModels.stream().filter(p -> p.equals(matchModel.getCategory())) builder2.poule(pouleModels.stream().filter(p -> p.equals(matchModel.getCategory()))
.map(CategoryModel::getName).findFirst().orElse("")); .map(CategoryModel::getName).findFirst().orElse(""));
builder2.end(matchModel.isEnd());
AtomicInteger pointMake = new AtomicInteger(); AtomicInteger pointMake = new AtomicInteger();
AtomicInteger pointTake = new AtomicInteger(); AtomicInteger pointTake = new AtomicInteger();
if (matchModel.isC1(id)) { if (matchModel.isC1(id)) {
builder2.adv(Utils.getFullName(matchModel.getC2_id(), matchModel.getC2_guest())); builder2.adv(matchModel.getC2Name());
if (matchModel.isEnd()) { if (matchModel.isEnd()) {
matchModel.getScores().stream() matchModel.getScores().stream()
.filter(s -> s.getS1() > -900 && s.getS2() > -900) .filter(s -> s.getS1() > -900 && s.getS2() > -900)
@ -409,7 +418,7 @@ public class ResultService {
} }
builder2.win(matchModel.isEnd() && matchModel.win() > 0); builder2.win(matchModel.isEnd() && matchModel.win() > 0);
} else { } else {
builder2.adv(Utils.getFullName(matchModel.getC1_id(), matchModel.getC1_guest())); builder2.adv(matchModel.getC1Name());
if (matchModel.isEnd()) { if (matchModel.isEnd()) {
matchModel.getScores().stream() matchModel.getScores().stream()
.filter(s -> s.getS1() > -900 && s.getS2() > -900) .filter(s -> s.getS1() > -900 && s.getS2() > -900)
@ -468,7 +477,7 @@ public class ResultService {
@Builder @Builder
@RegisterForReflection @RegisterForReflection
public static record MatchsData(Date date, String poule, String adv, List<Integer[]> score, float ratio, public static record MatchsData(Date date, String poule, String adv, List<Integer[]> score, float ratio,
boolean win, boolean eq) { boolean win, boolean eq, boolean end) {
} }
} }
@ -513,14 +522,19 @@ public class ResultService {
return Uni.createFrom().voidItem(); return Uni.createFrom().voidItem();
}) })
.chain(guests -> matchRepository.list( .chain(guests -> matchRepository.list(
"category.compet.uuid = ?1 AND (c1_guest IN ?2 OR c2_guest IN ?2)", uuid, guests) "SELECT DISTINCT m FROM MatchModel m LEFT JOIN m.c1_guest.guest c1g LEFT JOIN m.c2_guest.guest c2g " +
"WHERE m.category.compet.uuid = ?1 AND (m.c1_guest IN ?2 OR m.c2_guest IN ?2 OR c1g IN ?2 OR c2g IN ?2)",
uuid, guests)
.map(matchModels -> .map(matchModels ->
getClubArray2(clubName, guests.stream().map(o -> (CombModel) o).toList(), getClubArray2(clubName, guests.stream().map(o -> (CombModel) o).toList(),
matchModels, new ArrayList<>(), membreModel))); matchModels, new ArrayList<>(), membreModel)));
} else { } else {
return clubRepository.findById(id).chain(clubModel -> return clubRepository.findById(id).chain(clubModel ->
registerRepository.list("competition.uuid = ?1 AND membre.club = ?2", uuid, clubModel) registerRepository.list("competition.uuid = ?1 AND membre.club = ?2", uuid, clubModel)
.chain(registers -> matchRepository.list("category.compet.uuid = ?1", uuid) .chain(registers -> matchRepository.list(
"SELECT DISTINCT m FROM MatchModel m LEFT JOIN m.c1_guest.comb c1g LEFT JOIN m.c2_guest.comb c2g " +
"WHERE m.category.compet.uuid = ?1 AND (m.c1_id IN ?2 OR m.c2_id IN ?2 OR c1g IN ?2 OR c2g IN ?2)",
uuid, registers.stream().map(RegisterModel::getMembre).toList())
.map(matchModels -> .map(matchModels ->
getClubArray2(clubModel.getName(), getClubArray2(clubModel.getName(),
registers.stream().map(o -> (CombModel) o.getMembre()).toList(), registers.stream().map(o -> (CombModel) o.getMembre()).toList(),
@ -534,8 +548,8 @@ public class ResultService {
builder.name(name); builder.name(name);
builder.nb_insc(combs.size()); builder.nb_insc(combs.size());
AtomicInteger tt_win = new AtomicInteger(0); ArrayList<Long> win_ids = new ArrayList<>();
AtomicInteger tt_match = new AtomicInteger(0); ArrayList<Long> match_ids = new ArrayList<>();
List<ClubArrayData.CombData> combData = combs.stream().map(comb -> { List<ClubArrayData.CombData> combData = combs.stream().map(comb -> {
var builder2 = ClubArrayData.CombData.builder(); var builder2 = ClubArrayData.CombData.builder();
@ -562,16 +576,16 @@ public class ResultService {
builder2.pointTake(stat.pointTake); builder2.pointTake(stat.pointTake);
builder2.ratioPoint(stat.getPointRate()); builder2.ratioPoint(stat.getPointRate());
tt_win.addAndGet(stat.w); win_ids.addAll(stat.win_ids);
tt_match.addAndGet(stat.w + stat.l); match_ids.addAll(stat.match_ids);
return builder2.build(); return builder2.build();
}) })
.sorted(Comparator.comparing(ClubArrayData.CombData::name)) .sorted(Comparator.comparing(ClubArrayData.CombData::name))
.toList(); .toList();
builder.nb_match(tt_match.get()); builder.nb_match((int) match_ids.stream().distinct().count());
builder.match_w(tt_win.get()); builder.match_w((int) win_ids.stream().distinct().count());
builder.ratioVictoire((float) combData.stream().filter(c -> c.l + c.w != 0) builder.ratioVictoire((float) combData.stream().filter(c -> c.l + c.w != 0)
.mapToDouble(ClubArrayData.CombData::ratioVictoire).average().orElse(0L)); .mapToDouble(ClubArrayData.CombData::ratioVictoire).average().orElse(0L));
builder.pointMake(combData.stream().mapToInt(ClubArrayData.CombData::pointMake).sum()); builder.pointMake(combData.stream().mapToInt(ClubArrayData.CombData::pointMake).sum());
@ -588,11 +602,14 @@ public class ResultService {
matchModels.stream() matchModels.stream()
.filter(m -> m.isEnd() && (m.isC1(comb) || m.isC2(comb))) .filter(m -> m.isEnd() && (m.isC1(comb) || m.isC2(comb)))
.forEach(matchModel -> { .forEach(matchModel -> {
stat.match_ids.add(matchModel.getId());
int win = matchModel.win(); int win = matchModel.win();
if (win == 0) { if (win == 0) {
stat.score += 1; stat.score += 1;
} else if ((matchModel.isC1(comb) && win > 0) || matchModel.isC2(comb) && win < 0) { } else if ((matchModel.isC1(comb) && win > 0) || matchModel.isC2(comb) && win < 0) {
stat.w++; stat.w++;
stat.win_ids.add(matchModel.getId());
stat.score += 3; stat.score += 3;
} else { } else {
stat.l++; stat.l++;
@ -631,6 +648,8 @@ public class ResultService {
public int score; public int score;
public int pointMake; public int pointMake;
public int pointTake; public int pointTake;
public ArrayList<Long> win_ids = new ArrayList<>();
public ArrayList<Long> match_ids = new ArrayList<>();
public CombStat() { public CombStat() {
this.w = 0; this.w = 0;

View File

@ -393,9 +393,9 @@ function buildCombView(comb) {
<h3>${i18next.t('statistique')} :</h3> <h3>${i18next.t('statistique')} :</h3>
<ul> <ul>
<li>${i18next.t('tauxDeVictoire2', { <li>${i18next.t('tauxDeVictoire2', {
nb: comb.matchs.length === 0 ? "---" : (comb.totalWin / comb.matchs.length * 100).toFixed(0), nb: comb.matchs.length === 0 ? "---" : (comb.totalWin / comb.matchs.filter(m => m.end).length * 100).toFixed(0),
victoires: comb.totalWin, victoires: comb.totalWin,
matchs: comb.matchs.length matchs: comb.matchs.filter(m => m.end).length
})} })}
</li> </li>
<li>${i18next.t('pointsMarqués2', {nb: comb.pointMake})}</li> <li>${i18next.t('pointsMarqués2', {nb: comb.pointMake})}</li>
@ -423,7 +423,7 @@ function buildCombView(comb) {
<td class="has-text-align-center" data-align="center">${match.poule}</td> <td class="has-text-align-center" data-align="center">${match.poule}</td>
<td class="has-text-align-center" data-align="center">${match.adv}</td> <td class="has-text-align-center" data-align="center">${match.adv}</td>
<td class="has-text-align-center" data-align="center">${scoreToString(match.score)}</td> <td class="has-text-align-center" data-align="center">${scoreToString(match.score)}</td>
<td class="has-text-align-center" data-align="center">${match.ratio.toFixed(3)}</td> <td class="has-text-align-center" data-align="center">${match.end ? match.ratio.toFixed(3) : ""}</td>
<td class="has-text-align-center" data-align="center">${match.win ? cupImg : (match.eq ? cupImg2 : "")}</td> <td class="has-text-align-center" data-align="center">${match.win ? cupImg : (match.eq ? cupImg2 : "")}</td>
</tr>` </tr>`
} }

View File

@ -373,9 +373,9 @@ function CombResult({uuid, combId}) {
<h3>{t('statistique')} :</h3> <h3>{t('statistique')} :</h3>
<ul> <ul>
<li>{t('tauxDeVictoire2', { <li>{t('tauxDeVictoire2', {
nb: data.matchs.length === 0 ? "---" : (data.totalWin / data.matchs.length * 100).toFixed(0), nb: data.matchs.length === 0 ? "---" : (data.totalWin / data.matchs.filter(m => m.end).length * 100).toFixed(0),
victoires: data.totalWin, victoires: data.totalWin,
matchs: data.matchs.length matchs: data.matchs.filter(m => m.end).length
})} })}
</li> </li>
<li>{t('pointsMarqués2', {nb: data.pointMake})}</li> <li>{t('pointsMarqués2', {nb: data.pointMake})}</li>
@ -401,7 +401,7 @@ function CombResult({uuid, combId}) {
<td style={{textAlign: "center"}}>{match.poule}</td> <td style={{textAlign: "center"}}>{match.poule}</td>
<td style={{textAlign: "center"}}>{match.adv}</td> <td style={{textAlign: "center"}}>{match.adv}</td>
<td style={{textAlign: "center"}}>{scoreToString(match.score)}</td> <td style={{textAlign: "center"}}>{scoreToString(match.score)}</td>
<td style={{textAlign: "center"}}>{match.ratio.toFixed(3)}</td> <td style={{textAlign: "center"}}>{match.end && match.ratio.toFixed(3)}</td>
<td style={{textAlign: "left"}}>{match.win ? <CupImg/> : (match.eq ? <CupImg2/> : "")}</td> <td style={{textAlign: "left"}}>{match.win ? <CupImg/> : (match.eq ? <CupImg2/> : "")}</td>
</tr>)} </tr>)}
</tbody> </tbody>