<?php
namespace B2bSellersCore\Components\Order\Subscriber;
use B2bSellersCore\Components\B2bPlatform\B2bPlatformContext;
use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity;
use Shopware\Core\Framework\Context;
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 OrderSubscriber implements EventSubscriberInterface
{
private RequestStack $requestStack;
private EntityRepository $customerAddressRepository;
public function __construct(
RequestStack $requestStack,
EntityRepository $customerAddressRepository
)
{
$this->requestStack = $requestStack;
$this->customerAddressRepository = $customerAddressRepository;
}
public static function getSubscribedEvents(): array
{
return [
CartConvertedEvent::class => 'onCartConvertedEvent'
];
}
public function onCartConvertedEvent(CartConvertedEvent $event)
{
$convertedCart = $event->getConvertedCart();
$convertedCart['b2bOrderExtension'] = [];
$convertedCart = $this->addAdditionalOrderFields($convertedCart);
$convertedCart = $this->addLineItemCustomFields($convertedCart);
$convertedCart = $this->setOrderAdresses($convertedCart, $event->getContext());
$convertedCart = $this->setPaymentMethod($convertedCart);
$customFields = $event->getSalesChannelContext()->getCustomer()->getCustomFields();
if (isset($customFields['b2b_payment_condition_number'])) {
$convertedCart['customFields']['b2b_order_payment_condition'] = $customFields['b2b_payment_condition_number'];
}
$event->setConvertedCart($convertedCart);
if (!$event->getSalesChannelContext()->hasExtension('b2bPlatformContext')) {
return;
}
/** @var B2bPlatformContext $b2bPlatformContext */
$b2bPlatformContext = $event->getSalesChannelContext()->getExtension('b2bPlatformContext');
if ($b2bPlatformContext->isSalesRepresentative()) {
$convertedCart['customFields']['b2b_order_sales_representative_id'] = $b2bPlatformContext->getSalesRepresentative()->getId();
$convertedCart['b2bOrderExtension']['salesRepresentativeId'] = $b2bPlatformContext->getSalesRepresentative()->getId();
}
if ($b2bPlatformContext->isEmployee()) {
$convertedCart['customFields']['b2b_order_customer_employee_id'] = $b2bPlatformContext->getEmployee()->getId();
$convertedCart['b2bOrderExtension']['employeeId'] = $b2bPlatformContext->getEmployee()->getId();
}
$event->setConvertedCart($convertedCart);
}
private function addAdditionalOrderFields($convertedCart)
{
$request = $this->requestStack->getCurrentRequest();
if (empty($request)) {
return $convertedCart;
}
$convertedCart['customFields']['b2b_order_customer_note'] = $request->get('b2bCustomerNote', '');
$convertedCart['customFields']['b2b_order_customer_commission'] = $request->get('b2bCustomerCommission', '');
$convertedCart['customFields']['b2b_order_customer_employee_id'] = $request->get('b2bCustomerEmployeeId', null);
$convertedCart['customFields']['b2b_order_sales_representative_id'] = $request->get('b2bOrderSalesRepresentativeId', null);
$convertedCart['b2bOrderExtension']['employeeId'] = $request->get('b2bCustomerEmployeeId', null);
$convertedCart['b2bOrderExtension']['salesRepresentativeId'] = $request->get('b2bOrderSalesRepresentativeId', null);
return $convertedCart;
}
private function addLineItemCustomFields($convertedCart)
{
foreach ($convertedCart['lineItems'] as &$lineItem) {
$customFields = $lineItem['customFields'] ?? [];
$comment = $lineItem['payload']['comment'] ?? null;
$customFields['b2b_order_line_item_comment'] = $comment;
$lineItem['customFields'] = $customFields;
}
return $convertedCart;
}
private function setOrderAdresses($convertedCart, Context $context)
{
$request = $this->requestStack->getCurrentRequest();
if (empty($request)) {
return $convertedCart;
}
// works only for one delivery
if (!empty($request->get('shippingMethodId'))) {
$convertedCart['deliveries'][0]['shippingMethodId'] = $request->get('shippingMethodId');
}
if (!empty($request->get('billingAddressId'))) {
$billingAddress = $this->getAddressbyAddressId($request->get('billingAddressId'), $context);
$newBillingAddressId = Uuid::randomHex();
$convertedCart['billingAddressId'] = $newBillingAddressId;
$convertedCart['addresses'] = [[
"id" => $newBillingAddressId,
"company" => $billingAddress->getCompany(),
"salutationId" => $billingAddress->getSalutationId(),
"firstName" => $billingAddress->getFirstName(),
"lastName" => $billingAddress->getLastName(),
"street" => $billingAddress->getStreet(),
"zipcode" => $billingAddress->getZipcode(),
"city" => $billingAddress->getCity(),
"countryId" => $billingAddress->getCountryId()
]];
}
if (!empty($request->get('shippingAddressId'))) {
$shippingAddress = $this->getAddressbyAddressId($request->get('shippingAddressId'), $context);
$convertedCart['deliveries'][0]['shippingOrderAddress'] = [
"id" => Uuid::randomHex(),
"company" => $shippingAddress->getCompany(),
"salutationId" => $shippingAddress->getSalutationId(),
"firstName" => $shippingAddress->getFirstName(),
"lastName" => $shippingAddress->getLastName(),
"street" => $shippingAddress->getStreet(),
"zipcode" => $shippingAddress->getZipcode(),
"city" => $shippingAddress->getCity(),
"countryId" => $shippingAddress->getCountryId()
];
}
return $convertedCart;
}
private function setPaymentMethod(array $convertedCart)
{
$request = $this->requestStack->getCurrentRequest();
if (empty($request)) {
return $convertedCart;
}
// works only for one delivery
if (!empty($request->get('paymentMethodId'))) {
$convertedCart['transactions'][0]['paymentMethodId'] = $request->get('paymentMethodId');
}
return $convertedCart;
}
private function getAddressbyAddressId(string $addressId, Context $context): ?CustomerAddressEntity
{
$criteria = new Criteria([$addressId]);
return $this->customerAddressRepository->search($criteria, $context)->first();
}
}