<?php
declare(strict_types=1);
namespace WbfkExtensions\Subscriber;
use Exception;
use Shopware\Core\Content\Product\Events\ProductListingResolvePreviewEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelEntityLoadedEvent;
use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use WbfkExtensions\Core\Checkout\Cart\Delivery\PreCalculatedShippingAndDeliveryInformationService;
use WbfkExtensions\Core\Checkout\Cart\Delivery\ShippingAndDeliveryInformationService;
class AddShippingAndDeliveryInformationToProduct implements EventSubscriberInterface
{
public function __construct(
protected readonly PreCalculatedShippingAndDeliveryInformationService $preCalculatedShippingAndDeliveryInformationService,
protected readonly ShippingAndDeliveryInformationService $shippingAndDeliveryInformationService
) {
}
public static function getSubscribedEvents(): array
{
return [
'sales_channel.product.loaded' => [['findPreCalculatedSupplierDeliveryDateRange']],
ProductListingResolvePreviewEvent::class => [['addSupplierDeliveryTimesToQuery']],
ProductPageCriteriaEvent::class => [['addSupplierToQuery']],
ProductPageLoadedEvent::class => [['findCurrentSupplierDeliveryDateRange']]
];
}
/**
* @throws Exception
*/
public function findPreCalculatedSupplierDeliveryDateRange(SalesChannelEntityLoadedEvent $event): void
{
$this->preCalculatedShippingAndDeliveryInformationService->addSupplierDeliveryDateRangeToProducts(
$event->getEntities(),
$event->getSalesChannelContext()->getShippingLocation()->getCountry(),
$event->getContext()
);
}
public function addSupplierDeliveryTimesToQuery(ProductPageCriteriaEvent|ProductListingResolvePreviewEvent $event): void
{
$criteria = $event->getCriteria();
$criteria->addAssociation('supplierDeliveryTimes');
$criteria->getAssociation('supplierDeliveryTimes')->addFilter(
new EqualsFilter('countryId', $event->getSalesChannelContext()->getShippingLocation()->getCountry()->getId())
);
}
public function addSupplierToQuery(ProductPageCriteriaEvent $event): void
{
$criteria = $event->getCriteria();
$criteria->addAssociation('productSuppliers.wbfkSupplier.deliveryTimes');
$criteria->getAssociation('productSuppliers')->addFilter(
new EqualsFilter('wbfkSupplier.isActive', true),
new EqualsFilter('active', true)
);
}
/**
* @throws Exception
*/
public function findCurrentSupplierDeliveryDateRange(ProductPageLoadedEvent $event): void
{
/*
* NOTE : Shipping and delivery informations are also added from
* 1. \WbfkExtensions\Core\Content\Product\Cms\BuyBoxCmsElementResolverDecorator::enrich
* 2. \WbfkExtensions\Twig\ShippingInformation::loadProductWithDeliveryInformation
*/
$product = $event->getPage()->getProduct();
if ($product->getExtension('wbfk_bundle_product')->count()) {
// For bundle product we shipping and delivery informations are added from \Wbfk\Bundles\Subscriber\ProductSubscriber::onProductPageLoaded
return;
}
/** @noinspection PhpDeprecationInspection */
$product->addExtension(
'shippingAndDeliveryInformations',
$this->shippingAndDeliveryInformationService->getShippingAndDeliveryInformationSortedBySupplierPriority($product, $event->getSalesChannelContext())
);
}
}