wip: competition card system

This commit is contained in:
2026-01-26 22:36:26 +01:00
parent 197ee0d5b1
commit 189eb135bb
24 changed files with 1232 additions and 616 deletions

View File

@@ -0,0 +1,102 @@
package fr.titionfire.ffsaf.ws.recv;
import fr.titionfire.ffsaf.data.model.CardModel;
import fr.titionfire.ffsaf.data.model.MatchModel;
import fr.titionfire.ffsaf.data.repository.CardRepository;
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.domain.service.CardService;
import fr.titionfire.ffsaf.domain.service.TradService;
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
import fr.titionfire.ffsaf.ws.PermLevel;
import fr.titionfire.ffsaf.ws.send.SSCard;
import io.quarkus.hibernate.reactive.panache.Panache;
import io.quarkus.hibernate.reactive.panache.common.WithSession;
import io.quarkus.runtime.annotations.RegisterForReflection;
import io.quarkus.websockets.next.WebSocketConnection;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.unchecked.Unchecked;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.util.List;
@WithSession
@ApplicationScoped
@RegisterForReflection
public class RCard {
@Inject
MatchRepository matchRepository;
@Inject
CardRepository cardRepository;
@Inject
CardService cardService;
@Inject
CombRepository combRepository;
@Inject
CompetitionGuestRepository competitionGuestRepository;
@Inject
TradService trad;
private Uni<MatchModel> getById(long id, WebSocketConnection connection) {
return matchRepository.findById(id)
.invoke(Unchecked.consumer(o -> {
if (o == null)
throw new DNotFoundException(trad.t("matche.non.trouver"));
if (!o.getCategory().getCompet().getUuid().equals(connection.pathParam("uuid")))
throw new DForbiddenException(trad.t("permission.denied"));
}));
}
@WSReceiver(code = "getCardForMatch", permission = PermLevel.VIEW)
public Uni<List<CardModel>> getCardForMatch(WebSocketConnection connection, Long matchId) {
return getById(matchId, connection).chain(matchModel -> cardService.getForMatch(matchModel));
}
@WSReceiver(code = "sendCardAdd", permission = PermLevel.TABLE)
public Uni<Void> sendCardAdd(WebSocketConnection connection, SendCardAdd card) {
return getById(card.matchId(), connection)
.chain(matchModel -> cardService.checkCanBeAdded(card, matchModel)
.chain(c -> {
CardModel model = new CardModel();
model.setComb(card.combId());
model.setMatch(card.matchId());
model.setCategory(matchModel.getCategory().getId());
model.setCompetition(matchModel.getCategory().getCompet().getId());
model.setType(card.type());
return Panache.withTransaction(() -> cardRepository.persist(model));
})
)
.invoke(cardModel -> SSCard.sendCard(connection, cardModel))
.replaceWithVoid();
}
@WSReceiver(code = "sendCardRm", permission = PermLevel.ADMIN)
public Uni<Void> sendCardRm(WebSocketConnection connection, SendCardAdd card) {
return getById(card.matchId(), connection)
.chain(matchModel -> cardRepository.find("match = ?1 AND comb = ?2 AND type = ?3",
matchModel.getId(), card.combId(), card.type())
.firstResult()
.invoke(Unchecked.consumer(o -> {
if (o == null)
throw new DNotFoundException(trad.t("carton.non.trouver"));
SSCard.sendRmCard(connection, o.getId());
}))
.chain(cardModel -> Panache.withTransaction(() -> cardRepository.delete(cardModel)))
)
.replaceWithVoid();
}
@RegisterForReflection
public record SendCardAdd(long matchId, long combId, CardModel.CardType type) {
}
}

View File

