<?php declare(strict_types=1);
namespace AgiqonOci\Services;
use AgiqonOci\Models\OciSession;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\LineItem\LineItemCollection;
use Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
use Shopware\Core\System\Currency\CurrencyEntity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Core\Exception\SessionUnavailableException;
class DataResolverService
{
protected ?OciSession $session;
protected EntityRepository $productRepository;
protected EntityRepository $currencyRepository;
protected SystemConfigService $configService;
protected Cart $cart;
protected Context $context;
protected ?array $config;
protected LineItemCollection $lineItems;
protected EntitySearchResult $products;
protected CalculatedPrice $shippingCosts;
protected $shippingCostsRate;
protected ?CurrencyEntity $currency;
public function __construct(Session $session,
EntityRepository $productRepository,
EntityRepository $currencyRepository,
SystemConfigService $configService)
{
$this->session = $session->get(OciSession::OCI_SESSION_NAME);
$this->productRepository = $productRepository;
$this->currencyRepository = $currencyRepository;
$this->configService = $configService;
}
/**
* Resolves all needed data for OciSession
*
* @param Cart $cart
* @param Context $context
*/
public function resolveOciData(Cart $cart, SalesChannelContext $context)
{
if (!$this->session) {
throw new SessionUnavailableException(OciSession::OCI_SESSION_NAME . ' not found!');
}
$this->cart = $cart;
$this->context = $context->getContext();
$this->setConfig($context->getSalesChannelId());
$this->setLineItems();
$this->setProducts();
$this->setShippingCosts();
$this->setShippingCostsRate();
$this->setCurrency();
}
public function getSession()
{
return $this->session;
}
private function setConfig(?string $salesChannelId = null): void
{
$this->config = $this->configService->get('AgiqonOci.config', $salesChannelId);
}
public function getConfig(): ?array
{
return $this->config;
}
public function getConfigValue(string $key): string
{
return $this->config[$key] ?? '';
}
private function setLineItems(): void
{
$this->lineItems = $this->cart->getLineItems();
}
public function getLineItems()
{
return $this->lineItems;
}
private function setProducts(): void
{
$productIds = [];
foreach ($this->cart->getLineItems() as $lineItem) {
if ($lineItem->getType() === LineItem::PRODUCT_LINE_ITEM_TYPE ) {
$productIds[] = $lineItem->getReferencedId();
}
if($lineItem->getType() === 'customized-products'){
$customizedProduct = $lineItem->getChildren()->getElements();
$customizedProductID = array_values($customizedProduct)[0]->getReferencedId();
$productIds[] = $customizedProductID;
}
}
$criteria = new Criteria($productIds);
$criteria->addAssociation('tax');
$this->products = $this->productRepository->search($criteria, $this->context);
}
public function getProducts(): ?EntityCollection
{
return $this->products;
}
public function getProductById($productId): ?ProductEntity
{
return $this->products->get($productId);
}
private function setShippingCosts()
{
$this->shippingCosts = $this->cart->getDeliveries()->getShippingCosts()->sum();
}
public function getShippingCosts(): ?CalculatedPrice
{
return $this->shippingCosts;
}
public function setShippingCostsRate()
{
$this->shippingCostsRate = $this->cart->getDeliveries()->getShippingCosts()->getTaxRules()->first() ? $this->cart->getDeliveries()->getShippingCosts()->getTaxRules()->first()->getTaxRate() : 0;
}
public function getShippingCostsRate(): float
{
return $this->shippingCostsRate;
}
private function setCurrency()
{
$criteria = new Criteria([$this->context->getCurrencyId()]);
$this->currency = $this->currencyRepository->search($criteria, $this->context)->first();
}
public function getCurrency(): ?CurrencyEntity
{
return $this->currency;
}
}