Skip to content

Commit

Permalink
Merge pull request #29 from Smile-SA/fix-get-data-without-cache
Browse files Browse the repository at this point in the history
Get gift rule data without cache when there is no cache.
  • Loading branch information
maximequeneau authored Sep 14, 2020
2 parents 89379bd + 4ef5719 commit 5f499a1
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 20 deletions.
51 changes: 45 additions & 6 deletions Helper/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
*/
namespace Smile\GiftSalesRule\Helper;

use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\Exception\LocalizedException;
use Magento\Rule\Model\Condition\Sql\Builder;
use Magento\SalesRule\Model\Rule;
use Magento\SalesRule\Model\RuleFactory;
use Smile\GiftSalesRule\Api\Data\GiftRuleInterface;
use Smile\GiftSalesRule\Api\GiftRuleRepositoryInterface;

Expand Down Expand Up @@ -51,6 +53,11 @@ class Cache extends AbstractHelper
*/
protected $giftRuleRepository;

/**
* @var RuleFactory
*/
protected $ruleFactory;

/**
* @var CollectionFactory
*/
Expand All @@ -69,18 +76,21 @@ class Cache extends AbstractHelper
* @param GiftRuleRepositoryInterface $giftRuleRepository Gift rule repository
* @param CollectionFactory $productCollectionFactory Product collection factory
* @param Builder $sqlBuilder Sql builder
* @param RuleFactory $ruleFactory Rule factory
*/
public function __construct(
Context $context,
CacheInterface $cache,
GiftRuleRepositoryInterface $giftRuleRepository,
CollectionFactory $productCollectionFactory,
Builder $sqlBuilder
Builder $sqlBuilder,
RuleFactory $ruleFactory
) {
$this->cache = $cache;
$this->giftRuleRepository = $giftRuleRepository;
$this->productCollectionFactory = $productCollectionFactory;
$this->sqlBuilder = $sqlBuilder;
$this->ruleFactory = $ruleFactory;

parent::__construct($context);
}
Expand All @@ -93,7 +103,7 @@ public function __construct(
* @param int|GiftRuleInterface $giftRule Gift rule
*
* @return array
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function saveCachedGiftRule($identifier, $rule, $giftRule)
{
Expand Down Expand Up @@ -122,6 +132,7 @@ public function saveCachedGiftRule($identifier, $rule, $giftRule)
$items[$item->getId()] = $item->getSku();
$productCacheTags[] = Product::CACHE_TAG . '_' . $item->getEntityId();
}

$giftRuleData = [
self::DATA_LABEL => $rule->getStoreLabel(),
self::DATA_NUMBER_OFFERED_PRODUCT => $giftRule->getNumberOfferedProduct(),
Expand All @@ -144,22 +155,50 @@ public function saveCachedGiftRule($identifier, $rule, $giftRule)
}

/**
* Get cached gift rule
* Get cached gift rule.
*
* @param int|string $giftRuleCode Gift rule code
*
* @return array
*/
public function getCachedGiftRule($giftRuleCode)
{
return unserialize($this->cache->load(self::CACHE_IDENTIFIER . $giftRuleCode));
$cachedData = unserialize($this->cache->load(self::CACHE_IDENTIFIER . $giftRuleCode));
if (!$cachedData) {
$rule = $this->extractRuleFromCode($giftRuleCode);
if ($rule && $rule->getId()) {
try {
$giftRule = $this->giftRuleRepository->getById($rule->getId());
$cachedData = $this->saveCachedGiftRule($giftRuleCode, $rule, $giftRule);
} catch (LocalizedException $localizedException) {
$cachedData = null;
}
}
}

return $cachedData;
}

/**
* Flush cached gift rule
* Flush cached gift rule.
*/
public function flushCachedGiftRule()
{
$this->cache->clean(self::CACHE_DATA_TAG);
}

/**
* Extract rule from gift rule code.
*
* @param string $giftRuleCode Gift rule code
*
* @return \Magento\SalesRule\Api\Data\RuleInterface|null
*/
protected function extractRuleFromCode($giftRuleCode)
{
$explodedCode = explode('_', $giftRuleCode);
$ruleId = array_shift($explodedCode);

return $this->ruleFactory->create()->load($ruleId);
}
}
13 changes: 13 additions & 0 deletions Helper/GiftRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,17 @@ public function getAddUrl($giftRuleId, $giftRuleCode)

