Extended Voucher Rules: Technische Details
Technische Details der Extended Voucher Rules: Modul-ID, Validierungsreihenfolge, Vormerk-Mechanik, erweiterte Shop-Klassen, Services, Template-Erweiterung und Datenbanktabellen.
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:
- Zahlart-Beschränkung
- Versandart-Beschränkung
- Erstbesteller
- Zeitfenster
- Kombinationen (Höchstzahl, dann Sperrliste)
- Mindestbestellwert pro Zahlart
- 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:
layout/base.html.twigbindet das Stylesheetcss/voucherrules.cssim Blockbase_styleein.page/checkout/inc/summary_sidebar.html.twigergänzt den Blockcheckout_basketcontents_grandtotalum die Hinweisbox. Sie nutztoViewConf.getPendingVouchers()undoViewConf.getVoucherRulesHints(), der Entfernen-Link ruftindex.php?cl=basket&fnc=removePendingVouchermitvoucherNrund Session-Token auf.
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 EXISTSangelegt. Bei der Deaktivierung bleiben die Daten erhalten.