<?php declare(strict_types=1);
namespace Tds\MerwareDiscounts\Core\Exchange\Import\Customer\Subscriber;
use Shopware\Core\Checkout\Customer\CustomerEntity;
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\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Tds\Merware\Core\Exchange\Import\Event\Customer\CustomersReadEvent;
use Tds\Merware\Core\Exchange\Import\Struct\Customer\CustomerStruct;
/**
* Class CustomersReadSubscriber
*
* @package Tds\MerwareDiscounts\Core\Exchange\Import\Customer\Subscriber
*/
class CustomersReadSubscriber implements EventSubscriberInterface
{
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var EntityRepositoryInterface
*/
private $customerRepository;
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
CustomersReadEvent::class => 'onCustomersRead'
];
}
/**
* CustomersReadSubscriber constructor
*
* @param SystemConfigService $systemConfigService
* @param EntityRepositoryInterface $customerRepository
*/
public function __construct(SystemConfigService $systemConfigService, EntityRepositoryInterface $customerRepository)
{
$this->systemConfigService = $systemConfigService;
$this->customerRepository = $customerRepository;
}
/**
* Function to catch imported (but maybe unsaved customers).
*
* @param CustomersReadEvent $event
*
* @throws InconsistentCriteriaIdsException
*/
public function onCustomersRead(CustomersReadEvent $event)
{
$customerStructs = $event->getCustomerStructs();
if (!empty($customerStructs)) {
$this->updateCustomerDiscounts($event->getContext(), $customerStructs);
}
}
/**
* Function to update customer discounts.
*
* @param Context $context
* @param CustomerStruct[] $customerStructs
*/
private function updateCustomerDiscounts($context, $customerStructs)
{
$requests = $this->buildCustomerRequests($context, $customerStructs);
if (!empty($requests)) {
$this->customerRepository->update($requests, $context);
}
}
/**
* Helper-function to build a list of DAL requests to update customer custom fields.
*
* @param Context $context
* @param CustomerStruct[] $customerStructs
*
* @return array
*/
private function buildCustomerRequests($context, $customerStructs)
{
$requests = [];
foreach ($customerStructs as $customerStruct) {
$email = $customerStruct->getEmail();
if (!empty($email)) {
$customer = $this->getCustomer($context, $email);
if (!empty($customer)) {
$customFields = $customer->getCustomFields();
$customFields['tds_merware_customer_discount_general'] = $customerStruct->getGeneralDiscount();
$customFields['tds_merware_customer_discount_products'] = $this->buildDiscountedProductList($customerStruct);
$requests[] = [
'id' => $customer->getId(),
'customFields' => $customFields
];
}
}
}
return $requests;
}
/**
* Helper-function to build a JSON encoded string with a list of product discounts:
*
* - list
* -- artcode
* -- price
*
* @param CustomerStruct $customerStruct
*
* @return string
*/
private function buildDiscountedProductList($customerStruct)
{
$list = [];
$productDiscounts = $customerStruct->getProductDiscounts();
if (!empty($productDiscounts)) {
foreach ($productDiscounts as $productDiscount) {
$list[] = [
'artcode' => $productDiscount->getArtcode(),
'price' => $productDiscount->getPrice()
];
}
}
return json_encode($list);
}
/**
* Helper-function to load a customer.
*
* @param Context $context
* @param string $email
*
* @return CustomerEntity|null
*/
private function getCustomer($context, $email)
{
$criteria = new Criteria();
$criteria->addFilter(
new EqualsFilter('email', $email)
);
$result = $this->customerRepository->search($criteria, $context)->first();
return $result;
}
}