<?php
declare(strict_types=1);
namespace Okeonline\KejeDeliveryAddress\Storefront\Subscriber;
use Okeonline\KejeDeliveryDatePicker\Core\Checkout\Cart\DeliveryDateCartProcessor;
use Okeonline\KejeDeliveryDatePicker\OkeonlineKejeDeliveryDatePicker;
use Shopware\Core\Checkout\Cart\Delivery\Struct\Delivery;
use Shopware\Core\Checkout\Cart\Delivery\Struct\DeliveryCollection;
use Shopware\Core\Checkout\Cart\Delivery\Struct\ShippingLocation;
use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity;
use Shopware\Core\Framework\Api\Context\SalesChannelApiSource;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Uuid\Uuid;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class CartConvertedEventSubscriber implements EventSubscriberInterface
{
/**
* @var RequestStack
*/
private $request;
/**
* @var EntityRepository
*/
private $customerAddressRepository;
private $shipToCode = null;
public function __construct(
RequestStack $request,
EntityRepository $customerAddressRepository
) {
$this->request = $request;
$this->customerAddressRepository = $customerAddressRepository;
}
public static function getSubscribedEvents(): array
{
return [
CartConvertedEvent::class => 'setCustomFieldsFromForm'
];
}
public function setCustomFieldsFromForm(CartConvertedEvent $event)
{
// Whatever happends, we always need to set:
$currentConvertedCart = $event->getConvertedCart();
$currentConvertedCart['customFields']['customAddress'] = false;
$currentConvertedCart['customFields']['trackTraceEmailaddress'] = null;
$currentConvertedCart['customFields']['oo_order_delivery_instructions'] = null;
// conditionally we will set it to true
// First, capture and save track&Trace E-mailaddress
if ($this->request->getCurrentRequest()->request->has('trackTraceEmailaddress') && !is_null($this->request->getCurrentRequest()->request->get('trackTraceEmailaddress')))
$currentConvertedCart['customFields']['trackTraceEmailaddress'] = $this->request->getCurrentRequest()->request->get('trackTraceEmailaddress');
if ($this->request->getCurrentRequest()->request->has('deliveryInstructions') && !is_null($this->request->getCurrentRequest()->request->get('deliveryInstructions')))
$currentConvertedCart['customFields']['oo_order_delivery_instructions'] = $this->request->getCurrentRequest()->request->get('deliveryInstructions');
$event->setConvertedCart($currentConvertedCart);
// If no current delivery is set, we can not work further
if (
!$event->getCart()->getDeliveries()
|| !$event->getCart()->getDeliveries()->first()
|| !$event->getCart()->getDeliveries()->first() instanceof Delivery
)
return;
// get current delivery
$currentDelivery = $event->getCart()->getDeliveries()->first();
if (
(
!$this->request->getCurrentRequest()->request->has('selectedCustomAddress')
)
&&
(
!$this->request->getCurrentRequest()->request->has('hasCustomAddress')
|| !$this->request->getCurrentRequest()->request->has('customAddress')
|| !is_array($this->request->getCurrentRequest()->request->get('customAddress'))
)
)
return;
// If selectedCustomAddress is set, use that to get the address from database and use data
// Elseif hasCustomAddress is set, continue with custom fiilled-in address
// Else, do nothing
if (
($this->request->getCurrentRequest()->request->has('selectedCustomAddress') && !empty($this->request->getCurrentRequest()->request->get('selectedCustomAddress')))
&&
!$this->request->getCurrentRequest()->request->has('hasCustomAddress')
) {
$customAddressData = $this->request->getCurrentRequest()->request->get('selectedCustomAddress');
// get newly created entity
/** @var CustomerAddressEntity $newAddress */
$criteria = new Criteria([$customAddressData]);
$selectedAddress = $this->customerAddressRepository->search($criteria, $event->getContext())->first();
if (!$selectedAddress instanceof CustomerAddressEntity)
return;
$convertedCartDeliveryShippingAddress = [
'id' => $selectedAddress->getId(),
'salutationId' => $selectedAddress->getSalutationId(),
'firstName' => $selectedAddress->getFirstName(),
'lastName' => $selectedAddress->getLastName(),
'street' => $selectedAddress->getStreet(),
'zipcode' => $selectedAddress->getZipcode(),
'city' => $selectedAddress->getCity(),
'company' => $selectedAddress->getCompany(),
'phoneNumber' => $selectedAddress->getPhoneNumber(),
'countryId' => $selectedAddress->getCountryId(),
];
$this->shipToCode = $selectedAddress->getCustomFields()['oo_customer_address_ship_to_code'] ?? null;
// re-get the cart
$currentConvertedCart = $event->getConvertedCart();
// first: get current default address as billing address and add it to 'addresses'
$currentConvertedCart['addresses'][0] = $currentConvertedCart['deliveries'][0]['shippingOrderAddress'];
// second: get the generated billingAddressId, and replace it to above setted address
$currentConvertedCart['addresses'][0]['id'] = $currentConvertedCart['billingAddressId'];
// than, add custom address to deliveries
$currentConvertedCart['deliveries'][0]['shippingOrderAddress'] = $convertedCartDeliveryShippingAddress;
// and also add it to the addresses...
$currentConvertedCart['addresses'][1] = $convertedCartDeliveryShippingAddress;
$currentConvertedCart['customFields']['customAddress'] = $this->request->getCurrentRequest()->request->get('hasCustomAddress') === 'on';
} elseif ($this->request->getCurrentRequest()->request->has('hasCustomAddress')) {
$customAddressData = $this->request->getCurrentRequest()->request->get('customAddress');
$street = ($customAddressData['street'] ?? '') . ' ' . ($customAddressData['housenumber'] ?? '') . ' ' . ($customAddressData['housenumber-addition'] ?? '');
$street = trim($street);
// get address information from request stack
$customerId = $this->getCurrentCustomerIdFromDelivery($currentDelivery);
$countryId = $customAddressData['countryId'] ?? $this->getCurrentCountryIdFromDelivery($currentDelivery);
$salutationId = $this->getCurrentSalutationIdFromDelivery($currentDelivery);
$firstName = $customAddressData['firstName'] ?? '';
$lastName = $customAddressData['lastName'] ?? '';
$zipcode = $customAddressData['zipcode'] ?? '';
if (empty($zipcode))
$zipcode = '-';
$city = $customAddressData['city'] ?? '';
$company = $customAddressData['company'] ?? null;
$phoneNumber = $customAddressData['phoneNumber'] ?? null;
$street = $street ?? '';
// add address to customer
$customerAddressId = Uuid::randomHex();
$convertedCartDeliveryShippingAddress = [
'id' => $customerAddressId,
'salutationId' => $salutationId,
'firstName' => $firstName,
'lastName' => $lastName,
'street' => $street,
'zipcode' => $zipcode,
'city' => $city,
'company' => $company ?? null, // not required
'phoneNumber' => $phoneNumber ?? null, // not required
'countryId' => $countryId,
];
$this->shipToCode = null;
// re-get the cart
$currentConvertedCart = $event->getConvertedCart();
// first: get current default address as billing address and add it to 'addresses'
$currentConvertedCart['addresses'][0] = $currentConvertedCart['deliveries'][0]['shippingOrderAddress'];
// second: get the generated billingAddressId, and replace it to above setted address
$currentConvertedCart['addresses'][0]['id'] = $currentConvertedCart['billingAddressId'];
// than, add custom address to deliveries
$currentConvertedCart['deliveries'][0]['shippingOrderAddress'] = $convertedCartDeliveryShippingAddress;
// and also add it to the addresses...
$currentConvertedCart['addresses'][1] = $convertedCartDeliveryShippingAddress;
$currentConvertedCart['customFields']['customAddress'] = $this->request->getCurrentRequest()->request->get('hasCustomAddress') === 'on';
} else {
$criteria = new Criteria([$event->getCart()->getDeliveries()->getAddresses()->first()->getId()]);
$selectedAddress = $this->customerAddressRepository->search($criteria, $event->getContext())->first();
if ($selectedAddress instanceof CustomerAddressEntity)
$this->shipToCode = $selectedAddress->getCustomFields()['oo_customer_address_ship_to_code'] ?? null;
$currentConvertedCart['customFields']['ship_to_code'] = $this->shipToCode;
}
$currentConvertedCart['customFields']['ship_to_code'] = $this->shipToCode;
// the complete $currentConvertedCart will be added to $orderRepository->insert() in further process.
$event->setConvertedCart($currentConvertedCart);
}
private function getCurrentCustomerIdFromDelivery(Delivery $delivery)
{
return $delivery->getLocation()->getAddress()->getCustomerId();
}
private function getCurrentSalutationIdFromDelivery(Delivery $delivery)
{
return $delivery->getLocation()->getAddress()->getSalutationId();
}
private function getCurrentCountryIdFromDelivery(Delivery $delivery)
{
return $delivery->getLocation()->getAddress()->getCountryId();
}
}