<?php
namespace CioBudget\Subscriber;
use CioBudget\PaymentHandler\BudgetPayment;
use CioBudget\Service\StoreLoaderService;
use Shopware\Core\Checkout\Cart\Error\ErrorCollection;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Checkout\Customer\Event\CustomerLoginEvent;
use Shopware\Core\Checkout\Payment\Cart\PaymentHandler\DefaultPayment;
use Shopware\Core\Framework\Context;
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\Validation\DataBag\RequestDataBag;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextService;
use Shopware\Core\System\SalesChannel\SalesChannel\ContextSwitchRoute;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
class AutoChangePaymentMethodSubscriber implements EventSubscriberInterface
{
/** values coming from the database(payment_method) after payment method installation */
const BUDGET_PAYMENT_ID = '420fb71d2ae84fbbb322e55329a3707a';
private ContainerInterface $container;
private StoreLoaderService $storeLoaderService;
private RouterInterface $router;
public function __construct(ContainerInterface $container, StoreLoaderService $storeLoaderService, RouterInterface $router)
{
$this->container = $container;
$this->storeLoaderService = $storeLoaderService;
$this->router = $router;
}
public static function getSubscribedEvents()
{
return [
CustomerLoginEvent::class => 'onCustomerLoginEvent',
StorefrontRenderEvent::class => 'onStorefrontRender'
];
}
public function onCustomerLoginEvent(CustomerLoginEvent $event)
{
/** @var EntityRepositoryInterface $customerRepository */
$customerRepository = $this->container->get('customer.repository');
$customer = $event->getCustomer();
/** @var CartService $cartService */
$cartService = $this->container->get('Shopware\Core\Checkout\Cart\SalesChannel\CartService');
$cart = $cartService->getCart($event->getContextToken(), $event->getSalesChannelContext());
/** @var ContextSwitchRoute $contextSwitchRoute */
$contextSwitchRoute = $this->container->get('Shopware\Core\System\SalesChannel\SalesChannel\ContextSwitchRoute');
$customerStores = $this->storeLoaderService->getCustomerStores($customer);
if ($customer && count($customerStores)) {
$cart->setErrors(new ErrorCollection(array_filter($cart->getErrors()->getElements(), function ($key) {
return $key !== 'payment-method-blocked-Budget' && $key !== 'payment-method-blocked-Kostenstelle' && $key !== 'payment-method-blocked-Punkte';
}, ARRAY_FILTER_USE_KEY)));
$data = new RequestDataBag([
SalesChannelContextService::PAYMENT_METHOD_ID => self::BUDGET_PAYMENT_ID
]);
$customerRepository->update([
[
'id' => $customer->getId(),
'defaultPaymentMethodId' => self::BUDGET_PAYMENT_ID
]
], $event->getContext());
$contextSwitchRoute->switchContext($data, $event->getSalesChannelContext());
} else {
$cart->setErrors(new ErrorCollection(array_filter($cart->getErrors()->getElements(), function ($key) {
return $key !== 'payment-method-blocked-Budget' && $key !== 'payment-method-blocked-Kostenstelle' && $key !== 'payment-method-blocked-Punkte';
}, ARRAY_FILTER_USE_KEY)));
}
}
public function onStorefrontRender(StorefrontRenderEvent $event)
{
$route = $event->getRequest()->get('_route');
if (in_array($route, ['frontend.cart.offcanvas', 'frontend.checkout.confirm.page', 'frontend.checkout.cart.page'])) {
/** @var CartService $cartService */
$cartService = $this->container->get('Shopware\Core\Checkout\Cart\SalesChannel\CartService');
$cart = $cartService->getCart($event->getSalesChannelContext()->getToken(), $event->getSalesChannelContext(), CartService::SALES_CHANNEL, false);
if ($cart->getLineItems()->count() && count($cart->getErrors()->getElements())) {
$data = null;
if (array_key_exists('payment-method-blocked-Punkte', $cart->getErrors()->getElements())) {
$cart->setErrors(new ErrorCollection(array_filter($cart->getErrors()->getElements(), function ($key) {
return $key !== 'payment-method-blocked-Punkte';
}, ARRAY_FILTER_USE_KEY)));
$data = new RequestDataBag([
SalesChannelContextService::PAYMENT_METHOD_ID => $this->getPaymentMethodId(DefaultPayment::class, 'Keine Zahlungsdaten erforderlich')
]);
}
if (array_key_exists('payment-method-blocked-Keine Zahlungsdaten erforderlich', $cart->getErrors()->getElements())) {
$cart->setErrors(new ErrorCollection(array_filter($cart->getErrors()->getElements(), function ($key) {
return $key !== 'payment-method-blocked-Keine Zahlungsdaten erforderlich';
}, ARRAY_FILTER_USE_KEY)));
$data = new RequestDataBag([
SalesChannelContextService::PAYMENT_METHOD_ID => $this->getPaymentMethodId(BudgetPayment::class)
]);
}
if (!is_null($data)) {
/** @var ContextSwitchRoute $contextSwitchRoute */
$contextSwitchRoute = $this->container->get('Shopware\Core\System\SalesChannel\SalesChannel\ContextSwitchRoute');
$contextSwitchRoute->switchContext($data, $event->getSalesChannelContext());
$response = new RedirectResponse($this->router->generate($route));
$response->send();
}
} elseif (!$cart->getLineItems()->count()) {
if (array_key_exists('payment-method-blocked-Punkte', $cart->getErrors()->getElements())) {
$cart->setErrors(new ErrorCollection(array_filter($cart->getErrors()->getElements(), function ($key) {
return $key !== 'payment-method-blocked-Punkte';
}, ARRAY_FILTER_USE_KEY)));
$data = new RequestDataBag([
SalesChannelContextService::PAYMENT_METHOD_ID => $this->getPaymentMethodId(DefaultPayment::class, 'Keine Zahlungsdaten erforderlich')
]);
/** @var ContextSwitchRoute $contextSwitchRoute */
$contextSwitchRoute = $this->container->get('Shopware\Core\System\SalesChannel\SalesChannel\ContextSwitchRoute');
$contextSwitchRoute->switchContext($data, $event->getSalesChannelContext());
$response = new RedirectResponse($this->router->generate($route));
$response->send();
}
}
}
}
protected function getPaymentMethodId($handlerIdentifier, $distinguishableName = null)
{
/** @var EntityRepositoryInterface $paymentRepository */
$paymentRepository = $this->container->get('payment_method.repository');
$paymentCriteria = (new Criteria())
->addFilter(new EqualsFilter('handlerIdentifier', $handlerIdentifier));
if ($distinguishableName) {
$paymentCriteria
->addFilter(new EqualsFilter('name', $distinguishableName))
->addAssociation('payment_method_translation');
}
return $paymentRepository->searchIds($paymentCriteria, Context::createDefaultContext())->firstId();
}
}