<?php declare(strict_types=1);
/**
* Shopware
* Copyright © 2020
*
* @category Shopware
* @package SwpProductOptionsSix
* @subpackage ProductPageCriteriaSubscriber.php
*
* @copyright 2020 Iguana-Labs GmbH
* @author Module Factory <info at module-factory.com>
* @license https://www.module-factory.com/eula
*/
namespace Swp\RefundSystemSix\Storefront\Subscriber;
use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
use Shopware\Core\Content\Cms\CmsPageCollection;
use Shopware\Core\Content\Cms\CmsPageEntity;
use Shopware\Core\Content\Cms\SalesChannel\Struct\ProductBoxStruct;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Product\Events\ProductSuggestResultEvent;
use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Cms\Events\CmsPageLoadedEvent;
use Shopware\Core\Content\Product\ProductCollection;
class Frontend implements EventSubscriberInterface
{
/** @var SystemConfigService */
private $systemConfigService;
/** @var EntityRepositoryInterface */
protected $RefundSystemRepository;
/**
* Frontend constructor.
* @param SystemConfigService $systemConfigService
*/
public function __construct(
SystemConfigService $systemConfigService,
EntityRepositoryInterface $RefundSystemRepository
) {
$this->systemConfigService = $systemConfigService;
$this->RefundSystemRepository = $RefundSystemRepository;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
ProductListingResultEvent::class => 'onProductListingResult',
ProductPageLoadedEvent::class => 'onProductPageLoaded',
ProductSuggestResultEvent::class => 'onSuggestLoaded',
CmsPageLoadedEvent::class => 'onCmsPageLoaded'
];
}
/**
* @param CmsPageLoadedEvent $event
* @return void
*/
public function onCmsPageLoaded(CmsPageLoadedEvent $event): void
{
if ($this->isCannelActive($event->getSalesChannelContext()) !== true) {
return;
}
/** @var CmsPageCollection $cms */
$cms = $event->getResult();
/** @var CmsPageEntity $cmsEntity */
foreach ($cms->getIterator() as $cmsEntity) {
//Product
/** @var CmsSlotEntity $productBoxes */
$productBoxes = $cmsEntity->getElementsOfType('product-box');
/** @var CmsSlotEntity $productBox */
foreach ($productBoxes as $productBox) {
/** @var ProductBoxStruct $box */
$box=$productBox->getData();
/** @var SalesChannelProductEntity $product */
if (!method_exists($box, 'getProduct')) continue;
$product = $box->getProduct();
$refund = $this->productHasRefund($product->getID(), $product, $event);
if(count($refund)>0) {
$product->hasRefund = $refund;
}
}
//Slider
$productBoxes = $cmsEntity->getElementsOfType('product-slider');
/** @var CmsSlotEntity $productBox */
foreach ($productBoxes as $productBox) {
$productCollection = new ProductCollection();
$sliderProducts = $productBox->getData()->getProducts();
if ($sliderProducts === null) {
continue;
}
$products = array();
foreach ($sliderProducts->getElements() as $key => $product) {
$refund = $this->productHasRefund($product->getID(), $product, $event);
if(count($refund)>0) {
//$product->setTranslated(array('name' => $this->generateNewProductsName($product, $event, $refund)));
$product->hasRefund = $refund;
}
}
}
//product-description-reviews
$productBoxes = $cmsEntity->getElementsOfType('product-description-reviews');
/** @var CmsSlotEntity $productBox */
foreach ($productBoxes as $productBox) {
/** @var ProductBoxStruct $box */
$box=$productBox->getData();
/** @var SalesChannelProductEntity $product */
if (!method_exists($box, 'getProduct')) continue;
$product = $box->getProduct();
$refund = $this->productHasRefund($product->getID(), $product, $event);
if(count($refund)>0) {
//$product->setTranslated(array('name' => $this->generateNewProductsName($product, $event, $refund)));
$product->hasRefund = $refund;
}
}
//gallery-buybox
$productBoxes = $cmsEntity->getElementsOfType('buy-box');
//$productBoxes = array();
/** @var CmsSlotEntity $productBox */
foreach ($productBoxes as $productBox) {
/** @var ProductBoxStruct $box */
$box=$productBox->getData();
/** @var SalesChannelProductEntity $product */
if (!method_exists($box, 'getProduct')) continue;
$product = $box->getProduct();
$refund = $this->productHasRefund($product->getID(), $product, $event);
if(count($refund)>0) {
//$product->setTranslated(array('name' => $this->generateNewProductsName($product, $event, $refund)));
$product->hasRefund = $refund;
}
}
//CrossSelling
$productBoxes = $cmsEntity->getElementsOfType('cross-selling');
/** @var CmsSlotEntity $productBox */
foreach ($productBoxes as $productBox) {
$crossSellings = $productBox->getData()->getCrossSellings();
if ($crossSellings === null) {
continue;
}
foreach ($crossSellings->getElements() as $crossSelling) {
$productCollection = new ProductCollection();
$products = $crossSelling->getProducts()->getElements();
foreach ($products as $product) {
$refund = $this->productHasRefund($product->getID(), $product, $event);
if(count($refund)>0) {
//$product->setTranslated(array('name' => $this->generateNewProductsName($product, $event, $refund)));
$product->hasRefund = $refund;
}
}
}
}
}
}
/**
* @param ProductPageLoadedEvent $event
*/
public function onProductPageLoaded(ProductPageLoadedEvent $event)
{
if ($this->isCannelActive($event->getSalesChannelContext()) !== true) {
return;
}
$product = $event->getPage()->getProduct();
$id = $product->getId();
$refund = $this->productHasRefund($product->getId(), $product, $event);
if(count($refund)>0) {
//$product->setTranslated(array('name' => $this->generateNewProductsName($product, $event, $refund)));
$product->hasRefund = $refund;
}
}
/**
* @param ProductSuggestResultEvent $event
*/
public function onSuggestLoaded(ProductSuggestResultEvent $event): void
{
if ($this->isCannelActive($event->getSalesChannelContext()) !== true) {
return;
}
$result = $event->getResult();
$elements = $result->getElements();
foreach($elements as $id => &$product) {
$refund = $this->productHasRefund($id, $product, $event);
if(count($refund)>0) {
$product->setTranslated(array('name' => $this->generateNewProductsName($product, $event, $refund)));
$product->hasRefund = $refund;
}
}
}
/**
* @param ProductListingResultEvent $event
*/
public function onProductListingResult(ProductListingResultEvent $event): void
{
if ($this->isCannelActive($event->getSalesChannelContext()) !== true) {
return;
}
$result = $event->getResult();
$elements = $result->getElements();
/** @var SalesChannelProductEntity $product */
foreach($elements as $id => &$product) {
$refund = $this->productHasRefund($id, $product, $event);
if(count($refund)>0) {
//$product->setTranslated(array('name' => $this->generateNewProductsName($product, $event, $refund)));
$product->hasRefund = $refund;
}
}
}
/**
* @param string $id
* @return array
*/
private function productHasRefund($id, SalesChannelProductEntity $product, $event): array
{
$customFields = $product->getCustomFields();
if (!array_key_exists('refund_system', $customFields)){
return array();
}
$data = $this->RefundSystemRepository->search(
new Criteria([$customFields['refund_system']]),
$event->getContext()
);
$refund[]=$data->getElements();
$refundName = '';
$active = false;
foreach ($data->getElements() as $key => $val){
$active = $val->isActive();
$refundName = $val->getTranslation('name');
}
if (!$active){
return array();
}
//$return['refund']['data'] = $refund;
if (isset($customFields['refund_system_price'])) {
$return['price'] = $customFields['refund_system_price'];
if (isset($customFields['swp_refund_price_back'])) {
if ($customFields['swp_refund_price_back']==1){
$return['price']=$return['price']*(-1);
}
}
}else {
$return['price'] = 0;
}
$return['name'] = $refundName;
$return['calculated_price']=$this -> calculateRefundPrice($product, $event, $return);
return $return;
}
/**
* @param string $id
* @return array
*/
private function generateNewProductsName(SalesChannelProductEntity $product, $event, $refund): string
{
$productsName = $product->getTranslation('name');
$currency = $event->getSalesChannelContext()->getCurrency()->getIsoCode();
$currencyFactor = $event->getContext()->getCurrencyFactor();
//$currencyPrecission = $event->getContext()->getCurrencyPrecision();
$refundPrice = $this -> calculateRefundPrice($product, $event, $refund);
$newProductsName = $productsName.' - '.strtoupper($refund['name']);
return $newProductsName;
}
/**
* @param string $id
* @return array
*/
private function calculateRefundPrice(SalesChannelProductEntity $product, $event, $refund): float
{
$productsName = $product->getName();
$currency = $event->getSalesChannelContext()->getCurrency()->getIsoCode();
$currencyFactor = $event->getContext()->getCurrencyFactor();
//$currencyPrecission = $event->getContext()->getCurrencyPrecision();
$currencyPrecission = 2;
$taxRate = $product->getTax()->getTaxRate();
$taxStatus = $event->getContext()->getTaxState();
// if ($taxStatus == 'net'){
// //keine Steuer berechnen
// }else{
// //berechne Steuer
// }
return round($refund['price']*$currencyFactor, $currencyPrecission);
}
/**
* @param SalesChannelContext $event
* @return array|mixed|null
*/
private function isCannelActive(SalesChannelContext $event)
{
return $this->systemConfigService->get(
'SwpRefundSystemSix.config.channelActive',
$event->getSalesChannel()->getId()
);
}
}