# RiccardoLoyalty – Kundenkarte

Punktekonto für Online- und Filialeinkäufe, komplett selbst gebaut (keine Fremdplugins, keine externen Dienste).

## Funktionen
- **Karte**: EAN-13-Nummer (Präfix 29, interner Nummernbereich), Barcode als SVG ohne Bibliothek – am Handy an der Kasse scannbar
- **Sammeln**: Punkte je Euro Warenwert (nach Rabatten, ohne Versand). Online erst „vorgemerkt“, Gutschrift je nach Einstellung bei Zahlung oder Abschluss der Bestellung; Storno nimmt Punkte zurück, ein Wieder-Öffnen der Bestellung stellt sie wieder her
- **Einlösen**: im Warenkorb und im Checkout, in festen Schritten, ab einer Mindestpunktzahl und höchstens bis zu einem Anteil des Warenwerts. Die Position speichert nur die gewünschte Punktzahl – Betrag, Punktestand und Obergrenzen werden bei jeder Warenkorbberechnung neu geprüft
- **Seiten**: `/kundenkarte` (Info) und `/account/kundenkarte` (Karte, Punktestand, Buchungen)
- **Admin**: *Kunden → Kundenkarten* – Liste, Karte sperren, Kundenkonto verknüpfen, Punkte manuell buchen, alle Buchungen; Karten ohne Kundenkonto (Filialausgabe) möglich
- **Einstellungen**: *Erweiterungen → Riccardo Kundenkarte → Konfigurieren* (je Verkaufskanal)

## Kassen-Schnittstelle (Admin-API, Integration mit Schreibrechten)
```
GET  /api/_action/riccardo-loyalty/card/{cardNumber}
POST /api/_action/riccardo-loyalty/card                        { customerId?, cardNumber?, note? }
POST /api/_action/riccardo-loyalty/card/{cardNumber}/booking   { amount } oder { points }, + reference?, description?
POST /api/_action/riccardo-loyalty/account/{accountId}/booking { points, description? }
```
`amount` rechnet den Bonbetrag in Punkte um (negativer Betrag = Retoure), `points` bucht direkt.
Abbuchungen über dem Punktestand werden mit HTTP 422 abgelehnt.

## Datenmodell
- `riccardo_loyalty_account` – eine Karte, optional mit Kundenkonto verknüpft; Punktestände sind schreibgeschützt und werden nur über den `LoyaltyService` verändert
- `riccardo_loyalty_transaction` – jede Änderung ist eine Buchung (`welcome`, `earn`, `redeem`, `store`, `manual`) mit Status `pending`/`booked`/`cancelled`

## Kommandos
`bin/console riccardo:loyalty:enroll [--with-bonus]` – Karten für alle bestehenden Kunden ohne Karte anlegen.

## Build
`bin/build-storefront.sh` bzw. `bin/build-administration.sh` (als root, danach `chown -R www-data:www-data`).

## Offen / später
- Übernahme bestehender Filialkarten: Zuordnung aktuell manuell im Admin (Kundenkonto verknüpfen bzw. Punkte umbuchen)
- Anbindung an das Kassensystem über die API oben, sobald klar ist, welches System im Einsatz ist
