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.ClubCardRepository; import fr.titionfire.ffsaf.data.repository.CompetitionRepository; 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.Date; import java.util.List; @WithSession @ApplicationScoped @RegisterForReflection public class RCard { @Inject MatchRepository matchRepository; @Inject ClubCardRepository clubCardRepository; @Inject CardRepository cardRepository; @Inject CardService cardService; @Inject CompetitionRepository competitionRepository; @Inject TradService trad; private Uni 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> getCardForMatch(WebSocketConnection connection, Long matchId) { if (matchId == null) return Uni.createFrom().nullItem(); return getById(matchId, connection).chain(matchModel -> cardService.getForMatch(matchModel)); } @WSReceiver(code = "getAllForTeamNoDetail", permission = PermLevel.VIEW) public Uni> getAllForTeamNoDetail(WebSocketConnection connection, Object o) { return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult() .chain(c -> clubCardRepository.list("competition = ?1", c.getId())) .map(cards -> cards.stream() .map(card -> new SendTeamCards(card.getTeamUuid(), card.getTeamName(), List.of(), card.getType(), card.getReason(), card.getDate())) .toList()); } @WSReceiver(code = "sendCardAdd", permission = PermLevel.TABLE) public Uni 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()); model.setCompetitionId(matchModel.getCategory().getCompet().getId()); model.setType(card.type()); model.setReason(card.reason()); return Panache.withTransaction(() -> cardRepository.persist(model)); }) ) .invoke(cardModel -> SSCard.sendCards(connection, List.of(cardModel))) .replaceWithVoid(); } @WSReceiver(code = "sendCardRm", permission = PermLevel.ADMIN) public Uni 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.sendRmCards(connection, List.of(o.getId())); })) .chain(cardModel -> Panache.withTransaction(() -> cardRepository.delete(cardModel))) ) .replaceWithVoid(); } @WSReceiver(code = "applyTeamCards", permission = PermLevel.TABLE) public Uni applyTeamCards(WebSocketConnection connection, SendTeamCards teamCards) { return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult() .chain(c -> cardService.addTeamCard(c, teamCards.teamUuid(), teamCards.teamName(), teamCards.type, teamCards.reason())) .invoke(cards -> SSCard.sendTeamCard(connection, new SendTeamCards(teamCards.teamUuid(), teamCards.teamName(), cards, teamCards.type(), teamCards.reason(), new Date()))) .replaceWithVoid(); } @WSReceiver(code = "sendTeamCardReturnState", permission = PermLevel.TABLE) public Uni sendTeamCardReturnState(WebSocketConnection connection, SendTeamCardReturnState state) { if (state.state <= 0 || state.state > 2) return Uni.createFrom().voidItem(); return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult() .chain(c -> cardService.recvReturnState(c, state)) .invoke(cards -> SSCard.sendCards(connection, cards)) .replaceWithVoid(); } @WSReceiver(code = "removeTeamCards", permission = PermLevel.TABLE) public Uni removeTeamCards(WebSocketConnection connection, SendTeamCards teamCards) { return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult() .chain(c -> cardService.rmTeamCard(c, teamCards.teamUuid(), teamCards.teamName(), teamCards.type)) .invoke(cards -> SSCard.sendRmCards(connection, cards)) .invoke(__ -> SSCard.rmTeamCard(connection, teamCards)) .replaceWithVoid(); } @RegisterForReflection public record SendCardAdd(long matchId, long combId, CardModel.CardType type, String reason) { } @RegisterForReflection public record SendTeamCards(String teamUuid, String teamName, List cards, CardModel.CardType type, String reason, Date date) { } @RegisterForReflection public record SendTeamCardReturnState(String teamUuid, String teamName, CardModel.CardType type, int state, Long selectedCategory, Long selectedMatch) { } }