Dokumentation

Konfiguration des Order Printers

Der Order Printer bietet umfangreiche Konfigurationsmöglichkeiten, um das System an Ihre spezifischen Anforderungen anzupassen.

Umgebungskonfiguration

Die Hauptkonfiguration erfolgt über die .env.local-Datei. Hier sind die wichtigsten Einstellungen:

Shopware API-Konfiguration

# Shopware API-Zugang
SHOPWARE_HOST=https://ihre-shopware-domain.de
SHOPWARE_CLIENT_ID=ihre_client_id
SHOPWARE_CLIENT_SECRET=ihre_client_secret

# API-Timeout (in Sekunden)
SHOPWARE_API_TIMEOUT=30

# API-Rate-Limiting
SHOPWARE_API_RATE_LIMIT=100
SHOPWARE_API_RATE_LIMIT_INTERVAL=60

Druckerkonfiguration

# Druckeranbindung: file:///dev/usb/lp0, tcp://<host>:9100 oder dummy://
PRINTER_DSN=file:///dev/usb/lp0

# Optional: Restaurantname auf Testbons (bin/console printer:test), Standard ist die Domain aus SHOPWARE_HOST
SHOP_NAME="Masala Mio"

# Druckerauflösung (DPI)
PRINTER_DPI=203

# Zeichen pro Zeile
PRINTER_CHARACTERS_PER_LINE=42

# Druckgeschwindigkeit (1-5, 1 = langsam, 5 = schnell)
PRINTER_SPEED=3

# Druckerdichte (1-15)
PRINTER_DENSITY=10

Systemkonfiguration

# Polling-Intervall (in Sekunden)
POLLING_INTERVAL=10

# Maximale Anzahl gleichzeitiger Druckaufträge
MAX_CONCURRENT_PRINTS=5

# Warteschlangen-Timeout (in Sekunden)
QUEUE_TIMEOUT=300

# Datenverzeichnis für Bon-Archiv
DATA_DIR="/data/receipts/"

# Log-Level (debug, info, notice, warning, error, critical, alert, emergency)
LOG_LEVEL=info

Bon-Formatierung

Standard-Bon-Layout

Der Order Printer generiert Bons mit folgendem Standardlayout:

┌────────────────────────────────────────┐
│              IHR SHOP-NAME              │
│    Musterstraße 123 • 12345 Musterstadt │
│          Tel: 01234/567890              │
├────────────────────────────────────────┤
│                BON #1001                 │
│            11.01.2024 14:30            │
├────────────────────────────────────────┤
│ Kunde: Max Mustermann                    │
│ Tel: 0176/12345678                       │
├────────────────────────────────────────┤
│ 1x Pizza Margherita              8,99 € │
│ 2x Spaghetti Bolognese          15,98 € │
│ 1x Salat Caesar                  5,99 € │
├────────────────────────────────────────┤
│ Zwischensumme:                  30,96 € │
│ Lieferkosten:                    2,50 € │
│ Gesamt:                          33,46 € │
├────────────────────────────────────────┤
│ Zahlungsart: Barzahlung                  │
│ Lieferart: Abholung                      │
├────────────────────────────────────────┤
│           Vielen Dank für Ihren          │
│                Einkauf!                 │
└────────────────────────────────────────┘

Bon-Layout anpassen

Sie können das Bon-Layout durch Anpassung der ReceiptFormatter-Klasse ändern:

// In src/Infra/Printer/Epson/ReceiptFormatter.php

public function formatHeader(): self
{
    $this->content .= self::ALIGN_CENTER;
    $this->content .= self::DOUBLE_WIDTH_ON;
    $this->content .= "IHR SHOP-NAME\n";
    $this->content .= self::DOUBLE_WIDTH_OFF;
    $this->content .= self::ALIGN_CENTER;
    $this->content .= "Musterstraße 123 • 12345 Musterstadt\n";
    $this->content .= "Tel: 01234/567890\n";
    $this->content .= self::FEED;
    
    return $this;
}

Logo hinzufügen

Um ein Logo zum Bon hinzuzufügen, müssen Sie das Logo als ESC/POS-Bitmap konvertieren:

# Logo konvertieren (erfordert ImageMagick)
convert logo.png -resize 384x128 -colorspace Gray -dither None logo.bmp

# Logo in ESC/POS-Format konvertieren
php bin/console order-printer:convert-logo logo.bmp logo.escpos

Dann können Sie das Logo in der ReceiptFormatter-Klasse einbinden:

public function addLogo(): self
{
    $logoPath = __DIR__ . '/../../../public/logo.escpos';
    if (file_exists($logoPath)) {
        $this->content .= file_get_contents($logoPath);
        $this->content .= self::FEED;
    }
    
    return $this;
}

Wiederholungen bei Druckfehlern

Kurze Ausfälle sind normal: der Pi startet neu, das WLAN im Restaurant hängt, der Drucker hat kein Papier. Der Order Printer gibt deshalb nie nach einem einzigen fehlgeschlagenen Versuch auf:

  • Ein fehlgeschlagener Druckauftrag wird 10-mal mit steigendem Abstand wiederholt: nach 10 s, 20 s, 40 s, 80 s, 160 s und danach alle 5 Minuten, insgesamt rund 30 Minuten.
  • Die Bestellung bleibt in Shopware offen, bis der Bon tatsächlich gedruckt wurde. Erst ein erfolgreicher Druck setzt sie auf in Bearbeitung.
  • Während ein Auftrag auf seine Wiederholung wartet, stellt die Abfrage dieselbe Bestellung nicht erneut in die Warteschlange. Sobald der Drucker wieder da ist, wird jede Bestellung genau einmal gedruckt.
  • Nach dem letzten Versuch wird der Auftrag als fehlgeschlagen markiert und eine error-Logzeile mit der Bestellnummer geschrieben, zum Beispiel Printing order 10556 failed permanently after 11 attempt(s): Cannot connect to printer "tcp://…". Nutzen Sie sie für das Monitoring. Da die Bestellung weiterhin offen ist, stellt die nächste Abfrage sie erneut in die Warteschlange und ein neues Wiederholungsfenster beginnt. Es geht also nichts verloren, solange der Drucker irgendwann zurückkommt.

