# barox ProductPub

Erzeugt aus den Unterlagen eines Geräts die Zeilen für die Produkteliste
(`Laufende Produkteliste.xlsx`, Blatt *Laufende Produktelist*) – vier Zeilen je
Produkt (de / en / en-us / fr), 122 Spalten, fertig zum Einfügen.

Installation: siehe [INSTALL.md](INSTALL.md).

---

## Der Gedanke dahinter

Ein neuer Switch unterscheidet sich von einem bestehenden meist nur in einer
Handvoll Werte – Portzahlen, Backplane, Abmessungen, Speisung. Die übrigen
hundert Spalten sind entweder Textbausteine, die im Katalog längst gepflegt und
in alle Sprachen übersetzt sind, oder Steuerfelder.

Das Werkzeug erfindet deshalb nichts. Es kombiniert drei Quellen:

| Quelle | wofür | Markierung |
|---|---|---|
| **Unterlagen** (PDF, XLSX, DOCX, TXT/CSV – mehrere je Produkt) | Ports, Backplane, MAC-Tabelle, Temperatur, Abmessungen, Speisung, Konsole | `Datenblatt` |
| **Bestand** | alle Textbausteine und Übersetzungen aus einem vergleichbaren Produkt | `Vorlage`, `Textbaustein` |
| **Sprachmodell** *(freiwillig)* | passt die Freitexte an das neue Gerät an | `KI-Entwurf` |

Jede Zelle trägt in der Oberfläche ihre Herkunft. Was geprüft werden muss, ist
als `Prüfen` markiert und lässt sich mit einem Klick herausfiltern.

---

## Ablauf

1. **Unterlagen hochladen** – alle Dateien zum Gerät auf einmal (Datenblatt,
   Vorabspezifikation, Porttabelle, Notizen). Jede wird gelesen und
   ausgewertet, die Werte werden zusammengeführt.
2. **Vorlage wählen** – vorgeschlagen wird das ähnlichste bestehende Produkt,
   bewertet nach Artikelnummer, Kategorie, erkannten Merkmalen und Pflegezustand.
3. **Entwurf prüfen** – alle 122 Spalten in vier Sprachen, nach Abschnitten
   gegliedert. Änderungen werden beim Verlassen des Feldes gespeichert.
4. **Zeilen kopieren** – ein Klick, dann in Excel bei Spalte A einfügen.

---

## Was wo herkommt

**Sprachabhängig oder nicht?** Beim Einlesen der Produkteliste vergleicht das
Werkzeug für jede Spalte die vier Sprachzeilen aller Produkte. Spalten, deren
Werte sich unterscheiden, gelten als sprachabhängig und müssen übersetzt werden
(aktuell 45 von 122); alle übrigen werden unverändert übernommen. Diese
Einteilung entsteht aus den Daten selbst und passt sich mit jedem Import an.

**Übersetzungsgedächtnis.** Viele technische Felder sind formelhaft
(`0°C bis 50°C` / `0°C to 50°C` / `0°C à 50°C`). Statt sie neu zu übersetzen,
sucht das Werkzeug denselben deutschen Wert im Bestand und übernimmt die dort
gepflegten Übersetzungen. Findet es nur eine Entsprechung bis auf die Zahlen,
überträgt es das Muster und setzt die neuen Zahlen ein. Dadurch bleiben
Schreibweise und Terminologie mit der Webseite konsistent. Gibt es keinen
Treffer, wird das Feld als `Prüfen` markiert statt geraten.

**Sprachmodell.** Betrifft nur die Freitexte (Description, Kurzbeschreibung,
Stichwort, Besonderheit für Videonetzwerke, Spezielle Eigenschaften,
Systemhinweise). Das Modell bekommt den gepflegten Text des Vorlagenprodukts
sowie die alten und neuen technischen Werte und darf ausschliesslich die
Stellen ändern, die sich technisch unterscheiden – Satzbau, Wortwahl und
Formatierung (`<br />`, `|`) bleiben erhalten. Deutsch wird zuerst angepasst,
die übrigen Sprachen richten sich daran aus.

---

## Mehrere Unterlagen je Produkt

