Example #1
0
 /**
  * Quote item free shipping ability check
  * This process not affect information about applied rules, coupon code etc.
  * This information will be added during discount amounts processing
  *
  * @param   \Magento\Sales\Model\Quote\Item\AbstractItem $item
  * @return  \Magento\OfflineShipping\Model\SalesRule\Calculator
  */
 public function processFreeShipping(\Magento\Sales\Model\Quote\Item\AbstractItem $item)
 {
     $address = $item->getAddress();
     $item->setFreeShipping(false);
     foreach ($this->_getRules() as $rule) {
         /* @var $rule \Magento\SalesRule\Model\Rule */
         if (!$this->validatorUtility->canProcessRule($rule, $address)) {
             continue;
         }
         if (!$rule->getActions()->validate($item)) {
             continue;
         }
         switch ($rule->getSimpleFreeShipping()) {
             case \Magento\OfflineShipping\Model\SalesRule\Rule::FREE_SHIPPING_ITEM:
                 $item->setFreeShipping($rule->getDiscountQty() ? $rule->getDiscountQty() : true);
                 break;
             case \Magento\OfflineShipping\Model\SalesRule\Rule::FREE_SHIPPING_ADDRESS:
                 $address->setFreeShipping(true);
                 break;
         }
         if ($rule->getStopRulesProcessing()) {
             break;
         }
     }
     return $this;
 }
Example #2
0
 /**
  * @param \Magento\SalesRule\Model\Rule $rule
  * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item
  * @param float $qty
  * @return \Magento\SalesRule\Model\Rule\Action\Discount\Data
  */
 public function calculate($rule, $item, $qty)
 {
     /** @var \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData */
     $discountData = $this->discountFactory->create();
     $ruleTotals = $this->validator->getRuleItemTotalsInfo($rule->getId());
     $quote = $item->getQuote();
     $address = $item->getAddress();
     $itemPrice = $this->validator->getItemPrice($item);
     $baseItemPrice = $this->validator->getItemBasePrice($item);
     $itemOriginalPrice = $this->validator->getItemOriginalPrice($item);
     $baseItemOriginalPrice = $this->validator->getItemBaseOriginalPrice($item);
     /**
      * prevent applying whole cart discount for every shipping order, but only for first order
      */
     if ($quote->getIsMultiShipping()) {
         $usedForAddressId = $this->getCartFixedRuleUsedForAddress($rule->getId());
         if ($usedForAddressId && $usedForAddressId != $address->getId()) {
             return $discountData;
         } else {
             $this->setCartFixedRuleUsedForAddress($rule->getId(), $address->getId());
         }
     }
     $cartRules = $address->getCartFixedRules();
     if (!isset($cartRules[$rule->getId()])) {
         $cartRules[$rule->getId()] = $rule->getDiscountAmount();
     }
     if ($cartRules[$rule->getId()] > 0) {
         $store = $quote->getStore();
         if ($ruleTotals['items_count'] <= 1) {
             $quoteAmount = $store->convertPrice($cartRules[$rule->getId()]);
             $baseDiscountAmount = min($baseItemPrice * $qty, $cartRules[$rule->getId()]);
         } else {
             $discountRate = $baseItemPrice * $qty / $ruleTotals['base_items_price'];
             $maximumItemDiscount = $rule->getDiscountAmount() * $discountRate;
             $quoteAmount = $store->convertPrice($maximumItemDiscount);
             $baseDiscountAmount = min($baseItemPrice * $qty, $maximumItemDiscount);
             $this->validator->decrementRuleItemTotalsCount($rule->getId());
         }
         $baseDiscountAmount = $store->roundPrice($baseDiscountAmount);
         $cartRules[$rule->getId()] -= $baseDiscountAmount;
         $discountData->setAmount($store->roundPrice(min($itemPrice * $qty, $quoteAmount)));
         $discountData->setBaseAmount($baseDiscountAmount);
         $discountData->setOriginalAmount(min($itemOriginalPrice * $qty, $quoteAmount));
         $discountData->setBaseOriginalAmount($store->roundPrice($baseItemOriginalPrice));
     }
     $address->setCartFixedRules($cartRules);
     return $discountData;
 }
Example #3
0
 /**
  * Can apply rules check
  *
  * @param AbstractItem $item
  * @return bool
  */
 public function canApplyRules(AbstractItem $item)
 {
     $address = $item->getAddress();
     foreach ($this->_getRules() as $rule) {
         if (!$this->validatorUtility->canProcessRule($rule, $address) || !$rule->getActions()->validate($item)) {
             return false;
         }
     }
     return true;
 }
Example #4
0
 /**
  * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item
  * @param int[] $appliedRuleIds
  * @return $this
  */
 public function setAppliedRuleIds(\Magento\Sales\Model\Quote\Item\AbstractItem $item, array $appliedRuleIds)
 {
     $address = $item->getAddress();
     $quote = $item->getQuote();
     $item->setAppliedRuleIds(join(',', $appliedRuleIds));
     $address->setAppliedRuleIds($this->validatorUtility->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds));
     $quote->setAppliedRuleIds($this->validatorUtility->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds));
     return $this;
 }
Example #5
0
 /**
  * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item
  * @return array
  */
 protected function applyRules($item)
 {
     $address = $item->getAddress();
     $appliedRuleIds = array();
     /* @var $rule \Magento\SalesRule\Model\Rule */
     foreach ($this->_getRules() as $rule) {
         if ($this->_stopFurtherRules) {
             break;
         }
         if (!$this->_canProcessRule($rule, $address)) {
             continue;
         }
         if (!$this->_skipActionsValidation && !$rule->getActions()->validate($item)) {
             continue;
         }
         $this->applyRule($item, $rule, $address);
         $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId();
         if ($rule->getStopRulesProcessing()) {
             $this->_stopFurtherRules = true;
             break;
         }
     }
     return $appliedRuleIds;
 }