<?php
declare(strict_types=1);
namespace Wbfk\Offer\Subscriber;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Checkout\Order\OrderEvents;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\EntityWriteResult;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Wbfk\Offer\Core\Entity\Offer\OfferCollection;
use Wbfk\Offer\Core\Entity\Offer\OfferEntity;
use Wbfk\Offer\Core\Offer\Storefront\OfferService;
use Wbfk\Offer\Service\OfferLineItemHandler;
class AddOrderDetailsToOfferAndMarkAsOrdered implements EventSubscriberInterface
{
public function __construct(
private readonly OfferService $offerService,
private readonly EntityRepository $orderRepository,
) {
}
public static function getSubscribedEvents(): array
{
return [
OrderEvents::ORDER_WRITTEN_EVENT => 'addOrderDetailsToOfferAndMarkAsOrdered',
];
}
public function addOrderDetailsToOfferAndMarkAsOrdered(EntityWrittenEvent $event): void
{
foreach ($event->getWriteResults() as $result) {
$orderId = $result->getPayload()['id'] ?? null;
if (!$orderId) {
continue;
}
$criteria = new Criteria([$orderId]);
$criteria->addAssociation('lineItems');
/** @var ?OrderEntity $order */
$order = $this->orderRepository->search($criteria, $event->getContext())->first();
if (!$order) {
return;
}
$offerLineItems = $order->getLineItems()->filterByType(OfferLineItemHandler::TYPE_OFFER);
if ($offerLineItems->count() === 0) {
return;
}
$offerIds = $offerLineItems->fmap(function ($offerLineItem) {
return $offerLineItem->getReferencedId();
});
/** @var OfferCollection|OfferEntity[] $offers */
$offers = $this->offerService->getOffersByIds($offerIds, $event->getContext());
foreach ($offers as $offer) {
if ($offer->isRunning() || $offer->isOrdered()) {
// Do not update offer with order details if offer is running or already ordered
// When an existing order is edited and saved again, this event is triggered again,
// so already ordered offers would be updated again.
continue;
}
$offerContext = $this->offerService->createScContextForOffer($offer);
$this->offerService->addOrderDetailsAndMarkAsOrdered($offer, $order->getId(), $order->getVersionId(), $offerContext);
}
}
}
}