# Riccardo JTL-Schreibschutz

Die JTL-Wawi liefert nur die **Hülle** eines Artikels. Alles Inhaltliche wird in Shopware gepflegt
und vom Abgleich nicht überschrieben.

## Wer pflegt was

| Feld | Beim Anlegen | Danach |
|---|---|---|
| Artikelnummer, EAN | Wawi | Wawi |
| Erscheinungsdatum | Wawi | Wawi, solange sie eines liefert – ein leeres Feld löscht nichts |
| Preise, Staffel-/Kundengruppenpreise, Steuer, Grundpreisangaben | Wawi | Wawi |
| Bestand | Wawi | Wawi (abschaltbar, siehe unten) |
| Varianten (Optionen, neue Varianten) | Wawi | Wawi |
| Sichtbarkeit im Verkaufskanal | Wawi | Wawi (vorhandener Eintrag wird aktualisiert, kein Duplikat) |
| Beschreibung, Meta-Texte, Kurzbeschreibung | Wawi (Rohfassung) | Shopware |
| Name | Wawi (Rohfassung) | **Shopware** |
| Kategorie | Wawi (erste Zuordnung) | **Shopware**, außer „Kategoriezuordnungen“ ist zugeschaltet |
| Suchbegriffe | – | **Shopware** |
| Bilder | Wawi, wenn „Produktbilder aus der Wawi“ zugeschaltet ist | dito |
| Eigenschaften, Tags, Cross-Selling | – | **Shopware** |
| Hersteller, Gewicht/Maße, Bestellregeln, Aktiv-Status | – | **Shopware** (zuschaltbar) |
| Abverkauf-Haken (`isCloseout`) | – | **Shopware**, und zwar immer – die Wawi kommt an das Feld nicht heran |

Stammdaten (Kategorien, Hersteller, Eigenschaftsgruppen und -werte, Tags, Einheiten, Lieferzeiten)
darf die Wawi **anlegen**, aber nicht mehr ändern oder löschen – Kategorienamen, SEO-Texte und
Herstellerbeschreibungen aus Shopware bleiben erhalten.

## Der Abverkauf-Haken bleibt bei uns

`isCloseout` steht in keiner zuschaltbaren Gruppe, sondern in
`ProductPayloadGuard::NIEMALS` – das Feld wird auch dann verworfen, wenn
„Bestellregeln" eingeschaltet ist, und auch beim Anlegen.

Grund: Der Haken bedeutet in Shopware „wenn nicht auf Lager, dann weg", und
zwar nicht nur aus der Trefferliste – die Artikelseite antwortet dann mit 404.
Die Wawi hatte ihn bei 1.380 Artikeln gesetzt; 846 davon waren dadurch
unerreichbar, darunter 182 mit eigener SEO-Adresse. Ob ein Artikel ausläuft,
entscheiden wir in Shopware und bewusst.

### Auslauf aus der Wawi steuern

Der Konnektor schickt `isCloseout` bei **jedem** Artikel als `true` – in den
Mitschnitten unter `var/log/jtl-sync/` 90 von 90. Dieser Wert ist deshalb
wertlos und wird immer verworfen.

Soll die Wawi den Auslauf trotzdem bestimmen, geht das über ein **eigenes Feld
(Attribut)** am Artikel:

1. In der JTL-Wawi ein eigenes Feld anlegen, das die Abverkaufsmarkierung
   trägt, und es an den Konnektor übergeben. Es kommt dann im Abgleich unter
   `customFields` an – die Wawi hat dafür bereits ein eigenes Feldset
   (`custom_jtl`, enthält heute nur `short_description`).
2. In den Plugin-Einstellungen unter **Wawi-Feld für „Auslauf"** den Namen
   dieses Feldes eintragen.

Danach gilt: Feld gesetzt → Auslauf-Haken an, Feld leer oder `false` → aus.
Liefert die Wawi das Feld gar nicht mit, bleibt der in Shopware gesetzte Wert
unangetastet – ein fehlendes Feld hebt nichts auf.

Einmalig aufräumen (setzt Hauptartikel auf `false`, Varianten auf `null`):

```bash
php dev/daten/artikel/abverkauf-haken-entfernen.php --trocken   # nur zählen
php dev/daten/artikel/abverkauf-haken-entfernen.php             # schreiben
```

