PIN parser korrigiert.
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 52s
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 52s
This commit is contained in:
@@ -147,6 +147,9 @@ class PDFParserService {
|
||||
*/
|
||||
static parseStandardFormat(lines, clubId, lineEntries = null) {
|
||||
const matches = [];
|
||||
// nuLiga PIN lists identify the team's club in the document header. The
|
||||
// PIN in each row belongs to that team, not inherently to the guest.
|
||||
const documentTeamName = lines[0]?.trim() || null;
|
||||
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
@@ -218,6 +221,7 @@ class PDFParserService {
|
||||
const pinMatch = cleanLine3.match(/(\d{4})$/);
|
||||
|
||||
let code = null;
|
||||
let pin = null;
|
||||
let homePin = null;
|
||||
let guestPin = null;
|
||||
let teamsPart = cleanLine3;
|
||||
@@ -228,31 +232,8 @@ class PDFParserService {
|
||||
teamsPart = cleanLine3.substring(0, cleanLine3.length - code.length).trim();
|
||||
} else if (pinMatch) {
|
||||
// PIN gefunden (4 Ziffern)
|
||||
const pin = pinMatch[1];
|
||||
pin = pinMatch[1];
|
||||
teamsPart = cleanLine3.substring(0, cleanLine3.length - pin.length).trim();
|
||||
|
||||
// Die PIN gehört immer zu "Harheimer TC"
|
||||
// Prüfe, ob "Harheimer TC" am Anfang oder am Ende steht
|
||||
const harheimerIndex = teamsPart.indexOf('Harheimer TC');
|
||||
|
||||
if (harheimerIndex >= 0) {
|
||||
// "Harheimer TC" gefunden
|
||||
let beforeHarheimer = teamsPart.substring(0, harheimerIndex).trim();
|
||||
|
||||
// Entferne führende Spielnummer (z.B. "1", "2", etc.)
|
||||
beforeHarheimer = beforeHarheimer.replace(/^\d+/, '').trim();
|
||||
|
||||
if (beforeHarheimer && beforeHarheimer.length > 0) {
|
||||
// Es gibt einen Team-Namen vor "Harheimer TC" → Harheimer ist Gastteam → guestPin
|
||||
guestPin = pin;
|
||||
} else {
|
||||
// "Harheimer TC" steht am Anfang (nur Spielnummer davor) → Harheimer ist Heimteam → homePin
|
||||
homePin = pin;
|
||||
}
|
||||
} else {
|
||||
// "Harheimer TC" nicht gefunden → Standardlogik: PIN gehört zum Gastteam
|
||||
guestPin = pin;
|
||||
}
|
||||
}
|
||||
|
||||
if (!code && codeFromColumns) {
|
||||
@@ -264,15 +245,22 @@ class PDFParserService {
|
||||
// columns unambiguously. Use them directly instead of trying
|
||||
// to reconstruct column boundaries from the flattened text.
|
||||
// This also preserves names with characters such as "ä".
|
||||
if (code && homeFromColumns && guestFromColumns) {
|
||||
if ((code || pin) && homeFromColumns && guestFromColumns) {
|
||||
if (pin && documentTeamName) {
|
||||
if (PDFParserService.namesRoughlyMatch(homeFromColumns, documentTeamName)) {
|
||||
homePin = pin;
|
||||
} else if (PDFParserService.namesRoughlyMatch(guestFromColumns, documentTeamName)) {
|
||||
guestPin = pin;
|
||||
}
|
||||
}
|
||||
matches.push({
|
||||
date: date,
|
||||
time: time,
|
||||
homeTeamName: homeFromColumns,
|
||||
guestTeamName: guestFromColumns,
|
||||
code: code,
|
||||
homePin: null,
|
||||
guestPin: null,
|
||||
homePin: homePin,
|
||||
guestPin: guestPin,
|
||||
clubId: clubId,
|
||||
rawLine: line
|
||||
});
|
||||
@@ -329,17 +317,18 @@ class PDFParserService {
|
||||
} else {
|
||||
// Fallback: Versuche mit einzelnen Leerzeichen zu trennen
|
||||
|
||||
// Strategie 1: Suche nach "Harheimer TC" als Heimteam oder Gastteam
|
||||
if (teamsPart.includes('Harheimer TC')) {
|
||||
const harheimerIndex = teamsPart.indexOf('Harheimer TC');
|
||||
let beforeHarheimer = teamsPart.substring(0, harheimerIndex).trim();
|
||||
let afterHarheimer = teamsPart.substring(harheimerIndex + 'Harheimer TC'.length).trim();
|
||||
// Strategy 1: use the team named in the document header
|
||||
// as the split point when PDF text lacks column spacing.
|
||||
if (documentTeamName && teamsPart.includes(documentTeamName)) {
|
||||
const documentTeamIndex = teamsPart.indexOf(documentTeamName);
|
||||
let beforeDocumentTeam = teamsPart.substring(0, documentTeamIndex).trim();
|
||||
let afterDocumentTeam = teamsPart.substring(documentTeamIndex + documentTeamName.length).trim();
|
||||
|
||||
beforeHarheimer = beforeHarheimer
|
||||
beforeDocumentTeam = beforeDocumentTeam
|
||||
.replace(/^\(\d+\)/, '')
|
||||
.replace(/^\d+/, '')
|
||||
.trim();
|
||||
afterHarheimer = afterHarheimer
|
||||
afterDocumentTeam = afterDocumentTeam
|
||||
.replace(/^\(\d+\)/, '')
|
||||
.replace(/^\d+/, '')
|
||||
.trim();
|
||||
@@ -385,23 +374,23 @@ class PDFParserService {
|
||||
return { roman: null, tokens: tokensCopy };
|
||||
};
|
||||
|
||||
if (!beforeHarheimer && afterHarheimer) {
|
||||
const tokens = afterHarheimer.split(/\s+/).filter(Boolean);
|
||||
if (!beforeDocumentTeam && afterDocumentTeam) {
|
||||
const tokens = afterDocumentTeam.split(/\s+/).filter(Boolean);
|
||||
const { roman: homeRoman, tokens: guestTokens } = extractLeadingRomanFromTokens(tokens);
|
||||
const homeSuffix = homeRoman ? ` ${homeRoman}` : '';
|
||||
homeTeamName = `Harheimer TC${homeSuffix}`;
|
||||
homeTeamName = `${documentTeamName}${homeSuffix}`;
|
||||
guestTeamName = guestTokens.join(' ').trim();
|
||||
} else if (beforeHarheimer && !afterHarheimer) {
|
||||
// "Harheimer TC" ist Gastteam ohne weitere Tokens
|
||||
homeTeamName = beforeHarheimer.replace(/\([^)]*\)/g, '').trim();
|
||||
guestTeamName = 'Harheimer TC';
|
||||
} else if (beforeHarheimer && afterHarheimer) {
|
||||
// "Harheimer TC" steht in der Mitte → Harheimer ist Gast, Tokens nach Harheimer gehören zu ihm
|
||||
homeTeamName = beforeHarheimer.replace(/\([^)]*\)/g, '').trim();
|
||||
const tokens = afterHarheimer.split(/\s+/).filter(Boolean);
|
||||
} else if (beforeDocumentTeam && !afterDocumentTeam) {
|
||||
// The document team is the guest team without a suffix.
|
||||
homeTeamName = beforeDocumentTeam.replace(/\([^)]*\)/g, '').trim();
|
||||
guestTeamName = documentTeamName;
|
||||
} else if (beforeDocumentTeam && afterDocumentTeam) {
|
||||
// The document team is guest; trailing tokens can contain its suffix.
|
||||
homeTeamName = beforeDocumentTeam.replace(/\([^)]*\)/g, '').trim();
|
||||
const tokens = afterDocumentTeam.split(/\s+/).filter(Boolean);
|
||||
const { roman: guestRoman, tokens: remainingTokens } = extractLeadingRomanFromTokens(tokens);
|
||||
const guestSuffix = guestRoman ? ` ${guestRoman}` : '';
|
||||
guestTeamName = `Harheimer TC${guestSuffix}`;
|
||||
guestTeamName = `${documentTeamName}${guestSuffix}`;
|
||||
if (remainingTokens.length > 0) {
|
||||
const trailingText = remainingTokens.join(' ').trim();
|
||||
if (trailingText) {
|
||||
@@ -409,7 +398,7 @@ class PDFParserService {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Nur "Harheimer TC" ohne weitere Kontexte → überspringen
|
||||
// Only the document team without opponent context → skip.
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -437,6 +426,13 @@ class PDFParserService {
|
||||
}
|
||||
|
||||
if (homeTeamName && guestTeamName) {
|
||||
if (pin && !homePin && !guestPin && documentTeamName) {
|
||||
if (PDFParserService.namesRoughlyMatch(homeTeamName, documentTeamName)) {
|
||||
homePin = pin;
|
||||
} else if (PDFParserService.namesRoughlyMatch(guestTeamName, documentTeamName)) {
|
||||
guestPin = pin;
|
||||
}
|
||||
}
|
||||
|
||||
matches.push({
|
||||
date: date,
|
||||
@@ -723,9 +719,18 @@ class PDFParserService {
|
||||
}
|
||||
if (matchData.homePin) {
|
||||
updateData.homePin = matchData.homePin;
|
||||
// Repair a PIN previously imported on the wrong side
|
||||
// without touching an independently stored guest PIN.
|
||||
if (matchingMatch.guestPin === matchData.homePin) {
|
||||
updateData.guestPin = null;
|
||||
}
|
||||
}
|
||||
if (matchData.guestPin) {
|
||||
updateData.guestPin = matchData.guestPin;
|
||||
// Repair the corresponding inverse case.
|
||||
if (matchingMatch.homePin === matchData.guestPin) {
|
||||
updateData.homePin = null;
|
||||
}
|
||||
}
|
||||
|
||||
await matchingMatch.update(updateData);
|
||||
|
||||
Reference in New Issue
Block a user