Endgültig fehlgeschlagene Aufträge lassen sich anzeigen und aufräumen:

bin/console messenger:failed:show
bin/console messenger:failed:remove <id>

Eine einzelne Bestellung von Hand nachdrucken:

bin/console app:print-order --order-number=10556

Erweiterte Konfiguration

Mehrere Drucker

Eine Order-Printer-Instanz druckt auf genau eine PRINTER_DSN. Für mehrere Drucker (zum Beispiel Küche und Theke) betreiben Sie je Drucker eine eigene Instanz mit eigener .env.local, eigenem DATA_DIR und eigener DATABASE_URL, die alle auf denselben Shopware-Shop zeigen. Da jede Instanz gedruckte Bestellungen auf in Bearbeitung setzt, sollte nur eine davon mit --mark-in-progress laufen; die übrigen starten Sie mit bin/console app:print-order --all-open --no-mark-in-progress in einem eigenen Zeitplan oder filtern die Bestellungen je Instanz wie unten beschrieben.

Bestellfilter

Sie können die abzurufenden Bestellungen filtern, indem Sie die OrderRepository-Klasse anpassen:

// In src/Infra/Shopware/OrderRepository.php

public function findNewNumbers(): array
{
    // Nur Bestellungen mit bestimmten Zahlungsarten
    $paymentMethods = ['cash', 'card'];
    
    // Nur Bestellungen über einem bestimmten Wert
    $minOrderValue = 5.00;
    
    // Nur Bestellungen für bestimmte Lieferarten
    $deliveryTypes = ['delivery', 'takeaway'];
    
    return $this->shopwareClient->getOrders(
        $paymentMethods,
        $minOrderValue,
        $deliveryTypes
    );
}

Benachrichtigungen

Sie können Benachrichtigungen für bestimmte Ereignisse einrichten:

# In config/packages/messenger.yaml

framework:
    messenger:
        routing:
            'Veliu\OrderPrinter\Domain\Event\OrderPrintedEvent': async
            'Veliu\OrderPrinter\Domain\Event\PrintFailedEvent': failed

Dann können Sie Event-Listener erstellen:

#[AsMessageHandler]
final class OrderPrintedNotificationHandler
{
    public function __construct(
        private MailerInterface $mailer,
        private string $adminEmail
    ) {}
    
    public function __invoke(OrderPrintedEvent $event): void
    {
        $email = (new Email())
            ->from('noreply@shopbite.de')
            ->to($this->adminEmail)
            ->subject('Bestellung gedruckt: ' . $event->orderNumber)
            ->text('Die Bestellung ' . $event->orderNumber . ' wurde erfolgreich gedruckt.');
        
        $this->mailer->send($email);
    }
}

Performance-Optimierung

Caching

Aktivieren Sie das Caching für häufig abgerufene Daten:

# In config/packages/cache.yaml

framework:
    cache:
        app: cache.adapter.filesystem
        default_redis_provider: 'redis://localhost'
        pools:
            shopware.cache:
                adapter: cache.adapter.redis
                default_lifetime: 3600

Batch-Verarbeitung

Für hohe Bestellvolumen können Sie die Batch-Verarbeitung aktivieren:

# Batch-Konfiguration
BATCH_SIZE=10
BATCH_INTERVAL=30

Lastverteilung

Für Systeme mit hohem Durchsatz können Sie mehrere Worker einrichten:

# Mehrere Worker starten
bin/console messenger:consume async --limit=10 --time-limit=3600 &
bin/console messenger:consume async --limit=10 --time-limit=3600 &
bin/console messenger:consume async --limit=10 --time-limit=3600 &

Sicherheit

API-Sicherheit

  • HTTPS erzwingen: Stellen Sie sicher, dass Ihre Shopware-Instanz HTTPS verwendet
  • IP-Beschränkung: Beschränken Sie den API-Zugriff auf bestimmte IP-Adressen
  • Rate-Limiting: Konfigurieren Sie angemessene Rate-Limits

Druckersicherheit

  • Drucker-IP-Beschränkung: Beschränken Sie den Zugriff auf den Drucker
  • Drucker-Passwort: Richten Sie ein Drucker-Passwort ein
  • Verschlüsselung: Verwenden Sie verschlüsselte Verbindungen für Netzwerkdrucker

Wartungskonfiguration

Log-Rotation

Richten Sie eine Log-Rotation ein, um Speicherplatz zu sparen:

# Logrotate-Konfiguration (/etc/logrotate.d/order-printer)
/var/log/order-printer-*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 644 www-data www-data
}

Datenbereinigung

Richten Sie eine regelmäßige Datenbereinigung ein:

# Cron-Job für Datenbereinigung (täglich um 3 Uhr)
0 3 * * * /pfad/zum/project/bin/console order-printer:cleanup --days=30

Nächste Schritte