Markus Michalski FAQ

Extended Voucher Rules: Technische Details

Technische Details der Extended Voucher Rules: Modul-ID, Validierungsreihenfolge, Vormerk-Mechanik, erweiterte Shop-Klassen, Services, Template-Erweiterung und Datenbanktabellen.

English Version

Zurück zur Übersicht

Extended Voucher Rules: Technische Details

Live Demo: Teste dieses und weitere Plugins live — ohne Installation, ohne Risiko: demo.markus-michalski.net

Modul im Überblick

Eigenschaft Wert
Composer-Paket mmd/oxid7-voucherrules
Modul-ID mmd_voucherrules
Namespace Mmd\VoucherRules (PSR-4, Verzeichnis src/)
Zielverzeichnis mmd/voucherrules
Metadata-Version 2.1
Events onActivate legt die Tabellen an, onDeactivate ist bewusst leer

Validierungsreihenfolge

Die zentrale Prüfung liegt in VoucherValidationService::validate(). Sie wird aus der erweiterten Voucher-Klasse aufgerufen, nachdem die Standardprüfung von OXID bestanden wurde. Die Regeln laufen in dieser Reihenfolge, die erste ausgelöste Ausnahme beendet die Prüfung:

  1. Zahlart-Beschränkung
  2. Versandart-Beschränkung
  3. Erstbesteller
  4. Zeitfenster
  5. Kombinationen (Höchstzahl, dann Sperrliste)
  6. Mindestbestellwert pro Zahlart
  7. Mindestbestellwert pro Versandart

Folge der Reihenfolge: Solange eine Zahl- oder Versandart-Regel noch aussteht, werden die Regeln danach (zum Beispiel das Zeitfenster) noch nicht ausgewertet.

graph TD
    A[VoucherValidationService.validate] --> B[Zahlart-Beschränkung]
    B --> C[Versandart-Beschränkung]
    C --> D[Erstbesteller]
    D --> E[Zeitfenster]
    E --> F[Kombinationen]
    F --> G[Mindestbestellwert Zahlart]
    G --> H[Mindestbestellwert Versandart]
    H --> I[Alle Regeln bestanden]
    B -->|Zahlart fehlt oder passt nicht| P[VoucherRulePendingException]
    C -->|Versandart fehlt oder passt nicht| P
    G -->|Zahlart fehlt oder Wert nicht erreicht| P
    H -->|Versandart fehlt oder Wert nicht erreicht| P
    D -->|nicht Erstbesteller| V[VoucherRuleViolationException]
    E -->|außerhalb des Fensters| V
    F -->|gesperrt oder Höchstzahl| V

Verhalten je Regel

Regel Bedingung Ergebnis
Zahlart Beschränkung vorhanden, keine Zahlart in der Session vorgemerkt (Hinweis "Zahlart ausstehend")
Zahlart Beschränkung vorhanden, Zahlart nicht erlaubt vorgemerkt (Hinweis "Zahlart passt nicht")
Versandart analog zur Zahlart vorgemerkt
Erstbesteller Option gesetzt und Benutzer hat nicht stornierte Bestellungen (OXSTORNO = 0, gleicher Shop); ohne Benutzer-ID wird nicht geprüft abgelehnt
Zeitfenster aktive Fenster vorhanden, keines passt zu Wochentag und Uhrzeit abgelehnt
Kombination Höchstzahl > 0 und Zahl der unterschiedlichen Serien der anderen eingelösten Gutscheine (ohne den Gutschein selbst, vorgemerkte nicht mitgezählt) >= Höchstzahl, oder Sperrpaar mit einem eingelösten Gutschein abgelehnt
Mindestbestellwert Einträge vorhanden, keine Zahl-/Versandart gewählt vorgemerkt
Mindestbestellwert Eintrag für die gewählte Zahl-/Versandart, Warenkorbwert kleiner vorgemerkt (Hinweis mit Betrag)

Der Wochentag wird mit date('N') ermittelt, die Uhrzeit mit CURTIME() der Datenbank. Die Fensterprüfung ist CURTIME() BETWEEN STARTTIME AND ENDTIME, bei Eingabe als HH:MM endet ein Fenster also bei Sekunde 00.

Vormerk-Mechanik

Ein Gutschein mit offener Bedingung löst eine VoucherRulePendingException aus. Die Klasse Extension\Model\Voucher fängt sie, merkt die Gutscheinnummer vor und legt einen Hinweis ab. Die Ausnahme wird erneut geworfen, damit OXID keinen Rabatt anrechnet. Eine VoucherRuleViolationException entfernt die Vormerkung und weist den Gutschein ab. Beide Ausnahmen erweitern die OXID-VoucherException.

Gespeichert wird in der Session unter zwei Schlüsseln: mmd_voucherrules_pending (Liste der Gutscheinnummern) und mmd_voucherrules_hints (Hinweise mit Schlüssel und Mindestwert). Gelesen werden die Session-Werte paymentid und sShipSet.

