Hallo allerseits,
wir haben folgendes Problem.
Wir wollen in unserem StorefrontController einen Gast-Benutzer anlegen und anschließend eine Bestellung erstellen.
Die Reihenfolge in der wir vorgehen:
- Gast-Benutzer erstellen über das customer repository (funktioniert)
- Dabei erstellen wir die CustomerId per Uuid::randomHex
- Login über den AccountService mit loginById
- Das daraus erhaltene contextToken ersetzt nun unser altes Token
- Speichern des Contexts über den SalesChannelContextPersister
$this->salesChannelContextPersister->save(
$this->contextToken,
[‚customerId‘ => $customerId],
$this->context->getSalesChannelId()
);
- Platzieren der Bestellung über den OrderService
$this->orderService->createOrder($orderDataBag, $this->context);
Anschließend erhalten wir die Fehlermeldung: „Customer is not logged in.“
Was außerdem interessant ist. Wenn wir nachdem wir auf der Fehlerseite gelandet sind, das Ganze per Reload erneut ausführen, wird die Bestellung ohne Probleme angelegt.
Haben wir hier irgendeinen Schritt vergessen oder falsch gemacht? Mir scheint, als wäre das Problem wohl hauptsächlich, dass User und Context nichts miteinander anfangen können. Sicher bin ich mir allerdings nicht.
Mal aus meiner Wühlkiste:
$customerSalesChannelContext = $this->salesChannelContextFactory->create(
Uuid::randomHex(),
$salesChannelId,
[
SalesChannelContextService::CUSTOMER_ID => $customer->getId(),
SalesChannelContextService::PAYMENT_METHOD_ID => $paymentMethodId,
SalesChannelContextService::SHIPPING_METHOD_ID => $shippingMethodId
SalesChannelContextService::BILLING_ADDRESS_ID => $customer->getDefaultBillingAddressId(),
SalesChannelContextService::SHIPPING_ADDRESS_ID => $customer->getDefaultShippingAddressId(),
]
);
$cart = new Cart(
$customerSalesChannelContext->getToken()
);
$lineItem = new LineItem(
Uuid::randomHex(),
'product',
Uuid::randomHex(),
1
);
$lineItem->setLabel('...')
->setGood(true)
->setStackable(true)
->setRemovable(true)
->setDescription(null)
->setQuantityInformation(new QuantityInformation())
->setCover(null)
->setPayload([
'productNumber' => '...'
'customFields' => null,
'taxId' => $taxId,
'options' => [],
])
->setStates([State::IS_PHYSICAL]);
try {
$cart = $this->cartService->add(
$cart,
[$lineItem],
$customerSalesChannelContext
);
$this->cartService->recalculate(
$cart,
$customerSalesChannelContext
);
$response = $this->cartOrderRoute->order(
$cart,
$customerSalesChannelContext,
new RequestDataBag()
);
}
catch (\Exception $exception) { // ...
}
Also einfach einen neuen saleschannelcontext aus dem customer erstellen.
Viele Grüße
Hi,
danke für die schnelle Antwort. Ich versuche das gerade mal testweise umzusetzen. Allerdings bekomme ich dabei einen Fehler.
Argument #15 ($salesChannelContextFactory) must be of type Shopware\Core\System\SalesChannel\Context\SalesChannelContextFactory, Shopware\Core\System\SalesChannel\Context\CachedSalesChannelContextFactory given
Injected ist aber definitiv SalesChannelContextFactory. Sowohl im Constructor, als auch in der Services.xml.
Mein Problem hat sich nun wohl erledigt. Den Fehler konnte ich beseitigen, indem ich den Parameter im Constructor als AbstractSalesChannelContextFactory definiere. In der Service.xml allerdings die ChannelContextFactory injecte.
Die Lösung von @EikeBrandtWarneke hat damit dann zum Erfolg geführt. Vielen Dank.