# Riccardo Partnerportal

Verkaufsplattform für Lieferanten im Design von riccardozigarette.com.
Hersteller und Händler registrieren sich, laden Produkte mit allen Pflichtunterlagen hoch,
Riccardo prüft und gibt frei, danach wird der Artikel per JTL-API angelegt.

## Starten

```bash
npm install
npm start
```

Dann http://localhost:3000 öffnen. Datenbank und Uploads liegen in `data/` (SQLite, in Node ≥ 22.13 eingebaut).
`npm run reset-db` löscht alles, beim nächsten Start werden die Demo-Daten neu angelegt.

### Demo-Zugänge (nur lokal)

Passwort für alle: Wert von `SEED_PASSWORD` in `.env`, Standard `riccardo-demo-2026`.

| Rolle | E-Mail | Zeigt |
|---|---|---|
| Riccardo-Admin | admin@riccardo.test | Prüfung, Freigabe, JTL, Partner, Promotionen |
| Händler Extrade | extrade@partner.test | Upload, Rückfrage, Status |
| Hersteller OXVA | oxva@partner.test | Marken-Portfolio: OXVA-Produkte, die Extrade verkauft |

## Ablauf

1. **Registrierung** als *Hersteller* (mit eigenen Marken) oder *Händler/Distributor*. Riccardo schaltet das Firmenkonto frei.
2. **Produkt hochladen** (7 Schritte): Stammdaten & EAN (Prüfziffer), Preise, TPD/EU-CEG, H-/P-Sätze, Piktogramme,
   Signalwort, UFI, Gerät/Akku, Fotos & Dokumente (SDB, Etikett, CE, Anleitung, UN 38.3), Vertriebskanal, Promotion.
3. **Vollständigkeitscheck** je Kategorie – Einreichen erst bei 100 %.
4. **Prüfung** durch Riccardo mit Prüfpunkten, Rückfrage an Partner oder Ablehnung.
5. **Zum Verkauf geeignet** → **In JTL anlegen** (API oder manuell mit Artikelnummer).

**Hersteller-Sicht:** Lädt ein Händler ein Produkt mit einer Marke hoch, die ein freigeschalteter Hersteller registriert hat,
erscheint es im Marken-Portfolio des Herstellers – ohne Einkaufspreise. Der Hersteller kann den Vertrieb bestätigen oder widersprechen
(nur für Riccardo sichtbar).

**Promotion:** Onlineshop-Banner (Startseite / Kategorie) und Filial-Lage A–D. Texte und Konditionen unter *Admin → Einstellungen*.

## Stellplatz-Logik (Platzierungen)

Fachgrundlage: [docs/MARGENWACHE-DOC-2026-V1.1-Nachtrag-Stellplatz.md](docs/MARGENWACHE-DOC-2026-V1.1-Nachtrag-Stellplatz.md).

- **Filialen** (*Admin → Filialen*): 26 Filialen mit SKU-Plätzen und Vollkosten je SKU-Platz und Monat, übernommen aus
  PYLAX `parameter/filialkosten.yaml` (PARAM-FILIALKOSTEN-2026-V1.0, Auszug vom 07.09.2026, `src/data/filialkosten-2026.json`).
  Vollkosten = Umlage Miete, Personal, IT auf vorhandene Plätze, keine reine Miete. Fehlt ein Wert → „fehlt“, nie € 0,00.
- **Preise**: Standard je Lage unter *Einstellungen*, abweichend je Filiale unter *Filialen*. Leer = „Preis noch festzulegen“.
- **Platzierungsvertrag** je Artikel × Lage × Filiale: Laufzeit, Werbekostenzuschuss, Listungsgebühr, Umsatzziel, Rückgaberecht (Standard 6 Wochen).
  Anlegen aus einer Promotion-Anfrage (*Promotionen → Vertrag anlegen*).
- **Lieferant** sieht unter *Platzierungen*: „€ 12.000,00 von € 20.000,00 · 60,00 % · nicht erreicht“, Laufzeitfortschritt, Rückgabefrist – keine Kosten, keine Margen.
- **Riccardo** sieht zusätzlich Vollkosten des Stellplatzes, Deckung durch die Lieferantenzahlung und offene Listungsgebühren.
- **Listungsgebühr**: Abrechnung in JTL; im Portal wird nach der Rechnung die JTL-Rechnungsnummer eingetragen.
- **Ist-Umsatz**: bis zur MARGENWACHE-/PYLAX-Anbindung per CSV (*Platzierungen → Umsatz importieren*, Spalten `EAN;Filiale;Woche;Umsatz`, Filiale = kWarenlager oder `ONLINE`, Bruttoumsatz).
- **Neueröffnungen**: Filiale mit Status „In Eröffnung“ erscheint bei Lieferanten unter *Neue Filialen*; Interessenmeldungen landen bei *Platzierungen*.

## JTL-Anbindung

Ohne Zugangsdaten läuft das Portal im Testmodus und zeigt nur den Payload (`/admin/produkte/:id/jtl-vorschau`).
Für den Echtbetrieb `.env.example` nach `.env` kopieren und `JTL_*` setzen. Unterstützt:

- JTL-Cloud ERP API (`Authorization: Bearer …`, `x-tenant-id`)
- lokale JTL-Wawi REST-API (`Authorization: Wawi …`, `x-appid`, `x-appversion`)

Angelegt wird per `POST {JTL_API_URL}/v1/items`. Die Feldzuordnung steht in `src/jtl.js` → `buildItemPayload()`
und sollte einmal gegen die Swagger-Doku eurer Wawi-Version geprüft werden. Hersteller- und Kategorie-IDs über
`JTL_MANUFACTURER_MAP` / `JTL_CATEGORY_MAP`. Fotos werden noch nicht an JTL übertragen.

## Aufbau

```
server.js              Express-App, Sicherheits-Header, Flash, CSRF
src/db.js              SQLite-Schema
src/catalog.js         Kategorien, Status, H-/P-Sätze, Dokumentarten, Vollständigkeitsprüfung
src/products.js        Produkt speichern/laden, Zugriffsrechte, Hersteller-Verknüpfung
src/jtl.js             JTL-Payload & API-Aufruf
src/upload.js          Datei-Upload (Typ- und Inhaltsprüfung, 15 MB)
src/routes/*.js        Öffentlich, Partner, Admin
src/views/product.js   Produktformular & Produktansicht
public/                CSS & JS
```

## Vor dem Livegang

- HTTPS + `COOKIE_SECURE=1`, `TRUST_PROXY=1` hinter Reverse Proxy
- Demo-Daten entfernen (`npm run reset-db`, eigenen Admin anlegen) – oder `SEED_PASSWORD` ändern
- E-Mail-Benachrichtigungen (Rückfrage, Freigabe) sind noch nicht eingebaut
- H-/P-Satz-Liste in `src/catalog.js` fachlich gegenprüfen und ggf. erweitern
- Backups für `data/`
