# DfProforma Shopware — Pro-forma-Angebote mit Kundenakzeptanz und Auto-Konvertierung

> Was DfProforma leistet Shopware 6.7 kann Rechnungen, Lieferscheine und Gutschriften ausstellen — aber keine Pro-forma-Angebote. Dabei muss der Kunde in nahezu allen B2B-Kontexten (Industrieausrüstung, Geschäftsdienstleistungen, öffentliche Beschaffung, Ausschreibungsverkäufe) ein formelles…

- Seite: <https://www.datafirefly.com/de/documentation/dfproforma-shopware-proforma-angebot/>
- Sprache: de
- Aktualisiert am: 2026-07-01
- Weitere Sprachen: [fr](https://www.datafirefly.com/documentation/dfproforma-devis-shopware/index.md), [en](https://www.datafirefly.com/en/documentation/dfproforma-shopware-pro-forma-quote/index.md), [es](https://www.datafirefly.com/es/documentation/dfproforma-shopware-presupuesto-proforma/index.md), [it](https://www.datafirefly.com/it/documentation/dfproforma-shopware-preventivo-proforma/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfproforma-devis-shopware/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfproforma-devis-shopware/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfproforma-devis-shopware/index.md)
- Index: <https://www.datafirefly.com/de/documentation/llms.txt>

## Was DfProforma leistet

Shopware 6.7 kann Rechnungen, Lieferscheine und Gutschriften ausstellen — aber keine Pro-forma-Angebote. Dabei muss der Kunde in nahezu allen B2B-Kontexten (Industrieausrüstung, Geschäftsdienstleistungen, öffentliche Beschaffung, Ausschreibungsverkäufe) ein formelles Dokument erhalten, das er akzeptiert, _bevor_ die Bestellung verbindlich wird.

DfProforma schließt diese Lücke ohne Workarounds: ein echter nativer Shopware-Dokumenttyp `df_proforma`, ein eigener Nummernkreis `PF{n}`, eine markenkonforme Twig-PDF-Vorlage, ein eigenständiger Kundenakzeptanz-Workflow mit einer per HMAC-SHA256 signierten öffentlichen URL und eine automatische Konvertierung in eine feste Bestellung, sobald die zugrunde liegende Transaktion in den Status bezahlt wechselt.

**Kurz gesagt:** Der Verkäufer erstellt ein Angebot von der Bestelldetailseite im Admin, versendet es per E-Mail, der Kunde klickt auf den Link, akzeptiert online ohne Shopware-Konto, bezahlt, und das Angebot wechselt automatisch in den Status _Konvertiert_. Kein manueller Klick nach der Zahlung.

## Voraussetzungen

- **Shopware** 6.7.0 oder höher (das Plugin ist aufgrund der Umgestaltung des Dokumentensystems nicht abwärtskompatibel mit 6.6)
- **PHP** 8.2 mindestens
- **MySQL** 8.0+ oder **MariaDB** 10.6+
- Aktive Shopware-Message-Worker (empfohlen für die automatische Ablaufverwaltung)
- Konfigurierter Shopware Mail Service (funktionierendes SMTP für Transaktionsversand)

## Installation

### 1. Plugin hochladen

Gehen Sie in der Shopware-Administration zu _Erweiterungen → Meine Erweiterungen → Erweiterung hochladen_ und wählen Sie die Datei `DfProforma-1.0.6.zip`.

### 2. Installieren und aktivieren

Klicken Sie in der Erweiterungsliste auf _Installieren_ und dann auf _Aktivieren_. Die Shopware-Migrationen laufen automatisch und erstellen:

- Die SQL-Tabelle `df_proforma` mit Indizes auf `order_id`, `status`, `public_token`
- Den Dokumenttyp `df_proforma` in `document_type`
- Den Nummernkreis `document_df_proforma` im konfigurierbaren Format `PF{n}`
- Die Basis-Transaktions-E-Mail-Vorlage für Erstellung, Versand und Akzeptanz

### 3. Administration neu kompilieren

Das Plugin liefert ein Vite-Admin-Modul, das die Bestelldetailseite (`sw-order-detail-base`) erweitert. Sie müssen das globale Administrations-Bundle neu kompilieren, damit der Tab _Pro forma_ erscheint:

```
bin/build-administration.sh
bin/console cache:clear
```

**Diesen Schritt zu überspringen** ist die häufigste Ursache dafür, dass "der Pro-forma-Tab auf der Bestelldetailseite nicht erscheint" — denken Sie nach jedem Plugin-Update daran, neu zu kompilieren.

## Konfiguration

### Globale Einstellungen

Unter _Erweiterungen → Meine Erweiterungen → DfProforma → Konfigurieren_ greifen Sie auf folgende Einstellungen zu:

- **Standardgültigkeit** — Anzahl der Tage, während derer der Akzeptanzlink gültig bleibt (30 standardmäßig). Jedes Angebot kann diesen Wert individuell überschreiben.
- **Auto-Konvertierung bei Zahlung** — Standardmäßig aktiviert. Deaktivieren Sie sie, wenn Sie die manuelle Kontrolle über den Übergang _Akzeptiert → Konvertiert_ behalten möchten.
- **Absendername** — Als Absender der Transaktions-E-Mails angezeigter Name (Standard: der Sales-Channel-Name).
- **PDF-Markenfarbe** — Akzentfarbe in der mitgelieferten PDF-Vorlage (Kopfband, Trennlinie, Status-Badge).

### Konfiguration pro Sales-Channel

Die obigen Einstellungen können pro Sales-Channel in _Einstellungen → Sales Channels → [Ihr Kanal] → Plugin-Konfiguration_ überschrieben werden. Nützlich, wenn Sie mehrere Shops mit unterschiedlichen Gültigkeitsrichtlinien betreiben (z. B. 30 Tage für B2C, 60 Tage für B2B).

## Ein Pro-forma-Angebot erstellen

### Von der Bestelldetailseite (Admin)

1. Öffnen Sie eine Bestellung in _Bestellungen → Übersicht_
2. Klicken Sie auf den Tab _Pro forma_ (neben _Dokumente_)
3. Klicken Sie auf _Pro-forma-Angebot generieren_
4. Das PDF wird erstellt, das Angebot erscheint in der Liste mit einer Nummer `PF-…` und dem Status _Entwurf_

### Über die Admin-API

Drei Endpunkte werden bereitgestellt, um die Erzeugung in Ihre externen Workflows zu integrieren:

```
POST /api/_action/df-proforma/generate
Body: { "orderId": "…" }

POST /api/_action/df-proforma/mark-sent
Body: { "proformaId": "…" }

GET  /api/_action/df-proforma/by-order/{orderId}
```

Standard-Shopware-OAuth2-Admin-Authentifizierung. Nützlich, um DfProforma an ein externes CRM oder eine Automatisierungs-Pipeline anzubinden.

## Ein Angebot an den Kunden senden

### Transaktions-E-Mail

Klicken Sie in der Angebotsliste (Pro-forma-Tab auf der Bestelldetailseite) auf das Umschlag-Symbol neben dem Angebot. Das Modul:

1. Setzt das Angebot auf Status _Gesendet_ (mit Zeitstempel)
2. Sendet eine E-Mail an den Kunden über den Shopware Mail Service unter Verwendung der Vorlage `df_proforma_sent`, in der Sales-Channel-Sprache
3. Hängt das Angebots-PDF an und enthält die öffentliche Akzeptanz-URL
4. Emittiert das Event `ProformaGeneratedEvent` (Flow-Builder-Trigger)

### Öffentliche Akzeptanz-URL

Jedes versendete Angebot trägt eine URL der Form:

```
https://ihr-shop.com/proforma/accept/{token}
```

Das Token ist mit HMAC-SHA256 unter Verwendung des Shopware-Geheimschlüssels (`APP_SECRET` / `kernel.secret`) verschlüsselt und signiert. Unmöglich zu fälschen oder zu erraten. Die URL läuft nach der Angebotsgültigkeit ab (30 Tage standardmäßig).

## Öffentliche Kundenakzeptanzseite

Der Kunde öffnet die URL — **kein Shopware-Konto erforderlich** (die Seite umgeht die Standard-Kundenkonto-Authentifizierung). Er sieht:

- Eine saubere Bestellzusammenfassung: Positionen, Preise, MwSt., Summen, Bedingungen
- Einen primären Button _Dieses Angebot annehmen_
- Einen sekundären Button _Mit Begründung ablehnen_
- Die angezeigte Gültigkeit ("Gültig bis 20.06.2026")

Bei der Akzeptanz:

- Signatur auf die Millisekunde genau zeitgestempelt und in der Datenbank persistiert
- Kunden-IP-Adresse als Beweis persistiert
- Status wechselt zu _Akzeptiert_ mit markiertem Übergangsverlauf
- Event `ProformaAcceptedEvent` an Flow Builder dispatched

Bei einer Ablehnung ist das Feld _Begründung_ obligatorisch — nützlich für Ihre Verkäufer, die den Kunden mit einem Gegenangebot kontaktieren können.

**Anpassung:** Die Akzeptanzseite verwendet die Standard-Twig-Blöcke des Storefronts und erbt Ihr Theme. Sie können `@DfProforma/storefront/page/account/proforma/quote.html.twig` von Ihrem Theme aus überschreiben.

## Status-Workflow

Sechs Status decken den gesamten Lebenszyklus eines Angebots ab:

- **Entwurf** — Angebot erstellt, aber noch nicht an den Kunden versendet
- **Gesendet** — E-Mail versendet, Kundenantwort erwartet
- **Akzeptiert** — Kunde hat auf _Annehmen_ auf der öffentlichen Seite geklickt
- **Abgelehnt** — Kunde hat auf _Ablehnen_ mit Begründung geklickt
- **Abgelaufen** — Gültigkeit ohne Antwort überschritten (automatischer Übergang über Scheduled Task)
- **Konvertiert** — Zugrunde liegende Bestellung bezahlt, automatische Konvertierung

Jeder Übergang wird mit Zeitstempel auf die Sekunde genau, Akteur-Kennung, Auslöser-Typ (_Verkäufer_, _Kunde_, _System_, _Zahlung_) und JSON-Payload für freie Metadaten persistiert. Sie können jederzeit den genauen Verlauf eines Angebots rekonstruieren.

## Auto-Konvertierung bei Zahlung

Das Modul registriert einen Subscriber auf das Event `order_transaction.state.paid` der Shopware-Statemachine. Wenn eine Transaktion in den Status _bezahlt_ wechselt (Stripe, Überweisung, PayPal usw.), der Subscriber:

1. Sucht alle Pro-forma-Angebote im Status _Akzeptiert_, die mit der Bestellung verknüpft sind
2. Wechselt sie in den Status _Konvertiert_
3. Markiert den Übergangsverlauf mit Auslöser-Typ _Zahlung_

Kein menschliches Eingreifen, kein Cron, keine Verzögerung. Ihre Vertriebsberichte bleiben mühelos konsistent.

Um die Auto-Konvertierung zu deaktivieren (falls Ihr Team manuelle Kontrolle bevorzugt), deaktivieren Sie die Option unter _Plugin-Konfiguration → Auto-Konvertierung bei Zahlung_.

## Flow Builder — Business Events

Zwei Standard-Shopware-Business-Events werden vom Modul emittiert:

- `ProformaGeneratedEvent` — Bei der Angebotserstellung (implementiert `BusinessEventInterface`)
- `ProformaAcceptedEvent` — Bei der Kundenakzeptanz (implementiert `BusinessEventInterface`)

Beide erscheinen automatisch in der Trigger-Liste des nativen Shopware Flow Builders. Sie können jede Flow-Aktion daran anhängen:

- Slack-Benachrichtigung an das Vertriebsteam bei Akzeptanz
- Interne Zusammenfassungs-E-Mail an den zuständigen Verkäufer
- Webhook an Ihr CRM (HubSpot, Salesforce, Pipedrive…)
- Aktualisierung eines Custom-Feldes am Kunden (z. B. Tag `quote-accepted`)
- Mobile Push-Benachrichtigung über einen Drittanbieter-Service

Kein Eingriff in den Code des Moduls nötig — alles wird unter _Einstellungen → Shop → Flow Builder_ konfiguriert.

## Anpassung der PDF-Vorlage

Das Angebots-PDF wird über `DocumentFileRendererRegistry` gerendert (das neue Dateirendering-System von Shopware 6.7), aus der Twig-Vorlage `@DfProforma/documents/proforma.html.twig`, die mit dem Modul geliefert wird.

Um sie anzupassen, erstellen Sie ein Custom-Plugin oder überschreiben Sie sie von Ihrem Theme aus unter Beachtung der Shopware-Standard-Twig-Vorlagenhierarchie:

```
custom/plugins/YourTheme/src/Resources/views/documents/proforma.html.twig
```

Die mitgelieferte Vorlage stellt folgende identifizierte Twig-Blöcke bereit:

- Kopfzeile mit Logo und Firmenangaben
- Kundenblock
- Zusammenfassung der Bestellpositionen
- HT-/TTC-Summen mit MwSt.-Aufschlüsselung
- Zusammenfassungsstreifen am Fuß (PF-Nummer, Ausstellungs- und Ablaufdatum)
- Wasserzeichen _PRO FORMA_
- Markenfarbe konfigurierbar über `config.accentColor`

In der Vorlage verfügbare Variablen: `order` (OrderEntity mit allen ihren Assoziationen geladen), `config` (Dokumentkonfiguration einschließlich `documentNumber`, `documentDate`, `validUntil`, `validityDays`), `context`.

## Mehrsprachigkeit

FR, EN, DE und ES werden standardmäßig mitgeliefert, Storefront- und Admin-Snippets. Um weitere Sprachen hinzuzufügen, erstellen Sie eine Snippet-Datei pro Locale in `src/Resources/snippet/` gemäß der Shopware-Standardkonvention.

Die Transaktions-E-Mail-Vorlagen sind ebenfalls mehrsprachig: Die richtige Vorlage wird automatisch basierend auf der Sales-Channel-Sprache des Kunden zum Versandzeitpunkt ausgewählt. Sie können Vorlagen pro Sprache unter _Einstellungen → Shop → E-Mail-Vorlagen_ anpassen.

## API — verfügbare Admin-Endpunkte

```
POST   /api/_action/df-proforma/generate         # Generiert ein Angebot für eine Bestellung
POST   /api/_action/df-proforma/mark-sent        # Als gesendet markieren (manueller Übergang)
GET    /api/_action/df-proforma/by-order/{id}    # Listet die Angebote einer Bestellung
```

`df_proforma`-Entitäten sind auch über die Standard-Shopware-DAL-API (`/api/df-proforma`) für Suchen, Exporte oder erweiterte Integrationen zugänglich.

## Deinstallation

Standardmäßig werden Geschäftsdaten bei der Deinstallation beibehalten (Option _Keep User Data_ aktiviert). Sie bewahren so die Audit-Historie der ausgestellten Angebote, nützlich für Compliance und kommerzielle Nachvollziehbarkeit.

Um die vollständige Entfernung zu erzwingen (Tabelle `df_proforma`, Dokumenttyp, Nummernkreis, E-Mail-Vorlage), deaktivieren Sie die Option _Keep User Data_ im Deinstallations-Prompt.

**Empfehlung:** Behalten Sie die Daten standardmäßig bei. Erzwingen Sie die Entfernung nur, wenn Sie sicher sind, dass Sie nie wieder aus kommerziellen, buchhalterischen oder rechtlichen Gründen auf die Angebotshistorie zugreifen müssen.

## Fehlerbehebung

### Der Pro-forma-Tab erscheint nicht auf der Bestelldetailseite

Das Administrations-Bundle wurde nach der Installation nicht neu kompiliert. Führen Sie `bin/build-administration.sh` aus, dann `bin/console cache:clear`.

### Fehler "Unable to find a document generator with type df_proforma"

Der Service-Tag des Renderers ist nicht korrekt — dieser Bug wurde ab 1.0.2 behoben. Stellen Sie sicher, dass Sie eine Plugin-Version ≥ 1.0.2 verwenden.

### Fehler "Call to undefined method Context::getSalesChannelId()"

Historische Ursache: alte Signatur des Konstruktors `RenderedDocument`. Behoben in 1.0.4. Aktualisieren Sie auf 1.0.6.

### Twig-Fehler "Cannot rewind a generator that was already run"

Behoben in 1.0.6 — die Vorlage wurde angepasst, um einen aus `|filter()` erzeugten Generator nicht zweimal zu konsumieren.

### Der Kunde erhält die E-Mail, aber die Akzeptanz-URL liefert einen 404-Fehler

Prüfen Sie, dass der Storefront-Sales-Channel korrekt als Domain des für die Bestellung verwendeten Sales Channels registriert ist. Die öffentliche Route `/proforma/accept/{token}` ist auf dem Storefront registriert — sie funktioniert nicht, wenn Sie die URL über die Admin-Domain aufrufen.

### Der automatische Ablauf funktioniert nicht

Prüfen Sie, dass die Shopware-_Message-Worker_ im Hintergrund laufen (`bin/console messenger:consume` oder über einen Supervisor wie systemd/supervisord). Der Ablauf läuft über die Standard-Shopware-Message-Queue.

## Support und Updates

12 Monate Updates enthalten (Shopware-Kompatibilität, Bugfixes, kleinere Funktionserweiterungen). E-Mail-Support auf Französisch und Englisch innerhalb von 24 Werkstunden. PHP-Quellcode im Klartext geliefert, PSR-4-konform, auditierbar und modifizierbar.

Bei Fragen oder Meldungen: [contact@datafirefly.com](https://www.datafirefly.com/contact/).
