I want to mark an order as shipped and add the tracking code inside a Shopware 6 CLI command.
I understand that I have to create a delivery and attach the tracking code. I could do this via DAL. But I am wondering if there is a higher-level service for this? Do I have to use the state machine to change the status ? Or can this done in one step?
I have already written a test to check the tracking code:
$this->assertEquals('01234567890123', $order->get('deliveries')[0]->get('tracking_codes')[0]);
I think I can use the logic from \Shopware\Core\Checkout\Order\Api\OrderActionController::orderDeliveryStateTransition
but it would require copy & paste.
EDIT For the tracking code I tried this:
// FIXME: get the right context
$context = Context::createDefaultContext();
$order = $this->findOrder($orderNumber);
/** @var \Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryCollection $deliveries */
$deliveries = $order->get('deliveries');
if (count($deliveries) == 0) {
throw new \LogicException('No delivery found');
}
if (count($deliveries) > 1) {
throw new \LogicException('We support only 1 delivery per order');
}
$deliveries->first()->setTrackingCodes([$trackingCode]);
$this->orderRepository->update([
[
'id' => $order->getId(),
'deliveries' => json_decode( json_encode($deliveries), true)
]
], $context);
But I get:
1. [/] Expected data to be array.
1. [/] Expected data to be array.
1. [/] Expected data to be array.
1. [/] Expected data to be array.
1. [/] Expected data to be array.
1. [/0/deliveries/0/shippingOrderAddress/salutation/translations/2fbb5fe2e29a4d70aa5854ce7ce3e20b/displayName] Dieser Wert sollte nicht leer sein.
1. [/0/deliveries/0/shippingOrderAddress/salutation/translations/2fbb5fe2e29a4d70aa5854ce7ce3e20b/letterName] Dieser Wert sollte nicht leer sein.
1. [/] Expected data to be array.
I also tried
$this->orderRepository->update([
[
'id' => $order->getId(),
'deliveries' => [
$deliveries->first()->getId() => [
'trackingCodes' => [ $trackingCode ]
]
]
]
], $context);
Which makes more sense to my, as I just want to update the tracking code, not the full shipment.
This throws:
Shopware\Core\Framework\DataAbstractionLayer\Write\WriteException : There are 5 error(s) while writing data.
1. [/0/deliveries/9272d3693d014b25aaeadb8249ede5c2/shippingOrderAddressId] Dieser Wert sollte nicht leer sein.
2. [/0/deliveries/9272d3693d014b25aaeadb8249ede5c2/shippingMethodId] Dieser Wert sollte nicht leer sein.
3. [/0/deliveries/9272d3693d014b25aaeadb8249ede5c2/stateId] Dieser Wert sollte nicht leer sein.
4. [/0/deliveries/9272d3693d014b25aaeadb8249ede5c2/shippingDateEarliest] Dieser Wert sollte nicht null sein.
5. [/0/deliveries/9272d3693d014b25aaeadb8249ede5c2/shippingDateLatest] Dieser Wert sollte nicht null sein.
here is how i set an order shipped and complete
use Shopware\Core\System\StateMachine\Aggregation\StateMachineTransition\StateMachineTransitionActions;
use Shopware\Core\System\StateMachine\StateMachineRegistry;
use Shopware\Core\System\StateMachine\Transition;
private function setOrderComplete(OrderEntity $order, Context $context): void
{
$this->stateMachineRegistry->transition(new Transition(
OrderDefinition::ENTITY_NAME,
$order->getId(),
StateMachineTransitionActions::ACTION_COMPLETE,
'stateId'
), $context);
}
private function setDeliveryShipped(OrderDeliveryEntity $delivery, Context $context): void
{
$this->stateMachineRegistry->transition(new Transition(
OrderDeliveryDefinition::ENTITY_NAME,
$delivery->getId(),
StateMachineTransitionActions::ACTION_SHIP,
'stateId'
), $context);
}