<?php declare(strict_types=1);
namespace Acris\Tax\Subscriber;
use Acris\Tax\Core\Checkout\Customer\Validation\Constraint\CustomerVatId;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Framework\Validation\BuildValidationEvent;
use Shopware\Core\PlatformRequest;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class VatIdValiationSubscriber implements EventSubscriberInterface
{
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var RequestStack
*/
private $requestStack;
public function __construct(SystemConfigService $systemConfigService, RequestStack $requestStack)
{
$this->systemConfigService = $systemConfigService;
$this->requestStack = $requestStack;
}
public static function getSubscribedEvents(): array
{
return [
'framework.validation.customer.profile.update' => 'onValidateCustomerUpdate',
'framework.validation.customer.create' => 'onValidateCustomerCreate',
'framework.validation.order.update' => 'onValidateOrder',
'framework.validation.order.create' => 'onValidateOrder'
];
}
public function onValidateCustomerUpdate(BuildValidationEvent $event): void
{
if(empty($this->requestStack) === true || empty($request = $this->requestStack->getCurrentRequest()) === true) {
return;
}
$salesChannelContext = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
$salesChannelId = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
if(!$salesChannelContext instanceof SalesChannelContext || empty($salesChannelId) === true) {
return;
}
if (!$this->systemConfigService->get('AcrisTaxCS.config.validateVatID', $salesChannelId)) {
return;
}
$customer = $salesChannelContext->getCustomer();
if(!$customer instanceof CustomerEntity) {
return;
}
$billingAddress = $customer->getDefaultBillingAddress();
if (empty($billingAddress) === true) {
return;
}
$billingAddressArray = $this->convertAddress($billingAddress);
$this->validateVatIds($request->get('vatIds'), $billingAddressArray, $event, $salesChannelContext);
}
public function onValidateCustomerCreate(BuildValidationEvent $event): void
{
if(empty($this->requestStack) === true || empty($request = $this->requestStack->getCurrentRequest()) === true) {
return;
}
$salesChannelContext = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
$salesChannelId = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
if(!$salesChannelContext instanceof SalesChannelContext || empty($salesChannelId) === true) {
return;
}
if (!$this->systemConfigService->get('AcrisTaxCS.config.validateVatID', $salesChannelId)) {
return;
}
$billingAddress = $request->get('billingAddress');
if (empty($billingAddress) === true) {
$billingAddress = $request->get('address');
}
if (empty($billingAddress) === true) {
return;
}
$this->validateVatIds($request->get('vatIds'), $billingAddress, $event, $salesChannelContext);
}
public function onValidateOrder(BuildValidationEvent $event)
{
if(empty($this->requestStack) === true || empty($request = $this->requestStack->getCurrentRequest()) === true) {
return;
}
$salesChannelContext = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
$salesChannelId = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
if(!$salesChannelContext instanceof SalesChannelContext || empty($salesChannelId) === true) {
return;
}
if (!$this->systemConfigService->get('AcrisTaxCS.config.validateVatID', $salesChannelId) ||
!$this->systemConfigService->get('AcrisTaxCS.config.validateVatIDOnOrder', $salesChannelId)) {
return;
}
if(empty($salesChannelContext->getCustomer()) === true || empty($salesChannelContext->getCustomer()->getDefaultBillingAddress())) {
return;
}
$billingAddressArray = $this->convertAddress($salesChannelContext->getCustomer()->getDefaultBillingAddress());
$this->validateVatIds($salesChannelContext->getCustomer()->getVatIds(), $billingAddressArray, $event, $salesChannelContext);
}
private function convertAddress(CustomerAddressEntity $addressEntity): array
{
return [
'street' => $addressEntity->getStreet(),
'city' => $addressEntity->getCity(),
'zipcode' => $addressEntity->getZipcode(),
'countryId' => $addressEntity->getCountryId()
];
}
private function validateVatIds($vatIds, array $billingAddress, BuildValidationEvent $event, SalesChannelContext $salesChannelContext)
{
if(empty($vatIds)) {
return;
}
foreach ($vatIds as $vatId) {
if(empty($vatId)) {
continue;
}
$options = [
'address' => $billingAddress,
'vatId' => $vatId,
'context' => $event->getContext(),
'salesChannelContext' => $salesChannelContext,
'isCheckOrder' => false
];
$properties = $event->getDefinition()->getProperties();
if (!array_key_exists('vatIds', $properties)) {
$event->getDefinition()->add('vatIds', new CustomerVatId($options));
}
}
}
}