<?php declare(strict_types=1);
namespace Acris\Tax\Storefront\Subscriber;
use Acris\Tax\Components\Service\VatIdValidationService;
use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
use Shopware\Core\Checkout\Customer\CustomerEvents;
use Shopware\Core\Framework\Event\DataMappingEvent;
use Shopware\Core\Framework\Validation\DataBag\DataBag;
use Shopware\Core\PlatformRequest;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\Address\Listing\AddressListingPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class AddressVatIdSubscriber implements EventSubscriberInterface
{
/**
* @var VatIdValidationService
*/
private $vatIdValidationService;
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var RequestStack
*/
private $requestStack;
public function __construct(
VatIdValidationService $vatIdValidationService,
SystemConfigService $systemConfigService,
RequestStack $requestStack
) {
$this->vatIdValidationService = $vatIdValidationService;
$this->systemConfigService = $systemConfigService;
$this->requestStack = $requestStack;
}
public static function getSubscribedEvents(): array
{
return [
CustomerEvents::MAPPING_REGISTER_CUSTOMER => 'onRegisterCustomerEvent',
CustomerEvents::MAPPING_ADDRESS_CREATE => 'onMappingEventAddressCreate',
CustomerEvents::MAPPING_REGISTER_ADDRESS_SHIPPING => 'onMappingEventAddressShippingRegister',
CustomerEvents::MAPPING_REGISTER_ADDRESS_BILLING => 'onMappingEventAddressBillingRegister',
CustomerEvents::MAPPING_CUSTOMER_PROFILE_SAVE => 'onMappingEventCustomerProfileSave',
AddressListingPageLoadedEvent::class => 'onAddressListingPageLoaded',
CartConvertedEvent::class => 'onCartConverted'
];
}
public function onRegisterCustomerEvent(DataMappingEvent $event): void
{
if(empty($this->requestStack) === true || empty($request = $this->requestStack->getCurrentRequest()) === true) {
return;
}
$salesChannelId = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
if (!$this->assignAddressVatId($salesChannelId)) return;
$output = $event->getOutput();
$input = $event->getInput();
if (!$input->get('billingAddress')) {
return;
}
if (!$input->get('vatIds')) {
return;
}
$vatIds = $event->getInput()->get('vatIds');
/** @var DataBag $billing */
$billing = $event->getInput()->get('billingAddress');
$customFields = $billing->get('customFields') ?? [];
if ($customFields instanceof DataBag) {
$customFields->set('acris_address_vat_id', $vatIds[0]);
}
elseif (is_array($customFields)) {
$customFields['acris_address_vat_id'] = $vatIds[0];
}
$billing->set('customFields', $customFields);
$event->setOutput($output);
}
public function onMappingEventAddressCreate(DataMappingEvent $event): void
{
$inputData = $event->getInput();
$outputData = $event->getOutput();
$customFields = $inputData->get('customFields') ?? [];
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 (!$this->assignAddressVatId($salesChannelId)) return;
if($salesChannelContext instanceof SalesChannelContext && empty($salesChannelId) !== true && !empty($this->systemConfigService->get('AcrisTaxCS.config.addressVatIdSavingBehavior', $salesChannelId)) === true
&& (empty($customFields) === true || empty($customFields->get('acris_address_vat_id')) === true)) {
if (array_key_exists('customFields', $outputData)) {
$outputData['customFields']['acris_address_vat_id'] = null;
} else {
$outputData['customFields'] = ['acris_address_vat_id' => null];
}
$event->setOutput($outputData);
return;
}
if (empty($customFields)) return;
$addressVatId = $customFields->get('acris_address_vat_id');
$addressVatIdNew = ($addressVatId) ?? null;
if (array_key_exists('customFields', $outputData)) {
$outputData['customFields']['acris_address_vat_id'] = $addressVatIdNew;
} else {
$outputData['customFields'] = ['acris_address_vat_id' => $addressVatIdNew];
}
$event->setOutput($outputData);
}
public function onMappingEventAddressBillingRegister(DataMappingEvent $event)
{
if(empty($this->requestStack) === true || empty($request = $this->requestStack->getCurrentRequest()) === true) {
return;
}
$salesChannelId = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
if (!$this->assignAddressVatId($salesChannelId)) return;
$output = $event->getOutput();
$customFields = $event->getInput()->get('customFields') ?? [];
if (empty($customFields)) return;
if ($customFields instanceof DataBag) {
$vatId = $customFields->get('acris_address_vat_id');
}
elseif (is_array($customFields)) {
$vatId = $customFields['acris_address_vat_id'];
}
if (empty($vatId)) return;
if (array_key_exists('customFields', $output)) {
$output['customFields']['acris_address_vat_id'] = $vatId;
} else {
$output['customFields'] = ['acris_address_vat_id' => $vatId];
}
$event->setOutput($output);
}
public function onMappingEventCustomerProfileSave(DataMappingEvent $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 (!$this->assignAddressVatId($salesChannelId)) return;
if(!$salesChannelContext instanceof SalesChannelContext || empty($salesChannelId) === true || !$this->systemConfigService->get('AcrisTaxCS.config.personalDataVatIdSavingBehavior', $salesChannelId)) {
return;
}
$output = $event->getOutput();
$vatIds = $event->getInput()->get('vatIds');
if (empty($vatIds)) {
$output['vatIds'] = null;
}
$event->setOutput($output);
}
public function onMappingEventAddressShippingRegister(DataMappingEvent $event): void
{
if(empty($this->requestStack) === true || empty($request = $this->requestStack->getCurrentRequest()) === true) {
return;
}
$salesChannelId = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID);
if (!$this->assignAddressVatId($salesChannelId)) return;
$inputData = $event->getInput();
$outputData = $event->getOutput();
$customFields = $inputData->get('customFields') ?? [];
if (empty($customFields)) return;
$addressVatId = $customFields->get('acris_address_vat_id');
$addressVatIdNew = ($addressVatId) ?? null;
if (array_key_exists('customFields', $outputData)) {
$outputData['customFields']['acris_address_vat_id'] = $addressVatIdNew;
} else {
$outputData['customFields'] = ['acris_address_vat_id' => $addressVatIdNew];
}
$event->setOutput($outputData);
}
public function onAddressListingPageLoaded(AddressListingPageLoadedEvent $event): void
{
if (empty($event->getSalesChannelContext()->getCustomer()) || $event->getPage()->getAddresses()->count() === 0) return;
$this->vatIdValidationService->checkPageAddresses($event->getPage()->getAddresses(), $event->getSalesChannelContext()->getCustomer(), $event->getSalesChannelContext());
}
public function onCartConverted(CartConvertedEvent $event): void
{
if (empty($event->getSalesChannelContext()) || empty($event->getSalesChannelContext()->getCustomer())) return;
$customer = $event->getSalesChannelContext()->getCustomer();
$convertedCart = $event->getConvertedCart();
if (empty($customer->getCustomFields()) || !array_key_exists('orderCustomer', $convertedCart)) return;
$convertedCart['orderCustomer']['customFields'] = $customer->getCustomFields();
$event->setConvertedCart($convertedCart);
}
private function assignAddressVatId(?string $salesChannelId): bool
{
return $this->systemConfigService->get('AcrisTaxCS.config.vatIdAt', $salesChannelId) === VatIdValidationService::DEFAULT_OPTION_SAVE_ADDRESS_VAT_ID;
}
}