return $this->_getUrl('giftsalesrule/cart/add', $routeParams);
}

/**
* Get range of a gift rule for a quote.
*
* @param Quote $quote Quote
* @param GiftRuleInterface $giftRule Gift rule
*
* @return float
*/
public function getRange($quote, $giftRule)
{
return floor($quote->getGrandTotal() / $giftRule->getPriceRange());
}
}
15 changes: 14 additions & 1 deletion Model/GiftRuleService.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,12 @@ public function getAvailableGifts(Quote $quote)

if (is_array($giftRules)) {
foreach ($giftRules as $giftRuleId => $giftRuleCode) {
$gifts[$giftRuleId] = $this->giftRuleCacheHelper->getCachedGiftRule($giftRuleCode);
$giftRuleCachedData = $this->giftRuleCacheHelper->getCachedGiftRule($giftRuleCode);
if (!$giftRuleCachedData) {
continue;
}

$gifts[$giftRuleId] = $giftRuleCachedData;
$gifts[$giftRuleId][GiftRuleDataInterface::RULE_ID] = $giftRuleId;
$gifts[$giftRuleId][GiftRuleDataInterface::CODE] = $giftRuleCode;
$gifts[$giftRuleId][GiftRuleDataInterface::REST_NUMBER]
Expand Down Expand Up @@ -151,6 +156,9 @@ public function addGiftProducts(Quote $quote, array $products, string $identifie
}

$giftRuleData = $this->giftRuleCacheHelper->getCachedGiftRule($identifier);
if (!$giftRuleData) {
throw new Exception(__('The gift rule is not valid.'));
}

foreach ($products as $product) {
if (!(isset($product['id']) && isset($product['qty']))) {
Expand All @@ -177,6 +185,7 @@ public function addGiftProducts(Quote $quote, array $products, string $identifie
* @throws LocalizedException
* @SuppressWarnings(PHPMD.ElseExpression)
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function replaceGiftProducts(Quote $quote, array $products, string $identifier, int $giftRuleId = null)
{
Expand All @@ -185,6 +194,10 @@ public function replaceGiftProducts(Quote $quote, array $products, string $ident
}

$giftRuleData = $this->giftRuleCacheHelper->getCachedGiftRule($identifier);
if (!$giftRuleData) {
throw new Exception(__('The gift rule is not valid.'));
}

$quoteGiftItems = $this->getQuoteGiftItems($quote, $giftRuleId);

foreach ($products as $product) {
Expand Down
2 changes: 2 additions & 0 deletions Model/ResourceModel/GiftRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ public function load(AbstractModel $object, $value, $field = null)
$objectId = $this->getObjectId($value, $field);

if ($objectId) {
$object->beforeLoad($value, $field);
$this->entityManager->load($object, $objectId);
$object->afterLoad();
}

return $this;
Expand Down
3 changes: 0 additions & 3 deletions Model/Rule/Action/Discount/OfferProduct.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ public function calculate($rule, $item, $qty)
/** @var GiftRule $giftRule */
$giftRule = $this->giftRuleRepository->getById($rule->getRuleId());

// Set number offered product.
$giftRule->setNumberOfferedProduct($giftRule->getMaximumNumberProduct());

// Save active gift rule in session.
$giftRuleSessionData = $this->checkoutSession->getGiftRules();
$giftRuleSessionData[$rule->getRuleId()] = $rule->getRuleId();
Expand Down
17 changes: 10 additions & 7 deletions Model/Rule/Action/Discount/OfferProductPerPriceRange.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@
use Magento\SalesRule\Model\Rule\Action\Discount\Data as DiscountData;
use Magento\SalesRule\Model\Rule\Action\Discount\DataFactory;
use Magento\SalesRule\Model\Validator;
use Magento\SalesRule\Api\Data\RuleInterface;
use Smile\GiftSalesRule\Api\Data\GiftRuleInterface;
use Smile\GiftSalesRule\Api\GiftRuleRepositoryInterface;
use Smile\GiftSalesRule\Helper\Cache as GiftRuleCacheHelper;
use Smile\GiftSalesRule\Helper\GiftRule as GiftRuleHelper;
use Smile\GiftSalesRule\Model\GiftRule;

/**
Expand All @@ -45,6 +44,11 @@ class OfferProductPerPriceRange extends AbstractDiscount
*/
protected $giftRuleCacheHelper;

/**
* @var GiftRuleHelper
*/
protected $giftRuleHelper;

/**
* @var GiftRuleRepositoryInterface
*/
Expand All @@ -58,6 +62,7 @@ class OfferProductPerPriceRange extends AbstractDiscount
* @param PriceCurrencyInterface $priceCurrency Price currency
* @param checkoutSession $checkoutSession Checkout session
* @param GiftRuleCacheHelper $giftRuleCacheHelper Gift rule cache helper
* @param GiftRuleHelper $giftRuleHelper Gift rule helper
* @param GiftRuleRepositoryInterface $giftRuleRepository Gift rule repository
*/
public function __construct(
Expand All @@ -66,10 +71,12 @@ public function __construct(
PriceCurrencyInterface $priceCurrency,
checkoutSession $checkoutSession,
GiftRuleCacheHelper $giftRuleCacheHelper,
GiftRuleHelper $giftRuleHelper,
GiftRuleRepositoryInterface $giftRuleRepository
) {
$this->checkoutSession = $checkoutSession;
$this->giftRuleCacheHelper = $giftRuleCacheHelper;
$this->giftRuleHelper = $giftRuleHelper;
$this->giftRuleRepository = $giftRuleRepository;

parent::__construct(
Expand Down Expand Up @@ -108,17 +115,13 @@ public function calculate($rule, $item, $qty)
$giftRule = $this->giftRuleRepository->getById($rule->getRuleId());

if ($quote->getGrandTotal() >= $giftRule->getPriceRange()) {
/** @var int $level */
$range = floor($quote->getGrandTotal() / $giftRule->getPriceRange());
$range = $this->giftRuleHelper->getRange($quote, $giftRule);

// Save active gift rule in session.
$giftRuleSessionData = $this->checkoutSession->getGiftRules();
$giftRuleSessionData[$rule->getRuleId()] = $rule->getRuleId() . '_' . $range;
$this->checkoutSession->setGiftRules($giftRuleSessionData);

// Set number offered product.
$giftRule->setNumberOfferedProduct($giftRule->getMaximumNumberProduct() * $range);

$this->giftRuleCacheHelper->saveCachedGiftRule(
$rule->getRuleId() . '_' . $range,
$rule,
Expand Down
7 changes: 5 additions & 2 deletions Observer/CollectGiftRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ public function execute(Observer $observer)
}
}
} else {
$giftRuleData = $this->giftRuleCacheHelper->getCachedGiftRule($giftRuleCode);
if (!$giftRuleData) {
continue;
}

$newGiftRulesList[$giftRuleId] = $giftRuleCode;
$giftItem = [];
$giftItemQty = 0;
Expand All @@ -143,8 +148,6 @@ public function execute(Observer $observer)
}
}

$giftRuleData = $this->giftRuleCacheHelper->getCachedGiftRule($giftRuleCode);

// If only 1 gift product available => add automatic gift product.
if ($this->giftRuleConfigHelper->isAutomaticAddEnabled() && count($giftItem) == 0 &&
count($giftRuleData[GiftRuleCacheHelper::DATA_PRODUCT_ITEMS]) == 1) {
Expand Down
75 changes: 75 additions & 0 deletions Observer/SetNumberOfferedProduct.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade this module to newer
* versions in the future.
*
* @category Smile
* @package Smile\GiftSalesRule
* @author Pierre Le Maguer <[email protected]>
* @copyright 2020 Smile
* @license Open Software License ("OSL") v. 3.0
*/
namespace Smile\GiftSalesRule\Observer;

use Magento\Checkout\Model\Session as CheckoutSession;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Exception\LocalizedException;
use Smile\GiftSalesRule\Helper\GiftRule as GiftRuleHelper;
use Smile\GiftSalesRule\Model\GiftRule;

/**
* Class SetNumberOfferedProduct
*
* @author Pierre Le Maguer <[email protected]>
* @copyright 2019 Smile
*/
class SetNumberOfferedProduct implements ObserverInterface
{
/**
* @var CheckoutSession
*/
protected $checkoutSession;

/**
* @var GiftRuleHelper
*/
protected $giftRuleHelper;

/**
* SetNumberOfferedProduct constructor.
*
* @param CheckoutSession $checkoutSession Checkout session
* @param GiftRuleHelper $giftRuleHelper Gift rule config helper
*/
public function __construct(
CheckoutSession $checkoutSession,
GiftRuleHelper $giftRuleHelper
) {
$this->checkoutSession = $checkoutSession;
$this->giftRuleHelper = $giftRuleHelper;
}

/**
* Set number offered product after load the gift rule.
*
* @param Observer $observer Oberver
*/
public function execute(Observer $observer)
{
/** @var GiftRule $giftRule */
$giftRule = $observer->getEvent()->getData('data_object');
$giftRule->setNumberOfferedProduct($giftRule->getMaximumNumberProduct());
try {
$quote = $this->checkoutSession->getQuote();
if (floatval($giftRule->getPriceRange()) > 0) {
$range = $this->giftRuleHelper->getRange($quote, $giftRule);
$giftRule->setNumberOfferedProduct($giftRule->getMaximumNumberProduct() * $range);
}
} catch (LocalizedException $localizedException) {
// In this case, we do nothing.
}
}
}
1 change: 0 additions & 1 deletion Observer/UpdateGiftRuleActions.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Serialize\Serializer\Json as serializer;
use Magento\SalesRule\Api\Data\RuleInterface;
use Smile\GiftSalesRule\Helper\GiftRule as GiftRuleHelper;
Expand Down
3 changes: 3 additions & 0 deletions etc/events.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@
<event name="sales_quote_collect_totals_after">
<observer name="smile_gift_salesrule_collect_totals_after" instance="Smile\GiftSalesRule\Observer\CollectGiftRule"/>
</event>
<event name="smile_gift_sales_rule_gift_rule_load_after">
<observer name="smile_gift_salesrule_set_number_offered_product_after_load" instance="Smile\GiftSalesRule\Observer\SetNumberOfferedProduct"/>
</event>
</config>
1 change: 1 addition & 0 deletions i18n/en_US.csv
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"Maximum number of products offered","Maximum number of products offered"
"Price range","Price range"
"Select gift product:","Select gift product:"
"The gift rule is not valid.","The gift rule is not valid."
"to offer product","to offer product"
"to offer product per price range","to offer product per price range"
"We can't add this gift item to your shopping cart.","We can't add this gift item to your shopping cart."
Expand Down
1 change: 1 addition & 0 deletions i18n/fr_FR.csv
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"Maximum number of products offered","Nombre maximum de produit offert"
"Price range","Tranche de prix"
"Select gift product:","Sélecteur des produits offerts:"
"The gift rule is not valid.","La règle de produits offerts n'est pas valide."
"to offer product","Offir un produit"
"to offer product per price range","Offrir un produit par tranche de prix"
"We can't add this gift item to your shopping cart.","Impossible d'ajouter ce produit cadeau"
Expand Down

0 comments on commit 5f499a1

Please sign in to comment.