custom/plugins/AcrisTaxCS/src/Storefront/Subscriber/VatIdValidationSubscriber.php line 73

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Acris\Tax\Storefront\Subscriber;
  3. use Acris\Tax\Components\Service\VatIdValidationService;
  4. use Acris\Tax\Core\Checkout\Customer\Validation\Constraint\CustomerVatId;
  5. use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity;
  6. use Shopware\Core\Checkout\Customer\CustomerEntity;
  7. use Shopware\Core\Checkout\Customer\Event\CustomerRegisterEvent;
  8. use Shopware\Core\Checkout\Customer\Event\GuestCustomerRegisterEvent;
  9. use Shopware\Core\Framework\Validation\BuildValidationEvent;
  10. use Shopware\Core\Framework\Validation\DataBag\DataBag;
  11. use Shopware\Core\PlatformRequest;
  12. use Shopware\Core\System\Country\CountryEntity;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Shopware\Core\System\SystemConfig\SystemConfigService;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. use Symfony\Component\HttpFoundation\RequestStack;
  17. class VatIdValidationSubscriber implements EventSubscriberInterface
  18. {
  19.     /**
  20.      * @var SystemConfigService
  21.      */
  22.     private $systemConfigService;
  23.     /**
  24.      * @var RequestStack
  25.      */
  26.     private $requestStack;
  27.     /**
  28.      * @var VatIdValidationService
  29.      */
  30.     private $vatIdValidationService;
  31.     /**
  32.      * @var array
  33.      */
  34.     private $vatIds;
  35.     /**
  36.      * @var bool
  37.      */
  38.     private $addressAllowed;
  39.     private int $count;
  40.     public function __construct(SystemConfigService $systemConfigServiceRequestStack $requestStackVatIdValidationService $vatIdValidationService)
  41.     {
  42.         $this->systemConfigService $systemConfigService;
  43.         $this->requestStack $requestStack;
  44.         $this->vatIdValidationService $vatIdValidationService;
  45.         $this->vatIds = [];
  46.         $this->addressAllowed false;
  47.         $this->count 0;
  48.     }
  49.     public static function getSubscribedEvents(): array
  50.     {
  51.         return [
  52.             'framework.validation.customer.profile.update' => 'onValidateCustomerUpdate',
  53.             'framework.validation.customer.create' => 'onValidateCustomerCreate',
  54.             'framework.validation.address.create' => 'onValidateAddress',
  55.             'framework.validation.address.update' => 'onValidateAddress',
  56.             'framework.validation.order.update' => 'onValidateOrder',
  57.             'framework.validation.order.create' => 'onValidateOrder',
  58.             CustomerRegisterEvent::class => 'onCustomerRegister',
  59.             GuestCustomerRegisterEvent::class => 'onGuestCustomerRegister'
  60.         ];
  61.     }
  62.     public function onValidateCustomerUpdate(BuildValidationEvent $event): void
  63.     {
  64.         if(empty($this->requestStack) === true || empty($request $this->requestStack->getCurrentRequest()) === true) {
  65.             return;
  66.         }
  67.         $salesChannelContext $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  68.         $salesChannelId $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
  69.         if(!$salesChannelContext instanceof SalesChannelContext || empty($salesChannelId) === true || empty($request->get('vatIds')) === true || !is_array($request->get('vatIds'))) {
  70.             return;
  71.         }
  72.         $customer $salesChannelContext->getCustomer();
  73.         if(!$customer instanceof CustomerEntity) {
  74.             return;
  75.         }
  76.         $billingAddress $customer->getDefaultBillingAddress();
  77.         if (empty($billingAddress) === true) {
  78.             return;
  79.         }
  80.         $billingAddressArray $this->convertAddress($billingAddress$customer->getId(), $customer->getCompany(), $event->getData());
  81.         if (empty($billingAddressArray) === true || !array_key_exists('company'$billingAddressArray) || empty($billingAddressArray['company'])) {
  82.             return;
  83.         }
  84.         $this->vatIdValidationService->checkVatIdsForCustomer($request->get('vatIds'), $customer$salesChannelContext);
  85.         $this->checkVatIdValidation($billingAddressArray$event$salesChannelId$salesChannelContext$request->get('vatIds'), 'customer-update'false'customerUpdate');
  86.     }
  87.     public function onValidateCustomerCreate(BuildValidationEvent $event): void
  88.     {
  89.         if(empty($this->requestStack) === true || empty($request $this->requestStack->getCurrentRequest()) === true) {
  90.             return;
  91.         }
  92.         $salesChannelContext $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  93.         $salesChannelId $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
  94.         if(!$salesChannelContext instanceof SalesChannelContext || empty($salesChannelId) === true || empty($request->get('vatIds')) === true || !is_array($request->get('vatIds'))) {
  95.             return;
  96.         }
  97.         $billingAddress $request->get('billingAddress');
  98.         if (empty($billingAddress) === true) {
  99.             $billingAddress $request->get('address');
  100.         }
  101.         if (empty($billingAddress) === true || !array_key_exists('company'$billingAddress) || empty($billingAddress['company'])) {
  102.             return;
  103.         }
  104.         $this->checkVatIdValidation($billingAddress$event$salesChannelId$salesChannelContext$request->get('vatIds'), 'customer-create'false'customerCreate');
  105.     }
  106.     public function onValidateAddress(BuildValidationEvent $event): void
  107.     {
  108.         $this->count++;
  109.         $currentAddress 'billingAddress';
  110.         if(empty($this->requestStack) === true || empty($request $this->requestStack->getCurrentRequest()) === true) {
  111.             return;
  112.         }
  113.         $salesChannelContext $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  114.         $salesChannelId $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
  115.         if(!$salesChannelContext instanceof SalesChannelContext || empty($salesChannelId) === true) {
  116.             return;
  117.         }
  118.         //check address
  119.         $address $request->get('shippingAddress');
  120.         if (!empty($address)) $currentAddress 'shippingAddress';
  121.         if ($this->addressAllowed !== true) {
  122.             $this->addressAllowed true;
  123.             if (!empty($address)) {
  124.                 return;
  125.             }
  126.         }
  127.         if (!empty($address)) {
  128.             if (!$request->request->has('differentShippingAddress') || boolval($request->request->get('differentShippingAddress')) !== true) {
  129.                 return;
  130.             }
  131.         }
  132.         if (empty($address) === true) {
  133.             $address $request->get('address');
  134.         }
  135.         if (empty($address) === true || !array_key_exists('company'$address) || empty($address['company'])) {
  136.             return;
  137.         }
  138.         if (!empty($address) && array_key_exists('customFields'$address) && !empty($address['customFields'])) {
  139.             $customFields $address['customFields'];
  140.             if (is_array($customFields) && array_key_exists('acris_address_vat_id'$customFields) && empty($customFields['acris_address_vat_id']) !== true) {
  141.                 $addressVatId $customFields['acris_address_vat_id'];
  142.                 if (empty($addressVatId) || !is_string($addressVatId) || in_array($addressVatId$this->vatIds)) return;
  143.                 $this->vatIds[] = $addressVatId;
  144.                 $this->checkVatIdValidation($address$event$salesChannelId$salesChannelContext, [$addressVatId], 'address-save-or-update'false$currentAddress);
  145.             }
  146.         }
  147.     }
  148.     public function onValidateOrder(BuildValidationEvent $event)
  149.     {
  150.         if(empty($this->requestStack) === true || empty($request $this->requestStack->getCurrentRequest()) === true) {
  151.             return;
  152.         }
  153.         $salesChannelContext $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  154.         $salesChannelId $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
  155.         if(!$salesChannelContext instanceof SalesChannelContext || empty($salesChannelId) === true) {
  156.             return;
  157.         }
  158.         if (!$this->systemConfigService->get('AcrisTaxCS.config.validateVatIDOnOrder'$salesChannelId)) {
  159.             return;
  160.         }
  161.         // validate personal data and billing address
  162.         if(empty($salesChannelContext->getCustomer()) !== true && !empty($salesChannelContext->getCustomer()->getDefaultBillingAddress())) {
  163.             $billingAddressVatId = !empty($salesChannelContext->getCustomer() && !empty($salesChannelContext->getCustomer()->getDefaultBillingAddress())) ? $this->getBillingAddressVatId($salesChannelContext->getCustomer()->getDefaultBillingAddress()) : null;
  164.             $billingAddressArray $this->convertAddress($salesChannelContext->getCustomer()->getDefaultBillingAddress(), $salesChannelContext->getCustomer()->getId(), $salesChannelContext->getCustomer()->getCompany());
  165.             if (empty($billingAddressArray) !== true && array_key_exists('company'$billingAddressArray) && !empty($billingAddressArray['company'])) {
  166.                 if (!empty($salesChannelContext->getCustomer()->getVatIds()) && is_array($salesChannelContext->getCustomer()->getVatIds())) {
  167.                     $billingAddressArray['vatIdValidationEntry'] = 'personalData';
  168.                     $this->checkVatIdValidation($billingAddressArray$event$salesChannelId$salesChannelContext$salesChannelContext->getCustomer()->getVatIds(), 'order-save-or-update'true'orderAddress');
  169.                 }
  170.                 if (!empty($billingAddressVatId) && is_string($billingAddressVatId)) {
  171.                     $billingAddressArray['vatIdValidationEntry'] = 'billingAddress';
  172.                     if (array_key_exists('addressCompany'$billingAddressArray) && !empty($billingAddressArray['addressCompany'])) $billingAddressArray['company'] = $billingAddressArray['addressCompany'];
  173.                     $this->checkVatIdValidation($billingAddressArray$event$salesChannelId$salesChannelContext, [$billingAddressVatId], 'order-save-or-update'true'orderAddress');
  174.                 }
  175.             }
  176.         }
  177.         // validate shipping address
  178.         if(empty($salesChannelContext->getCustomer()) !== true && !empty($salesChannelContext->getCustomer()->getDefaultShippingAddress())) {
  179.             $shippingAddressVatId = !empty($salesChannelContext->getCustomer() && !empty($salesChannelContext->getCustomer()->getDefaultShippingAddress())) ? $this->getBillingAddressVatId($salesChannelContext->getCustomer()->getDefaultShippingAddress()) : null;
  180.             $shippingAddressArray $this->convertAddress($salesChannelContext->getCustomer()->getDefaultShippingAddress(), $salesChannelContext->getCustomer()->getId(), $salesChannelContext->getCustomer()->getCompany());
  181.             if (empty($shippingAddressArray) !== true && array_key_exists('company'$shippingAddressArray) && !empty($shippingAddressArray['company'])) {
  182.                 if (!empty($shippingAddressVatId) && is_string($shippingAddressVatId)) {
  183.                     $shippingAddressArray['vatIdValidationEntry'] = 'shippingAddress';
  184.                     if (array_key_exists('addressCompany'$shippingAddressArray) && !empty($shippingAddressArray['addressCompany'])) $shippingAddressArray['company'] = $shippingAddressArray['addressCompany'];
  185.                     $this->checkVatIdValidation($shippingAddressArray$event$salesChannelId$salesChannelContext, [$shippingAddressVatId], 'order-save-or-update'true'orderAddress');
  186.                 }
  187.             }
  188.         }
  189.     }
  190.     public function onCustomerRegister(CustomerRegisterEvent $event): void
  191.     {
  192.         if (empty($event->getCustomerId())) return;
  193.         $this->vatIdValidationService->assignTheCustomerToLogEntity($event->getCustomer(), $event->getSalesChannelContext());
  194.     }
  195.     public function onGuestCustomerRegister(GuestCustomerRegisterEvent $event): void
  196.     {
  197.         if (empty($event->getCustomerId())) return;
  198.         $this->vatIdValidationService->assignTheCustomerToLogEntity($event->getCustomer(), $event->getSalesChannelContext());
  199.     }
  200.     private function convertAddress(CustomerAddressEntity $addressEntitystring $customerId, ?string $company, ?DataBag $dataBag null): array
  201.     {
  202.         $addressData = [
  203.             'customerId' => $customerId,
  204.             'street' => $addressEntity->getStreet(),
  205.             'city' => $addressEntity->getCity(),
  206.             'zipcode' => $addressEntity->getZipcode(),
  207.             'countryId' => $addressEntity->getCountryId()
  208.         ];
  209.         if (!empty($addressEntity->getCompany())) $addressData['addressCompany'] = $addressEntity->getCompany();
  210.         if (!empty($company)) {
  211.             if (array_key_exists('addressCompany'$addressData) && !empty($addressData['addressCompany'])) {
  212.                 $addressData['company'] = $company;
  213.             }
  214.         }
  215.         if (!empty($dataBag) && !empty($dataBag->get('company'))) {
  216.             $addressData['company'] = $dataBag->get('company');
  217.         }
  218.         return $addressData;
  219.     }
  220.     private function validateVatIds($vatIds, array $billingAddressBuildValidationEvent $eventSalesChannelContext $salesChannelContext, ?CountryEntity $countrystring $causebool $checkOrderstring $currentAddress)
  221.     {
  222.         if(empty($vatIds)) {
  223.             return;
  224.         }
  225.         foreach ($vatIds as $vatId) {
  226.             if(empty($vatId)) {
  227.                 continue;
  228.             }
  229.             $options = [
  230.                 'address' => $billingAddress,
  231.                 'vatId' => $vatId,
  232.                 'context' => $event->getContext(),
  233.                 'salesChannelContext' => $salesChannelContext,
  234.                 'country' => $country,
  235.                 'cause' => $cause,
  236.                 'isCheckOrder' => $checkOrder,
  237.                 'currentAddress' => $currentAddress
  238.             ];
  239.             $properties $event->getDefinition()->getProperties();
  240.             if (!array_key_exists('vatIds'$properties) || $cause 'customer-update') {
  241.                 $event->getDefinition()->add('vatIds', new CustomerVatId($options));
  242.             }
  243.         }
  244.     }
  245.     private function checkVatIdValidation(array $address$eventstring $salesChannelIdSalesChannelContext $salesChannelContext, ?array $vatIdsstring $causebool $checkOrderstring $currentAddress): void
  246.     {
  247.         if (empty($vatIds)) return;
  248.         $countryId array_key_exists('countryId'$address) && !empty($address['countryId']) ? $address['countryId'] : null;
  249.         if (empty($countryId)) return;
  250.         $country $this->vatIdValidationService->getCountry($countryId$event->getContext());
  251.         $vatIdFormatValidation $this->systemConfigService->get('AcrisTaxCS.config.validateVatIDFormatAllEUCountries'$salesChannelId);
  252.         $vatIdApiServiceValidation $this->systemConfigService->get('AcrisTaxCS.config.VatIDAPIValidationAllEUCountries'$salesChannelId);
  253.         if ((!empty($vatIdFormatValidation) && ($vatIdFormatValidation === VatIdValidationService::DEFAULT_ENABLE_FORMAT_VAT_ID_ALL_EU_COUNTRIES || ($vatIdFormatValidation === VatIdValidationService::DEFAULT_OPTION_STANDARD && $this->vatIdValidationService->checkCountryFormatValidation($country))))
  254.             || (!empty($vatIdApiServiceValidation) && (($vatIdApiServiceValidation === VatIdValidationService::DEFAULT_ENABLE_VAT_ID_VALIDATION_API_SERVICE_ALL_EU_COUNTRIES || $vatIdApiServiceValidation === VatIdValidationService::DEFAULT_ENABLE_VAT_ID_COMPANY_VALIDATION_API_SERVICE_ALL_EU_COUNTRIES
  255.                         || $vatIdApiServiceValidation === VatIdValidationService::DEFAULT_ENABLE_VAT_ID_ADDRESS_VALIDATION_API_SERVICE_ALL_EU_COUNTRIES || $vatIdApiServiceValidation === VatIdValidationService::DEFAULT_ENABLE_VAT_ID_COMPANY_ADDRESS_VALIDATION_API_SERVICE_ALL_EU_COUNTRIES)
  256.                     || ($vatIdApiServiceValidation === VatIdValidationService::DEFAULT_OPTION_STANDARD && $this->vatIdValidationService->checkCountryVatIdValidationApiService($country))))) {
  257.             $this->validateVatIds($vatIds$address$event$salesChannelContext$country$cause$checkOrder$currentAddress);
  258.         }
  259.     }
  260.     private function getBillingAddressVatId(CustomerAddressEntity $address): ?string
  261.     {
  262.         if (empty($address->getCustomFields()) || !is_array($address->getCustomFields()) || !array_key_exists('acris_address_vat_id'$address->getCustomFields()) || empty($address->getCustomFields()['acris_address_vat_id'])) return null;
  263.         return $address->getCustomFields()['acris_address_vat_id'];
  264.     }
  265. }