<?php
namespace B2bOffer\Subscriber;
use B2bOffer\Components\Offer\OfferEntity;
use B2bSellersCore\Components\B2bPlatform\Exception\B2bPlatformContextException;
use B2bSellersCore\Components\B2bPlatform\Traits\B2bContextTrait;
use B2bSellersCore\Components\Employee\Exception\InvalidCustomerException;
use B2bSellersCore\Components\Employee\Service\EmployeeService;
use B2bSellersCore\Components\Employee\Service\EmployeeServiceInterface;
use B2bSellersCore\Components\System\SalesChannel\Events\B2bPlatformConfigAddedEvent;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Framework\Routing\StorefrontResponse;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RouterInterface;
class B2bPlatformSubscriber implements EventSubscriberInterface
{
use B2bContextTrait;
private SystemConfigService $configService;
private EmployeeService $employeeService;
private EntityRepositoryInterface $offerRepository;
private RouterInterface $router;
public function __construct(
SystemConfigService $configService,
EmployeeServiceInterface $employeeService,
EntityRepositoryInterface $offerRepository,
RouterInterface $router
)
{
$this->configService = $configService;
$this->employeeService = $employeeService;
$this->offerRepository = $offerRepository;
$this->router = $router;
}
public static function getSubscribedEvents(): array
{
return [
B2bPlatformConfigAddedEvent::class => 'addB2bOfferConfig',
KernelEvents::RESPONSE => 'switchCustomerOnOfferDetail'
];
}
public function addB2bOfferConfig(B2bPlatformConfigAddedEvent $event)
{
$config = $event->getB2bPlatformContext()->getConfig();
$config['b2bOffer'] = [];
if (!empty($this->configService->get('B2bOffer.config'))) {
$b2bOfferConfig = $this->configService->get('B2bOffer.config');
if (isset($b2bOfferConfig['customArticleId'])) {
$config['b2bOffer']['customArticleId'] = $b2bOfferConfig['customArticleId'];
}
if (isset($b2bOfferConfig['defaultOpenStatusId'])) {
$config['b2bOffer']['defaultOpenStatusId'] = $b2bOfferConfig['defaultOpenStatusId'];
}
if (isset($b2bOfferConfig['defaultCartStatusId'])) {
$config['b2bOffer']['defaultCartStatusId'] = $b2bOfferConfig['defaultCartStatusId'];
}
if (isset($b2bOfferConfig['defaultClosedStatusId'])) {
$config['b2bOffer']['defaultClosedStatusId'] = $b2bOfferConfig['defaultClosedStatusId'];
}
}
$event->getB2bPlatformContext()->setConfig($config);
}
public function switchCustomerOnOfferDetail(ResponseEvent $event)
{
$response = $event->getResponse();
if (!$response instanceof StorefrontResponse) {
return;
}
$request = $event->getRequest();
if ($request->attributes->get('_route') !== 'frontend.b2b_platform.path'
|| strpos($request->attributes->get('path'), 'offer')
&& !$request->query->has('useCustomer')) {
return;
}
$offerId = explode("offer/detail/", $request->getRequestUri());
if (!isset($offerId[1])){
return;
}
$offer = $this->getOfferById($offerId[1], $response->getContext()->getContext());
if (!$offer) {
return;
}
if (!$this->shouldSwitchCustomer($offer, $response->getContext())) {
return;
}
try {
$this->employeeService->changeCustomerLogin(
$offer->getOfferCustomer()->getCustomerId(),
$response->getContext()
);
} catch (InvalidCustomerException|B2bPlatformContextException $e) {
$event->setResponse(
new RedirectResponse(
$this->router->generate('frontend.b2b_platform.path', [
'path' => 'offer'
]), 301
)
);
return;
}
$event->setResponse(
new RedirectResponse(
$this->router->generate('frontend.b2b_platform.path', [
'path' => 'offer/detail/' . $offerId[1]
]), 301
)
);
}
private function shouldSwitchCustomer(OfferEntity $offer, SalesChannelContext $context): bool
{
if (empty($offer->getOfferCustomer()->getCustomerId())) {
return false;
}
if ($offer->getOfferCustomer()->getCustomerId() === $context->getCustomer()->getId()) {
return false;
}
$assignedCustomers = $this->getEmployee($context)->getCustomers();
$customer = $assignedCustomers->filterByProperty('customerId', $offer->getOfferCustomer()->getCustomerId());
if (empty($customer) || $customer->count() < 1) {
return false;
}
return true;
}
private function getOfferById(string $offerId, Context $context): ?OfferEntity
{
$criteria = new Criteria([$offerId]);
$criteria->addAssociation('offerCustomer');
return $this->offerRepository->search($criteria, $context)->get($offerId);
}
}