started tournament implementation
This commit is contained in:
249
backend/services/tournamentService.js
Normal file
249
backend/services/tournamentService.js
Normal 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();
|
||||
Reference in New Issue
Block a user