<?php
declare(strict_types=1);
namespace WbfkExtensions\Subscriber;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use WbfkExtensions\Core\Checkout\WbfkOrderLineItemExtension\WbfkOrderLineItemExtensionEntity;
class AddPurchasePricesOnCartConversion implements EventSubscriberInterface
{
public function __construct(private readonly EntityRepository $productRepository)
{
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents(): array
{
return [
CartConvertedEvent::class => 'addPurchasePricesToConvertedCart',
];
}
public function addPurchasePricesToConvertedCart(CartConvertedEvent $event): void
{
$convertedCart = $event->getConvertedCart();
$cartLineItems = $event->getCart()->getLineItems();
// Find products whose purchase price needs to be fetched
$productIdsWhosePurchasePricesAreNotSet = [];
foreach ($cartLineItems->filterFlatByType(LineItem::PRODUCT_LINE_ITEM_TYPE) as $cartLineItem) {
/** @var ?WbfkOrderLineItemExtensionEntity $wbfkOrderLineItemExtension */
$wbfkOrderLineItemExtension = $cartLineItem->getExtension('wbfkOrderLineItemExtension');
if ($wbfkOrderLineItemExtension === null || $wbfkOrderLineItemExtension->getPurchasePrice() === null) {
$productIdsWhosePurchasePricesAreNotSet[$cartLineItem->getId()] = $cartLineItem->getReferencedId();
}
}
$products = null;
if (count($productIdsWhosePurchasePricesAreNotSet) > 0) {
$products = $this->productRepository->search(new Criteria($productIdsWhosePurchasePricesAreNotSet), $event->getContext());
}
// Set wbfkOrderLineItemExtension to converted cart, after setting missing purchase prices
foreach ($convertedCart['lineItems'] as $key => $lineItem) {
if ($lineItem['type'] !== LineItem::PRODUCT_LINE_ITEM_TYPE) {
continue;
}
// check if line item already has wbfk order line item extension (maybe already added from some other place)
$extension = $lineItem['extensions']['wbfkOrderLineItemExtension'] ?? null;
if ($extension === null) {
$cartLineItemExtension = $cartLineItems->get($lineItem['identifier'])->getExtension('wbfkOrderLineItemExtension') ?? (new WbfkOrderLineItemExtensionEntity());
$data = $cartLineItemExtension->getVars();
if (isset($datap['taricId'])) {
$extension['taricId'] = $data['taricId'];
}
if (isset($data['weight'])) {
$extension['weight'] = $data['weight'];
}
if (isset($data['countryOfOrigin'])) {
$extension['countryOfOrigin'] = $data['countryOfOrigin'];
}
if (isset($data['serialNumbers'])) {
$extension['serialNumbers'] = $data['serialNumbers'];
}
if (isset($data['purchasePrice'])) {
$extension['purchasePrice'] = $data['purchasePrice'];
}
if (isset($data['id'])) {
$extension['id'] = $data['id'];
}
}
/*
* Note: On an offer cart, admin might have already set the purchase price and comment.
* This needs to be preserved in the converted cart.
* In an offer cart, this info is available as part of line item payload specialPurchasePrice, specialPurchasePriceComment.
*/
/** @var ?ProductEntity $product */
$product = $products?->get($lineItem['referencedId']);
if ($product) {
if (!isset($extension['purchasePrice'])) {
$extension['purchasePrice'] = $lineItem['payload']['specialPurchasePrice'] ?? $product->getPurchasePrices()->first()->getNet();
}
if (
!isset($convertedCart['lineItems'][$key]['customFields']['wbfk_purchase_price_comment']) ||
!$convertedCart['lineItems'][$key]['customFields']['wbfk_purchase_price_comment']
) {
$convertedCart['lineItems'][$key]['customFields']['wbfk_purchase_price_comment'] = $lineItem['payload']['specialPurchasePriceComment'] ?? ($product->getCustomFields() ? $product->getCustomFields()['wbfk_cheapest_supplier_name_and_comment'] ?? null : null);
}
}
$convertedCart['lineItems'][$key]['extensions']['wbfkOrderLineItemExtension'] = $extension;
}
$event->setConvertedCart($convertedCart);
}
}