**Kategorien löschen kann die Wawi nicht** – weder per Sync noch direkt über
`DELETE /api/category/{id}` (so löscht der Connector tatsächlich). Der direkte Aufruf wird mit 204
quittiert, ohne etwas zu löschen, damit der Connector weiterläuft. Entfernt werden Kategorien nur
in Shopware.

Kategorien, die im Shop nicht existieren, werden weggelassen statt den ganzen Abgleich scheitern
zu lassen – beim Anlegen wie beim Ergänzen.

## Kategoriesatz aus der Wawi nachziehen

Normalerweise sortiert Shopware ein. Soll einmalig ein Kategoriesatz aus der Wawi kommen, gibt es
den Schalter **„Kategoriezuordnungen auch bei bestehenden Artikeln“**.

Vorher prüfen, hinterher gegenprüfen – beides schreibt nichts:

```bash
php dev/daten/jtl-kategorien-holen.php   /tmp/wawi.jsonl
php dev/daten/jtl-kategorien-abgleich.php /tmp/wawi.jsonl
```

**Wichtig: Shopware ergänzt beim Schreiben von `categories`, es entfernt nichts.** Ein Artikel,
den die Wawi umsortiert hat, läge danach in alter *und* neuer Kategorie. Der Abgleich zeigt unter
Punkt 4, ob überhaupt etwas zu entfernen wäre (am 23.09.2026: 2.478 fehlende Zuordnungen,
**0** zu entfernende – also rein additiv und damit unbedenklich).

Die Wawi führt mehrere Kategoriebäume nebeneinander; relevant ist nur der unter der
Wurzelkategorie des Connectors (`Onlineshop Neu -> Riccardo Online`). Die anderen enthalten unter
anderem „Kategorien - ALT - Nicht aktiv stellen“ und gehören nicht in den Shop.

Nach dem Lauf: Schalter wieder ausschalten und Meta-Texte für neu entstandene Kategorien pflegen
(`dev/daten/meta/`).

## Wie es funktioniert

`GuardedSyncService` dekoriert Shopwares `SyncService` (`/api/_action/sync`). Nur Anfragen einer
Integration, deren Name in der Konfiguration steht (Standard: `JTL`), werden gefiltert – die
Administration, eigene Skripte und der Import bleiben unberührt. Die Regeln stehen in
`ProductPayloadGuard` (reine Logik ohne Datenbank).

Was entfernt wurde, steht im Log (`RiccardoJtlGuard: Wawi-Abgleich gefiltert`), z. B.:

    grep RiccardoJtlGuard var/log/dev.log | tail

## Konfiguration

Einstellungen › Erweiterungen › Riccardo JTL-Schreibschutz:

- **Schreibschutz aktiv** – aus: Die Wawi darf wieder alles überschreiben (einmaliger Komplettabgleich).
- **Integrationen der Wawi** – Name(n) der Integration, kommagetrennt.
- **Texte einmalig aus der Wawi übernehmen** – an: bestehende Artikel bekommen beim nächsten
  Abgleich Beschreibung, Meta-Texte, Suchbegriffe und Kurzbeschreibung aus der Wawi (Name und
  Kategorien bleiben geschützt). Nach dem Abgleich **wieder ausschalten**, sonst überschreibt die
  Wawi in Shopware überarbeitete Texte erneut. Artikel mit dem Schalter **„Von Shopware optimiert“**
  (RiccardoCatalog) bekommen auch bei eingeschaltetem Import keine Wawi-Texte.
- **Zusätzlich aus der Wawi übernehmen** – Bestand (Standard), Aktiv-Status, Hersteller,
  Gewicht/Maße, Bestellregeln, Beschreibung/Meta-Texte beim Anlegen, **Produktbilder**.
  Ohne „Produktbilder aus der Wawi“ verwirft der Schutz alle Bild-Operationen des Connectors.

## Grenzen

- Gefiltert werden der Sync-Endpunkt und `DELETE /api/category/{id}` (`WawiDeleteGuard`). Weitere
  Einzel-Endpunkte, die der Connector nutzt, greifen am Schutz vorbei – derzeit
  `PATCH /api/property-group/{id}` und `DELETE /api/product/{id}/visibilities/{id}`. Übersicht:

      grep 88.84.141.4 /var/log/apache2/shopware-dev/access.log | awk '{print $6,$7}' \
        | grep -v '"GET\|search\|_info\|oauth' | sed -E 's#/[0-9a-f]{32}#/{id}#g; s#\?.*##' | sort | uniq -c
- Artikel, die vor der Installation angelegt wurden, behalten ihre Wawi-Texte als Rohfassung.