Selten steht alles in einer Datei. Das Datenblatt nennt die Ports, die
Vorabspezifikation das Gewicht, eine Tabelle die Bestellnummern, eine Notiz aus
dem Vertrieb die Speisung. Deshalb werden **alle Unterlagen zu einem Gerät
zusammen hochgeladen** – auf einmal beim Anlegen, später jederzeit nachträglich
auf der Seite *Vorlage wählen* und im Entwurf.

Gelesen werden:

| Format | wie |
|---|---|
| PDF | eigener Parser (Fonts, CMaps, Layout) oder `pdftotext -layout` |
| XLSX / XLSM | eigener Leser; jedes Blatt wird als Tabelle mit Spaltenraster ausgelegt |
| DOCX | Absätze und Tabellen aus `word/document.xml` |
| TXT / CSV / MD | direkt; bei CSV wird das Trennzeichen erkannt |

**Jede Unterlage wird einzeln ausgewertet**, erst danach werden die Werte
zusammengeführt. Ein zusammengeworfener Text würde die Tabellen der einzelnen
Dokumente durcheinanderbringen: Spalten werden über ihre Zeichenposition
erkannt, und die ist je Dokument eine andere.

Beim Zusammenführen gilt:

- Für jede Spalte der Produkteliste wird der **verlässlichste** Wert genommen;
  bei gleicher Verlässlichkeit der aus der **führenden** Unterlage.
- Die führende Unterlage ist zunächst die erste hochgeladene. Sie lässt sich in
  der Liste mit *nach vorn* ändern – die Reihenfolge des Uploads ist kein
  Urteil darüber, welche Quelle die verbindliche ist.
- **Widersprüche werden nicht stillschweigend aufgelöst.** Der abweichende Wert
  steht als Hinweis beim Feld und als Meldung nach dem Einlesen, samt Angabe,
  welche Unterlage was nennt.
- Jeder Vorschlag trägt den Dateinamen seiner Quelle. In der Liste steht bei
  jeder Unterlage, wie viele Angaben aus ihr stammen – so ist sofort zu sehen,
  ob eine Datei überhaupt etwas beigetragen hat.
- Dieselbe Datei zweimal hochzuladen wird erkannt und übersprungen (Prüfsumme).

Werte werden ausserdem in zwei Formen gefunden: als Tabelle unter einem
nummerierten Abschnitt (so bauen die Hersteller ihre Datenblätter) und
zeilenweise als `Beschriftung: Wert` bzw. als zwei Tabellenzellen. Nur dadurch
lassen sich auch Tabellenblätter und Wordnotizen auswerten, die keine
nummerierte Gliederung haben.

Neu gelesene Werte füllen einen bestehenden Entwurf **nicht rückwirkend**. Wer
eine Unterlage nachträgt, erstellt den Entwurf danach erneut aus der Vorlage
(Schritt 2) – oder trägt die neuen Angaben von Hand nach.

Die Höchstzahl der Unterlagen je Produkt steht in `config.php` unter
`max_documents` (Vorgabe 8), die Grösse je Datei unter `max_upload_mb`.

---

## Datenblatt als PDF

Aus jedem Entwurf lässt sich ein Datenblatt im barox-Layout erzeugen – im
selben Aufbau wie die von der Webseite generierten PDFs: Deckblatt mit
Produktbild, Artikelnummer, Stichwortliste und Einleitung, dann
*Produktinformationen*, dann *Technische Daten* als zweispaltige Tabelle.

Die Schaltfläche steht im Entwurf und auf der Ausgabeseite, dort für jede
Sprache einzeln.

Maße, Schriftgrössen und Farben sind aus einem bestehenden Datenblatt
übernommen (A4, Rand 42 pt, Titel 21 pt, Fusszeile 7,5 pt, Bernsteinlinie
1,5 pt, Tabellentrenner 0,75 pt). Geschrieben wird in Helvetica – eine der 14
PDF-Standardschriften, die in jedem Betrachter vorhanden ist und Arial
entspricht. Deshalb muss keine Schrift eingebettet werden.

Zum Produktbild: gesucht wird die in der Spalte `Bilddatei` hinterlegte Datei
im Ordner aus `datasheet.image_dir`. PNG und JPEG werden unterstützt,
Transparenz bleibt erhalten. Fehlt die Datei, erscheint an ihrer Stelle ein
Platzhalter mit dem erwarteten Dateinamen und ein Hinweis.

