feat(tournament): update PDF generation for top 3 participants

- Enhanced the TournamentPlacementsTab component to identify and process only the top 3 participants for PDF generation.
- Added logic to handle cases where no top 3 placements are available, emitting appropriate messages to the user.
- Updated internationalization files to include new translation keys for top 3 related messages and PDF titles across multiple languages.
This commit is contained in:
Torsten Schulz (local)
2026-02-06 16:33:39 +01:00
parent d09de49018
commit b470e728ed
16 changed files with 120 additions and 8 deletions

View File

@@ -541,7 +541,43 @@ export default {
async generateMissingDataPDF() {
this.pdfLoading = true;
try {
// 1. Alle Teilnehmer-Daten laden
// 1. Top-3-Platzierte ermitteln (aus K.O.-Runden und Gruppen)
const top3Names = new Set();
const top3Ids = new Set();
// Aus K.O.-Endplatzierungen (finalPlacementsByClass)
for (const [, placements] of Object.entries(this.finalPlacementsByClass)) {
for (const entry of placements) {
if (Number(entry.position) > 3) continue;
if (entry.displayName) {
// Doppel: beide Namen extrahieren
entry.displayName.split('/').forEach(n => top3Names.add(n.trim()));
} else if (entry.member) {
const fn = (entry.member.firstName || '').trim();
const ln = (entry.member.lastName || '').trim();
if (fn || ln) top3Names.add(`${fn} ${ln}`.trim());
if (entry.member.id != null) top3Ids.add(Number(entry.member.id));
}
}
}
// Aus Gruppen-Platzierungen (wenn keine K.O.-Runde vorhanden)
if (top3Names.size === 0) {
for (const gp of this.groupPlacements) {
for (const r of (gp.rankings || [])) {
if (Number(r.position) > 3) continue;
if (r.name) top3Names.add(r.name.trim());
if (r.id != null) top3Ids.add(Number(r.id));
}
}
}
if (top3Names.size === 0) {
this.$emit('show-info', this.$t('messages.info'), this.$t('tournaments.noPlacementsYet'));
return;
}
// 2. Teilnehmer-Daten laden
const allPlayerData = [];
// Interne Mitglieder laden
@@ -566,12 +602,22 @@ export default {
console.error('Fehler beim Laden der externen Teilnehmer:', e);
}
// Interne Teilnehmer verarbeiten
// Hilfsfunktion: prüft ob ein Spieler in den Top 3 ist
const isTop3 = (name, id) => {
if (id != null && top3Ids.has(Number(id))) return true;
if (name && top3Names.has(name.trim())) return true;
return false;
};
// Interne Teilnehmer verarbeiten (nur Top 3)
for (const p of this.participants) {
const memberId = p.member?.id || p.clubMemberId;
const member = members.find(m => m.id === memberId);
if (!member) continue;
const name = `${member.firstName || ''} ${member.lastName || ''}`.trim();
if (!isTop3(name, memberId)) continue;
let address = '';
const parts = [];
if (member.street) parts.push(member.street);
@@ -593,7 +639,6 @@ export default {
phone = member.phone;
}
const name = `${member.firstName || ''} ${member.lastName || ''}`.trim();
const gender = member.gender && member.gender !== 'unknown' ? member.gender : null;
allPlayerData.push({
@@ -606,11 +651,13 @@ export default {
});
}
// Externe Teilnehmer verarbeiten
// Externe Teilnehmer verarbeiten (nur Top 3)
for (const ext of this.externalParticipants) {
const found = externals.find(e => e.id === ext.id);
const src = found || ext;
const name = `${src.firstName || ''} ${src.lastName || ''}`.trim();
if (!isTop3(name, ext.id)) continue;
const gender = src.gender && src.gender !== 'unknown' ? src.gender : null;
allPlayerData.push({
@@ -623,14 +670,19 @@ export default {
});
}
// 2. Nur Teilnehmer mit fehlenden Daten filtern
// 3. Nur Teilnehmer mit fehlenden Daten filtern
const fields = ['birthDate', 'gender', 'address', 'email', 'phone'];
const playersWithMissing = allPlayerData.filter(p =>
fields.some(f => !p[f])
);
if (allPlayerData.length === 0) {
this.$emit('show-info', this.$t('messages.info'), this.$t('tournaments.noTop3Yet'));
return;
}
if (playersWithMissing.length === 0) {
this.$emit('show-info', this.$t('messages.info'), this.$t('tournaments.allDataComplete'));
this.$emit('show-info', this.$t('messages.info'), this.$t('tournaments.allDataCompleteTop3'));
return;
}
@@ -645,11 +697,11 @@ export default {
// Titel
pdf.setFontSize(16);
pdf.setFont('helvetica', 'bold');
pdf.text(t('tournaments.missingDataPDFTitle'), margin, 20);
pdf.text(t('tournaments.missingDataPDFTitleTop3'), margin, 20);
pdf.setFontSize(10);
pdf.setFont('helvetica', 'normal');
pdf.text(t('tournaments.missingDataPDFSubtitle'), margin, 27);
pdf.text(t('tournaments.missingDataPDFSubtitleTop3'), margin, 27);
// Formatierung der Felder
const formatGender = (g) => {

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "Fehlendi Teilnehmerdaten Minimeisterschaft",
"missingDataPDFSubtitle": "Bitte d'fehlende Date (markiert mit ____) bi de Teilnehmer nochfroge und do notiere.",
"allDataComplete": "Alli Teilnehmerdaten sind vollständig.",
"allDataCompleteTop3": "Alli Date vo de erschte 3 Plätz sind vollständig.",
"noTop3Yet": "D'erschte 3 Plätz stönd no nid fescht.",
"missingDataPDFTitleTop3": "Fehlendi Date Top 3 Minimeisterschaft",
"missingDataPDFSubtitleTop3": "Fehlendi Date vo de erschte 3 (markiert mit ____) bitte nochfroge und do notiere.",
"address": "Adrässe",
"phone": "Telefon",
"generatingPDF": "PDF wird erstellt...",

View File

@@ -279,6 +279,10 @@
"missingDataPDFTitle": "Fehlende Teilnehmerdaten Minimeisterschaft",
"missingDataPDFSubtitle": "Bitte die fehlenden Daten (markiert mit ____) bei den Teilnehmern erfragen und hier notieren.",
"allDataComplete": "Alle Teilnehmerdaten sind vollständig.",
"allDataCompleteTop3": "Alle Daten der Top-3-Platzierten sind vollständig.",
"noTop3Yet": "Es stehen noch keine Top-3-Platzierungen fest.",
"missingDataPDFTitleTop3": "Fehlende Daten Top 3 Minimeisterschaft",
"missingDataPDFSubtitleTop3": "Fehlende Daten der ersten 3 Plätze (markiert mit ____) bitte erfragen und hier notieren.",
"address": "Adresse",
"phone": "Telefon",
"generatingPDF": "PDF wird erstellt...",

View File

@@ -585,6 +585,10 @@
"missingDataPDFTitle": "Fehlende Teilnehmerdaten Minimeisterschaft",
"missingDataPDFSubtitle": "Bitte die fehlenden Daten (markiert mit ____) bei den Teilnehmern erfragen und hier notieren.",
"allDataComplete": "Alle Teilnehmerdaten sind vollständig.",
"allDataCompleteTop3": "Alle Daten der Top-3-Platzierten sind vollständig.",
"noTop3Yet": "Es stehen noch keine Top-3-Platzierungen fest.",
"missingDataPDFTitleTop3": "Fehlende Daten Top 3 Minimeisterschaft",
"missingDataPDFSubtitleTop3": "Fehlende Daten der ersten 3 Plätze (markiert mit ____) bitte erfragen und hier notieren.",
"address": "Adresse",
"phone": "Telefon",
"generatingPDF": "PDF wird erstellt...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "Missing participant data Mini championship",
"missingDataPDFSubtitle": "Please collect the missing data (marked with ____) from participants and note them here.",
"allDataComplete": "All participant data is complete.",
"allDataCompleteTop3": "All data for the top 3 placed players is complete.",
"noTop3Yet": "No top 3 placements have been determined yet.",
"missingDataPDFTitleTop3": "Missing data Top 3 Mini championship",
"missingDataPDFSubtitleTop3": "Please collect missing data of the top 3 (marked with ____) and note them here.",
"address": "Address",
"phone": "Phone",
"generatingPDF": "Generating PDF...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "Missing participant data Mini championship",
"missingDataPDFSubtitle": "Please collect the missing data (marked with ____) from participants and note them here.",
"allDataComplete": "All participant data is complete.",
"allDataCompleteTop3": "All data for the top 3 placed players is complete.",
"noTop3Yet": "No top 3 placements have been determined yet.",
"missingDataPDFTitleTop3": "Missing data Top 3 Mini championship",
"missingDataPDFSubtitleTop3": "Please collect missing data of the top 3 (marked with ____) and note them here.",
"address": "Address",
"phone": "Phone",
"generatingPDF": "Generating PDF...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "Missing participant data Mini championship",
"missingDataPDFSubtitle": "Please collect the missing data (marked with ____) from participants and note them here.",
"allDataComplete": "All participant data is complete.",
"allDataCompleteTop3": "All data for the top 3 placed players is complete.",
"noTop3Yet": "No top 3 placements have been determined yet.",
"missingDataPDFTitleTop3": "Missing data Top 3 Mini championship",
"missingDataPDFSubtitleTop3": "Please collect missing data of the top 3 (marked with ____) and note them here.",
"address": "Address",
"phone": "Phone",
"generatingPDF": "Generating PDF...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "Datos de participantes faltantes Mini campeonato",
"missingDataPDFSubtitle": "Por favor, recopile los datos faltantes (marcados con ____) de los participantes y anótelos aquí.",
"allDataComplete": "Todos los datos de los participantes están completos.",
"allDataCompleteTop3": "Todos los datos de los 3 primeros clasificados están completos.",
"noTop3Yet": "Aún no se han determinado los 3 primeros puestos.",
"missingDataPDFTitleTop3": "Datos faltantes Top 3 Mini campeonato",
"missingDataPDFSubtitleTop3": "Por favor, recopile los datos faltantes de los 3 primeros (marcados con ____) y anótelos aquí.",
"address": "Dirección",
"phone": "Teléfono",
"generatingPDF": "Generando PDF...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "Nawawalang datos ng mga kalahok Mini championship",
"missingDataPDFSubtitle": "Pakikolekta ang nawawalang datos (may markang ____) mula sa mga kalahok at itala dito.",
"allDataComplete": "Kumpleto na ang lahat ng datos ng mga kalahok.",
"allDataCompleteTop3": "Kumpleto na ang lahat ng datos ng unang 3 puwesto.",
"noTop3Yet": "Hindi pa natutukoy ang unang 3 puwesto.",
"missingDataPDFTitleTop3": "Nawawalang datos Top 3 Mini championship",
"missingDataPDFSubtitleTop3": "Pakikolekta ang nawawalang datos ng unang 3 (may markang ____) at itala dito.",
"address": "Address",
"phone": "Telepono",
"generatingPDF": "Gumagawa ng PDF...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "Données manquantes des participants Mini-championnat",
"missingDataPDFSubtitle": "Veuillez collecter les données manquantes (marquées ____) auprès des participants et les noter ici.",
"allDataComplete": "Toutes les données des participants sont complètes.",
"allDataCompleteTop3": "Toutes les données des 3 premiers sont complètes.",
"noTop3Yet": "Les 3 premiers ne sont pas encore déterminés.",
"missingDataPDFTitleTop3": "Données manquantes Top 3 Mini-championnat",
"missingDataPDFSubtitleTop3": "Veuillez collecter les données manquantes des 3 premiers (marquées ____) et les noter ici.",
"address": "Adresse",
"phone": "Téléphone",
"generatingPDF": "Génération du PDF...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "Dati mancanti dei partecipanti Mini campionato",
"missingDataPDFSubtitle": "Si prega di raccogliere i dati mancanti (contrassegnati con ____) dai partecipanti e annotarli qui.",
"allDataComplete": "Tutti i dati dei partecipanti sono completi.",
"allDataCompleteTop3": "Tutti i dati dei primi 3 classificati sono completi.",
"noTop3Yet": "I primi 3 posti non sono ancora stati determinati.",
"missingDataPDFTitleTop3": "Dati mancanti Top 3 Mini campionato",
"missingDataPDFSubtitleTop3": "Si prega di raccogliere i dati mancanti dei primi 3 (contrassegnati con ____) e annotarli qui.",
"address": "Indirizzo",
"phone": "Telefono",
"generatingPDF": "Generazione PDF...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "参加者の不足データ ミニ選手権",
"missingDataPDFSubtitle": "不足しているデータ____で表示を参加者から収集し、ここに記入してください。",
"allDataComplete": "すべての参加者データが揃っています。",
"allDataCompleteTop3": "上位3名のデータはすべて揃っています。",
"noTop3Yet": "上位3名がまだ確定していません。",
"missingDataPDFTitleTop3": "不足データ トップ3 ミニ選手権",
"missingDataPDFSubtitleTop3": "トップ3の不足データ____で表示を収集し、ここに記入してください。",
"address": "住所",
"phone": "電話",
"generatingPDF": "PDF作成中...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "Brakujące dane uczestników Mini mistrzostwa",
"missingDataPDFSubtitle": "Proszę zebrać brakujące dane (oznaczone ____) od uczestników i zanotować je tutaj.",
"allDataComplete": "Wszystkie dane uczestników są kompletne.",
"allDataCompleteTop3": "Wszystkie dane pierwszych 3 miejsc są kompletne.",
"noTop3Yet": "Pierwsze 3 miejsca nie zostały jeszcze ustalone.",
"missingDataPDFTitleTop3": "Brakujące dane Top 3 Mini mistrzostwa",
"missingDataPDFSubtitleTop3": "Proszę zebrać brakujące dane pierwszych 3 (oznaczone ____) i zanotować je tutaj.",
"address": "Adres",
"phone": "Telefon",
"generatingPDF": "Generowanie PDF...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "ข้อมูลผู้เข้าร่วมที่ขาดหาย มินิแชมเปี้ยนชิพ",
"missingDataPDFSubtitle": "กรุณาเก็บข้อมูลที่ขาดหาย (ทำเครื่องหมาย ____) จากผู้เข้าร่วมและจดบันทึกที่นี่",
"allDataComplete": "ข้อมูลผู้เข้าร่วมทั้งหมดครบถ้วน",
"allDataCompleteTop3": "ข้อมูล 3 อันดับแรกครบถ้วน",
"noTop3Yet": "ยังไม่ได้กำหนด 3 อันดับแรก",
"missingDataPDFTitleTop3": "ข้อมูลที่ขาดหาย 3 อันดับแรก มินิแชมเปี้ยนชิพ",
"missingDataPDFSubtitleTop3": "กรุณาเก็บข้อมูลที่ขาดหายของ 3 อันดับแรก (ทำเครื่องหมาย ____) และจดบันทึกที่นี่",
"address": "ที่อยู่",
"phone": "โทรศัพท์",
"generatingPDF": "กำลังสร้าง PDF...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "Nawawalang datos ng mga kalahok Mini championship",
"missingDataPDFSubtitle": "Pakikolekta ang nawawalang datos (may markang ____) mula sa mga kalahok at itala dito.",
"allDataComplete": "Kumpleto na ang lahat ng datos ng mga kalahok.",
"allDataCompleteTop3": "Kumpleto na ang lahat ng datos ng unang 3 puwesto.",
"noTop3Yet": "Hindi pa natutukoy ang unang 3 puwesto.",
"missingDataPDFTitleTop3": "Nawawalang datos Top 3 Mini championship",
"missingDataPDFSubtitleTop3": "Pakikolekta ang nawawalang datos ng unang 3 (may markang ____) at itala dito.",
"address": "Address",
"phone": "Telepono",
"generatingPDF": "Gumagawa ng PDF...",

View File

@@ -111,6 +111,10 @@
"missingDataPDFTitle": "参赛者缺失数据 迷你锦标赛",
"missingDataPDFSubtitle": "请向参赛者收集缺失数据标记为____并在此记录。",
"allDataComplete": "所有参赛者数据已完整。",
"allDataCompleteTop3": "前3名的所有数据已完整。",
"noTop3Yet": "前3名尚未确定。",
"missingDataPDFTitleTop3": "缺失数据 前3名迷你锦标赛",
"missingDataPDFSubtitleTop3": "请收集前3名的缺失数据标记为____并在此记录。",
"address": "地址",
"phone": "电话",
"generatingPDF": "正在生成PDF...",