<?php declare(strict_types=1);
namespace Shopware\Commercial\MultiWarehouse\Subscriber;
use Doctrine\DBAL\Connection;
use Shopware\Commercial\Licensing\License;
use Shopware\Commercial\MultiWarehouse\Domain\Order\MultiWarehouseStockUpdater;
use Shopware\Commercial\MultiWarehouse\Domain\Product\MultiWarehouseProductFilter;
use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\Uuid\Uuid;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* @internal
*
* @package inventory
*/
class CheckoutOrderPlacedSubscriber implements EventSubscriberInterface
{
private MultiWarehouseStockUpdater $stockUpdater;
private MultiWarehouseProductFilter $productFilter;
private Connection $connection;
public function __construct(
MultiWarehouseStockUpdater $stockUpdater,
MultiWarehouseProductFilter $productFilter,
Connection $connection
) {
$this->stockUpdater = $stockUpdater;
$this->productFilter = $productFilter;
$this->connection = $connection;
}
public static function getSubscribedEvents(): array
{
return [
CheckoutOrderPlacedEvent::class => 'onOrderPlaced',
];
}
public function onOrderPlaced(CheckoutOrderPlacedEvent $event): void
{
if (!License::get('MULTI_INVENTORY-3749997')) {
return;
}
$lineItems = $event->getOrder()->getLineItems();
if ($lineItems === null || $lineItems->count() <= 0) {
return;
}
$groupIds = $this->getOrderWarehouseGroups($event->getContext(), $event->getOrder()->getId());
if (empty($groupIds)) {
return;
}
/** @var list<string> $lineItemRefIds */
$lineItemRefIds = $lineItems->fmap(static function (OrderLineItemEntity $orderLineItem) {
if ($orderLineItem->getType() !== LineItem::PRODUCT_LINE_ITEM_TYPE) {
return null;
}
return $orderLineItem->getReferencedId();
});
$warehouseLineItemIds = $this->productFilter->filterProductIdsWithWarehouses($lineItemRefIds);
if (empty($warehouseLineItemIds)) {
return;
}
$ids = [];
/** @var OrderLineItemEntity $lineItem */
foreach ($lineItems as $lineItem) {
if (!\in_array($lineItem->getReferencedId(), $warehouseLineItemIds, true)) {
continue;
}
if (!\array_key_exists($lineItem->getReferencedId(), $ids)) {
$ids[$lineItem->getReferencedId()] = 0;
}
$ids[$lineItem->getReferencedId()] += $lineItem->getQuantity();
}
$this->stockUpdater->update(
$event->getContext(),
$event->getOrderId(),
$groupIds,
$ids
);
}
/**
* @return list<string>
*/
private function getOrderWarehouseGroups(Context $context, string $orderId): array
{
/** @var list<string> $groups */
$groups = $this->connection->fetchFirstColumn(
'SELECT LOWER(HEX(warehouse_group_id)) FROM order_warehouse_group WHERE order_id = :orderId AND order_version_id = :versionId',
[
'orderId' => Uuid::fromHexToBytes($orderId),
'versionId' => Uuid::fromHexToBytes($context->getVersionId()),
]
);
return $groups;
}
}