Update worshipController.js to enhance worship data parsing and conflict resolution. Introduce unparsedText for better tracking of source data. Modify date handling functions for improved accuracy in event filtering. Update .gitignore to exclude generated frontend artifacts, including index.html and assets directory, to streamline deployment.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
This commit is contained in:
@@ -490,9 +490,16 @@ function parseNbrSegment(segment, baseDateUtc, leaderNormalizedMap) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const title = tokens.join(' ').trim() || 'Gottesdienst';
|
||||
const unparsedText = tokens.join(' ').trim();
|
||||
|
||||
return { dateUtc, time, title, officiant };
|
||||
return {
|
||||
dateUtc,
|
||||
time,
|
||||
title: 'Gottesdienst',
|
||||
officiant,
|
||||
sourceText: raw,
|
||||
unparsedText,
|
||||
};
|
||||
}
|
||||
|
||||
// Hilfsfunktion zum Parsen eines Gottesdienstes aus der zweiten Spalte
|
||||
@@ -1511,20 +1518,32 @@ async function parseNbrPlanningRecords(records) {
|
||||
const imported = [];
|
||||
const errors = [];
|
||||
|
||||
const getDateKey = (dateValue) => {
|
||||
const date = dateValue instanceof Date ? dateValue : new Date(dateValue);
|
||||
const y = date.getUTCFullYear();
|
||||
const m = String(date.getUTCMonth() + 1).padStart(2, '0');
|
||||
const d = String(date.getUTCDate()).padStart(2, '0');
|
||||
return `${y}-${m}-${d}`;
|
||||
};
|
||||
|
||||
const findExisting = (dateUtc, time, eventPlaceId) => {
|
||||
const dateKey = getDateKey(dateUtc);
|
||||
const timeKey = time ? String(time).substring(0, 5) : '';
|
||||
return existingWorships.find((w) => {
|
||||
const wKey = getDateKey(w.date);
|
||||
const wTime = w.time ? String(w.time).substring(0, 5) : '';
|
||||
return wKey === dateKey && wTime === timeKey && String(w.eventPlaceId || '') === String(eventPlaceId || '');
|
||||
});
|
||||
};
|
||||
|
||||
const findDayPlaceConflicts = (dateUtc, eventPlaceId) => {
|
||||
const y = dateUtc.getUTCFullYear();
|
||||
const m = String(dateUtc.getUTCMonth() + 1).padStart(2, '0');
|
||||
const d = String(dateUtc.getUTCDate()).padStart(2, '0');
|
||||
const dateKey = `${y}-${m}-${d}`;
|
||||
const timeKey = time ? String(time).substring(0, 5) : '';
|
||||
return existingWorships.find((w) => {
|
||||
const wDate = w.date instanceof Date ? w.date : new Date(w.date);
|
||||
const wy = wDate.getUTCFullYear();
|
||||
const wm = String(wDate.getUTCMonth() + 1).padStart(2, '0');
|
||||
const wd = String(wDate.getUTCDate()).padStart(2, '0');
|
||||
const wKey = `${wy}-${wm}-${wd}`;
|
||||
const wTime = w.time ? String(w.time).substring(0, 5) : '';
|
||||
return wKey === dateKey && wTime === timeKey && String(w.eventPlaceId || '') === String(eventPlaceId || '');
|
||||
return existingWorships.filter((w) => {
|
||||
const wKey = getDateKey(w.date);
|
||||
return wKey === dateKey && String(w.eventPlaceId || '') === String(eventPlaceId || '');
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1578,10 +1597,13 @@ async function parseNbrPlanningRecords(records) {
|
||||
sacristanService: normalizeText(service),
|
||||
organPlaying: normalizeText(music),
|
||||
eventPlaceId,
|
||||
_sourceText: parsed.sourceText,
|
||||
_unparsedText: parsed.unparsedText,
|
||||
};
|
||||
|
||||
const existing = findExisting(worshipData.date, worshipData.time, worshipData.eventPlaceId);
|
||||
if (!hasChanges(worshipData, existing)) {
|
||||
const dayPlaceConflicts = findDayPlaceConflicts(worshipData.date, worshipData.eventPlaceId);
|
||||
if (!hasChanges(worshipData, existing) && dayPlaceConflicts.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1601,6 +1623,20 @@ async function parseNbrPlanningRecords(records) {
|
||||
worshipData._isNew = true;
|
||||
}
|
||||
|
||||
if (dayPlaceConflicts.length > 0) {
|
||||
worshipData._hasDayPlaceConflict = true;
|
||||
worshipData._importChoice = 'keepExisting';
|
||||
worshipData._replaceExistingIds = dayPlaceConflicts.map((w) => w.id);
|
||||
worshipData._conflictingWorships = dayPlaceConflicts.map((w) => ({
|
||||
id: w.id,
|
||||
date: getDateKey(w.date),
|
||||
time: w.time ? String(w.time).substring(0, 5) : '',
|
||||
title: w.title || '',
|
||||
organizer: w.organizer || '',
|
||||
eventPlaceId: w.eventPlaceId,
|
||||
}));
|
||||
}
|
||||
|
||||
imported.push(worshipData);
|
||||
}
|
||||
}
|
||||
@@ -1670,6 +1706,10 @@ exports.saveImportedWorships = async (req, res) => {
|
||||
|
||||
for (const worshipData of worships) {
|
||||
try {
|
||||
if (worshipData._importChoice === 'keepExisting') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Prüfen ob Datum in der Vergangenheit liegt
|
||||
const worshipDate = new Date(worshipData.date);
|
||||
worshipDate.setHours(0, 0, 0, 0);
|
||||
@@ -1677,21 +1717,51 @@ exports.saveImportedWorships = async (req, res) => {
|
||||
continue; // Überspringe vergangene Daten
|
||||
}
|
||||
|
||||
if (!worshipData.date || !worshipData.time || !worshipData.eventPlaceId) {
|
||||
errors.push(`Pflichtfelder fehlen: ${worshipData.date || 'kein Datum'} ${worshipData.time || 'keine Uhrzeit'} - kein Ort`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Freigabe-Status aus Import-Dialog übernehmen (Checkbox in der UI).
|
||||
// Fallback: wenn kein Wert gesetzt ist, bleibt es false.
|
||||
worshipData.approved = !!worshipData.approved;
|
||||
worshipData.title = normalizeText(worshipData.title) || 'Gottesdienst';
|
||||
|
||||
const replaceExistingIds = Array.isArray(worshipData._replaceExistingIds)
|
||||
? worshipData._replaceExistingIds.filter(Boolean)
|
||||
: [];
|
||||
const cleanWorshipData = {
|
||||
date: worshipData.date,
|
||||
dayName: worshipData.dayName || '',
|
||||
time: worshipData.time,
|
||||
title: worshipData.title,
|
||||
organizer: worshipData.organizer || '',
|
||||
collection: worshipData.collection || '',
|
||||
sacristanService: worshipData.sacristanService || '',
|
||||
organPlaying: worshipData.organPlaying || '',
|
||||
approved: worshipData.approved,
|
||||
eventPlaceId: worshipData.eventPlaceId,
|
||||
};
|
||||
|
||||
if (replaceExistingIds.length > 0) {
|
||||
await Worship.destroy({
|
||||
where: {
|
||||
id: { [Op.in]: replaceExistingIds },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Prüfen ob bereits ein Eintrag für dieses Datum und diese Uhrzeit existiert
|
||||
const whereClause = {
|
||||
date: {
|
||||
[Op.eq]: sequelize.fn('DATE', worshipData.date)
|
||||
[Op.eq]: sequelize.fn('DATE', cleanWorshipData.date)
|
||||
},
|
||||
time: worshipData.time
|
||||
time: cleanWorshipData.time
|
||||
};
|
||||
|
||||
// Wenn eventPlaceId gesetzt ist, auch danach suchen
|
||||
if (worshipData.eventPlaceId) {
|
||||
whereClause.eventPlaceId = worshipData.eventPlaceId;
|
||||
if (cleanWorshipData.eventPlaceId) {
|
||||
whereClause.eventPlaceId = cleanWorshipData.eventPlaceId;
|
||||
} else {
|
||||
// Wenn kein eventPlaceId, suche nach Einträgen ohne eventPlaceId
|
||||
whereClause.eventPlaceId = { [Op.is]: null };
|
||||
@@ -1701,11 +1771,11 @@ exports.saveImportedWorships = async (req, res) => {
|
||||
|
||||
if (existingWorship) {
|
||||
// Update bestehenden Eintrag
|
||||
await existingWorship.update(worshipData);
|
||||
await existingWorship.update(cleanWorshipData);
|
||||
updatedCount++;
|
||||
} else {
|
||||
// Neuen Eintrag erstellen
|
||||
await Worship.create(worshipData);
|
||||
await Worship.create(cleanWorshipData);
|
||||
savedCount++;
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user