started tournament implementation

This commit is contained in:
Torsten Schulz
2025-02-24 16:21:43 +01:00
parent 9442e3683b
commit df41720b50
14 changed files with 906 additions and 15 deletions

View File

@@ -0,0 +1,249 @@
import Club from "../models/Club.js";
import Member from "../models/Member.js";
import Tournament from "../models/Tournament.js";
import TournamentGroup from "../models/TournamentGroup.js";
import TournamentMatch from "../models/TournamentMatch.js";
import TournamentMember from "../models/TournamentMember.js";
import { checkAccess } from '../utils/userUtils.js';
class TournamentService {
async getTournaments(userToken, clubId) {
await checkAccess(userToken, clubId);
const tournaments = await Tournament.findAll(
{
where: { clubId },
order: [['date', 'DESC']],
attributes: ['id', 'name', 'date']
}
);
return JSON.parse(JSON.stringify(tournaments));
}
async addTournament(userToken, clubId, tournamentName, date) {
await checkAccess(userToken, clubId);
const club = await Club.findByPk(clubId);
await Tournament.create({
name: tournamentName,
date: date,
clubId: club.id,
bestOfEndroundSize: 0,
type: '',
name: '',
});
return await this.getTournaments(userToken, clubId);
}
async addParticipant(token, clubId, tournamentId, participantId) {
await checkAccess(token, clubId);
const tournament = await Tournament.findByPk(tournamentId);
if (!tournament || tournament.clubId != clubId) {
throw new Error('Tournament not found');
}
const participant = TournamentMember.findAll({
where: { tournamentId: tournamentId, groupId: participantId, clubMemberId: participantId },
});
if (participant) {
throw new Error('Participant already exists');
}
await TournamentMember.create({
tournamentId: tournamentId,
groupId: participantId,
clubMemberId: participantId,
});
}
async getParticipants(token, clubId, tournamentId) {
await checkAccess(token, clubId);
const tournament = await Tournament.findByPk(tournamentId);
if (!tournament || tournament.clubId != clubId) {
throw new Error('Tournament not found');
}
return await TournamentMember.findAll({
where: {
tournamentId: tournamentId,
},
include: [
{
model: Member,
as: 'member',
attributes: ['id', 'lastName', 'firstName'],
order: [['firstName', 'ASC'], ['lastName', 'ASC']],
}
]
});
}
async setModus(token, clubId, tournamentId, type, numberOfGroups) {
await checkAccess(token, clubId);
const tournament = await Tournament.findByPk(tournamentId);
if (!tournament || tournament.clubId != clubId) {
throw new Error('Tournament not found');
}
await tournament.update({ type, numberOfGroups });
}
async createGroups(token, clubId, tournamentId) {
await checkAccess(token, clubId);
const tournament = await Tournament.findByPk(tournamentId);
if (!tournament || tournament.clubId != clubId) {
throw new Error('Tournament not found');
}
const existingGroups = await TournamentGroup.findAll({ where: { tournamentId } });
const desiredGroupCount = tournament.numberOfGroups;
if (existingGroups.length < desiredGroupCount) {
const missingGroups = desiredGroupCount - existingGroups.length;
for (let i = 0; i < missingGroups; i++) {
await TournamentGroup.create({ tournamentId });
}
} else if (existingGroups.length > desiredGroupCount) {
existingGroups.sort((a, b) => a.id - b.id);
const groupsToRemove = existingGroups.slice(desiredGroupCount);
for (const group of groupsToRemove) {
await group.destroy();
}
}
}
async fillGroups(token, clubId, tournamentId) {
await checkAccess(token, clubId);
const tournament = await Tournament.findByPk(tournamentId);
if (!tournament || tournament.clubId != clubId) {
throw new Error('Tournament not found');
}
const groups = await TournamentGroup.findAll({ where: { tournamentId } });
if (!groups || groups.length === 0) {
throw new Error('No groups available. Please create groups first.');
}
const members = await TournamentMember.findAll({ where: { tournamentId } });
if (!members || members.length === 0) {
throw new Error('No tournament members found.');
}
await TournamentMatch.destroy({ where: { tournamentId } });
const shuffledMembers = [...members];
for (let i = shuffledMembers.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffledMembers[i], shuffledMembers[j]] = [shuffledMembers[j], shuffledMembers[i]];
}
const numberOfGroups = groups.length;
for (let i = 0; i < shuffledMembers.length; i++) {
const groupAssignment = groups[i % numberOfGroups].id;
await shuffledMembers[i].update({ groupId: groupAssignment });
}
for (const group of groups) {
const groupMembers = await TournamentMember.findAll({ where: { groupId: group.id } });
for (let i = 0; i < groupMembers.length; i++) {
for (let j = i + 1; j < groupMembers.length; j++) {
await TournamentMatch.create({
tournamentId: tournamentId,
groupId: group.id,
round: 'group',
player1Id: groupMembers[i].id,
player2Id: groupMembers[j].id,
});
}
}
}
return await TournamentMember.findAll({ where: { tournamentId } });
}
async getGroups(token, clubId, tournamentId) {
await checkAccess(token, clubId);
const tournament = await Tournament.findByPk(tournamentId);
if (!tournament || tournament.clubId != clubId) {
throw new Error('Tournament not found');
}
const groups = await TournamentGroup.findAll({ where: { tournamentId } });
return groups;
}
async getGroupsWithParticipants(token, clubId, tournamentId) {
await checkAccess(token, clubId);
const tournament = await Tournament.findByPk(tournamentId);
if (!tournament || tournament.clubId != clubId) {
throw new Error('Tournament not found');
}
const groups = await TournamentGroup.findAll({
where: { tournamentId },
include: [
{
model: TournamentMember,
as: 'tournamentGroupMembers',
required: false,
include: [
{
model: Member,
as: 'member',
attributes: ['id', 'firstName', 'lastName']
}
]
}
],
order: [['id', 'ASC']]
});
return groups.map(group => ({
groupId: group.id,
participants: group.tournamentGroupMembers.map(p => ({
id: p.id,
name: `${p.member.firstName} ${p.member.lastName}`
}))
}));
}
async getTournament(token, clubId, tournamentId) {
await checkAccess(token, clubId);
const tournament = await Tournament.findOne({
where: { id: tournamentId, clubId },
});
if (!tournament) {
throw new Error('Tournament not found');
}
return tournament;
}
async getTournamentMatches(token, clubId, tournamentId) {
await checkAccess(token, clubId);
const tournament = await Tournament.findOne({
where: { id: tournamentId, clubId },
});
if (!tournament) {
throw new Error('Tournament not found');
}
const matches = await TournamentMatch.findAll({
where: { tournamentId },
include: [
{
model: TournamentMember,
as: 'player1',
include: {
model: Member,
as: 'member',
}
},
{
model: TournamentMember,
as: 'player2',
include: {
model: Member,
as: 'member',
}
}
],
order: [['id', 'ASC']]
});
return matches;
}
async addMatchResult(token, clubId, tournamentId, matchId, result) {
await checkAccess(token, clubId);
const match = await TournamentMatch.findByPk(matchId);
if (!match || match.tournamentId != tournamentId) {
throw new Error("Match not found or doesn't belong to this tournament");
}
match.result = result;
await match.save();
}
}
export default new TournamentService();