# Mail-Prozess

## Überblick

Der Versand aller Bestellmails ist zentral in `includes/functions.php` implementiert und wird synchron innerhalb der jeweiligen HTTP-Requests ausgeführt.

- Kernfunktion für Versand: `sendEmail(...)`
- Fachliche Mail-Trigger: `createOrder(...)` und `confirmOrderByToken(...)`
- Laufzeit-Einstellungen: `getSystemSettings()` aus `data/settings.json`
- Startwerte/Fallbacks: `config.php`

Hinweis:

- Es gibt keine Queue, keinen Hintergrundjob und keine Retry-Logik. Versand erfolgt direkt per PHP-`mail()`.

## Relevante Einstellungen

Die folgenden Parameter steuern den Mailfluss:

| Schlüssel | Quelle | Wirkung |
|---|---|---|
| `order_recipient_email` | Admin-Einstellungen (`data/settings.json`) | Empfänger für interne Bestellmail |
| `order_confirmation_required` | Admin-Einstellungen | Erzwingt Bestätigungsmail vor interner Weiterleitung |
| `order_confirmation_expiry_days` | Admin-Einstellungen | Gültigkeit des Bestätigungslinks |
| `attach_order_pdf_to_admin_email` | Admin-Einstellungen | Hängt PDF an interne Bestellmail an |
| `FROM_EMAIL`, `FROM_NAME` | `config.php` | Absender/Anzeigename für alle ausgehenden Mails |
| `SITE_URL` | `config.php` | Basis für Bestätigungslink in Mails |

## Mail-Typen und Auslöser

### 1) Bestätigung an Besteller

- Funktion: `sendOrderConfirmationRequestEmail($order)`
- Trigger: direkt nach `createOrder(...)`, wenn `order_confirmation_required = true`
- Empfänger: `order.customer_email`
- Inhalt: Bestellzusammenfassung + Button/Link auf `order-confirm.php?token=...`

### 2) Eingangsbestätigung an Besteller (ohne Pflichtbestätigung)

- Funktion: `sendOrderCreatedCustomerEmail($order)`
- Trigger: direkt nach `createOrder(...)`, wenn `order_confirmation_required = false`
- Empfänger: `order.customer_email`
- Inhalt: Bestellung erfasst und intern weitergeleitet

### 3) Bestätigungsinfo an Besteller (nach Klick auf Token-Link)

- Funktion: `sendOrderConfirmedCustomerEmail($order)`
- Trigger: nach erfolgreicher Token-Bestätigung in `confirmOrderByToken(...)`
- Empfänger: `order.customer_email`
- Inhalt: Bestellung bestätigt und intern weitergeleitet

### 4) Interne Bestellmail

- Funktion: `sendConfirmedOrderAdminNotification($order)`
- Trigger:
  - direkt nach `createOrder(...)`, wenn `order_confirmation_required = false`
  - nach erfolgreicher Token-Bestätigung in `confirmOrderByToken(...)`, wenn vorher `pending`
- Empfänger: `getOrderRecipientEmail()` (normalisiert/validiert)
- Inhalt: HTML-Bestellzusammenfassung
- Optional: PDF-Anhang `bestellung-<order-id>.pdf` bei aktivem `attach_order_pdf_to_admin_email`

## Ablauf nach Konfiguration

### Fall A: Bestätigung erforderlich

1. `createOrder(...)` speichert Bestellung mit `confirmation_status = pending`.
2. Besteller erhält Bestätigungsmail mit Token-Link.
3. Klick auf Link ruft `order-confirm.php` auf und startet `confirmOrderByToken(...)`.
4. Bei gültigem, nicht abgelaufenem Token:
   - `confirmation_status` wird auf `confirmed` gesetzt,
   - interne Bestellmail wird versendet,
   - Besteller erhält Bestätigungsinfo.

### Fall B: Keine Bestätigung erforderlich

1. `createOrder(...)` speichert Bestellung mit `confirmation_status = not_required` und `confirmed_at`.
2. Interne Bestellmail wird sofort versendet.
3. Besteller erhält direkt Eingangsbestätigung.

## Ablauf bei Fristablauf

- Offene Bestätigungen (`pending`) wechseln nach Frist auf `expired`.
- Der Status wird in `refreshOrderState(...)` berechnet und über `expirePendingOrders()` beim Aufruf von `admin/index.php`, `admin/orders.php` und `order-confirm.php` fortgeschrieben.
- Für `expired` gibt es keine zusätzliche Mail.

## Technische Versanddetails

- Ohne Anhang: HTML- oder Textmail direkt über `mail($to, $subject, $message, $headers)`.
- Mit Anhang: `multipart/mixed` mit Base64-kodierten Attachments.
- Standard-Header:
  - `From: <FROM_NAME> <FROM_EMAIL>`
  - `Reply-To: FROM_EMAIL`
  - `X-Mailer: PHP/<version>`
- Bestätigungslink wird über `buildAbsoluteUrl(...)` erzeugt:
  - absolute `SITE_URL` wird direkt verwendet,
  - bei relativer `SITE_URL` wird aus Request-Kontext (`HTTP_HOST`, HTTPS) eine absolute URL gebaut.

## Fehlerverhalten und Nachvollziehbarkeit

- Rückgaben von `sendEmail(...)` werden nur teilweise ausgewertet:
  - Bei interner Bestellmail wird bei Erfolg `admin_notified_at` gesetzt.
  - Schlägt die interne Mail fehl, bleibt `admin_notified_at` leer.
  - Fehlschläge von Bestellermails blockieren den Bestellprozess nicht.
- Es gibt keine automatische Wiederholung fehlgeschlagener Mails.
- Betriebsvoraussetzung bleibt eine funktionierende Server-Mailkonfiguration für PHP-`mail()`.