graph TD
    A[Kunde wählt Zahlart oder Versandart] --> B[Basket.calculateBasket]
    B --> C{Vormerkungen in der Session?}
    C -->|Nein| D[Normale Berechnung]
    C -->|Ja| E[addVoucher je vorgemerkter Nummer]
    E --> F{Ergebnis}
    F -->|bestanden| G[Gutschein aktiv, Vormerkung entfernt]
    F -->|weiter offen| H[bleibt vorgemerkt]
    F -->|endgültig ungültig| I[Vormerkung entfernt]

Die Auto-Aktivierung läuft nur, wenn in der Session eine Zahl- oder eine Versandart gesetzt ist. Nach Order::finalizeOrder() werden Vormerkungen, Hinweise sowie paymentid und sShipSet gelöscht. Bei leerem Warenkorb (Basket::calculateBasket()) werden nur Vormerkungen und Hinweise gelöscht.

Erweiterte Shop-Klassen

OXID-Klasse Modul-Klasse Aufgabe
Voucher Extension\Model\Voucher Erweiterte Prüfung in checkVoucherAvailability() und checkBasketVoucherAvailability(), Vormerkung
VoucherSerie Extension\Model\VoucherSerie Zugriff auf Erstbesteller-Flag und Höchstzahl
Basket Extension\Model\Basket Auto-Aktivierung und Hinweise in calculateBasket(), Ausblenden der roten Fehlerbanner für Vormerkungen
BasketController Extension\Controller\BasketController addVoucher() ohne Fehlerbanner bei Vormerkung, Aktion removePendingVoucher
ViewConfig Extension\Core\ViewConfig getVoucherRulesHints(), getPendingVouchers(), hasPendingVouchers() für Templates
Order Extension\Model\Order Aufräumen in finalizeOrder()

Admin-Controller

Controller-ID Klasse Tab-ID in menu.xml
mmd_voucherrules_main VoucherRulesMain tbclvoucherserie_rules_main
mmd_voucherrules_timewindow VoucherRulesTimeWindow tbclvoucherserie_rules_timewindow
mmd_voucherrules_combination VoucherRulesCombination tbclvoucherserie_rules_combination
mmd_voucherrules_payment_minval VoucherRulesPaymentMinVal tbclvoucherserie_rules_payment_minval

Die Tabs hängen unter dem Menüpunkt mxvouchers (Hauptmenü mxshopsett). Alle schreibenden Aktionen prüfen die Session-Challenge, Löschen und Ändern prüft zusätzlich Serie und Shop des Eintrags.

Services und Erweiterbarkeit

Die Services und Repositories sind im Symfony-Container als öffentlich markiert (services.yaml) und können über die ContainerFactory bezogen werden: VoucherValidationService, FirstOrderCheckService, TimeWindowCheckService, CombinationCheckService, VoucherRestrictionHintService sowie die Repositories VoucherRulesConfigRepository, PaymentRestrictionRepository, DeliveryRestrictionRepository, TimeWindowRepository, CombinationRepository, PaymentMinValueRepository und DeliveryMinValueRepository. Ein dokumentiertes Erweiterungs-API oder Events gibt es nicht.

Erweiterung der Templates

Für das Theme Apex liefert das Modul zwei Template-Erweiterungen mit:

Für andere Themes kann dasselbe Muster in der Checkout-Zusammenfassung des Themes umgesetzt werden.

Datenbanktabellen

Sieben Tabellen mit dem Präfix mmd_voucherrules_, alle mit OXSHOPID, die Gutscheinserie steht in OXVOUCHERSERIEID:

Tabelle Zweck Wichtige Spalten
mmd_voucherrules_config Einstellungen je Serie (eindeutig je Serie und Shop) FIRSTORDERONLY, MAXCOMBINED
mmd_voucherrules_payment Erlaubte Zahlarten OXPAYMENTID
mmd_voucherrules_delivery Erlaubte Versandarten OXDELIVERYSETID
mmd_voucherrules_timewindow Zeitfenster WEEKDAYS (Bitmaske Bit 0 = Montag bis Bit 6 = Sonntag, 127 = alle), STARTTIME, ENDTIME, ACTIVE
mmd_voucherrules_combination Gesperrte Paare, Serien-IDs in sortierter Reihenfolge abgelegt OXVOUCHERSERIEID_A, OXVOUCHERSERIEID_B
mmd_voucherrules_payment_minval Mindestbestellwert je Zahlart OXPAYMENTID, MINORDERVALUE
mmd_voucherrules_delivery_minval Mindestbestellwert je Versandart OXDELIVERYSETID, MINORDERVALUE

Die Tabellen werden bei der Aktivierung mit CREATE TABLE IF NOT EXISTS angelegt. Bei der Deaktivierung bleiben die Daten erhalten.