Model/Cart/CartConflict.php
<?php
namespace MundiPagg\MundiPagg\Model\Cart;
use Magento\Checkout\Model\Cart;
use Magento\Framework\Exception\LocalizedException;
use Mundipagg\Core\Kernel\Services\LocalizationService;
use Mundipagg\Core\Recurrence\Interfaces\ProductPlanInterface;
use Mundipagg\Core\Recurrence\Services\CartRules\CurrentProduct;
use Mundipagg\Core\Recurrence\Services\RecurrenceService;
use Mundipagg\Core\Recurrence\Services\RepetitionService;
use Mundipagg\Core\Recurrence\Services\CartRules\MoreThanOneRecurrenceProduct;
use Mundipagg\Core\Recurrence\Services\CartRules\NormalWithRecurrenceProduct;
use Mundipagg\Core\Recurrence\Services\CartRules\ProductListInCart;
use MundiPagg\MundiPagg\Concrete\Magento2CoreSetup;
use Mundipagg\Core\Recurrence\Aggregates\Repetition;
use Magento\Catalog\Model\Product\Interceptor;
use MundiPagg\MundiPagg\Helper\RecurrenceProductHelper;
use Magento\Catalog\Model\Product\Option;
use Magento\Catalog\Api\Data\ProductCustomOptionValuesInterface;
use Magento\Catalog\Model\Product\Option\Value;
use Mundipagg\Core\Recurrence\Services\ProductSubscriptionService;
use Mundipagg\Core\Recurrence\Services\PlanService;
use Mundipagg\Core\Recurrence\Services\CartRules\JustProductPlanInCart;
use Mundipagg\Core\Recurrence\Services\CartRules\JustSelfProductPlanInCart;
use MundiPagg\MundiPagg\Helper\RulesCartRun;
use Mundipagg\Core\Kernel\Aggregates\Configuration;
class CartConflict
{
/**
* @var RepetitionService
*/
private $repetitionService;
/**
* @var RecurrenceService
*/
private $recurrenceService;
/**
* @var RecurrenceProductHelper
*/
private $recurrenceProductHelper;
/**
* @var ProductSubscriptionService
*/
private $productSubscriptionService;
/**
* @var PlanService
*/
private $planService;
/**
* @var Configuration
*/
private $mundipaggConfig;
/**
* CartConflict constructor.
* @throws \Exception
*/
public function __construct()
{
Magento2CoreSetup::bootstrap();
$this->repetitionService = new RepetitionService();
$this->recurrenceService = new RecurrenceService();
$this->recurrenceProductHelper = new RecurrenceProductHelper();
$this->productSubscriptionService = new ProductSubscriptionService();
$this->planService = new PlanService();
$this->rulesCartRun = new RulesCartRun();
$this->mundipaggConfig = Magento2CoreSetup::getModuleConfiguration();
}
/**
* @param Cart $cart
* @param $dataQty
* @throws LocalizedException
*/
public function beforeUpdateItems(Cart $cart, $dataQty)
{
if (
!$this->mundipaggConfig->isEnabled() ||
!$this->mundipaggConfig->getRecurrenceConfig()->isEnabled()
) {
return;
}
$items = $cart->getQuote()->getAllVisibleItems();
foreach ($items as $item) {
if (!isset($dataQty[$item->getItemId()]['qty'])) {
continue;
}
$productPlan = $this->planService->findByProductId(
$item->getProduct()->getId()
);
if (($productPlan !== null) && ($dataQty[$item->getItemId()]['qty'] > 1)) {
$i18n = new LocalizationService();
$message = $i18n->getDashboard(
'You must have only one product plan in the cart'
);
throw new LocalizedException(__($message));
}
}
}
/**
* @param Cart $cart
* @param Interceptor $productInfo
* @param mixed|null $requestInfo
* @return array
* @throws LocalizedException
*/
public function beforeAddProduct(
Cart $cart,
Interceptor $productInfo,
$requestInfo = null
) {
if (
!$this->mundipaggConfig->isEnabled() ||
!$this->mundipaggConfig->getRecurrenceConfig()->isEnabled()
) {
return [$productInfo, $requestInfo];
}
$currentProduct = $this->buildCurrentProduct(
$productInfo,
$requestInfo
);
$productListInCart = $this->buildProductListInCart($cart);
$this->rulesCartRun->runRulesProductPlan(
$currentProduct,
$productListInCart
);
$this->rulesCartRun->runRulesProductSubscription(
$currentProduct,
$productListInCart
);
return [$productInfo, $requestInfo];
}
/**
* @param Interceptor $productInfo
* @param mixed|null $requestInfo
* @return CurrentProduct
*/
protected function buildCurrentProduct(
Interceptor $productInfo,
$requestInfo = null
) {
$productPlan = $this->planService->findByProductId($requestInfo['product']);
$currentProduct = new CurrentProduct();
$quantity = 1;
if (isset($requestInfo['qty'])) {
$quantity = $requestInfo['qty'];
}
$currentProduct->setQuantity($quantity);
if ($productPlan !== null) {
$currentProduct->setIsNormalProduct(false);
$currentProduct->setProductPlanSelected($productPlan);
return $currentProduct;
}
$isNormalProduct = $this->checkIsNormalProduct($requestInfo);
if ($isNormalProduct) {
$currentProduct->setIsNormalProduct($isNormalProduct);
return $currentProduct;
}
$repetitionSelected = $this->getOptionRecurrenceSelected(
$productInfo->getOptions(),
$requestInfo['options']
);
if (!$repetitionSelected) {
$currentProduct->setIsNormalProduct(true);
return $currentProduct;
}
$currentProduct->setRepetitionSelected($repetitionSelected);
$productSubscriptionSelected =
$this->productSubscriptionService->findById(
$repetitionSelected->getSubscriptionId()
);
$currentProduct->setProductSubscriptionSelected(
$productSubscriptionSelected
);
return $currentProduct;
}
/**
* @param Cart $cart
* @return ProductListInCart
*/
protected function buildProductListInCart(Cart $cart)
{
$productList = new ProductListInCart();
$itemQuoteList = $cart->getQuote()->getAllVisibleItems();
foreach ($itemQuoteList as $item) {
$productPlan = $this->planService->findByProductId(
$item->getProduct()->getId()
);
if ($productPlan !== null) {
$productList->addProductPlan($productPlan);
continue;
}
$repetitionInCart = $this->recurrenceProductHelper->getSelectedRepetition(
$item
);
if (is_null($repetitionInCart)) {
$productList->addNormalProducts($item);
continue;
}
$productSubscriptionInCart = $this->productSubscriptionService->findById(
$repetitionInCart->getSubscriptionId()
);
$productList->setRepetition($repetitionInCart);
$productList->setRecurrenceProduct($productSubscriptionInCart);
$productList->addRecurrenceProduct($productSubscriptionInCart);
}
return $productList;
}
/**
* @param array $requestInfo
* @return bool
*/
public function checkIsNormalProduct($requestInfo)
{
if (!isset($requestInfo['options'])) {
return true;
}
return false;
}
/**
* @param Option[] $optionsList
* @param array $optionsSelected
* @return Repetition|null
*/
public function getOptionRecurrenceSelected(array $optionsList, array $optionsSelected)
{
$productOptionValue = null;
foreach ($optionsList as $option) {
if ($option->getSku() != 'recurrence') {
continue;
}
/* @var Value[]|ProductCustomOptionValuesInterface[] $valueList */
$valueList = $option->getValues();
$productOptionValue = $this->getOptionsValues($valueList, $optionsSelected);
}
if (is_null($productOptionValue)) {
return null;
}
return $this->repetitionService->getRepetitionById(
$productOptionValue->getSortOrder()
);
}
/**
* @param Value[] $valueList
* @param array $optionsSelected
* @return Value|null
*/
private function getOptionsValues(array $valueList, array $optionsSelected)
{
$optionValueSelected = null;
foreach ($valueList as $value) {
$optionValueSelected = $this->getOptionValueSelected($value, $optionsSelected);
if (!is_null($optionValueSelected)) {
return $optionValueSelected;
}
}
return $optionValueSelected;
}
/**
* @param Value $value
* @param array $optionsSelected
* @return Value|null
*/
private function getOptionValueSelected(Value $value, array $optionsSelected)
{
$optionValueSelected = null;
foreach ($optionsSelected as $optionId => $optionTypeId) {
if (($value->getOptionTypeId() == $optionTypeId) &&
($value->getData()['option_id'] == $optionId)) {
$optionValueSelected = $value;
}
}
return $optionValueSelected;
}
}