From e89a7d4bff3cc7b61378c5969c6beadb0f61557f Mon Sep 17 00:00:00 2001 From: Michel ten Voorde Date: Mon, 25 Aug 2025 23:37:35 +0200 Subject: [PATCH] Various improvements --- .../swiss/controller/TestController.java | 1 + .../swiss/{dto => domain}/StandingsEntry.java | 3 +- .../swiss/domain/entity/Event.java | 5 +- .../swiss/domain/entity/Group.java | 7 +- .../swiss/domain/entity/Round.java | 2 + .../connectedit/swiss/domain/entity/Team.java | 5 +- .../swiss/domain/entity/TournamentPlayer.java | 5 ++ .../nl/connectedit/swiss/dto/RoundDto.java | 3 + .../connectedit/swiss/mapper/EventMapper.java | 8 +- .../connectedit/swiss/mapper/RoundMapper.java | 6 +- .../swiss/mapper/StandingsMapper.java | 11 +-- .../swiss/mapper/TournamentMapper.java | 21 +++-- .../swiss/service/StandingsService.java | 3 +- .../service/TournamentDivideService.java | 3 +- .../swiss/service/TournamentPlayService.java | 82 ++++++++++++++++++- 15 files changed, 133 insertions(+), 32 deletions(-) rename src/main/java/nl/connectedit/swiss/{dto => domain}/StandingsEntry.java (96%) diff --git a/src/main/java/nl/connectedit/swiss/controller/TestController.java b/src/main/java/nl/connectedit/swiss/controller/TestController.java index 28bd10f..b25f4f4 100644 --- a/src/main/java/nl/connectedit/swiss/controller/TestController.java +++ b/src/main/java/nl/connectedit/swiss/controller/TestController.java @@ -168,6 +168,7 @@ public class TestController { tournamentDto.setMaxEvents(2L); tournamentDto.setCourts(9L); tournamentDto.setCostsPerEvent(List.of(6f, 10f, 0f)); + tournamentDto.setActive(true); return tournamentDto; } diff --git a/src/main/java/nl/connectedit/swiss/dto/StandingsEntry.java b/src/main/java/nl/connectedit/swiss/domain/StandingsEntry.java similarity index 96% rename from src/main/java/nl/connectedit/swiss/dto/StandingsEntry.java rename to src/main/java/nl/connectedit/swiss/domain/StandingsEntry.java index 7b87537..6c99689 100644 --- a/src/main/java/nl/connectedit/swiss/dto/StandingsEntry.java +++ b/src/main/java/nl/connectedit/swiss/domain/StandingsEntry.java @@ -1,6 +1,5 @@ -package nl.connectedit.swiss.dto; +package nl.connectedit.swiss.domain; -import java.util.Comparator; import lombok.Getter; import lombok.Setter; import lombok.ToString; diff --git a/src/main/java/nl/connectedit/swiss/domain/entity/Event.java b/src/main/java/nl/connectedit/swiss/domain/entity/Event.java index 1f3ee24..34bfeb4 100644 --- a/src/main/java/nl/connectedit/swiss/domain/entity/Event.java +++ b/src/main/java/nl/connectedit/swiss/domain/entity/Event.java @@ -27,8 +27,7 @@ public class Event extends AbstractEntity { private Tournament tournament; @OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY) -// @Builder.Default - private List registrations;// = new ArrayList<>(); + private List registrations; @Enumerated(EnumType.STRING) private Status status; @@ -37,7 +36,7 @@ public class Event extends AbstractEntity { private EventType type; @OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY) - private List groups;// = new ArrayList<>(); + private List groups; public static List getBlankEventSet(Tournament tournament) { return Arrays.stream(EventType.values()) diff --git a/src/main/java/nl/connectedit/swiss/domain/entity/Group.java b/src/main/java/nl/connectedit/swiss/domain/entity/Group.java index 94e2edb..a00aeb8 100644 --- a/src/main/java/nl/connectedit/swiss/domain/entity/Group.java +++ b/src/main/java/nl/connectedit/swiss/domain/entity/Group.java @@ -33,7 +33,12 @@ public class Group extends AbstractEntity { @OrderBy("name") private List rounds; - @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinTable( + name = "eventgroup_teams", + joinColumns = @JoinColumn(name = "group_id"), + inverseJoinColumns = @JoinColumn(name = "teams_id") + ) private List teams; } diff --git a/src/main/java/nl/connectedit/swiss/domain/entity/Round.java b/src/main/java/nl/connectedit/swiss/domain/entity/Round.java index e669e8d..b47a167 100644 --- a/src/main/java/nl/connectedit/swiss/domain/entity/Round.java +++ b/src/main/java/nl/connectedit/swiss/domain/entity/Round.java @@ -37,4 +37,6 @@ public class Round extends AbstractEntity { @ManyToOne private Team drawnOut; + private Boolean isFinalsRound = Boolean.FALSE; + } diff --git a/src/main/java/nl/connectedit/swiss/domain/entity/Team.java b/src/main/java/nl/connectedit/swiss/domain/entity/Team.java index dbeb28b..674365a 100644 --- a/src/main/java/nl/connectedit/swiss/domain/entity/Team.java +++ b/src/main/java/nl/connectedit/swiss/domain/entity/Team.java @@ -2,6 +2,7 @@ package nl.connectedit.swiss.domain.entity; import jakarta.annotation.Nullable; import jakarta.persistence.*; +import java.util.List; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; @@ -17,8 +18,8 @@ public class Team extends AbstractEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne - private Group group; + @ManyToMany(mappedBy = "teams", fetch = FetchType.LAZY) + private List groups; @ManyToOne private Player player1; diff --git a/src/main/java/nl/connectedit/swiss/domain/entity/TournamentPlayer.java b/src/main/java/nl/connectedit/swiss/domain/entity/TournamentPlayer.java index e092098..c49b9be 100644 --- a/src/main/java/nl/connectedit/swiss/domain/entity/TournamentPlayer.java +++ b/src/main/java/nl/connectedit/swiss/domain/entity/TournamentPlayer.java @@ -32,4 +32,9 @@ public class TournamentPlayer extends AbstractEntity { private boolean counting; private Long counts; + + public void incrementCounts() { + this.counts++; + } + } diff --git a/src/main/java/nl/connectedit/swiss/dto/RoundDto.java b/src/main/java/nl/connectedit/swiss/dto/RoundDto.java index 85b0cba..8183035 100644 --- a/src/main/java/nl/connectedit/swiss/dto/RoundDto.java +++ b/src/main/java/nl/connectedit/swiss/dto/RoundDto.java @@ -23,4 +23,7 @@ public class RoundDto extends AbstractDto { private StandingsDto standings; + private Boolean isFinalsRound; + + } diff --git a/src/main/java/nl/connectedit/swiss/mapper/EventMapper.java b/src/main/java/nl/connectedit/swiss/mapper/EventMapper.java index 3a573b0..3b4c38c 100644 --- a/src/main/java/nl/connectedit/swiss/mapper/EventMapper.java +++ b/src/main/java/nl/connectedit/swiss/mapper/EventMapper.java @@ -1,13 +1,16 @@ package nl.connectedit.swiss.mapper; -import java.util.Arrays; import lombok.RequiredArgsConstructor; +import nl.connectedit.swiss.domain.EventType; import nl.connectedit.swiss.domain.Status; import nl.connectedit.swiss.domain.entity.Event; -import nl.connectedit.swiss.domain.EventType; +import nl.connectedit.swiss.domain.entity.Group; import nl.connectedit.swiss.dto.EventDto; import org.springframework.stereotype.Component; +import java.util.Arrays; +import java.util.Comparator; + @Component @RequiredArgsConstructor public class EventMapper implements DtoMapper, EntityMapper { @@ -56,6 +59,7 @@ public class EventMapper implements DtoMapper, EntityMapper, E tournamentDto.setEvents( tournament.getEvents() .stream() + .sorted(Comparator.comparing(Event::getType)) .map(eventMapper::toDto) .toList() ); diff --git a/src/main/java/nl/connectedit/swiss/service/StandingsService.java b/src/main/java/nl/connectedit/swiss/service/StandingsService.java index 44a2170..edda74e 100644 --- a/src/main/java/nl/connectedit/swiss/service/StandingsService.java +++ b/src/main/java/nl/connectedit/swiss/service/StandingsService.java @@ -1,10 +1,9 @@ package nl.connectedit.swiss.service; -import nl.connectedit.swiss.domain.entity.Group; +import nl.connectedit.swiss.domain.StandingsEntry; import nl.connectedit.swiss.domain.entity.Match; import nl.connectedit.swiss.domain.entity.Round; import nl.connectedit.swiss.domain.entity.Team; -import nl.connectedit.swiss.dto.StandingsEntry; import org.springframework.stereotype.Service; import java.util.ArrayList; diff --git a/src/main/java/nl/connectedit/swiss/service/TournamentDivideService.java b/src/main/java/nl/connectedit/swiss/service/TournamentDivideService.java index 1f35b73..63421d4 100644 --- a/src/main/java/nl/connectedit/swiss/service/TournamentDivideService.java +++ b/src/main/java/nl/connectedit/swiss/service/TournamentDivideService.java @@ -64,6 +64,7 @@ public class TournamentDivideService { event.getGroups().add(group); } else { var groups = getGroups(registrations, event.getType()); + groups.forEach(group -> group.setEvent(event)); event.getGroups().addAll(groups); } } @@ -146,7 +147,7 @@ nextRegistration: var team = new Team(); team.setPlayer1(registration.getPlayer()); team.setPlayer2(registration.getPartner()); - team.setGroup(group); + team.setGroups(List.of(group)); return team; } diff --git a/src/main/java/nl/connectedit/swiss/service/TournamentPlayService.java b/src/main/java/nl/connectedit/swiss/service/TournamentPlayService.java index df2289c..67b6678 100644 --- a/src/main/java/nl/connectedit/swiss/service/TournamentPlayService.java +++ b/src/main/java/nl/connectedit/swiss/service/TournamentPlayService.java @@ -2,11 +2,12 @@ package nl.connectedit.swiss.service; import lombok.RequiredArgsConstructor; import lombok.extern.java.Log; +import nl.connectedit.swiss.domain.EventType; +import nl.connectedit.swiss.domain.StandingsEntry; import nl.connectedit.swiss.domain.Status; import nl.connectedit.swiss.domain.TournamentStatus; import nl.connectedit.swiss.domain.entity.*; import nl.connectedit.swiss.dto.ResultDto; -import nl.connectedit.swiss.dto.StandingsEntry; import nl.connectedit.swiss.repository.TournamentRepository; import org.springframework.stereotype.Service; @@ -14,7 +15,6 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.Random; import java.util.stream.Collectors; import static nl.connectedit.swiss.service.ServiceUtil.*; @@ -42,11 +42,86 @@ public class TournamentPlayService { } public Tournament finishGroup(Tournament tournament, Long groupId) { - getGroup(tournament, groupId).setStatus(Status.FINISHED); + var group = getGroup(tournament, groupId); + group.setStatus(Status.FINISHED); + + checkForEventCompletion(tournament, group.getType()); + tournamentRepository.save(tournament); return tournament; } + private void checkForEventCompletion(Tournament tournament, EventType type) { + Group group1 = null; + Group group2 = null; + Event event = null; + + for (var e : tournament.getEvents()) { + if (e.getType() == type) { + if (e.getGroups().size() != 2) { + return; + } + group1 = e.getGroups().getFirst(); + if (group1.getStatus() != Status.FINISHED) { + return; + } + + group2 = e.getGroups().getLast(); + if (group2.getStatus() != Status.FINISHED) { + return; + } + event = e; + } + } + + var finalsGroup = new Group(); + finalsGroup.setName(type.getText()); + finalsGroup.setType(type); + finalsGroup.setStatus(Status.IN_PROGRESS); + finalsGroup.setEvent(group1.getEvent()); + + var standings1 = standingsService.getStandings(group1.getRounds(), group1.getTeams()); + var standings2 = standingsService.getStandings(group2.getRounds(), group2.getTeams()); + + var team1_1 = standings1.get(0).getTeam(); + var team1_2 = standings1.get(1).getTeam(); + var team2_1 = standings2.get(0).getTeam(); + var team2_2 = standings2.get(1).getTeam(); + + team1_1.getGroups().add(finalsGroup); + team1_2.getGroups().add(finalsGroup); + team2_1.getGroups().add(finalsGroup); + team2_2.getGroups().add(finalsGroup); + + finalsGroup.setTeams(List.of(team1_1, team1_2, team2_1, team2_2)); + + var finalsRound = new Round(); + finalsRound.setGroup(finalsGroup); + finalsRound.setStatus(Status.NOT_STARTED); + finalsRound.setName("Finales"); + finalsRound.setIsFinalsRound(Boolean.TRUE); + + var match1 = new Match(); + match1.setRound(finalsRound); + match1.setType(type); + match1.setStatus(Status.NOT_STARTED); + match1.setPlayed(false); + match1.setTeam1(standings1.get(0).getTeam()); + match1.setTeam2(standings2.get(0).getTeam()); + + var match2 = new Match(); + match2.setRound(finalsRound); + match2.setType(type); + match2.setStatus(Status.NOT_STARTED); + match2.setPlayed(false); + match2.setTeam1(standings1.get(1).getTeam()); + match2.setTeam2(standings2.get(1).getTeam()); + + finalsRound.setMatches(List.of(match1, match2)); + finalsGroup.setRounds(List.of(finalsRound)); + event.getGroups().add(finalsGroup); + } + public Tournament reopenGroup(Tournament tournament, Long groupId) { getGroup(tournament, groupId).setStatus(Status.IN_PROGRESS); tournamentRepository.save(tournament); @@ -215,6 +290,7 @@ public class TournamentPlayService { var countingPlayer = getPlayer(tournament, match.getCounter().getId()); countingPlayer.setCounting(false); + countingPlayer.incrementCounts(); match.setCounter(null); tournamentRepository.save(tournament);