fix: KoePi verwandte Ketten (Netto Marken-/Getraenke-Discount) werden jetzt gemeinsam durchsucht
This commit is contained in:
@@ -62,10 +62,20 @@ function addressesMatch(a, b) {
|
||||
// aktuellen und kürzlich abgelaufenen Prospekte GENAU dieser Kette, ganz ohne
|
||||
// Umkreis-Raten. addressMatch bestimmt, welche der (ggf. mehreren
|
||||
// bundesweiten) Filialen dieser Kette tatsächlich eure ist.
|
||||
// Manche Ketten teilen sich bei marktguru offenbar denselben Datentopf — ein
|
||||
// Prospekt kann unter der "falschen" uniqueName auftauchen (z.B. das
|
||||
// Getränke-Discount-Prospekt bei "netto-marken-discount" statt bei
|
||||
// "netto-getraenke-discount"). Für solche Familien wird beim Auflösen die
|
||||
// gesamte Gruppe gemeinsam durchsucht, nicht nur die eigene Liste.
|
||||
const RETAILER_FAMILIES = {
|
||||
'netto-marken-discount': ['netto-marken-discount', 'netto-getraenke-discount'],
|
||||
'netto-getraenke-discount':['netto-marken-discount', 'netto-getraenke-discount'],
|
||||
};
|
||||
|
||||
const LOCAL_STORE_TARGETS = [
|
||||
{ retailer: 'Netto Marken-Discount', uniqueName: 'netto-marken-discount', addressMatch: 'Im Bonnefeld 19' },
|
||||
{ retailer: 'Netto Getränke-Discount', uniqueName: 'netto-getraenke-discount', addressMatch: 'Im Bonnefeld 21' },
|
||||
{ retailer: 'trinkgut', uniqueName: 'trinkgut-discount', addressMatch: 'Keniastraße 39' },
|
||||
{ retailer: 'trinkgut', uniqueName: 'trinkgut', addressMatch: 'Keniastraße 39' },
|
||||
{ retailer: 'REWE', uniqueName: 'rewe', addressMatch: 'Fischerstr. 110-112' },
|
||||
{ retailer: 'Kaufland', uniqueName: 'kaufland', addressMatch: 'Auf der Höhe 20' },
|
||||
{ retailer: 'Penny', uniqueName: 'penny', addressMatch: 'Sittardsberger Allee 10' },
|
||||
@@ -249,9 +259,20 @@ async function resolveLocalStores() {
|
||||
const cache = new Map();
|
||||
let resolved = 0;
|
||||
|
||||
// Alle benötigten uniqueNames einmal laden (Mehrfachabrufe vermeiden, falls
|
||||
// mehrere Ziele/Familien sich eine uniqueName teilen)
|
||||
const uniqueNames = [...new Set(LOCAL_STORE_TARGETS.map(t => t.uniqueName))];
|
||||
const leafletsByUniqueName = new Map();
|
||||
for (const uniqueName of uniqueNames) {
|
||||
leafletsByUniqueName.set(uniqueName, await fetchLeafletsForRetailer(uniqueName));
|
||||
}
|
||||
|
||||
for (const target of LOCAL_STORE_TARGETS) {
|
||||
const leaflets = await fetchLeafletsForRetailer(target.uniqueName);
|
||||
console.log(`🍺 KöPi: "${target.retailer}" (${target.uniqueName}) — ${leaflets.length} Prospekt(e) gefunden`);
|
||||
// Bei verwandten Ketten (siehe RETAILER_FAMILIES) alle Prospekte der
|
||||
// ganzen Familie gemeinsam durchsuchen, sonst nur die eigene Liste
|
||||
const familyNames = RETAILER_FAMILIES[target.uniqueName] || [target.uniqueName];
|
||||
const leaflets = familyNames.flatMap(name => leafletsByUniqueName.get(name) || []);
|
||||
console.log(`🍺 KöPi: "${target.retailer}" (${target.uniqueName}) — ${leaflets.length} Prospekt(e) durchsucht${familyNames.length>1?` (Familie: ${familyNames.join(', ')})`:''}`);
|
||||
let found = null;
|
||||
for (const l of leaflets) {
|
||||
if (!l.mainLeafletId) continue;
|
||||
@@ -617,11 +638,21 @@ async function scrapeProspekte() {
|
||||
}).map(({ rawName, ...rest }) => rest); // rawName war nur intern nötig
|
||||
const targeted = withoutSondermagazin.filter(b => b.isTarget);
|
||||
|
||||
// Chronologisch in "aktuell laufend" und "kommend" trennen
|
||||
const todayIso = new Date().toISOString().slice(0, 10);
|
||||
// Chronologisch in "aktuell laufend" und "kommend" trennen — WICHTIG: in
|
||||
// lokaler Zeit vergleichen, nicht per rohem UTC-Substring. "22:00 UTC" ist
|
||||
// bei uns lokal schon der nächste Tag (z.B. "2026-07-19T22:00:00Z" = lokal
|
||||
// 20.07., 00:00 Uhr) — ein reiner String-Schnitt hätte das um einen Tag
|
||||
// verschoben.
|
||||
const localDateStr = isoOrDate => {
|
||||
const d = isoOrDate instanceof Date ? isoOrDate : new Date(isoOrDate);
|
||||
if (Number.isNaN(d.getTime())) return '';
|
||||
const pad = n => String(n).padStart(2, '0');
|
||||
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
||||
};
|
||||
const todayIso = localDateStr(new Date());
|
||||
const isCurrent = b => {
|
||||
const from = (b.validFrom || '').slice(0, 10);
|
||||
const to = (b.validTo || '').slice(0, 10);
|
||||
const from = localDateStr(b.validFrom);
|
||||
const to = localDateStr(b.validTo);
|
||||
if (!from) return true; // ohne Datum lieber anzeigen als verstecken
|
||||
if (from > todayIso) return false; // startet erst noch
|
||||
if (to && to < todayIso) return false; // schon abgelaufen
|
||||
|
||||
Reference in New Issue
Block a user