<?php declare(strict_types=1);
namespace Econsor\Shopware\AtBitConfiguratorConnector\Subscriber;
use Shopware\Core\Checkout\Cart\CartEvents;
use Shopware\Core\Checkout\Cart\Event\LineItemQuantityChangedEvent;
use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
use Shopware\Core\Checkout\Cart\Event\LineItemRemovedEvent;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice;
use Shopware\Core\Checkout\Cart\Tax\Struct\CalculatedTax;
use Shopware\Core\Checkout\Cart\Tax\Struct\CalculatedTaxCollection;
use Shopware\Core\Checkout\Cart\Tax\Struct\TaxRule;
use Shopware\Core\Checkout\Cart\Tax\Struct\TaxRuleCollection;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
use Shopware\Storefront\Page\PageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Session\Session;
class AtBitSessionCleaner implements EventSubscriberInterface
{
private $session;
public function __construct(
Session $session
)
{
$this->session = $session;
}
public static function getSubscribedEvents(): array
{
return [
LineItemRemovedEvent::class => 'onLineItemRemoved',
LineItemQuantityChangedEvent::class => 'onQuantityChanged',
CheckoutOrderPlacedEvent::class => 'onOrderPlaced'
];
}
public function onLineItemRemoved(LineItemRemovedEvent $event): void
{
$URI = $_SERVER['REQUEST_URI'];
if(str_contains($URI, '/delete')) {
$id = explode('/', $URI);
$id = array_pop($id);
$config = $this->session->has('atBitConfiguratorProducts') ? $this->session->get('atBitConfiguratorProducts') : null;
if($config && in_array($id, array_keys($config))) {
unset($config[$id]);
$this->session->set('atBitConfiguratorProducts', $config);
}
}
}
public function onQuantityChanged(LineItemQuantityChangedEvent $event)
{
if($configuratorProduct = $this->getLineItemFromSession($event->getLineItem()->getId())) {
$quantity = $event->getLineItem()->getQuantity();
/** @var ArrayStruct $extension */
$extension = $configuratorProduct->getExtension('atbitConfiguration');
$netPrice = $extension->get('GesamtpreisOhneMwSt');
$tax = $extension->get('MwSt');
$newPrice = $this->getCalculatedPrice($netPrice, $tax, $quantity);
$configuratorProduct->setQuantity($quantity);
$configuratorProduct->setPrice($newPrice);
$this->setLineItemFromSession($configuratorProduct, $event->getLineItem()->getId());
}
}
public function onOrderPlaced(CheckoutOrderPlacedEvent $event)
{
$this->session->remove('atBitConfiguratorProducts');
}
private function getLineItemFromSession(string $id): ?LineItem
{
if(
($lineItems = $this->session->get('atBitConfiguratorProducts')) &&
array_key_exists($id, $lineItems)
) {
return $lineItems[$id];
}
return null;
}
private function setLineItemFromSession(LineItem $lineItem, string $id)
{
if($lineItems = $this->session->get('atBitConfiguratorProducts')) {
$lineItems[$id] = $lineItem;
$this->session->set('atBitConfiguratorProducts', $lineItems);
}
}
private function getCalculatedPrice(float $netPrice, float $tax, int $quantity): CalculatedPrice
{
$netPrice = $netPrice * $quantity;
$taxAmount = $netPrice * ($tax / 100);
$grossPrice = $netPrice + $taxAmount;
$calculatedTaxes = new CalculatedTaxCollection([
new CalculatedTax($taxAmount, $tax, $netPrice)
]);
$taxRules = new TaxRuleCollection([
new TaxRule($tax)
]);
return new CalculatedPrice(
($grossPrice / $quantity),
$grossPrice,
$calculatedTaxes,
$taxRules,
$quantity
);
}
}