wip: competition card system
This commit is contained in:
37
src/main/java/fr/titionfire/ffsaf/data/model/CardModel.java
Normal file
37
src/main/java/fr/titionfire/ffsaf/data/model/CardModel.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package fr.titionfire.ffsaf.data.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@RegisterForReflection
|
||||
|
||||
@Entity
|
||||
@Table(name = "card")
|
||||
public class CardModel {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
Long id;
|
||||
|
||||
Long comb;
|
||||
Long match;
|
||||
Long category;
|
||||
Long competition;
|
||||
|
||||
CardType type;
|
||||
|
||||
public enum CardType {
|
||||
BLUE,
|
||||
YELLOW,
|
||||
RED,
|
||||
BLACK
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package fr.titionfire.ffsaf.data.repository;
|
||||
|
||||
import fr.titionfire.ffsaf.data.model.CardModel;
|
||||
import io.quarkus.hibernate.reactive.panache.PanacheRepositoryBase;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
@ApplicationScoped
|
||||
public class CardRepository implements PanacheRepositoryBase<CardModel, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package fr.titionfire.ffsaf.domain.service;
|
||||
|
||||
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.domain.entity.MatchEntity;
|
||||
import fr.titionfire.ffsaf.rest.exception.DBadRequestException;
|
||||
import fr.titionfire.ffsaf.ws.recv.RCard;
|
||||
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||
import io.quarkus.panache.common.Sort;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@WithSession
|
||||
@ApplicationScoped
|
||||
public class CardService {
|
||||
@Inject
|
||||
CardRepository cardRepository;
|
||||
|
||||
@Inject
|
||||
TradService trad;
|
||||
|
||||
private static final List<CardModel.CardType> COMPETITION_LEVEL_CARDS = List.of(
|
||||
CardModel.CardType.YELLOW,
|
||||
CardModel.CardType.RED,
|
||||
CardModel.CardType.BLACK
|
||||
);
|
||||
|
||||
private List<Long> extractCombIds(MatchModel match) {
|
||||
List<Long> ids = new ArrayList<>();
|
||||
if (match.getC1_id() != null)
|
||||
ids.add(match.getC1_id().getId());
|
||||
if (match.getC2_id() != null)
|
||||
ids.add(match.getC2_id().getId());
|
||||
if (match.getC1_guest() != null)
|
||||
ids.add(match.getC1_guest().getId() * -1);
|
||||
if (match.getC2_guest() != null)
|
||||
ids.add(match.getC2_guest().getId() * -1);
|
||||
return ids;
|
||||
}
|
||||
|
||||
private Collection<Long> extractCombIds(MatchEntity match) {
|
||||
List<Long> ids = new ArrayList<>();
|
||||
if (match.getC1() != null)
|
||||
ids.add(match.getC1().getId());
|
||||
if (match.getC2() != null)
|
||||
ids.add(match.getC2().getId());
|
||||
return ids;
|
||||
}
|
||||
|
||||
public Uni<List<CardModel>> getForMatch(MatchModel match) {
|
||||
return cardRepository.list(
|
||||
"competition = ?1 AND (type IN ?2 OR (type = CardType.BLUE AND category = ?4)) AND comb IN ?3",
|
||||
match.getCategory().getCompet().getId(), COMPETITION_LEVEL_CARDS,
|
||||
extractCombIds(match), match.getCategory().getId());
|
||||
}
|
||||
|
||||
public Uni<List<CardModel>> getAll(Long competitionId) {
|
||||
return cardRepository.list("competition = ?1", competitionId);
|
||||
}
|
||||
|
||||
public Uni<RCard.SendCardAdd> checkCanBeAdded(RCard.SendCardAdd card, MatchModel matchModel) {
|
||||
return cardRepository.find("competition = ?1 AND comb = ?2",
|
||||
Sort.descending("type"),
|
||||
matchModel.getCategory().getCompet().getId(), card.combId())
|
||||
.firstResult()
|
||||
.map(card_ -> {
|
||||
if (card.type() == CardModel.CardType.BLUE) {
|
||||
return card_ == null || (card_.getType() == CardModel.CardType.BLUE
|
||||
&& !Objects.equals(card_.getCategory(), matchModel.getCategory().getId()));
|
||||
}
|
||||
if (card.type() == CardModel.CardType.BLACK) {
|
||||
return card_ != null && card_.getType() == CardModel.CardType.RED;
|
||||
}
|
||||
|
||||
return card_ == null || card_.getType().ordinal() < card.type().ordinal();
|
||||
})
|
||||
.chain(b -> {
|
||||
if (b)
|
||||
return Uni.createFrom().item(card);
|
||||
else
|
||||
return Uni.createFrom().failure(new DBadRequestException(trad.t("card.cannot.be.added")));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public class CompetitionWS {
|
||||
RRegister rRegister;
|
||||
|
||||
@Inject
|
||||
RCardboard rCardboard;
|
||||
RCard rCard;
|
||||
|
||||
@Inject
|
||||
RTeam rTeam;
|
||||
@@ -93,7 +93,7 @@ public class CompetitionWS {
|
||||
getWSReceiverMethods(RMatch.class, rMatch);
|
||||
getWSReceiverMethods(RCategorie.class, rCategorie);
|
||||
getWSReceiverMethods(RRegister.class, rRegister);
|
||||
getWSReceiverMethods(RCardboard.class, rCardboard);
|
||||
getWSReceiverMethods(RCard.class, rCard);
|
||||
getWSReceiverMethods(RTeam.class, rTeam);
|
||||
|
||||
executor = notifyExecutor;
|
||||
|
||||
102
src/main/java/fr/titionfire/ffsaf/ws/recv/RCard.java
Normal file
102
src/main/java/fr/titionfire/ffsaf/ws/recv/RCard.java
Normal 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) {
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
16
src/main/java/fr/titionfire/ffsaf/ws/send/SSCard.java
Normal file
16
src/main/java/fr/titionfire/ffsaf/ws/send/SSCard.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package fr.titionfire.ffsaf.ws.send;
|
||||
|
||||
import fr.titionfire.ffsaf.data.model.CardModel;
|
||||
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
||||
import io.quarkus.websockets.next.WebSocketConnection;
|
||||
|
||||
public class SSCard {
|
||||
|
||||
public static void sendCard(WebSocketConnection connection, CardModel cardModel) {
|
||||
CompetitionWS.sendNotifyToOtherEditor(connection, "sendCard", cardModel);
|
||||
}
|
||||
|
||||
public static void sendRmCard(WebSocketConnection connection, Long id) {
|
||||
CompetitionWS.sendNotifyToOtherEditor(connection, "rmCard", id);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package fr.titionfire.ffsaf.ws.send;
|
||||
|
||||
import fr.titionfire.ffsaf.domain.entity.CardboardEntity;
|
||||
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
||||
import io.quarkus.websockets.next.WebSocketConnection;
|
||||
|
||||
public class SSCardboard {
|
||||
|
||||
public static void sendCardboard(WebSocketConnection connection, CardboardEntity cardboardEntity) {
|
||||
CompetitionWS.sendNotifyToOtherEditor(connection, "sendCardboard", cardboardEntity);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user