<?php
namespace NetInventors\NetiNextGoogleCustomerReviews\Subscriber;
use Doctrine\DBAL\Connection;
use NetInventors\NetiNextGoogleCustomerReviews\Service\PluginConfig;
use NetInventors\NetiNextGoogleCustomerReviews\Struct\GoogleSurveyOptin;
use Shopware\Core\Checkout\Cart\LineItem\LineItemCollection;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class Checkout implements EventSubscriberInterface
{
/**
* @var PluginConfig
*/
private $pluginConfig;
/**
* @var Connection
*/
private $db;
/**
* @var EntityRepositoryInterface
*/
private $countryRepository;
/**
* @var EntityRepositoryInterface
*/
private $productRepository;
/**
* Checkout constructor.
*
* @param PluginConfig $pluginConfig
* @param Connection $db
* @param EntityRepositoryInterface $countryRepository
* @param EntityRepositoryInterface $productRepository
*/
public function __construct(
PluginConfig $pluginConfig,
Connection $db,
EntityRepositoryInterface $countryRepository,
EntityRepositoryInterface $productRepository
) {
$this->pluginConfig = $pluginConfig;
$this->countryRepository = $countryRepository;
$this->db = $db;
$this->productRepository = $productRepository;
}
public static function getSubscribedEvents(): array
{
return [
CheckoutFinishPageLoadedEvent::class => 'onFinishPageLoaded',
];
}
public function onFinishPageLoaded(CheckoutFinishPageLoadedEvent $event): void
{
if (!$this->pluginConfig->isActive()) {
return;
}
$order = $event->getPage()->getOrder();
$deliverDate = new \DateTime('now +' . $this->pluginConfig->getDeliveryDate() . ' days');
$countryId = current($order->getDeliveries()->getShippingAddress()->getCountryIds());
$deliveryCountry = $this->getCountryIsoById($countryId, $event->getContext());
$struct = new GoogleSurveyOptin();
$struct->setMerchantId($this->pluginConfig->getMerchantId());
$struct->setOrderId($order->getId());
$struct->setEmail($order->getOrderCustomer()->getEmail());
$struct->setDeliveryCountry($deliveryCountry);
$struct->setEstimatedDeliveryDate($deliverDate);
$struct->setOptionalFields($this->pluginConfig->getOptionalFields());
if ($this->pluginConfig->isGtinActive()) {
$products = $this->loadProducts($order->getLineItems(), $event->getContext());
$struct->setProducts($products);
}
$event->getPage()->addExtension('netiNextGoogleCustomerReviewsFinish', $struct);
}
/**
* @param OrderLineItemCollection $lineItems
* @param Context $context
*
* @return array
* @throws InconsistentCriteriaIdsException
*/
protected function loadProducts(OrderLineItemCollection $lineItems, Context $context): array
{
$productIds = [];
foreach ($lineItems as $lineItem) {
if ('product' === $lineItem->getType()) {
$productIds[] = $lineItem->getProductId();
}
}
$criteria = new Criteria($productIds);
$products = $this->productRepository->search($criteria, $context);
$result = [];
/** @var ProductEntity $product */
foreach ($products as $product) {
if (!$product->getEan()) {
continue;
}
$result[] = [
'gtin' => $product->getEan(),
];
}
return $result;
}
/**
* @param string $countryId
* @param Context $context
*
* @return string|null
* @throws InconsistentCriteriaIdsException
*/
protected function getCountryIsoById(string $countryId, Context $context): ?string
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $countryId));
$countries = $this->countryRepository->search($criteria, $context);
if ($countries->count() > 0) {
return $countries->first()->getIso();
}
return null;
}
}