<?php
namespace Orcamultimedia\OciPunchout\Subscriber;
use Orcamultimedia\OciPunchout\Checkout\Cart\PunchoutLineItemFactory;
use Orcamultimedia\OciPunchout\Service\OciService;
use Orcamultimedia\OciPunchout\Struct\OciCartData;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Checkout\Cart\Tax\Struct\CalculatedTaxCollection;
use Shopware\Core\Checkout\Cart\Tax\Struct\TaxRuleCollection;
use Shopware\Core\System\SalesChannel\Context\AbstractSalesChannelContextFactory;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextPersister;
use Shopware\Core\System\SalesChannel\Event\SalesChannelContextSwitchEvent;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class SalesChannelContextSwitchSubscriber implements EventSubscriberInterface
{
private CartService $cartService;
private SalesChannelContextPersister $contextPersister;
private AbstractSalesChannelContextFactory $factory;
private OciService $ociService;
private SystemConfigService $systemConfigService;
private TranslatorInterface $translator;
public function __construct(
CartService $cartService,
SalesChannelContextPersister $contextPersister,
AbstractSalesChannelContextFactory $factory,
OciService $ociService,
SystemConfigService $systemConfigService,
TranslatorInterface $translator
) {
$this->cartService = $cartService;
$this->contextPersister = $contextPersister;
$this->factory = $factory;
$this->ociService = $ociService;
$this->systemConfigService = $systemConfigService;
$this->translator = $translator;
}
public static function getSubscribedEvents(): array
{
return [
SalesChannelContextSwitchEvent::class => 'onSalesChannelContextSwitch'
];
}
public function onSalesChannelContextSwitch(SalesChannelContextSwitchEvent $event): void
{
$context = $event->getSalesChannelContext();
$cart = $this->cartService->getCart($context->getToken(), $context);
if (
!$this->ociService->isPunchout()
|| !$this->systemConfigService->get(
'OciPunchout.config.addShippingCostsAtPunchout',
$context->getSalesChannel()->getId()
)
|| $cart->getLineItems()->count() === 0
|| empty($event->getRequestDataBag()->get('shippingMethodId'))
) {
return;
}
try {
$session = $this->contextPersister->load($context->getToken(), $context->getSalesChannel()->getId());
$newContext = $this->factory->create($context->getToken(), $context->getSalesChannel()->getId(), $session);
} catch (\Exception $e) {
return;
}
$newCart = $this->cartService->getCart($newContext->getToken(), $newContext);
$newCart = $this->cartService->recalculate($newCart, $newContext);
if ($cart->has('shipping-costs')){
$cart->remove('shipping-costs');
}
$extensionData = new OciCartData();
$extensionData->assign([
'matgroup' => $this->systemConfigService->get(
'OciPunchout.config.shippingCostsMatgroup',
$context->getSalesChannel()->getId()
),
'unit' => 'PCE'
]);
// Adding leadtime
if ($this->systemConfigService->get('OciPunchout.config.isSubmitMaximumLeadTimeForShippingCosts',
$context->getSalesChannel()->getId())) {
$extensionData->assign([
'leadtime' => $this->systemConfigService->get(
'OciPunchout.config.maximumLeadTime',
$context->getSalesChannel()->getId()
)
]);
}
// Adding extschematype
if ($this->systemConfigService->get('OciPunchout.config.isSubmitShippingCostsExtschematype',
$context->getSalesChannel()->getId())) {
$extensionData->assign([
'extschematype' => $this->systemConfigService->get(
'OciPunchout.config.extschematype',
$context->getSalesChannel()->getId()
)
]);
}
// Adding extcategoryid
if ($this->systemConfigService->get('OciPunchout.config.shippingCostsExtcategoryid',
$context->getSalesChannel()->getId())) {
$extensionData->assign([
'extcategoryid' => $this->systemConfigService->get(
'OciPunchout.config.extcategoryid',
$context->getSalesChannel()->getId()
)
]);
}
// Adding Customfield
if (strcasecmp($this->systemConfigService->get('OciPunchout.config.isSubmitShippingCostsCustomfield',
$context->getSalesChannel()->getId()), 'default') !== 0) {
$extensionData->assign([
'extcategoryid' => $this->systemConfigService->get(
'OciPunchout.config.' . $this->systemConfigService->get('OciPunchout.config.isSubmitShippingCostsCustomfield',
$context->getSalesChannel()->getId()),
$context->getSalesChannel()->getId()
)
]);
}
$lineItem = (new LineItem('shipping-costs', PunchoutLineItemFactory::TYPE, 'shipping-costs', 1))
->setLabel($this->translator->trans('orca-ocipunchout.shippingCosts', ['%type%' =>
$newContext->getShippingMethod()->getName()]))
->setRemovable(true)
->setPayloadValue('productNumber', 'shipping-costs')
->setPrice(
new CalculatedPrice(
$newCart->getDeliveries()->getShippingCosts()->sum()->getUnitPrice(),
$newCart->getDeliveries()->getShippingCosts()->sum()->getTotalPrice(),
new CalculatedTaxCollection(),
new TaxRuleCollection()
)
);
$alternativeCaptionShippingCosts = $this->systemConfigService->get(
'OciPunchout.config.alternativeCaptionOfShippingCosts',
$context->getSalesChannel()->getId()
);
if (strlen($alternativeCaptionShippingCosts) > 0) {
$alternativeCaptionShippingCosts = trim($alternativeCaptionShippingCosts);
$lineItem->setLabel($alternativeCaptionShippingCosts);
}
$lineItem->addExtension(OciCartData::EXTENSION_NAME, $extensionData);
$cart->add($lineItem);
$cart->markModified();
$this->cartService->recalculate($cart, $context);
}
}