<?php declare(strict_types=1);
namespace Maxia\MaxiaTaxSwitch6\Subscriber;
use Maxia\MaxiaTaxSwitch6\Events\CustomerGroupAssignedEvent;
use Maxia\MaxiaTaxSwitch6\Service\TaxSwitchService;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerGroup\CustomerGroupEntity;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Checkout\Customer\Event\CustomerLoginEvent;
use Shopware\Core\Checkout\Customer\Event\CustomerRegisterEvent;
use Shopware\Core\Checkout\Customer\Event\GuestCustomerRegisterEvent;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* @package Maxia\MaxiaAdvBlockPrices6\Subscriber
*/
class LoginRegisterSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
CustomerLoginEvent::class => 'setTaxSettingOnLogin',
CustomerRegisterEvent::class => 'setCustomerGroupOnRegister',
GuestCustomerRegisterEvent::class => 'setGuestCustomerGroupOnRegister'
];
}
/**
* @var EventDispatcherInterface
*/
private $eventDispatcher;
/**
* @var EntityRepositoryInterface
*/
private $customerGroupRepository;
/**
* @var EntityRepositoryInterface
*/
private $customerRepository;
/**
* @var TaxSwitchService
*/
private $taxSwitchService;
public function __construct(
RequestStack $requestStack,
EventDispatcherInterface $eventDispatcher,
EntityRepositoryInterface $customerGroupRepository,
EntityRepositoryInterface $customerRepository,
TaxSwitchService $taxSwitchService
) {
$this->requestStack = $requestStack;
$this->eventDispatcher = $eventDispatcher;
$this->customerGroupRepository = $customerGroupRepository;
$this->customerRepository = $customerRepository;
$this->taxSwitchService = $taxSwitchService;
}
public function setTaxSettingOnLogin(CustomerLoginEvent $event)
{
$context = $event->getSalesChannelContext();
$config = $this->taxSwitchService->getConfig($context);
if (!$config['pluginEnabled'] || $this->isApiRequest()) {
return;
}
if ($config['updateSettingOnLogin']) {
// get the actual 'displayGross' setting from DB
/** @var CustomerGroupEntity $group */
$group = $this->customerGroupRepository->search(
new Criteria([$event->getCustomer()->getGroupId()]),
$context->getContext()
)->first();
$this->taxSwitchService->setDisplayNet($event->getSalesChannelContext(), !$group->getDisplayGross());
}
}
public function setCustomerGroupOnRegister(CustomerRegisterEvent $event)
{
$this->handleRegistration($event->getCustomer(), $event->getSalesChannelContext());
}
public function setGuestCustomerGroupOnRegister(GuestCustomerRegisterEvent $event)
{
$this->handleRegistration($event->getCustomer(), $event->getSalesChannelContext());
}
protected function handleRegistration(CustomerEntity $customer, SalesChannelContext $context)
{
$config = $this->taxSwitchService->getConfig($context);
if (!$config['pluginEnabled'] || !$config['groupRegistrationMode']
|| $config['groupRegistrationMode'] === 'disabled'
|| $this->isApiRequest()
) {
return;
}
// check if customer has filled the company field
$hasEnteredCompany = false;
foreach ($customer->getAddresses() as $address) {
if ($address->getCompany()) {
$hasEnteredCompany = true;
break;
}
}
$groupId = $hasEnteredCompany ? $config['businessCustomerGroup'] : $config['privateCustomerGroup'];
if ($config['groupRegistrationMode'] === 'assign') {
$this->updateGroup($customer, $groupId, $context);
} else if ($config['groupRegistrationMode'] === 'request') {
$this->updateRequestedGroup($customer, $groupId, $context);
}
}
protected function updateGroup(CustomerEntity $customer, $groupId, SalesChannelContext $context)
{
// fetch the group to assign
/** @var CustomerGroupEntity $group */
$group = $this->customerGroupRepository->search(
new Criteria([$groupId]), $context->getContext()
)->first();
if (!$group || $groupId === $customer->getGroupId()) {
return;
}
// assign customer group
$customer->setGroupId($group->getId());
$customer->setGroup($group);
$this->customerRepository->update([[
'id' => $customer->getId(),
'groupId' => $group->getId()
]], $context->getContext());
// update tax switch setting for new group
$groupIsNet = !$group->getDisplayGross();
if ($groupIsNet !== $this->taxSwitchService->getDisplayNet($context)) {
$this->taxSwitchService->setDisplayNet($context, $groupIsNet);
}
$this->eventDispatcher->dispatch(new CustomerGroupAssignedEvent($customer, $group, $groupIsNet, $context));
}
protected function updateRequestedGroup(CustomerEntity $customer, $groupId, SalesChannelContext $context)
{
if (!method_exists($customer, 'getRequestedGroupId')
|| $customer->getRequestedGroupId())
{
// request group not supported or already set
return;
}
if ($customer->getGroupId() !== $groupId) {
$customer->setRequestedGroupId($groupId);
$this->customerRepository->update([[
'id' => $customer->getId(),
'requestedGroupId' => $groupId
]], $context->getContext());
}
}
/**
* @return \Symfony\Component\HttpFoundation\Request|null
*/
protected function getMainRequest()
{
return method_exists($this->requestStack, 'getMainRequest')
? $this->requestStack->getMainRequest()
: $this->requestStack->getMasterRequest();
}
/**
* Checks if the current request is a Store-API request.
*/
protected function isApiRequest(): bool
{
return $this->getMainRequest() &&
(str_starts_with($this->getMainRequest()->getPathInfo(), '/api/_proxy/store-api/') ||
str_starts_with($this->getMainRequest()->getPathInfo(), '/api/_proxy-order/') ||
str_starts_with($this->getMainRequest()->getPathInfo(), '/store-api/'));
}
}