diff --git a/backend/services/tournamentService.js b/backend/services/tournamentService.js
index 5b7b3c3..3901d5c 100644
--- a/backend/services/tournamentService.js
+++ b/backend/services/tournamentService.js
@@ -1656,12 +1656,30 @@ class TournamentService {
}
classGroups.forEach((g, idx) => {
- // Berechne Rankings für diese Gruppe
+ // Bei zusammengeführten Klassen (Pool): Teilnehmer-classId pro ID
+ const participantIdToClassId = {};
+ for (const tm of g.tournamentGroupMembers || []) {
+ participantIdToClassId[tm.id] = tm.classId ?? g.classId;
+ }
+ for (const ext of g.externalGroupMembers || []) {
+ participantIdToClassId[ext.id] = ext.classId ?? g.classId;
+ }
+ const classIdsInGroup = [...new Set(Object.values(participantIdToClassId).filter(c => c != null))];
+ const isPool = !!g.poolId || classIdsInGroup.length > 1;
+ const participantClassIds = isPool && classIdsInGroup.length > 0 ? classIdsInGroup : [g.classId];
+
+ participantClassIds.forEach((participantClassId) => {
const stats = {};
-
+ const effectiveClassId = isPool ? participantClassId : g.classId;
+
if (isDoubles && pairingsByGroup[g.id]) {
- // Bei Doppel: Verwende Paarungen
+ // Bei Doppel: Verwende Paarungen (bei Pool nur Paarungen dieser Klasse)
for (const pairing of pairingsByGroup[g.id]) {
+ if (isPool) {
+ const c1 = pairing.member1?.classId ?? pairing.external1?.classId ?? g.classId;
+ const c2 = pairing.member2?.classId ?? pairing.external2?.classId ?? g.classId;
+ if (c1 !== effectiveClassId || c2 !== effectiveClassId) continue;
+ }
const player1Name = pairing.member1?.member
? `${pairing.member1.member.firstName} ${pairing.member1.member.lastName}`
: pairing.external1
@@ -1695,9 +1713,9 @@ class TournamentService {
};
}
} else {
- // Bei Einzel: Verwende einzelne Spieler
- // Interne Teilnehmer
+ // Bei Einzel: Verwende einzelne Spieler (bei Pool nur Teilnehmer dieser Klasse)
for (const tm of g.tournamentGroupMembers || []) {
+ if (isPool && (tm.classId ?? g.classId) !== effectiveClassId) continue;
stats[tm.id] = {
id: tm.id,
name: `${tm.member.firstName} ${tm.member.lastName}`,
@@ -1714,9 +1732,8 @@ class TournamentService {
matchesLost: 0
};
}
-
- // Externe Teilnehmer
for (const ext of g.externalGroupMembers || []) {
+ if (isPool && (ext.classId ?? g.classId) !== effectiveClassId) continue;
stats[ext.id] = {
id: ext.id,
name: `${ext.firstName} ${ext.lastName}`,
@@ -1735,8 +1752,13 @@ class TournamentService {
}
}
- // Berechne Statistiken aus Matches
+ // Berechne Statistiken aus Matches (bei Pool nur Spiele innerhalb derselben Klasse)
for (const m of groupMatches.filter(m => m.groupId === g.id)) {
+ if (isPool) {
+ const c1 = participantIdToClassId[m.player1Id];
+ const c2 = participantIdToClassId[m.player2Id];
+ if (c1 !== effectiveClassId || c2 !== effectiveClassId) continue;
+ }
if (isDoubles) {
// Bei Doppel: Finde die Paarungen für player1Id und player2Id
const pairing1Key = Object.keys(stats).find(key =>
@@ -2020,10 +2042,11 @@ class TournamentService {
result.push({
groupId: g.id,
- classId: g.classId,
+ classId: effectiveClassId,
groupNumber: idx + 1, // Nummer innerhalb der Klasse
participants: participantsWithPosition
});
+ }); // participantClassIds.forEach
});
}
diff --git a/frontend/src/components/tournament/TournamentGroupsTab.vue b/frontend/src/components/tournament/TournamentGroupsTab.vue
index 63eae3e..72042d5 100644
--- a/frontend/src/components/tournament/TournamentGroupsTab.vue
+++ b/frontend/src/components/tournament/TournamentGroupsTab.vue
@@ -118,14 +118,14 @@
{{ $t('tournaments.sets') }} |
{{ $t('tournaments.diff') }} |
{{ $t('tournaments.pointsRatio') }} |
-
+ |
G{{ String.fromCharCode(96 + group.groupNumber) }}{{ idx + 1 }}
|
{{ $t('tournaments.livePosition') }} |
-
+
| G{{ String.fromCharCode(96 + group.groupNumber) }}{{ idx + 1 }} |
{{ pl.position }}. |
★{{ pl.name }}{{ $t('tournaments.gaveUp') }} |
@@ -140,7 +140,7 @@
({{ (Math.abs(pl.pointsWon || 0) - Math.abs(pl.pointsLost || 0)) >= 0 ? '+' : '' }}{{ Math.abs(pl.pointsWon || 0) - Math.abs(pl.pointsLost || 0) }})
-
@@ -151,7 +151,7 @@
-
|
- {{ getLivePosition(pl.id, group.groupId) }}. |
+ {{ getLivePosition(pl.id, group) }}. |
@@ -285,6 +285,10 @@ export default {
}
},
methods: {
+ groupRankingsForGroup(group) {
+ const key = `${group.groupId}-${group.classId ?? 'null'}`;
+ return this.groupRankings[key] || [];
+ },
filterMatchesByClass(matches) {
// Wenn keine Klasse ausgewählt ist (null), zeige alle
if (this.selectedViewClass === null || this.selectedViewClass === undefined) {
@@ -403,8 +407,9 @@ export default {
return classes;
},
- getLivePosition(playerId, groupId) {
- const groupPlayers = this.groupRankings[groupId] || [];
+ getLivePosition(playerId, group) {
+ const groupId = group && typeof group === 'object' ? group.groupId : group;
+ const groupPlayers = this.groupRankingsForGroup && group && typeof group === 'object' ? this.groupRankingsForGroup(group) : (this.groupRankings[groupId] || []);
const liveStats = groupPlayers.map(player => {
let livePoints = player.points || 0;
let liveSetsWon = player.setsWon || 0;
@@ -455,7 +460,7 @@ export default {
});
const position = liveStats.findIndex(p => p.id === playerId) + 1;
- return position || groupPlayers.findIndex(p => p.id === playerId) + 1;
+ return position || (groupPlayers.findIndex(p => p.id === playerId) + 1) || 0;
},
handleMatchClick(player1Id, player2Id, groupId) {
// Highlight das Match
diff --git a/frontend/src/components/tournament/TournamentPlacementsTab.vue b/frontend/src/components/tournament/TournamentPlacementsTab.vue
index d85c9ba..e857122 100644
--- a/frontend/src/components/tournament/TournamentPlacementsTab.vue
+++ b/frontend/src/components/tournament/TournamentPlacementsTab.vue
@@ -409,10 +409,11 @@ export default {
},
groupPlacements() {
const placements = [];
- // Primär: aus groups + groupRankings
+ // Primär: aus groups + groupRankings (Schlüssel groupId-classId bei Pool)
if ((this.groups || []).length > 0) {
this.groups.forEach(group => {
- const rankings = this.groupRankings[group.groupId] || [];
+ const key = `${group.groupId}-${group.classId ?? 'null'}`;
+ const rankings = this.groupRankings[key] || [];
if (rankings.length > 0) {
placements.push({
groupId: group.groupId,
diff --git a/frontend/src/views/TournamentTab.vue b/frontend/src/views/TournamentTab.vue
index 845f812..4446a2a 100644
--- a/frontend/src/views/TournamentTab.vue
+++ b/frontend/src/views/TournamentTab.vue
@@ -479,10 +479,11 @@ export default {
},
groupRankings() {
- // Die Teilnehmer kommen bereits sortiert vom Backend mit allen benötigten Statistiken
+ // Schlüssel: groupId-classId (bei Pool mehrere Einträge pro Gruppe, pro Klasse getrennt)
const rankings = {};
this.groups.forEach(g => {
- rankings[g.groupId] = g.participants.map(p => ({
+ const key = `${g.groupId}-${g.classId ?? 'null'}`;
+ rankings[key] = g.participants.map(p => ({
id: p.id,
name: p.name,
seeded: p.seeded || false,
@@ -502,6 +503,9 @@ export default {
});
return rankings;
},
+ groupRankingsKey(groupId, classId) {
+ return `${groupId}-${classId ?? 'null'}`;
+ },
// Mapping von groupId zu groupNumber für die Teilnehmer-Auswahl
groupIdToNumberMap() {