<?php declare(strict_types=1);
namespace Shopware\B2B\Budget\BridgePlatform;
use Shopware\B2B\Budget\Framework\BudgetRepository;
use Shopware\B2B\Budget\Framework\BudgetService;
use Shopware\B2B\Common\IdValue;
use Shopware\B2B\Common\Repository\NotFoundException;
use Shopware\B2B\Currency\Framework\CurrencyService;
use Shopware\B2B\Order\BridgePlatform\OrderContextCreatedEvent;
use Shopware\B2B\StoreFrontAuthentication\Framework\AuthenticationService;
use Shopware\B2B\StoreFrontAuthentication\Framework\OwnershipContext;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class BudgetPreferenceSubscriber implements EventSubscriberInterface
{
/**
* @var CurrencyService
*/
private $currencyService;
/**
* @var BudgetService
*/
private $budgetService;
/**
* @var AuthenticationService
*/
private $authenticationService;
/**
* @var BudgetRepository
*/
private $budgetRepository;
public static function getSubscribedEvents(): array
{
return [
CheckoutConfirmPageLoadedEvent::class => 'updateCartPreference',
OrderContextCreatedEvent::class => 'addBudgetPreference',
];
}
public function __construct(
AuthenticationService $authenticationService,
BudgetRepository $budgetRepository,
CurrencyService $currencyService,
BudgetService $budgetService
) {
$this->authenticationService = $authenticationService;
$this->budgetRepository = $budgetRepository;
$this->currencyService = $currencyService;
$this->budgetService = $budgetService;
}
public function updateCartPreference(CheckoutConfirmPageLoadedEvent $event): void
{
if (!$this->authenticationService->isB2b()) {
return;
}
$ownershipContext = $this->authenticationService->getIdentity()->getOwnershipContext();
try {
$this->budgetRepository->fetchOrderBudgetPreferenceByCart($ownershipContext);
return;
} catch (NotFoundException $e) {
//nth
}
$amount = $event->getPage()->getCart()->getPrice()->getNetPrice();
$context = $this->authenticationService->getIdentity()->getOwnershipContext();
$budgetId = $this->findPreferredBudgetId($context, $amount);
$this->budgetRepository
->setOrderBudgetPreferenceByCart($budgetId);
}
public function addBudgetPreference(OrderContextCreatedEvent $event): void
{
$orderContext = $event->getOrderContext();
$ownershipContext = $this->authenticationService->getIdentity()->getOwnershipContext();
try {
$budgetId = $this->budgetRepository
->fetchOrderBudgetPreferenceByCart($ownershipContext);
} catch (NotFoundException $e) {
return;
}
$this->budgetRepository
->setOrderBudgetPreferenceByOrderContextId($orderContext->id, $budgetId);
$this->budgetRepository
->setOrderBudgetPreferenceByCart(IdValue::null());
}
/**
* @internal
*/
protected function findPreferredBudgetId(OwnershipContext $context, float $amount): IdValue
{
$currencyContext = $this->currencyService->createCurrencyContext();
$budgets = $this->budgetService
->getUserSelectableBudgetsWithStatus($context, $amount, $currencyContext);
$budgetId = IdValue::null();
foreach ($budgets as $budget) {
if ($budget->currentStatus->isSufficient) {
$budgetId = $budget->id;
break;
}
}
return $budgetId;
}
}