feat: cm table matches & scores
This commit is contained in:
@@ -1,18 +1,17 @@
|
||||
package fr.titionfire.ffsaf.ws.recv;
|
||||
|
||||
import fr.titionfire.ffsaf.data.model.CategoryModel;
|
||||
import fr.titionfire.ffsaf.data.model.MatchModel;
|
||||
import fr.titionfire.ffsaf.data.repository.CategoryRepository;
|
||||
import fr.titionfire.ffsaf.data.repository.CombRepository;
|
||||
import fr.titionfire.ffsaf.data.repository.CompetitionGuestRepository;
|
||||
import fr.titionfire.ffsaf.data.repository.MatchRepository;
|
||||
import fr.titionfire.ffsaf.data.model.*;
|
||||
import fr.titionfire.ffsaf.data.repository.*;
|
||||
import fr.titionfire.ffsaf.domain.entity.MatchEntity;
|
||||
import fr.titionfire.ffsaf.domain.entity.TreeEntity;
|
||||
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
||||
import fr.titionfire.ffsaf.utils.ScoreEmbeddable;
|
||||
import fr.titionfire.ffsaf.ws.PermLevel;
|
||||
import fr.titionfire.ffsaf.ws.send.SSMatch;
|
||||
import io.quarkus.hibernate.reactive.panache.Panache;
|
||||
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||
import io.quarkus.panache.common.Sort;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import io.quarkus.websockets.next.WebSocketConnection;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
@@ -21,9 +20,7 @@ import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@WithSession
|
||||
@@ -41,6 +38,9 @@ public class RMatch {
|
||||
@Inject
|
||||
CategoryRepository categoryRepository;
|
||||
|
||||
@Inject
|
||||
TreeRepository treeRepository;
|
||||
|
||||
@Inject
|
||||
CompetitionGuestRepository competitionGuestRepository;
|
||||
|
||||
@@ -140,6 +140,140 @@ public class RMatch {
|
||||
.replaceWithVoid();
|
||||
}
|
||||
|
||||
@WSReceiver(code = "updateMatchScore", permission = PermLevel.TABLE)
|
||||
public Uni<Void> updateMatchScore(WebSocketConnection connection, MatchScore score) {
|
||||
return getById(score.matchId(), connection)
|
||||
.chain(matchModel -> {
|
||||
int old_win = matchModel.win();
|
||||
Optional<ScoreEmbeddable> optional = matchModel.getScores().stream()
|
||||
.filter(s -> s.getN_round() == score.n_round()).findAny();
|
||||
boolean b = score.s1() != -1000 || score.s2() != -1000;
|
||||
if (optional.isPresent()) {
|
||||
if (b) {
|
||||
optional.get().setS1(score.s1());
|
||||
optional.get().setS2(score.s2());
|
||||
} else {
|
||||
matchModel.getScores().remove(optional.get());
|
||||
}
|
||||
} else if (b) {
|
||||
matchModel.getScores().add(new ScoreEmbeddable(score.n_round(), score.s1(), score.s2()));
|
||||
}
|
||||
|
||||
return Panache.withTransaction(() -> matchRepository.persist(matchModel))
|
||||
.call(mm -> {
|
||||
if (mm.isEnd() && mm.win() != old_win && mm.getCategory_ord() == -42) {
|
||||
return updateEndAndTree(mm, new ArrayList<>())
|
||||
.call(l -> SSMatch.sendMatch(connection, l));
|
||||
}
|
||||
return Uni.createFrom().nullItem();
|
||||
});
|
||||
})
|
||||
.call(mm -> SSMatch.sendMatch(connection, MatchEntity.fromModel(mm)))
|
||||
.replaceWithVoid();
|
||||
}
|
||||
|
||||
@WSReceiver(code = "updateMatchEnd", permission = PermLevel.TABLE)
|
||||
public Uni<Void> updateMatchEnd(WebSocketConnection connection, MatchEnd matchEnd) {
|
||||
List<MatchEntity> toSend = new ArrayList<>();
|
||||
|
||||
return getById(matchEnd.matchId(), connection)
|
||||
.chain(mm -> {
|
||||
if (mm.getCategory_ord() == -42 && mm.win() == 0) { // Tournois
|
||||
mm.setDate(null);
|
||||
mm.setEnd(false);
|
||||
} else {
|
||||
mm.setDate((matchEnd.end) ? new Date() : null);
|
||||
mm.setEnd(matchEnd.end);
|
||||
}
|
||||
return Panache.withTransaction(() -> matchRepository.persist(mm));
|
||||
})
|
||||
.invoke(mm -> toSend.add(MatchEntity.fromModel(mm)))
|
||||
.chain(mm -> updateEndAndTree(mm, toSend))
|
||||
.call(__ -> SSMatch.sendMatch(connection, toSend))
|
||||
.replaceWithVoid();
|
||||
}
|
||||
|
||||
private Uni<List<MatchEntity>> updateEndAndTree(MatchModel mm, List<MatchEntity> toSend) {
|
||||
return (mm.getCategory_ord() != -42) ?
|
||||
Uni.createFrom().item(toSend) :
|
||||
treeRepository.list("category = ?1 AND level != 0", Sort.ascending("level"), mm.getCategory().getId())
|
||||
.chain(treeModels -> {
|
||||
List<TreeModel> node = treeModels.stream().flatMap(t -> t.flat().stream()).toList();
|
||||
List<TreeEntity> trees = treeModels.stream().map(TreeEntity::fromModel).toList();
|
||||
for (int i = 0; i < trees.size() - 1; i++) {
|
||||
TreeEntity.setAssociated(trees.get(i), trees.get(i + 1));
|
||||
}
|
||||
|
||||
TreeEntity root = trees.stream()
|
||||
.filter(t -> t.getMatchNode(mm.getId()) != null)
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
|
||||
TreeEntity currentNode = root.getMatchNode(mm.getId());
|
||||
if (currentNode == null) {
|
||||
LOGGER.error(
|
||||
"currentNode is empty for " + mm.getId() + " in " + mm.getCategory().getId());
|
||||
return Uni.createFrom().voidItem();
|
||||
}
|
||||
|
||||
TreeEntity parent = TreeEntity.getParent(root, currentNode);
|
||||
if (parent == null) {
|
||||
LOGGER.error("parent is empty for " + mm.getId() + " in " + mm.getCategory().getId());
|
||||
return Uni.createFrom().voidItem();
|
||||
}
|
||||
|
||||
int w = mm.win();
|
||||
MembreModel toSetWin = null;
|
||||
MembreModel toSetLose = null;
|
||||
CompetitionGuestModel toSetWinGuest = null;
|
||||
CompetitionGuestModel toSetLoseGuest = null;
|
||||
|
||||
if (mm.isEnd() && w != 0) {
|
||||
toSetWin = (w > 0) ? mm.getC1_id() : mm.getC2_id();
|
||||
toSetLose = (w > 0) ? mm.getC2_id() : mm.getC1_id();
|
||||
toSetWinGuest = (w > 0) ? mm.getC1_guest() : mm.getC2_guest();
|
||||
toSetLoseGuest = (w > 0) ? mm.getC2_guest() : mm.getC1_guest();
|
||||
}
|
||||
|
||||
MatchModel modelWin = node.stream()
|
||||
.filter(n -> Objects.equals(n.getId(), parent.getId()))
|
||||
.findAny()
|
||||
.map(TreeModel::getMatch)
|
||||
.orElseThrow();
|
||||
|
||||
MatchModel modelLose = (parent.getAssociatedNode() == null) ? null : node.stream()
|
||||
.filter(n -> Objects.equals(n.getId(), parent.getAssociatedNode().getId()))
|
||||
.findAny()
|
||||
.map(TreeModel::getMatch)
|
||||
.orElseThrow();
|
||||
|
||||
if (currentNode.equals(parent.getLeft())) {
|
||||
modelWin.setC1_id(toSetWin);
|
||||
modelWin.setC1_guest(toSetWinGuest);
|
||||
if (modelLose != null) {
|
||||
modelLose.setC1_id(toSetLose);
|
||||
modelLose.setC1_guest(toSetLoseGuest);
|
||||
}
|
||||
} else if (currentNode.equals(parent.getRight())) {
|
||||
modelWin.setC2_id(toSetWin);
|
||||
modelWin.setC2_guest(toSetWinGuest);
|
||||
if (modelLose != null) {
|
||||
modelLose.setC2_id(toSetLose);
|
||||
modelLose.setC2_guest(toSetLoseGuest);
|
||||
}
|
||||
}
|
||||
|
||||
return Panache.withTransaction(() -> matchRepository.persist(modelWin)
|
||||
.invoke(mm2 -> toSend.add(MatchEntity.fromModel(mm2)))
|
||||
.call(__ -> modelLose == null ? Uni.createFrom().nullItem() :
|
||||
matchRepository.persist(modelLose)
|
||||
.invoke(mm2 -> toSend.add(MatchEntity.fromModel(mm2)))
|
||||
)
|
||||
.replaceWithVoid());
|
||||
})
|
||||
.map(__ -> toSend);
|
||||
}
|
||||
|
||||
@WSReceiver(code = "deleteMatch", permission = PermLevel.ADMIN)
|
||||
public Uni<Void> deleteMatch(WebSocketConnection connection, Long idMatch) {
|
||||
return getById(idMatch, connection)
|
||||
@@ -190,6 +324,14 @@ public class RMatch {
|
||||
public record MatchComb(long id, Long c1, Long c2) {
|
||||
}
|
||||
|
||||
@RegisterForReflection
|
||||
public record MatchScore(long matchId, int n_round, int s1, int s2) {
|
||||
}
|
||||
|
||||
@RegisterForReflection
|
||||
public record MatchEnd(long matchId, boolean end) {
|
||||
}
|
||||
|
||||
@RegisterForReflection
|
||||
public record MatchOrder(long id, long pos) {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user