> Das PDF zeigt immer den **aktuellen Stand des Entwurfs**. Felder, die noch
> als `Prüfen` markiert sind, stehen also unverändert so im PDF, wie sie von
> der Vorlage kommen. Vor dem Versand also erst die Texte anpassen.

---

## Umrechnungen, die das Werkzeug vornimmt

Die Datenblätter der Hersteller schreiben anders als die Produkteliste:

| Datenblatt | Produkteliste | Anmerkung |
|---|---|---|
| `442 x 44 x 300` (WxHxD) | `442 x 300 x 44mm (BxTxH)` | Achsen werden umsortiert |
| `340Gbps` | `340GBit/s` | |
| `32K` | `32k` | |
| `0°C to 50°C` | `0°C bis 50°C` | |
| `Hot-swappable Dual AC PSUs / 100-250 VAC, 50~60 Hz` | `100-250VAC, 50-60Hz, redundante Speisung möglich` | |

Jede Umrechnung wird im Entwurf beim betreffenden Feld erklärt, zusammen mit
dem unveränderten Wert aus dem Datenblatt.

Steht im Datenblatt `TBD`, bleibt das Feld leer und wird als Hinweis gemeldet –
es wird nichts erfunden.

---

## Grenzen

- **Reine Scan-PDFs** ohne Textebene lassen sich nicht auswerten. Das Werkzeug
  sagt das deutlich, statt leere Werte zu liefern; die Datei bleibt zum
  Nachsehen hinterlegt, und die übrigen Unterlagen werden trotzdem ausgewertet.
- **XLS, DOC und ODT** (die alten bzw. offenen Formate) werden nicht gelesen –
  nur XLSX, XLSM und DOCX. Solche Dateien vorher als XLSX bzw. DOCX speichern.
- Felder, die es nur beim neuen Produkt gibt und für die es im Bestand kein
  Vorbild gibt (etwa eine neue Speisespannung), erhalten den deutschen Wert in
  allen Sprachen und die Markierung `Prüfen`.
- Gerätebezogene Werte werden bewusst **nicht** von der Vorlage übernommen:
  Portbestückung, Gewicht, Abmessungen, Backplane, MAC-Tabelle, Speisung,
  Temperatur, MTBF, optische Kennwerte und alle produktbezogenen Downloads
  (CE-CoC, Handbuch, CAD, Visio). Liefert das Datenblatt dazu nichts, bleibt
  das Feld leer – mit einem Hinweis, was bei der Vorlage steht. Sonst stünde
  im Entwurf stillschweigend das Gewicht eines anderen Geräts.
- **Bilddatei** wird nach dem üblichen Muster `<Artikelnummer>.png` gesetzt.
  Das Bild selbst muss noch abgelegt werden.
- Beim Einfügen werden echte Zeilenumbrüche in Zellen als `<br />` ausgegeben.
  Anders liesse sich Text nicht spaltentreu in Excel einfügen; die Liste
  verwendet `<br />` ohnehin durchgängig.

---

## Aufbau

```
public/          Front-Controller und statische Dateien (DocumentRoot)
src/
  Pdf/           PDF-Textextraktion in reinem PHP (Fonts, CMaps, Layout)
  Xlsx/          XLSX-Leser
  Support/       ZIP-Leser, UTF-Hilfen, Datenbank, HTTP, Sitzung
  Catalog/       Produkteliste als Modell, Import und Persistenz
  Extract/       Unterlagen lesen (PDF/XLSX/DOCX/Text), in Abschnitte und
                 Werte zerlegen, Werte mehrerer Unterlagen zusammenführen
  Draft/         Entwurf bauen, Übersetzungsgedächtnis, Vorlagenwahl
  Llm/           Anbieter (Claude API / lokal) und Textanpassung
  Export/        Zeilen für die Zwischenablage
  Auth/          Microsoft-365-Anmeldung
  Web/           Controller, Ansicht, Anfrage
templates/       Seitenvorlagen
db/schema.sql    Datenbankschema
```

Ohne Composer, ohne Fremdbibliotheken. PDF- und XLSX-Verarbeitung sind selbst
umgesetzt, damit auf dem Server nur Standard-PHP nötig ist.
