<?php
namespace AbasBecoCustomizations\Subscribers\Customer;
use Abas\AbasConnector\Service\Core\Content\CustomerRole\CustomerRoleEntity;
use Abas\AbasConnector\Service\Core\Content\CustomerRole\CustomerRoleRelationEntity;
use Abas\AbasConnector\Service\Core\Enums\CustomerRole;
use Abas\AbasConnector\Service\Sync\Customer\CustomerSync;
use AbasBecoCustomizations\Service\Sync\BecoProspectContactSync;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Checkout\Customer\CustomerEvents;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Entity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Routing\Event\SalesChannelContextResolvedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class BecoCustomerCreatedSubscriber implements EventSubscriberInterface
{
/**
* @var EntityRepositoryInterface
*/
private $customerRepository;
/**
* @var EntityRepositoryInterface
*/
private $customerRoleRelationRepository;
/**
* @var EntityRepositoryInterface
*/
private $customerRoleRepository;
/**
* @var CustomerSync
*/
private $customerSync;
/**
* @var BecoProspectContactSync
*/
private $prospectContactSync;
/**
* @var EntityRepositoryInterface
*/
private $customerGroupRepository;
/**
* @var EntityRepositoryInterface
*/
private $languageRepository;
public function __construct(
EntityRepositoryInterface $customerRepository,
EntityRepositoryInterface $customerRoleRelationRepository,
EntityRepositoryInterface $customerRoleRepository,
CustomerSync $customerSync,
BecoProspectContactSync $prospectContactSync,
EntityRepositoryInterface $customerGroupRepository,
EntityRepositoryInterface $languageRepository
) {
$this->customerRepository = $customerRepository;
$this->customerRoleRelationRepository = $customerRoleRelationRepository;
$this->customerRoleRepository = $customerRoleRepository;
$this->customerSync = $customerSync;
$this->prospectContactSync = $prospectContactSync;
$this->customerGroupRepository = $customerGroupRepository;
$this->languageRepository = $languageRepository;
}
public static function getSubscribedEvents()
{
return [
CustomerEvents::CUSTOMER_WRITTEN_EVENT => 'syncCustomerProspectToAbas'
];
}
/**
* @param EntityWrittenEvent $event
*/
public function syncCustomerProspectToAbas(EntityWrittenEvent $event)
{
$customerIds = $event->getIds();
$context = $event->getContext();
$executedIds = [];
foreach ($customerIds as $id) {
if (in_array($id, $executedIds)) {
continue;
}
$customer = $this->getCustomer($id, $context);
if($customer->getGuest()){
continue;
}
if ($customer && $this->shouldSyncCustomer($customer)) {
$this->customerSync->syncCustomer($customer);
// reload for customFields
$customer = $this->getCustomer($id, $context);
$this->createProspectContact($customer);
$roleKey = CustomerRole::USER;
$this->customerRoleRelationRepository->upsert(
[
[
'customerId' => $customer->getId(),
'customerRoleId' => $this->getCustomerRoleByKey($roleKey, $context)->getId()
]
],
$context
);
$executedIds[] = $id;
}
}
}
/**
* @param string $key
* @param Context $context
* @return CustomerRoleEntity|null
*/
private function getCustomerRoleByKey(string $key, Context $context)
{
return $this->customerRoleRepository->search(
(new Criteria())
->addAssociation('permissions')
->addFilter(new EqualsFilter('roleKey', $key)),
$context
)->first();
}
protected function shouldSyncCustomer(CustomerEntity $customerEntity)
{
return !($customerEntity->getCustomFields() &&
isset($customerEntity->getCustomFields()['abas_id']) &&
$customerEntity->getCustomFields()['abas_id']);
}
private function createProspectContact(?CustomerEntity $prospect)
{
if ($prospect === null){
return;
}
$abasComponent = null;
try {
$customFields = $prospect->getCustomFields();
$customFields['abas_database_and_group'] = "0:7";
$prospect->setCustomFields($customFields);// Interessentkontakt erstellen
$abasComponent = $this->prospectContactSync->prepareEntityToAbas($prospect);
$abasComponent->setFieldValue("firma", "$,," . $this->getCustSelectionIdentifier($prospect));
$abasComponent->setFieldValue("yvorname", $prospect->getFirstName());
$abasComponent->setFieldValue("kontakt", $prospect->getLastName());
$abasComponent->setFieldValue("ywebshopabsw", ".");
$erpLang = $this->getErpLanguage($prospect->getLanguageId());
$abasComponent->setFieldValue("spr", $erpLang);
$abasComponent->saveAndReload();
$this->prospectContactSync->syncContactIdentifierToShopware($abasComponent, $prospect->get("id"));
} catch (\Throwable $e) {
echo $e->getMessage();
} finally {
if ($abasComponent !== null) {
$abasComponent->close();
}
}
}
/**
* Get a customFields value
* @param Entity $entity
* @param string $key
* @return string|null
*/
protected function getCustomFieldValue(Entity $entity, string $key): ?string
{
if ($entity->has('customFields')) {
$customFields = $entity->get('customFields');
if ($customFields && isset($customFields[$key])) {
return $customFields[$key];
}
}
return null;
}
/**
* Return the abas identifier value (GUID or ID)
* @param Entity $entity
* @return string|null
*/
protected function getCustSelectionIdentifier(Entity $entity)
{
$guid = $this->getCustomFieldValue($entity, 'abas_guid');
if ($guid) {
return 'guid==' . $guid;
}
return 'id==' . $this->getCustomFieldValue($entity, 'abas_id');
}
private function getCustomer($id, Context $context): CustomerEntity
{
$criteria = (new Criteria())->addFilter(new EqualsFilter('id', $id));
$criteria->addAssociation('defaultBillingAddress');
$criteria->addAssociation('defaultShippingAddress');
$criteria->addAssociation('salutation');
$criteria->addAssociation('customFields');
/** @var CustomerEntity $customer */
return $this->customerRepository->search($criteria, $context)->first();
}
private function getErpLanguage(string $languageId): string
{
$language = $this->languageRepository->search(
(new Criteria([$languageId])),
Context::createDefaultContext()
)->first()->getName();
switch ($language) {
case 'English (EN)':
return "Englisch";
case 'Español (ES)':
return "Spanisch";
case 'Nederlands (NL)':
return "Niederländisch";
case 'Français (FR)':
return "Französisch";
default:
return "Deutsch";
}
}
}