Zum Inhalt

Erweiterbarkeit

Das Plugin ist über Symfony Tagged Services erweiterbar — du kannst eigene Format-Parser, Customer-Resolver oder Product-Resolver in einem eigenen Plugin oder direkt im Projekt hinzufügen, ohne den Kommora-Plugin-Code anzufassen.

Wann brauche ich das?

In 99 % der Fälle reichen die mitgelieferten CSV/JSON/XML-Parser. Eigene Parser brauchst du nur, wenn dein Großkunde ein proprietäres Format wie cXML, OpenTRANS oder EDIFACT sendet — und du nicht auf v1.1+ warten kannst.

Eigener Format-Parser

1. Klasse implementieren

<?php declare(strict_types=1);

namespace MyShop\B2BCxmlImport\Parser;

use Kommora\B2BOrderImport\Entity\Profile\ProfileEntity;
use Kommora\B2BOrderImport\Service\Parser\FormatParserInterface;
use Kommora\B2BOrderImport\Service\Parser\ParserException;

class CxmlParser implements FormatParserInterface
{
    public function getFormat(): string
    {
        return 'cxml';
    }

    public function parse(string $payload, ProfileEntity $profile): array
    {
        $xml = simplexml_load_string($payload);
        if ($xml === false) {
            throw new ParserException('Invalid cXML');
        }

        // Eigene Parsing-Logik …
        return [
            'orderHeader' => [
                'buyerEmail' => (string) $xml->Request->OrderRequest->OrderRequestHeader->Contact->Email,
                'orderNumber' => (string) $xml->Request->OrderRequest->OrderRequestHeader['orderID'],
            ],
            'lineItems' => array_map(fn($item) => [
                'sku'      => (string) $item->ItemID->SupplierPartID,
                'quantity' => (int) $item['quantity'],
            ], iterator_to_array($xml->Request->OrderRequest->ItemOut)),
        ];
    }
}

2. Service registrieren

In services.xml deines Plugins:

<service id="MyShop\B2BCxmlImport\Parser\CxmlParser">
    <tag name="kommora_b2b_order_import.format_parser"/>
</service>

3. Im Profil verfügbar machen

Erweitere das Format-Dropdown im Admin durch ein eigenes Snippet:

{
    "kommoraB2BOrderImport": {
        "format": {
            "cxml": "cXML (Coupa/Ariba)"
        }
    }
}

In der Admin-Vue-Komponente extending the formatChoices array.

4. Profile anlegen

Nach Cache-Clear erscheint cXML in der Format-Auswahl beim Anlegen eines neuen Profils.

Eigener Customer-Resolver

Wenn deine Kunden-Match-Logik vom Standard abweicht (z. B. Match per customField.erpNumber):

<?php declare(strict_types=1);

namespace MyShop\B2BCustomMatch;

use Kommora\B2BOrderImport\Entity\Profile\ProfileEntity;
use Kommora\B2BOrderImport\Service\Dto\ParsedOrder;
use Kommora\B2BOrderImport\Service\Resolver\CustomerResolverInterface;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;

class ErpNumberCustomerResolver implements CustomerResolverInterface
{
    public function __construct(private readonly EntityRepository $customerRepository) {}

    public function getStrategy(): string
    {
        return 'erpNumber';
    }

    public function resolve(ParsedOrder $order, ProfileEntity $profile, Context $context): ?CustomerEntity
    {
        $erp = $order->extra['erpNumber'] ?? null;
        if (!$erp) return null;

        $criteria = (new Criteria())
            ->addFilter(new EqualsFilter('customFields.erpNumber', $erp))
            ->setLimit(1);

        $customer = $this->customerRepository->search($criteria, $context)->first();
        return $customer instanceof CustomerEntity ? $customer : null;
    }
}
<service id="MyShop\B2BCustomMatch\ErpNumberCustomerResolver">
    <argument type="service" id="customer.repository"/>
    <tag name="kommora_b2b_order_import.customer_resolver"/>
</service>

Im Profil dann „Per ERP-Nummer" als Strategie auswählbar (über Snippet erweitern).

Eigener Product-Resolver

Gleiche Mechanik:

class ProductByCustomerSkuResolver implements ProductResolverInterface
{
    public function getStrategy(): string { return 'customerSku'; }

    public function resolve(ParsedLineItem $li, ProfileEntity $profile, Context $context): ?ProductEntity
    {
        // Lookup in einer Cross-Reference-Tabelle …
    }
}

Tag: kommora_b2b_order_import.product_resolver.

Tagged-Services-Übersicht

Tag Interface Wofür
kommora_b2b_order_import.format_parser FormatParserInterface Neues Format (cXML, EDIFACT, OpenTRANS, …)
kommora_b2b_order_import.customer_resolver CustomerResolverInterface Eigene Kunden-Match-Strategie
kommora_b2b_order_import.product_resolver ProductResolverInterface Eigene Produkt-Match-Strategie

Roadmap

Eigene Parser sind aktuell nur über Custom-Plugin möglich. Ab v1.1 liefern wir cXML mit, ab v1.3 EDIFACT. Der Tagged-Service-Ansatz bleibt aber erhalten — du kannst auch parallel zu unseren mitgelieferten Parsern eigene haben.

Nächster Schritt

Troubleshooting — häufige Fehler und Lösungen.