anzahl, wenn erst der Hersteller geklaert werden muss
$v2_marke = isset($_GET['marke']) ? trim($_GET['marke']) : ''; // gewaehlter Hersteller
$v2_variants = []; // BSH-Bauzustaende /01 /02 ..., wenn nur der Zeitraum unterscheidet
$v2_variant_base = ''; // gemeinsame Typnummer ohne Suffix, z.B. "WT46W560BY"
try {
// MySQL wird in beiden Fällen gebraucht (rechte Spalte = Artikel-Suche)
$db = new KremplDB(true);
if ($search_term !== '') {
// Links: Geräte-Suche (PostgreSQL)
$start_time = microtime(true);
$results = $db->searchGeraete($search_term, 20);
if ($show_shop_items) {
foreach ($results as &$device) {
$device['shop_items'] = $db->getAvailableItemsForGeraet($device['geraet_id'], 200);
}
unset($device);
}
$search_time = (microtime(true) - $start_time) * 1000;
// Rechts: Artikel-/Ersatzteil-Suche (MySQL)
$start_time2 = microtime(true);
$item_results = $db->searchItems($search_term, 20);
$item_search_time = (microtime(true) - $start_time2) * 1000;
// --- Hersteller-Filter (kommt aus der Hersteller-Rueckfrage) ---
if ($v2_marke !== '') {
$results = array_values(array_filter($results, function ($d) use ($v2_marke) {
return isset($d['marke']) && trim($d['marke']) === $v2_marke;
}));
}
// --- Stufe 1: muss erst der Hersteller geklaert werden? ---
// Dasselbe Modell laeuft oft unter mehreren Konzern-/Versandhausmarken. Dann haben
// alle Top-Treffer denselben Score und denselben Modellnamen -- eine Bestaetigung
// waere geraten. Der Hersteller steht dem Kunden aber auf dem Typenschild zur
// Verfuegung, also fragen wir zuerst danach. Beispiel MUFF21VLQS: 10x Score 100
// ueber AEG, Electrolux, Frigidaire, Gibson.
if (count($results) > 1) {
$top_score = (int)$results[0]['score'];
$topgroup = array_filter($results, function ($d) use ($top_score) {
return (int)$d['score'] === $top_score;
});
$brands = [];
$models = [];
foreach ($topgroup as $d) {
$m = trim($d['marke'] ?? '');
if ($m !== '') { $brands[$m] = ($brands[$m] ?? 0) + 1; }
$models[mb_strtolower(trim($d['modell_bezeichnung'] ?? ''))] = true;
}
// Nur fragen, wenn es wirklich EIN Modell bei MEHREREN Marken ist.
if (count($brands) > 1 && count($models) === 1) {
arsort($brands);
$v2_brandpick = $brands;
}
// --- Stufe 1b: Varianten-Auswahl (BSH-Bauzustaende) ---
// SIEMENS/BOSCH haengen "/01", "/02" ... an die Typnummer in nr. Laesst der Kunde
// das Suffix weg ("WT46W560BY"), kommen alle Bauzustaende mit gleichem Score
// zurueck und unterscheiden sich NUR im Produktionszeitraum. Dann fragen wir
// danach, statt zehn optisch identische Zeilen zu zeigen.
if (!$v2_brandpick) {
$basis = [];
foreach ($topgroup as $d) {
$n = trim($d['nr'] ?? '');
$basis[($p = strpos($n, '/')) !== false ? substr($n, 0, $p) : $n] = true;
}
if (count($basis) === 1 && count($topgroup) > 1 && count($brands) <= 1) {
$v2_variant_base = (string)array_key_first($basis);
// Nur wenn die Treffer wirklich Suffix-Varianten sind, nicht zufaellig
// gleichnamige Geraete: mindestens einer muss ein "/" tragen.
$has_suffix = false;
foreach ($topgroup as $d) { if (strpos((string)($d['nr'] ?? ''), '/') !== false) { $has_suffix = true; break; } }
if ($has_suffix) {
$det_batch = $db->getGeraetDetailsBatch(array_column($topgroup, 'geraet_id'));
foreach ($topgroup as $d) {
$det = $det_batch[$d['geraet_id']] ?? [];
$v2_variants[] = [
'nr' => (string)($d['nr'] ?? ''),
'id' => $d['geraet_id'],
'von' => $det['produktionsstart'] ?? '',
'bis' => $det['produktionsende'] ?? '',
'typ_de'=> $det['typ_de'] ?? '',
'marke' => $d['marke'] ?? '',
];
}
usort($v2_variants, function ($a, $b) { return strcmp($a['nr'], $b['nr']); });
}
}
}
}
// --- Stufe 2: gibt es EINEN klaren Top-Treffer? ---
// Nur dann darf man "Das ist dein Geraet" behaupten. Bedingung: Top-Score >= 95
// UND mindestens 10 Punkte Abstand zum Zweiten. Beispiel "Lavatherm 400": 100 vs. 75.
// Entfaellt, solange die Hersteller-Frage offen ist.
if (!$v2_brandpick && !$v2_variants && count($results) > 0) {
$v2_top_score_raw = (int)$results[0]['score'];
$v2_second_raw = isset($results[1]) ? (int)$results[1]['score'] : 0;
if ($v2_top_score_raw >= 95 && ($v2_top_score_raw - $v2_second_raw) >= 10) {
$v2_guided = true;
$v2_top_detail = $db->getGeraetDetails($results[0]['geraet_id']);
}
}
// --- Shop-Links fuer die Ersatzteil-Chips ---
// Die Chips kommen aus PostgreSQL und kennen nur navision_id. Damit sie -- wie die
// Artikel weiter unten -- in den Shop verlinken, wird einmalig gesammelt aufgeloest.
// Nur die tatsaechlich gerenderten (max. 10 je Geraet), sonst waeren es Tausende.
if ($results) {
$nav_ids = [];
foreach ($results as $d) {
foreach (array_slice($d['ersatzteile'] ?? [], 0, 10) as $p) {
if (!empty($p['navision_id'])) { $nav_ids[] = $p['navision_id']; }
}
}
if ($nav_ids) { $v2_shopmap = $db->getShopItemsByNavisionIds($nav_ids); }
}
}
} catch (Exception $e) {
$error_message = $e->getMessage();
}
?>
Krempl PostgreSQL Search Test
Krempl PostgreSQL Search Test
Fehler bei der Datenbankverbindung:
Geräte (PostgreSQL)
— Treffer
( ms)
Keine Geräte gefunden.
= 100) $score_class = 'score-100';
elseif ($score >= 95) $score_class = 'score-95';
elseif ($score >= 90) $score_class = 'score-90';
elseif ($score >= 80) $score_class = 'score-80';
elseif ($score >= 75) $score_class = 'score-75';
elseif ($score >= 60) $score_class = 'score-60';
?>
0): ?>
Verfügbare Shop-Artikel:
verfügbar
| Artikel-Nr |
Artikelname |
Navision-ID |
Lagerbestand |
|
|
|
Stück |
Keine verfügbaren Shop-Artikel gefunden
0): ?>
Passende Ersatzteile (Krempl):
gesamt
| Navision ID |
Krempl ID |
Originalnummer |
Marke |
|
|
|
|
Keine Ersatzteile gefunden
Ersatzteile / Artikel (MySQL items)
— Treffer
( ms)
Keine Artikel gefunden.
= htmlspecialchars($item['name']) ?>
Art-Nr: = htmlspecialchars($item['number']) ?>
· Navision: = htmlspecialchars($item['matched_navision_id']) ?>
· Lager:
k.A.';
} elseif ((int)$inv > 0) {
echo '' . (int)$inv . ' Stk';
} else {
echo '0';
}
?>
Jahr. In produktionsstart/-ende stecken ZWEI Formate:
* YYYYMMDD z.B. "19790101" (AEG Lavatherm 400)
* YYMM z.B. "8810" (SIEMENS WT46W560BY/01 = Oktober 1988)
* Bei YYMM gilt: >= 70 -> 19YY, sonst 20YY.
*/
function v2_jahr4($v) {
$s = preg_replace('/\D/', '', (string)$v);
if ($s === '') return '';
if (strlen($s) >= 6) return substr($s, 0, 4); // YYYYMM(DD)
if (strlen($s) === 4) { // YYMM
$yy = (int)substr($s, 0, 2);
return (string)($yy >= 70 ? 1900 + $yy : 2000 + $yy);
}
if (strlen($s) === 2) { // nur YY
$yy = (int)$s;
return (string)($yy >= 70 ? 1900 + $yy : 2000 + $yy);
}
return '';
}
/** Monat/Jahr fuer die Variantenliste, z.B. "10/1988". Leer, wenn nicht ableitbar. */
function v2_monat($v) {
$s = preg_replace('/\D/', '', (string)$v);
$j = v2_jahr4($s);
if ($j === '') return '';
if (strlen($s) >= 6) $m = substr($s, 4, 2); // YYYYMM(DD)
elseif (strlen($s) === 4) $m = substr($s, 2, 2); // YYMM
else return $j;
$m = (int)$m;
return ($m >= 1 && $m <= 12) ? sprintf('%02d/%s', $m, $j) : $j;
}
function v2_confidence($score) {
$s = (int)$score;
if ($s >= 100) return ['Exakter Treffer', '#2e7d32', '#e8f5e9', '✓'];
if ($s >= 90) return ['Sehr wahrscheinlich dein Gerät','#388e3c', '#edf7ee', '✓'];
if ($s >= 75) return ['Könnte passen', '#f9a825', '#fff8e1', '≈'];
return ['Ähnlich – bitte prüfen', '#9e9e9e', '#f5f5f5', '?'];
}
// nml/Nachfolger steckt im Artikelnamen: "(nml)"/"(nmle)" + "Nachfolger
"
function v2_nml_info($name) {
$is_nml = (bool)preg_match('/\(nml[e]?\)/i', $name);
$nachf = null;
// Nachfolger-Nummer muss mind. eine Ziffer enthalten (schließt "Nachfolger Original" aus)
if (preg_match('/Nachfolger\s+([A-Za-z0-9\-\/\.]*\d[A-Za-z0-9\-\/\.]*)/i', $name, $m)) {
$nachf = $m[1];
}
$kein_ersatz = (stripos($name, 'kein Ersatz') !== false);
// Anzeigename säubern: (nml)-Marker + "Nachfolger ... Original(teil)" raus
$clean = preg_replace('/\s*\(nml[e]?\)\s*/i', ' ', $name);
$clean = preg_replace('/\s*Nachfolger\s+[A-Za-z0-9\-\/\.]*\d[A-Za-z0-9\-\/\.]*\s*/i', ' ', $clean);
$clean = preg_replace('/\s*(Originalteil|Original)\s*$/i', '', $clean);
$clean = trim(preg_replace('/\s{2,}/', ' ', $clean));
return ['is_nml'=>$is_nml, 'nachfolger'=>$nachf, 'kein_ersatz'=>$kein_ersatz, 'clean'=>($clean ?: $name)];
}
}
// Treffer in "stark" (>=75) und "schwach" (<75) teilen
$v2_strong = []; $v2_weak = [];
foreach ($results as $d) { ((int)$d['score'] >= 75) ? $v2_strong[] = $d : $v2_weak[] = $d; }
// Artikel klassifizieren: kaufbar / ausgelaufen-mit-Nachfolger / tot
$g_buy = []; $g_succ = []; $g_dead = [];
foreach ($item_results as $it) {
$it['_nml'] = v2_nml_info($it['name']);
if (!$it['_nml']['is_nml']) $g_buy[] = $it; // regulär
elseif ($it['_nml']['nachfolger']) $g_succ[] = $it; // ausgelaufen, Nachfolger da
else $g_dead[] = $it; // ausgelaufen, kein Ersatz
}
$v2_top_score = isset($results[0]) ? (int)$results[0]['score'] : 0;
// Intent-Einordnung
if ($v2_top_score >= 90) $v2_headline = 'Wir haben dein Gerät gefunden.';
elseif (count($v2_strong) > 0) $v2_headline = 'Das könnte dein Gerät sein:';
elseif (count($item_results)) $v2_headline = 'Passende Artikel gefunden:';
else $v2_headline = 'Mehrere mögliche Treffer – grenz gern ein.';
?>
◇ Variante B – geführte Ansicht (Prototyp)
passende Geräte
· kaufbare Artikel
Mehrere Hersteller führen dieses Modell
Welcher Hersteller steht auf deinem Gerät?
Der Hersteller steht meist auf dem Typenschild oder als Logo auf der Blende.
Dieses Modell gibt es in mehreren Bauzuständen
· Varianten
Wann wurde dein Gerät gebaut? Die Nummer auf dem Typenschild endet auf
/01, /02 … – wenn du sie findest, ist das der schnellste Weg.
Ist das dein Gerät?
✓ Sofort erhältlich für dieses Gerät ():
·
passende Ersatzteile — Auswahl:
10): ?>
+ weitere
count($a); });
$v2_list = [];
foreach ($by_marke as $m => $ds) {
$v2_mcount[$m] = count($ds);
foreach ($ds as $d) { $d['_mgroup'] = $m; $v2_list[] = $d; }
}
}
?>
$d):
list($clabel,$ccol,$cbg,$cicon) = v2_confidence($d['score']);
$parts = $d['ersatzteile'] ?? [];
$buy = $d['shop_items'] ?? null; // nur wenn shop_items-Toggle an
if (!$v2_alt_open && ($v2_guided && $v2_top_detail)) {
echo '
Nicht mein Gerät – '
. $v2_alt_total . ' weitere Treffer anzeigen
';
$v2_alt_open = true;
}
// Bei der Varianten-Karte stehen dieselben Geraete schon als Buttons oben --
// die ausfuehrliche Liste (mit Ersatzteilen) deshalb ebenfalls einklappen.
if (!$v2_alt_open && $v2_variants) {
echo 'Alle '
. count($v2_variants) . ' Bauzustände mit Ersatzteilen anzeigen
';
$v2_alt_open = true;
}
// Dito bei der Hersteller-Rueckfrage: erst die Marke klaeren, die Rohliste
// (oft 20 optisch identische Kacheln) gehoert dahinter.
if (!$v2_alt_open && $v2_brandpick) {
echo 'Alle '
. count($results) . ' Treffer ungefiltert anzeigen
';
$v2_alt_open = true;
}
if (isset($d['_mgroup']) && $d['_mgroup'] !== $v2_last_mgroup) {
$v2_last_mgroup = $d['_mgroup'];
echo ''.htmlspecialchars($v2_last_mgroup)
. ' '.(int)($v2_mcount[$v2_last_mgroup] ?? 0).'
';
}
?>
✓ Sofort erhältlich für dieses Gerät ():
·
0) echo '· '.(int)$b['inventory'].' Stk'; ?>
passende Ersatzteile — Auswahl:
10): ?>
+ weitere
Weitere mögliche Geräte anzeigen () – schwächere Treffer
'; }
?>
🛒 Diese Artikel kannst du direkt kaufen
0 -- 10.160x 0, 8.724x NULL).
// Bestellbar steuert sie ueber items.active, und searchItems() filtert
// bereits mit WHERE i.active = 1 -> alles hier ist bestellbar.
// Shop-Artikel und Bilder liegen nur auf LIVE -> absolute URLs
$url = 'https://intelectra.de/index.php?item_id=' . (int)$it['id'];
$img = !empty($it['default_image_file_name'])
? 'https://intelectra.de/web/intelectra_shop/images/article/'.rawurlencode($it['default_image_file_name'])
: '';
$pb = isset($it['price_brutto']) ? (float)$it['price_brutto'] : 0;
$bb = !empty($it['bargain_brutto']) ? (float)$it['bargain_brutto'] : 0;
?>
kein Bild
0 && $pb > 0 && $bb < $pb): ?>
€
€
0): ?>
€
Preis auf Anfrage
0): ?>
inkl. MwSt.
Zum Artikel
🔄 Ausgelaufen – aber es gibt einen Nachfolger
Art-Nr · nicht mehr lieferbar
Nicht mehr lieferbar, kein Ersatz () – ausgeblendet
💡 Prototyp-Notiz (nicht final): Bild (aus items.default_image_file_name, geladen vom Live-Server)
+ Preis (item_prices Kundengruppe 1, brutto inkl. Steuersatz, Angebotspreis rot) sind jetzt drin.
nml/Nachfolger ist jetzt live: Der Marker (nml)/(nmle) im Artikelnamen wird erkannt —
ausgelaufene Teile mit „Nachfolger <Nr>" landen im orangen Block und verlinken per Klick auf den kaufbaren Nachfolger;
Teile ohne Ersatz werden ans Ende ausgeblendet. Score-Zahlen durch Vertrauens-Text ersetzt.
Tipp: oben „Nur verfügbare Shop-Artikel" aktivieren zeigt pro Gerät die kaufbaren Teile grün.
Gib einen Suchbegriff ein (z.B. "AWB 921 PH", "ZCS 2100B", "Kohlefilter Bauknecht")