<?php
declare(strict_types=1);
namespace Wbfk\ITScope\Subscriber;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Wbfk\ITScope\Service\CheapestBundlePurchasePriceUpdaterService;
class UpdatePurchasePriceOfBundleOnChildPurchasePriceUpdate implements EventSubscriberInterface
{
public function __construct(
private readonly CheapestBundlePurchasePriceUpdaterService $cheapestBundlePurchasePriceUpdaterService,
private readonly Connection $connection,
) {
}
public static function getSubscribedEvents(): array
{
return [
ProductEvents::PRODUCT_WRITTEN_EVENT => 'onProductWritten',
];
}
/**
* @throws \Doctrine\DBAL\Driver\Exception
* @throws Exception
*/
public function onProductWritten(EntityWrittenEvent $event): void
{
$productIds = $this->findPurchasePriceUpdatedProductIds($event->getPayloads());
if (empty($productIds)) {
return;
}
$bundleParentProductIds = $this->findBundleParentProductIds($productIds);
if (empty($bundleParentProductIds)) {
return;
}
foreach ($bundleParentProductIds as $bundleParentProductId) {
$this->cheapestBundlePurchasePriceUpdaterService->updateBestPurchasePriceForBundleProductId($bundleParentProductId);
}
}
public function findPurchasePriceUpdatedProductIds(array $payloads): array
{
return array_filter(array_map(static function ($payload) {
return isset($payload['purchasePrices']) ? $payload['id'] : false;
}, $payloads));
}
/**
* @throws Exception
* @throws \Doctrine\DBAL\Driver\Exception
*/
private function findBundleParentProductIds(array $childProductIds): array
{
$childProductIdsHex = implode(",", array_map(fn($childProductId) => '0x'.$childProductId, $childProductIds));
$liveVersionIdHex = '0x'.Defaults::LIVE_VERSION;
$parentProductIdQuery = <<<SQL
SELECT DISTINCT LOWER(HEX(product_id)) AS product_id
FROM wbfk_bundle_product
WHERE child_product_id IN ($childProductIdsHex)
AND product_version_id = $liveVersionIdHex
SQL;
$bundleProductRows = $this->connection->executeQuery($parentProductIdQuery)->fetchAllAssociative();
return array_map(fn($bundleProductRow) => $bundleProductRow['product_id'], $bundleProductRows);
}
}