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:
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.