@@ -1,129 +0,0 @@
package fr.titionfire.ffsaf.ws.recv;
import fr.titionfire.ffsaf.data.model.CardboardModel;
import fr.titionfire.ffsaf.data.model.MatchModel;
import fr.titionfire.ffsaf.data.repository.CardboardRepository;
import fr.titionfire.ffsaf.data.repository.MatchRepository;
import fr.titionfire.ffsaf.domain.entity.CardboardEntity;
import fr.titionfire.ffsaf.domain.service.TradService;
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
import fr.titionfire.ffsaf.ws.PermLevel;
import fr.titionfire.ffsaf.ws.send.SSCardboard;
import io.quarkus.hibernate.reactive.panache.Panache;
import io.quarkus.hibernate.reactive.panache.common.WithSession;
import io.quarkus.runtime.annotations.RegisterForReflection;
import io.quarkus.websockets.next.WebSocketConnection;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.unchecked.Unchecked;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import lombok.Data;
import java.util.Objects;
@WithSession
@ApplicationScoped
@RegisterForReflection
public class RCardboard {
@Inject
MatchRepository matchRepository;
@Inject
CardboardRepository cardboardRepository;
@Inject
TradService trad;
private Uni<MatchModel> getById(long id, WebSocketConnection connection) {
return matchRepository.findById(id)
.invoke(Unchecked.consumer(o -> {
if (o == null)
throw new DNotFoundException(trad.t("matche.non.trouver"));
if (!o.getCategory().getCompet().getUuid().equals(connection.pathParam("uuid")))
throw new DForbiddenException(trad.t("permission.denied"));
}));
}
@WSReceiver(code = "sendCardboardChange", permission = PermLevel.TABLE)
public Uni<Void> sendCardboardChange(WebSocketConnection connection, SendCardboard card) {
return getById(card.matchId, connection)
.chain(matchModel -> cardboardRepository.find("(comb.id = ?1 OR guestComb.id = ?2) AND match.id = ?3",
card.combId, card.combId * -1, card.matchId).firstResult()
.chain(model -> {
if (model != null) {
model.setRed(model.getRed() + card.red);
model.setYellow(model.getYellow() + card.yellow);
return Panache.withTransaction(() -> cardboardRepository.persist(model));
}
CardboardModel cardboardModel = new CardboardModel();
cardboardModel.setCompet(matchModel.getCategory().getCompet());
cardboardModel.setMatch(matchModel);
cardboardModel.setRed(card.red);
cardboardModel.setYellow(card.yellow);
cardboardModel.setComb(null);
cardboardModel.setGuestComb(null);
if (card.combId >= 0) {
if (matchModel.getC1_id() != null && matchModel.getC1_id().getId() == card.combId)
cardboardModel.setComb(matchModel.getC1_id());
if (matchModel.getC2_id() != null && matchModel.getC2_id().getId() == card.combId)
cardboardModel.setComb(matchModel.getC2_id());
} else {
if (matchModel.getC1_guest() != null && matchModel.getC1_guest()
.getId() == card.combId * -1)
cardboardModel.setGuestComb(matchModel.getC1_guest());
if (matchModel.getC2_guest() != null && matchModel.getC2_guest()
.getId() == card.combId * -1)
cardboardModel.setGuestComb(matchModel.getC2_guest());
}
if (cardboardModel.getComb() == null && cardboardModel.getGuestComb() == null)
return Uni.createFrom().nullItem();
return Panache.withTransaction(() -> cardboardRepository.persist(cardboardModel));
}))
.invoke(model -> SSCardboard.sendCardboard(connection, CardboardEntity.fromModel(model)))
.replaceWithVoid();
}
@WSReceiver(code = "getCardboardWithoutThis", permission = PermLevel.VIEW)
public Uni<CardboardAllMatch> getCardboardWithoutThis(WebSocketConnection connection, Long matchId) {
return getById(matchId, connection)
.chain(matchModel -> cardboardRepository.list("compet = ?1 AND match != ?2",
matchModel.getCategory().getCompet(), matchModel)
.map(models -> {
CardboardAllMatch out = new CardboardAllMatch();
for (CardboardModel c : models) {
if ((matchModel.getC1_id() != null && Objects.equals(c.getComb(),
matchModel.getC1_id())) || (matchModel.getC1_guest() != null && Objects.equals(
c.getGuestComb(), matchModel.getC1_guest()))) {
out.c1_yellow += c.getYellow();
out.c1_red += c.getRed();
}
if ((matchModel.getC2_id() != null && Objects.equals(c.getComb(),
matchModel.getC2_id())) || (matchModel.getC2_guest() != null && Objects.equals(
c.getGuestComb(), matchModel.getC2_guest()))) {
out.c2_yellow += c.getYellow();
out.c2_red += c.getRed();
}
}
return out;
}));
}
@RegisterForReflection
public record SendCardboard(long matchId, long combId, int yellow, int red) {
}
@Data
@RegisterForReflection
public static class CardboardAllMatch {
int c1_yellow = 0;
int c1_red = 0;
int c2_yellow = 0;
int c2_red = 0;
}
}

View File

@@ -1,11 +1,13 @@
package fr.titionfire.ffsaf.ws.recv;
import fr.titionfire.ffsaf.data.model.CardModel;
import fr.titionfire.ffsaf.data.model.CategoryModel;
import fr.titionfire.ffsaf.data.model.MatchModel;
import fr.titionfire.ffsaf.data.model.TreeModel;
import fr.titionfire.ffsaf.data.repository.*;
import fr.titionfire.ffsaf.domain.entity.MatchEntity;
import fr.titionfire.ffsaf.domain.entity.TreeEntity;
import fr.titionfire.ffsaf.domain.service.CardService;
import fr.titionfire.ffsaf.domain.service.TradService;
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
@@ -47,6 +49,9 @@ public class RCategorie {
@Inject
CardboardRepository cardboardRepository;
@Inject
CardService cardService;
@Inject
TradService trad;
@@ -84,6 +89,8 @@ public class RCategorie {
.call(cat -> treeRepository.list("category = ?1 AND level != 0", cat.getId())
.map(treeModels -> treeModels.stream().map(TreeEntity::fromModel).toList())
.invoke(fullCategory::setTrees))
.call(cat -> cardService.getAll(cat.getCompet().getId())
.invoke(fullCategory::setCards))
.map(__ -> fullCategory);
}
@@ -241,5 +248,6 @@ public class RCategorie {
String liceName;
List<TreeEntity> trees = null;
List<MatchEntity> matches;
List<CardModel> cards;
}
}