<?php
namespace B2bSellersCore\Components\Checkout\Subscriber;
use B2bSellersCore\Components\B2bPlatform\Traits\B2bContextTrait;
use B2bSellersCore\Components\Checkout\Service\OrderConfirmationRecipientsService;
use B2bSellersCore\Components\Checkout\Service\OrderConfirmationRecipientsServiceInterface;
use B2bSellersCore\Components\Employee\Aggregate\EmployeeCustomer\EmployeeCustomerCollection;
use B2bSellersCore\Components\PaymentCondition\Calculator\PaymentConditionCalculatorInterface;
use Exception;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\PageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CheckoutSubscriber implements EventSubscriberInterface
{
use B2bContextTrait;
private EntityRepositoryInterface $employeeCustomerRepository;
private PaymentConditionCalculatorInterface $paymentConditionCalculator;
private SystemConfigService $configService;
private OrderConfirmationRecipientsServiceInterface $orderConfirmationRecipientsService;
private array $config;
public function __construct(
EntityRepositoryInterface $employeeCustomerRepository,
PaymentConditionCalculatorInterface $paymentConditionCalculator,
SystemConfigService $configService,
OrderConfirmationRecipientsServiceInterface $orderConfirmationRecipientsService
)
{
$this->employeeCustomerRepository = $employeeCustomerRepository;
$this->paymentConditionCalculator = $paymentConditionCalculator;
$this->configService = $configService;
$this->orderConfirmationRecipientsService = $orderConfirmationRecipientsService;
$this->config = $this->configService->get('B2bSellersCore.config');
}
public static function getSubscribedEvents(): array
{
return [
CheckoutConfirmPageLoadedEvent::class => [
['addEmployees'],
['addPaymentConditionToConfirmPage'],
['addOrderConfirmationRecipients']
],
CheckoutCartPageLoadedEvent::class => [
['addEmployees'],
['addPaymentConditionToCartPage']
]
];
}
public function addPaymentConditionToConfirmPage(CheckoutConfirmPageLoadedEvent $event)
{
$this->addCalculatedPaymentCondition($event->getPage()->getCart(), $event->getSalesChannelContext());
}
public function addPaymentConditionToCartPage(CheckoutCartPageLoadedEvent $event)
{
$this->addCalculatedPaymentCondition($event->getPage()->getCart(), $event->getSalesChannelContext());
}
private function addCalculatedPaymentCondition(Cart $cart, SalesChannelContext $salesChannelContext)
{
if (empty($salesChannelContext->getCustomer())) {
return;
}
$calculatedPaymentCondition = $this->paymentConditionCalculator->build(
$salesChannelContext->getCustomer(),
$cart->getPrice()->getTotalPrice(),
$salesChannelContext
);
if (empty($calculatedPaymentCondition)) {
return;
}
$cart->addExtension('calculatedPaymentCondition', $calculatedPaymentCondition);
}
public function addEmployees(PageLoadedEvent $event)
{
$salesChannelContext = $event->getSalesChannelContext();
/** @var CustomerEntity $customerEntity */
$customerEntity = $salesChannelContext->getCustomer();
if (empty($customerEntity)) {
$event->getPage()->addExtension('employees', (new EmployeeCustomerCollection([]))->getEmployees());
return;
}
$employeeCustomers = $this->getEmployees($customerEntity->getId(), $salesChannelContext);
$event->getPage()->addExtension('employees', $employeeCustomers->getEmployees());
}
/**
* @throws Exception
*/
public function addOrderConfirmationRecipients(CheckoutConfirmPageLoadedEvent $event)
{
if (!$this->hasB2bPlatformContext($event->getSalesChannelContext())) {
return;
}
if (!isset($this->config['enableOrderMailRecipientSelection']) || !$this->config['enableOrderMailRecipientSelection']) {
return;
}
try {
$orderMailRecipientOptions = $this->orderConfirmationRecipientsService->getRecipients($event->getSalesChannelContext());
$orderMailRecipients = $this->orderConfirmationRecipientsService->getSelectedRecipients($event->getSalesChannelContext(), $event->getRequest());
if(!empty($orderMailRecipientOptions)) {
$event->getPage()->addExtension('orderMailRecipientOptions', new ArrayStruct($orderMailRecipientOptions));
$event->getPage()->addExtension('orderMailRecipients', new ArrayStruct($orderMailRecipients));
}
} catch (Exception $exception) {
throw new Exception('Something went wrong. Recipients could not be added to page');
}
}
private function getEmployees(string $customerId, SalesChannelContext $context): ?EmployeeCustomerCollection
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('customerId', $customerId));
$criteria->addAssociation('employee');
return $this->employeeCustomerRepository->search($criteria, $context->getContext())->getEntities();
}
}