<?php declare(strict_types=1);
namespace Proc\ProcAvailableStock\Subscriber;
use Proc\ProcAvailableStock\Helper\ErrorHandler;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\PageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Class AvailableStockSubscriber
* @package Proc\ProcAvailableStock\Subscriber
*/
class AvailableStockSubscriber implements EventSubscriberInterface
{
/**
* @var PageLoadedEvent
*/
private PageLoadedEvent $event;
/**
* @var EntityRepositoryInterface
*/
private EntityRepositoryInterface $productRepository;
/**
* @inheritDoc
*/
public static function getSubscribedEvents()
{
return [
// OffcanvasCartPageLoadedEvent::class => ['onCartLoaded', 1],
CheckoutCartPageLoadedEvent::class => ['onCartLoaded', 1],
CheckoutConfirmPageLoadedEvent::class => ['onCartLoaded', 1],
CheckoutFinishPageLoadedEvent::class => ['onFinishLoaded', 1]
];
}
/**
* @param SystemConfigService $config
* @param EntityRepositoryInterface $repositoryInterface
*/
function __construct(SystemConfigService $config, EntityRepositoryInterface $repositoryInterface)
{
$this->productRepository = $repositoryInterface;
}
/**
* @param PageLoadedEvent $event
*/
public function onCartLoaded(PageLoadedEvent $event)
{
$this->event = $event;
if (
// !($this->event instanceof OffcanvasCartPageLoadedEvent) &&
!($this->event instanceof CheckoutCartPageLoadedEvent) &&
!($this->event instanceof CheckoutConfirmPageLoadedEvent)
) return;
if (!$this->checkLogin()) return;
$lineItems = $this->event->getPage()->getCart()->getLineItems()->filterType(LineItem::PRODUCT_LINE_ITEM_TYPE);
if (count($lineItems) < 1) return;
foreach ($lineItems as $lineItem)
{
$product = $this->getProduct($lineItem->getReferencedId());
$lineItem->setExtensions(['availability' => $product->getStock() - $lineItem->getQuantity()]);
}
}
/**
* @param PageLoadedEvent $event
*/
public function onFinishLoaded(PageLoadedEvent $event)
{
$this->event = $event;
if (!($this->event instanceof CheckoutFinishPageLoadedEvent)) return;
if (!$this->checkLogin()) return;
$lineItems = $this->event->getPage()->getOrder()->getLineItems()->filterByType(LineItem::PRODUCT_LINE_ITEM_TYPE);
if (count($lineItems) < 1) return;
foreach ($lineItems as $lineItem)
{
$product = $this->getProduct($lineItem->getReferencedId());
$lineItem->setExtensions(['availability' => $product->getStock() - $lineItem->getQuantity()]);
}
}
/**
* @param string $productID
* @return ProductEntity
*/
public function getProduct(string $productID) : ProductEntity
{
$criteria = new Criteria([$productID]);
/** @var EntityCollection $products */
$products = $this->productRepository->search($criteria, Context::createDefaultContext());
$productList = $products->getElements();
/** @var ProductEntity $product */
$product = $productList[$productID];
return $product;
}
/**
* @return bool
*/
private function checkLogin() : bool
{
if ($this->event->getSalesChannelContext()->getCustomer() === null)
{
$this->error = (new ErrorHandler)->error(ErrorHandler::NO_CUSTOMER_ERROR);
return false;
}
return true;
}
}