Files
shop-old/tba-search.php.bak_20260730_lagerfix
T

817 lines
38 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Krempl PostgreSQL Search Test Interface
* Search for devices and show matching ersatzteile
*/
require_once __DIR__ . '/core/postgres/KremplDB.php';
$search_term = isset($_GET['q']) ? trim($_GET['q']) : '';
$results = [];
$item_results = [];
$search_time = 0;
$item_search_time = 0;
$error_message = '';
$show_shop_items = isset($_GET['shop_items']) && $_GET['shop_items'] === '1';
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;
}
} catch (Exception $e) {
$error_message = $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Krempl PostgreSQL Search Test</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: #f5f5f5;
padding: 20px;
}
.container {
max-width: 1600px;
margin: 0 auto;
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.split-results {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
margin-top: 20px;
}
.split-results > div {
min-width: 0;
}
.split-results h2 {
font-size: 16px;
color: #444;
background: #f4f4f4;
padding: 10px 14px;
border-left: 4px solid #4CAF50;
margin-bottom: 14px;
}
.split-results .right-pane h2 {
border-left-color: #1976D2;
}
.item-card {
border: 1px solid #e0e0e0;
border-radius: 4px;
margin-bottom: 8px;
padding: 10px 12px;
background: #fafafa;
font-size: 13px;
}
.item-card .item-name {
font-weight: 600;
color: #333;
margin-bottom: 4px;
}
.item-card .item-meta {
color: #666;
font-size: 12px;
}
.item-card .item-meta strong {color:#1976D2;}
.inventory-positive {color:#2e7d32;font-weight:bold;}
.inventory-zero {color:#aaa;}
.inventory-null {color:#aaa;font-style:italic;}
@media (max-width: 900px) {
.split-results { grid-template-columns: 1fr; }
}
h1 {
color: #333;
margin-bottom: 20px;
}
.search-box {
margin-bottom: 30px;
}
.search-input {
width: 100%;
padding: 12px 15px;
font-size: 16px;
border: 2px solid #ddd;
border-radius: 4px;
transition: border-color 0.3s;
}
.search-input:focus {
outline: none;
border-color: #4CAF50;
}
.search-btn {
padding: 10px 20px;
background: #4CAF50;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
transition: background 0.3s;
white-space: nowrap;
}
.search-btn:hover {
background: #45a049;
}
#shopItemsToggle {
cursor: pointer;
width: 18px;
height: 18px;
}
.search-info {
color: #666;
margin-bottom: 20px;
font-size: 14px;
}
.device-card {
border: 1px solid #e0e0e0;
border-radius: 4px;
margin-bottom: 20px;
background: #fafafa;
overflow: hidden;
}
.device-card.collapsed .ersatzteile-section {
display: none;
}
.device-header {
display: flex;
justify-content: space-between;
align-items: start;
padding: 15px;
margin-bottom: 0;
border-bottom: 2px solid #e0e0e0;
}
.score-badge {
cursor: pointer;
transition: all 0.2s;
user-select: none;
}
.score-badge:hover {
opacity: 0.9;
transform: scale(1.02);
}
.toggle-arrow {
display: inline-block;
margin-left: 8px;
transition: transform 0.3s;
font-size: 10px;
}
.device-card.collapsed .toggle-arrow {
transform: rotate(-90deg);
}
.device-info {
flex: 1;
}
.device-title {
font-size: 18px;
font-weight: bold;
color: #333;
margin-bottom: 5px;
}
.device-title a {
color: #333;
text-decoration: none;
transition: color 0.2s;
}
.device-title a:hover {
color: #4CAF50;
text-decoration: underline;
}
.device-details {
color: #666;
font-size: 14px;
}
.device-details span {
display: inline-block;
margin-right: 15px;
}
.score-badge {
display: inline-block;
padding: 5px 12px;
border-radius: 20px;
font-weight: bold;
font-size: 14px;
}
.score-100 { background: #4CAF50; color: white; }
.score-95 { background: #66BB6A; color: white; }
.score-90 { background: #81C784; color: white; }
.score-80 { background: #FFC107; color: white; }
.score-75 { background: #FFD54F; color: #333; }
.score-60 { background: #FFE082; color: #333; }
.score-default { background: #BDBDBD; color: white; }
.ersatzteile-section {
padding: 15px;
}
.ersatzteile-title {
font-weight: bold;
color: #333;
margin-bottom: 10px;
margin-top: 10px;
font-size: 14px;
}
.ersatzteile-table {
width: 100%;
border-collapse: collapse;
background: white;
border-radius: 4px;
overflow: hidden;
}
.ersatzteile-table th {
background: #f0f0f0;
padding: 8px;
text-align: left;
font-size: 13px;
font-weight: 600;
color: #555;
}
.ersatzteile-table td {
padding: 8px;
border-top: 1px solid #e0e0e0;
font-size: 13px;
}
.ersatzteile-table tr:hover {
background: #f9f9f9;
}
.navision-id {
font-weight: bold;
color: #1976D2;
}
.no-results {
text-align: center;
padding: 40px;
color: #999;
}
.match-type {
display: inline-block;
font-size: 11px;
padding: 2px 6px;
background: #e0e0e0;
border-radius: 3px;
color: #666;
margin-left: 8px;
}
.error-message {
background: #ffebee;
border: 1px solid #ef5350;
color: #c62828;
padding: 15px;
border-radius: 4px;
margin-bottom: 20px;
}
.error-message strong {
display: block;
margin-bottom: 5px;
}
</style>
</head>
<body>
<div class="container">
<h1>Krempl PostgreSQL Search Test</h1>
<div class="search-box">
<form method="GET" action="" id="searchForm">
<input
type="text"
name="q"
class="search-input"
placeholder="Gerätesuche (z.B. AWB 921 PH, ZCS 2100B, 2100B)"
value="<?php echo htmlspecialchars($search_term); ?>"
autofocus
/>
<div style="margin-top: 10px; display: flex; align-items: center; gap: 15px;">
<button type="submit" class="search-btn">Suchen</button>
<label style="font-size: 14px; cursor: pointer; display: flex; align-items: center; gap: 5px;">
<input type="checkbox" name="shop_items" value="1" <?php echo $show_shop_items ? 'checked' : ''; ?> id="shopItemsToggle" onchange="document.getElementById('searchForm').submit();">
<span>Nur verfügbare Shop-Artikel (MySQL)</span>
</label>
</div>
</form>
</div>
<?php if ($error_message): ?>
<div class="error-message">
<strong>Fehler bei der Datenbankverbindung:</strong>
<?php echo htmlspecialchars($error_message); ?>
</div>
<?php endif; ?>
<?php if ($search_term !== '' && !$error_message): ?>
<div class="split-results">
<!-- LINKS: Geräte-Suche (PostgreSQL) -->
<div class="left-pane">
<h2>Geräte (PostgreSQL)
— <?php echo count($results); ?> Treffer
(<?php echo number_format($search_time, 0); ?>&thinsp;ms)
</h2>
<?php if (count($results) === 0): ?>
<div class="no-results" style="padding:20px;">
Keine Geräte gefunden.
</div>
<?php endif; ?>
<?php foreach ($results as $device): ?>
<?php
$score = (int)$device['score'];
$score_class = 'score-default';
if ($score >= 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';
?>
<div class="device-card collapsed" id="device-<?php echo $device['geraet_id']; ?>">
<div class="device-header">
<div class="device-info">
<div class="device-title">
<a href="geraet.php?id=<?php echo $device['geraet_id']; ?>&q=<?php echo urlencode($search_term); ?><?php echo $show_shop_items ? '&shop_items=1' : ''; ?>" style="color: #333; text-decoration: none;">
<?php echo htmlspecialchars($device['modell_bezeichnung']); ?>
</a>
<span class="match-type"><?php echo htmlspecialchars($device['match_type']); ?></span>
</div>
<div class="device-details">
<span><strong>Marke:</strong> <?php echo htmlspecialchars($device['marke']); ?></span>
<span><strong>Typ:</strong> <?php echo htmlspecialchars($device['typ']); ?></span>
<span><strong>Nr:</strong> <?php echo htmlspecialchars($device['nr']); ?></span>
<span><strong>ID:</strong> <?php echo htmlspecialchars($device['geraet_id']); ?></span>
</div>
</div>
<div>
<span class="score-badge <?php echo $score_class; ?>" onclick="toggleDevice(<?php echo $device['geraet_id']; ?>)">
Score: <?php echo $score; ?>
<span class="toggle-arrow">▼</span>
</span>
</div>
</div>
<?php if ($show_shop_items && isset($device['shop_items'])): ?>
<!-- Show available shop items -->
<?php if (count($device['shop_items']) > 0): ?>
<div class="ersatzteile-section">
<div class="ersatzteile-title">
Verfügbare Shop-Artikel:
<span style="background: #4CAF50; color: white; padding: 3px 10px; border-radius: 12px; font-weight: bold; margin-left: 5px;">
<?php echo count($device['shop_items']); ?> verfügbar
</span>
</div>
<table class="ersatzteile-table">
<thead>
<tr>
<th>Artikel-Nr</th>
<th>Artikelname</th>
<th>Navision-ID</th>
<th>Lagerbestand</th>
</tr>
</thead>
<tbody>
<?php foreach ($device['shop_items'] as $item): ?>
<tr>
<td><?php echo htmlspecialchars($item['number']); ?></td>
<td><?php echo htmlspecialchars($item['name']); ?></td>
<td class="navision-id"><?php echo htmlspecialchars($item['matched_navision_id']); ?></td>
<td><?php echo (int)$item['inventory']; ?> Stück</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="ersatzteile-section">
<div class="ersatzteile-title" style="color: #999;">
Keine verfügbaren Shop-Artikel gefunden
</div>
</div>
<?php endif; ?>
<?php else: ?>
<!-- Show all Krempl ersatzteile -->
<?php if (count($device['ersatzteile']) > 0): ?>
<div class="ersatzteile-section">
<div class="ersatzteile-title">
Passende Ersatzteile (Krempl):
<span style="background: #2196F3; color: white; padding: 3px 10px; border-radius: 12px; font-weight: bold; margin-left: 5px;">
<?php echo count($device['ersatzteile']); ?> gesamt
</span>
</div>
<table class="ersatzteile-table">
<thead>
<tr>
<th>Navision ID</th>
<th>Krempl ID</th>
<th>Originalnummer</th>
<th>Marke</th>
</tr>
</thead>
<tbody>
<?php foreach ($device['ersatzteile'] as $ers): ?>
<tr>
<td class="navision-id"><?php echo htmlspecialchars($ers['navision_id']); ?></td>
<td><?php echo htmlspecialchars($ers['krempl_id']); ?></td>
<td><?php echo htmlspecialchars($ers['originalnummer']); ?></td>
<td><?php echo htmlspecialchars($ers['marke']); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="ersatzteile-section">
<div class="ersatzteile-title" style="color: #999;">
Keine Ersatzteile gefunden
</div>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div><!-- /left-pane -->
<!-- RECHTS: Artikel-/Ersatzteil-Suche (MySQL) -->
<div class="right-pane">
<h2>Ersatzteile / Artikel (MySQL items)
— <?php echo count($item_results); ?> Treffer
(<?php echo number_format($item_search_time, 0); ?>&thinsp;ms)
</h2>
<?php if (count($item_results) === 0): ?>
<div class="no-results" style="padding:20px;">
Keine Artikel gefunden.
</div>
<?php else: ?>
<?php foreach ($item_results as $item): ?>
<div class="item-card">
<div class="item-name"><?= htmlspecialchars($item['name']) ?></div>
<div class="item-meta">
Art-Nr: <strong><?= htmlspecialchars($item['number']) ?></strong>
· Navision: <strong><?= htmlspecialchars($item['matched_navision_id']) ?></strong>
· Lager:
<?php
$inv = $item['inventory'];
if ($inv === null) {
echo '<span class="inventory-null">k.A.</span>';
} elseif ((int)$inv > 0) {
echo '<span class="inventory-positive">' . (int)$inv . ' Stk</span>';
} else {
echo '<span class="inventory-zero">0</span>';
}
?>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div><!-- /right-pane -->
</div><!-- /split-results -->
<?php
// ==================================================================
// A/B – NEUE DARSTELLUNG (Prototyp, geführte Ergebnis-Ansicht)
// Nutzt dieselben Daten ($results / $item_results), nur menschlich.
// ==================================================================
if (!function_exists('v2_confidence')) {
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 <Nr>"
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.';
?>
<hr style="margin:40px 0 0; border:none; border-top:3px dashed #cfcfcf;">
<style>
.v2{margin-top:24px;font-size:15px}
.v2 .v2-flag{display:inline-block;background:#111;color:#fff;font-size:11px;font-weight:700;
letter-spacing:.5px;padding:3px 10px;border-radius:4px;text-transform:uppercase}
.v2 .v2-head{font-size:22px;font-weight:700;color:#222;margin:14px 0 4px}
.v2 .v2-sub{color:#777;font-size:13px;margin-bottom:22px}
.v2-dev{border:1px solid #e3e3e3;border-radius:10px;margin-bottom:16px;overflow:hidden;
box-shadow:0 1px 3px rgba(0,0,0,.05)}
.v2-dev-top{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;
padding:16px 18px;background:#fff}
.v2-dev-name{font-size:18px;font-weight:700;color:#1a1a1a;line-height:1.3}
.v2-dev-meta{color:#666;font-size:13px;margin-top:5px}
.v2-dev-meta b{color:#444}
.v2-conf{white-space:nowrap;font-size:12px;font-weight:700;padding:6px 12px;border-radius:20px}
.v2-parts{padding:14px 18px;border-top:1px solid #f0f0f0;background:#fcfcfc}
.v2-parts h4{font-size:13px;color:#555;margin-bottom:9px;font-weight:600}
.v2-chip{display:inline-block;background:#fff;border:1px solid #e0e0e0;border-radius:16px;
padding:4px 11px;margin:0 5px 6px 0;font-size:12px;color:#444}
.v2-chip b{color:#1565c0}
.v2-buy{background:#e8f5e9;border-color:#c8e6c9}
.v2-more{margin:6px 0 22px}
.v2-more summary{cursor:pointer;color:#1565c0;font-size:14px;padding:8px 0}
.v2-shop{margin-top:30px}
.v2-shop h3{font-size:16px;color:#333;margin-bottom:12px;border-left:4px solid #1976D2;padding-left:10px}
.v2-item{display:flex;justify-content:space-between;align-items:center;gap:14px;
border:1px solid #eee;border-radius:8px;padding:12px 15px;margin-bottom:8px;background:#fff}
.v2-item-name{font-weight:600;color:#222}
.v2-item-meta{color:#888;font-size:12px;margin-top:3px}
.v2-stock{white-space:nowrap;font-size:13px;font-weight:700}
.v2-in{color:#2e7d32}.v2-out{color:#c62828}.v2-na{color:#aaa;font-style:italic;font-weight:400}
.v2-cart{background:#4CAF50;color:#fff;border:none;border-radius:6px;padding:8px 14px;
font-size:13px;font-weight:600;cursor:pointer;white-space:nowrap}
.v2-cart:disabled{background:#ccc;cursor:not-allowed}
.v2-hint{background:#fffdf3;border:1px dashed #e6d9a8;border-radius:8px;padding:10px 14px;
font-size:12px;color:#8a7a3a;margin-top:20px}
</style>
<div class="v2">
<span class="v2-flag">◇ Variante B – geführte Ansicht (Prototyp)</span>
<div class="v2-head"><?php echo htmlspecialchars($v2_headline); ?></div>
<div class="v2-sub">
<?php echo count($v2_strong); ?> passende Geräte
· <?php echo count($g_buy); ?> kaufbare Artikel
<?php if (count($g_succ)) echo ' · '.count($g_succ).' mit Nachfolger'; ?>
<?php if (count($g_dead)) echo ' · '.count($g_dead).' ausgelaufen'; ?>
<?php if (count($v2_weak)) echo ' · '.count($v2_weak).' weitere mögliche Geräte'; ?>
</div>
<?php foreach ($v2_strong as $i => $d):
list($clabel,$ccol,$cbg,$cicon) = v2_confidence($d['score']);
$parts = $d['ersatzteile'] ?? [];
$buy = $d['shop_items'] ?? null; // nur wenn shop_items-Toggle an
?>
<div class="v2-dev">
<div class="v2-dev-top">
<div>
<div class="v2-dev-name"><?php echo htmlspecialchars($d['marke'].' '.$d['modell_bezeichnung']); ?></div>
<div class="v2-dev-meta">
<b>Typ:</b> <?php echo htmlspecialchars($d['typ']); ?>
· <b>Nr:</b> <?php echo htmlspecialchars($d['nr']); ?>
<?php if (!empty($d['produktionsstart']) || !empty($d['produktionsende'])): ?>
· <b>Baujahr:</b> <?php echo htmlspecialchars(trim(($d['produktionsstart']??'').'–'.($d['produktionsende']??''),'–')); ?>
<?php endif; ?>
</div>
</div>
<span class="v2-conf" style="color:<?php echo $ccol; ?>;background:<?php echo $cbg; ?>;">
<?php echo $cicon.' '.htmlspecialchars($clabel); ?>
</span>
</div>
<?php if ($buy && count($buy)): ?>
<div class="v2-parts">
<h4>✓ Sofort erhältlich für dieses Gerät (<?php echo count($buy); ?>):</h4>
<?php foreach (array_slice($buy,0,8) as $b): ?>
<span class="v2-chip v2-buy"><b><?php echo htmlspecialchars($b['number']); ?></b>
· <?php echo htmlspecialchars(mb_strimwidth($b['name'],0,42,'…')); ?>
<?php if ((int)$b['inventory']>0) echo '· '.(int)$b['inventory'].' Stk'; ?></span>
<?php endforeach; ?>
</div>
<?php elseif (count($parts)): ?>
<div class="v2-parts">
<h4><?php echo count($parts); ?> passende Ersatzteile — Auswahl:</h4>
<?php foreach (array_slice($parts,0,10) as $p): ?>
<span class="v2-chip"><b><?php echo htmlspecialchars($p['originalnummer']); ?></b>
<?php if (!empty($p['marke'])) echo '· '.htmlspecialchars($p['marke']); ?></span>
<?php endforeach; ?>
<?php if (count($parts) > 10): ?>
<span class="v2-chip" style="border-style:dashed;color:#999;">+<?php echo count($parts)-10; ?> weitere</span>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php if (count($v2_weak)): ?>
<details class="v2-more">
<summary>Weitere mögliche Geräte anzeigen (<?php echo count($v2_weak); ?>) – schwächere Treffer</summary>
<?php foreach ($v2_weak as $d): list($clabel,$ccol,$cbg,$cicon)=v2_confidence($d['score']); ?>
<div class="v2-dev" style="opacity:.75">
<div class="v2-dev-top">
<div>
<div class="v2-dev-name" style="font-size:15px"><?php echo htmlspecialchars($d['marke'].' '.$d['modell_bezeichnung']); ?></div>
<div class="v2-dev-meta"><b>Typ:</b> <?php echo htmlspecialchars($d['typ']); ?> · <b>Nr:</b> <?php echo htmlspecialchars($d['nr']); ?></div>
</div>
<span class="v2-conf" style="color:<?php echo $ccol; ?>;background:<?php echo $cbg; ?>;"><?php echo $cicon.' '.htmlspecialchars($clabel); ?></span>
</div>
</div>
<?php endforeach; ?>
</details>
<?php endif; ?>
<?php $keep_shop = $show_shop_items ? '&shop_items=1' : ''; ?>
<?php if (count($g_buy)): ?>
<div class="v2-shop">
<h3>🛒 Diese Artikel kannst du direkt kaufen</h3>
<?php foreach ($g_buy as $it):
$inv = $it['inventory'];
$can = ($inv !== null && (int)$inv > 0);
// Bilder liegen nur auf LIVE → absolute URL
$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;
?>
<div class="v2-item">
<div style="display:flex;align-items:center;gap:14px;min-width:0">
<?php if ($img): ?>
<img src="<?php echo $img; ?>" alt="" loading="lazy"
style="width:64px;height:64px;object-fit:contain;background:#fff;border:1px solid #eee;border-radius:6px;flex:0 0 64px"
onerror="this.style.display='none'">
<?php else: ?>
<div style="width:64px;height:64px;flex:0 0 64px;background:#f5f5f5;border:1px dashed #ddd;border-radius:6px;
display:flex;align-items:center;justify-content:center;color:#bbb;font-size:11px">kein Bild</div>
<?php endif; ?>
<div style="min-width:0">
<div class="v2-item-name"><?php echo htmlspecialchars($it['_nml']['clean']); ?></div>
<div class="v2-item-meta">Art-Nr <?php echo htmlspecialchars($it['number']); ?></div>
</div>
</div>
<div style="text-align:right;flex:0 0 auto">
<div style="font-size:17px;font-weight:700;color:#1a1a1a;margin-bottom:2px">
<?php if ($bb > 0 && $pb > 0 && $bb < $pb): ?>
<span style="color:#c62828"><?php echo number_format($bb, 2, ',', '.'); ?>&nbsp;€</span>
<span style="font-size:12px;color:#999;text-decoration:line-through;font-weight:400"><?php echo number_format($pb, 2, ',', '.'); ?>&nbsp;€</span>
<?php elseif ($pb > 0): ?>
<?php echo number_format($pb, 2, ',', '.'); ?>&nbsp;€
<?php else: ?>
<span style="font-size:12px;color:#999;font-weight:400">Preis auf Anfrage</span>
<?php endif; ?>
</div>
<?php if ($pb > 0): ?><div style="font-size:10px;color:#aaa;margin-bottom:4px">inkl. MwSt.</div><?php endif; ?>
<div class="v2-stock <?php echo $inv===null?'v2-na':($can?'v2-in':'v2-out'); ?>">
<?php echo $inv===null ? 'Lager k.A.' : ($can ? '● '.(int)$inv.' ab Lager' : '○ nicht am Lager'); ?>
</div>
<button class="v2-cart" <?php echo $can?'':'disabled'; ?> style="margin-top:6px">
<?php echo $can ? 'In den Warenkorb' : 'Bestellbar'; ?>
</button>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if (count($g_succ)): ?>
<div class="v2-shop">
<h3 style="border-left-color:#fb8c00">🔄 Ausgelaufen – aber es gibt einen Nachfolger</h3>
<?php foreach ($g_succ as $it): $nf = $it['_nml']['nachfolger']; ?>
<div class="v2-item" style="background:#fff8f0;border-color:#ffe0b2">
<div>
<div class="v2-item-name" style="color:#8a6d3b;text-decoration:line-through;text-decoration-color:#d9b38c">
<?php echo htmlspecialchars($it['_nml']['clean']); ?>
</div>
<div class="v2-item-meta">Art-Nr <?php echo htmlspecialchars($it['number']); ?> · nicht mehr lieferbar</div>
</div>
<div style="text-align:right">
<div style="font-size:12px;color:#e65100;font-weight:600;margin-bottom:6px">Nachfolger: <?php echo htmlspecialchars($nf); ?></div>
<a href="?q=<?php echo urlencode($nf).$keep_shop; ?>"
class="v2-cart" style="background:#fb8c00;text-decoration:none;display:inline-block">
→ Nachfolger anzeigen
</a>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if (count($g_dead)): ?>
<details class="v2-more" style="margin-top:20px">
<summary>Nicht mehr lieferbar, kein Ersatz (<?php echo count($g_dead); ?>) – ausgeblendet</summary>
<?php foreach ($g_dead as $it): ?>
<div class="v2-item" style="opacity:.55">
<div>
<div class="v2-item-name" style="text-decoration:line-through"><?php echo htmlspecialchars($it['_nml']['clean']); ?></div>
<div class="v2-item-meta">Art-Nr <?php echo htmlspecialchars($it['number']); ?></div>
</div>
<div class="v2-stock v2-out" style="white-space:nowrap">✕ entfällt</div>
</div>
<?php endforeach; ?>
</details>
<?php endif; ?>
<?php if (!count($g_buy) && !count($g_succ) && !count($g_dead)): ?>
<!-- keine Artikel -->
<?php endif; ?>
<div class="v2-hint">
💡 <b>Prototyp-Notiz (nicht final):</b> Bild (aus <code>items.default_image_file_name</code>, geladen vom Live-Server)
+ Preis (<code>item_prices</code> Kundengruppe 1, brutto inkl. Steuersatz, Angebotspreis rot) sind jetzt drin.
<b>nml/Nachfolger ist jetzt live:</b> Der Marker <code>(nml)</code>/<code>(nmle)</code> im Artikelnamen wird erkannt —
ausgelaufene Teile <b>mit</b> „Nachfolger &lt;Nr&gt;" landen im orangen Block und verlinken per Klick auf den kaufbaren Nachfolger;
Teile <b>ohne</b> 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.
</div>
</div>
<?php else: ?>
<div class="no-results">
Gib einen Suchbegriff ein (z.B. "AWB 921 PH", "ZCS 2100B", "Kohlefilter Bauknecht")
</div>
<?php endif; ?>
</div>
<script>
function toggleDevice(deviceId) {
const card = document.getElementById('device-' + deviceId);
if (card) {
card.classList.toggle('collapsed');
}
}
</script>
</body>
</html>