Magento 2申请优惠券代码后不适用其他购物车规则

时间:2016-12-15 04:27:58

标签: magento2

我正在使用Magento 2和Amasty Pormo模块。并且这个模块允许在购物车中添加一些促销/免费礼品与一些购物车规则。测试案例是这样的

如果我的购物车在购物车中有一些免费/促销商品,然后如果我应用优惠券或任何错误的优惠券代码,那么它将从购物车中删除先前与规则相关的免费商品/促销商品。所以没有免费礼物。

你能帮助我,让我知道为什么会这样吗?非常感谢你

1 个答案:

答案 0 :(得分:1)

我找到了它的原因,这是一个非常可靠的理由。

默认情况下,在Magento 2中有四种类型的规则

  1. 产品价格折扣百分比
  2. 固定金额折扣
  3. 整车的固定金额折扣
  4. 购买X免费
  5. 因此,如果我们看到上述四条规则,我们将得出结论

    • 所有规则都与折扣有关,任何促销免费礼品都没有默认规则。
    • 当我们将优惠券应用于购物车时,只有那些将有优惠券而不是没有优惠券的规则适用

    如果我们只有基于折扣的促销,上述结论是有意义的。但是如果我们添加新规则或者我们添加任何第三方模块,例如Amasty Promo模块。我们还有一些选项可以添加免费礼品相关规则。

    所以现在在上面的场景中,我们的网站将提供折扣和免费礼品。如果客户购物车同时享受基于优惠券的规则和免费礼品折扣,那么Magento将仅应用基于优惠券的规则并忽略所有其他规则。

    解决方案:

    我们可以通过覆盖\ Magento \ SalesRule \ Model \ Validator

    来实现我们的要求

    etc / di.xml将是这样的

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    
        <!-- We override it to apply the Amasty_Promo rules even after apply the coupon code -->
        <preference for="\Magento\SalesRule\Model\Validator" type="\YourPackage\YourModule\Rewrite\SalesRule\Model\Validator" />
    </config>
    

    YourPackage \ YourModule \ Rewrite \ SalesRule \ Model \ Validator.php

    namespace YourPackage\YourModule\Rewrite\SalesRule\Model;
    
    use Magento\Quote\Model\Quote\Address;
    use Magento\Quote\Model\Quote\Item\AbstractItem;
    
    class Validator extends \Magento\SalesRule\Model\Validator
    {
        /**
         * Quote item discount calculation process
         *
         * @param AbstractItem $item
         * @return $this
         */
        public function process(AbstractItem $item)
        {
            $item->setDiscountAmount(0);
            $item->setBaseDiscountAmount(0);
            $item->setDiscountPercent(0);
    
            $itemPrice = $this->getItemPrice($item);
            if ($itemPrice < 0) {
                return $this;
            }
    
            $appliedRuleIds = array();
    
            if($this->getCouponCode()) {
                $appliedRuleIds = $this->rulesApplier->applyRules(
                    $item,
                    $this->_getRules($item->getAddress()),
                    $this->_skipActionsValidation,
                    $this->getCouponCode()
                );
            }
            $promoItemRuleIds = $this->rulesApplier->applyRules(
                $item,
                $this->_getPromoItemRules($item->getAddress()),
                $this->_skipActionsValidation,
                $this->getCouponCode()
            );
    
            $appliedRuleIds = array_merge($appliedRuleIds,$promoItemRuleIds );
    
            $this->rulesApplier->setAppliedRuleIds($item, $appliedRuleIds);
    
            return $this;
        }
    
        /**
         * Get rules of promo items
         *
         * @param Address|null $address
         * @return \Magento\SalesRule\Model\ResourceModel\Rule\Collection
         */
        protected function _getPromoItemRules(Address $address = null)
        {
            $addressId = $this->getAddressId($address);
            $key = $this->getWebsiteId() . '_'
                . $this->getCustomerGroupId() . '_'
                . '_'
                . $addressId;
            if (!isset($this->_rules[$key])){
                $this->_rules[$key] = $this->_collectionFactory->create()
                    ->setValidationFilter(
                        $this->getWebsiteId(),
                        $this->getCustomerGroupId(),
                        '',
                        null,
                        $address
                    )
                    ->addFieldToFilter('is_active', 1)
                    ->addFieldToFilter('simple_action', array('like'=>'%ampromo%'))//Condition for promo rules only
                    ->load();
            }
            return $this->_rules[$key];
        }
    }