/** * Get address object which can be used for discount calculation * * @param Mage_Sales_Model_Quote_Item_Abstract $item * @return Mage_Sales_Model_Quote_Address */ protected function _getAddress(Mage_Sales_Model_Quote_Item_Abstract $item) { if ($item instanceof Mage_Sales_Model_Quote_Address_Item) { $address = $item->getAddress(); } elseif ($this->_address) { $address = $this->_address; } elseif ($item->getQuote()->getItemVirtualQty() > 0) { $address = $item->getQuote()->getBillingAddress(); } else { $address = $item->getQuote()->getShippingAddress(); } return $address; }
public function apply(Mage_Sales_Model_Quote_Item_Abstract $item) { # Do not apply any discount if Ext is Disabled if (Mage::helper('referafriend')->getExtDisabled()) { return $this; } $this->_quote = $quote = $item->getQuote(); if ($item instanceof Mage_Sales_Model_Quote_Address_Item) { $address = $item->getAddress(); } elseif ($quote->isVirtual()) { $address = $quote->getBillingAddress(); } else { $address = $quote->getShippingAddress(); } # allow additional discount logic start $hasAdditional = $item->getQuote()->getCouponCode() ? true : false; $helper = Mage::helper('referafriend/referrer'); $baseSubtotal = $address->getBaseSubtotal(); $clearUse = array(); if (!$this->_discount) { Mage::helper('referafriend')->setCustomerDiscount(0); $customer = $quote->getCustomer(); $referrerId = $customer->getId(); $discounts = Mage::getResourceModel('referafriend/discount_collection')->loadByReferrer($referrerId); if (count($discounts)) { foreach ($discounts as $discount) { $rule = Mage::getSingleton('referafriend/rule')->load($discount->getRuleId()); if ($rule->getDiscountUsage() == 0 || $rule->getDiscountUsage() > $discount->getDiscountUsed()) { # allow additional discount logic if ($hasAdditional && $rule->getAllowAdditionalDiscount() || !$hasAdditional) { $this->_discount[$discount->getId()] = $discount; } else { $clearUse[] = $discount->getId(); } } } } } if (!count($this->_discount)) { # Reset used discount $customer = Mage::getSingleton('customer/session'); if ($customer->isLoggedIn()) { $customer->setDiscountUsed(array()); } return $this; } $this->_getCouponCode(); // $this->_couponCode = $this->_getCouponCode(); $customer = Mage::getSingleton('customer/session'); if ($customer->isLoggedIn()) { $discountUsed = (array) $customer->getDiscountUsed(); } $rafDiscount = Mage::helper('referafriend')->getCustomerDiscount(false) ? Mage::helper('referafriend')->getCustomerDiscount(false) : 0; $notUsed = array(); foreach ($this->_discount as $discountId => $discount) { $discountAmount = 0; $baseDiscountAmount = 0; $rule = Mage::getModel('referafriend/rule')->load($discount->getRuleId()); switch ($discount->getType()) { case self::TYPE_PERCENT: $discountPercent = min(100, $discount->getAmount()); $discountAmount = ($item->getRowTotal() - $item->getDiscountAmount()) * $discountPercent / 100; $baseDiscountAmount = ($item->getBaseRowTotal() - $item->getBaseDiscountAmount()) * $discountPercent / 100; $checkDiscountAmount = $baseSubtotal * $discountPercent / 100; if (!($rule->getDiscountGreater() && $checkDiscountAmount < $rule->getDiscountGreater()) && !($rule->getTotalGreater() && $baseSubtotal < $rule->getTotalGreater())) { if (isset($discountUsed)) { if (!isset($discountUsed[$discountId])) { $discountUsed[$discountId] = false; } } $rafDiscount += $baseDiscountAmount; $discountAmount = min($discountAmount + $item->getDiscountAmount(), $item->getRowTotal()); $baseDiscountAmount = min($baseDiscountAmount + $item->getBaseDiscountAmount(), $item->getBaseRowTotal()); //$discountPercent = min(100, $item->getDiscountPercent()+$percentDiscount); $item->setDiscountPercent(min(100, $item->getDiscountPercent() + $discountPercent)); $discountAmount = $quote->getStore()->roundPrice($discountAmount); $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount); $item->setDiscountAmount($discountAmount); $item->setBaseDiscountAmount($baseDiscountAmount); } else { $notUsed[] = $discountId; if (isset($discountUsed[$discountId])) { unset($discountUsed[$discountId]); } } break; case self::TYPE_FLATRATE: $discountAmount = min($item->getRowTotal() - $item->getDiscountAmount(), $quote->getStore()->convertPrice($discount->getAmount())); $baseDiscountAmount = min($item->getBaseRowTotal() - $item->getBaseDiscountAmount(), $discount->getAmount()); $checkDiscountAmount = $discount->getAmount(); if (!($rule->getDiscountGreater() && $checkDiscountAmount < $rule->getDiscountGreater()) && !($rule->getTotalGreater() && $baseSubtotal < $rule->getTotalGreater())) { if (isset($discountUsed)) { if (!isset($discountUsed[$discountId])) { $discountUsed[$discountId] = false; } } $rafDiscount += $baseDiscountAmount; $this->_discount[$discountId]->setAmount($discount->getAmount() - $baseDiscountAmount); /*$discountAmount = $quote->getStore()->roundPrice($discountAmount); $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount);*/ $discountAmount = min($discountAmount + $item->getDiscountAmount(), $item->getRowTotal()); $baseDiscountAmount = min($baseDiscountAmount + $item->getBaseDiscountAmount(), $item->getBaseRowTotal()); $item->setDiscountAmount($discountAmount); $item->setBaseDiscountAmount($baseDiscountAmount); } else { $notUsed[] = $discountId; if (isset($discountUsed[$discountId])) { unset($discountUsed[$discountId]); } } break; } } $trueDiscounts = Mage::helper('referafriend')->getTrueDiscount(); if (isset($trueDiscounts[$item->getId()]['discounts'][1])) { $item->setDiscountAmount($trueDiscounts[$item->getId()]['discounts'][1]); } Mage::helper('referafriend')->setTrueDiscount($item->getId(), $item->getDiscountAmount()); if (!$this->_couponCode) { $this->_couponCode = $this->_getPostCouponCode($notUsed); } $couponCode = explode(', ', $address->getCouponCode()); $couponCode[] = $helper->getCouponCodeDescription($this->_couponCode); $couponCode = array_unique(array_filter($couponCode)); $address->setCouponCode(implode(', ', $couponCode)); # injectin to Discount Description Array directly if (Mage::helper('referafriend')->checkVersion('1.4.0.0')) { $arr = array(); $arr[1] = implode(', ', $couponCode); $address->setDiscountDescriptionArray($arr); } # put discount amount in session store for future history Mage::helper('referafriend')->setCustomerDiscount($rafDiscount); if (count($clearUse) && $discountUsed && is_array($discountUsed) && count($discountUsed)) { foreach ($clearUse as $discountId) { if (isset($discountUsed[$discountId])) { unset($discountUsed[$discountId]); } } } if (isset($discountUsed)) { $customer->setDiscountUsed($discountUsed); } return $this; }
protected function getAddress_new(Mage_Sales_Model_Quote_Item_Abstract $item) { if ($item instanceof Mage_Sales_Model_Quote_Address_Item) { $address = $item->getAddress(); } elseif ($item->getQuote()->isVirtual()) { $address = $item->getQuote()->getBillingAddress(); } else { $address = $item->getQuote()->getShippingAddress(); } return $address; }
/** * return true if the item is giftwrapped; false otherwise. * * @param Mage_Sales_Model_Quote_Item_Abstract * @return bool */ protected function isItemGiftWrapped(Mage_Sales_Model_Quote_Item_Abstract $item) { return (bool) $item->getGwId() || $item->getAddress() && $item->getAddress()->getGwId(); }
public function process(Mage_Sales_Model_Quote_Item_Abstract $item) { $item->setFreeShipping(false); $item->setDiscountAmount(0); $item->setBaseDiscountAmount(0); $item->setDiscountPercent(0); $quote = $item->getQuote(); $address = $item->getAddress(); if (!$address) { $address = $item->getQuote()->getShippingAddress(); } $customerId = $quote->getCustomerId(); $ruleCustomer = Mage::getModel('salesrule/rule_customer'); $appliedRuleIds = array(); foreach ($this->_rules as $rule) { /** * already tried to validate and failed */ if ($rule->getIsValid() === false) { continue; } if ($rule->getIsValid() !== true) { /** * too many times used in general */ if ($rule->getUsesPerCoupon() && $rule->getTimesUsed() >= $rule->getUsesPerCoupon()) { $rule->setIsValid(false); continue; } /** * too many times used for this customer */ if ($ruleId = $rule->getId()) { $ruleCustomer->loadByCustomerRule($customerId, $ruleId); if ($ruleCustomer->getId()) { if ($ruleCustomer->getTimesUsed() >= $rule->getUsesPerCustomer()) { continue; } } } $rule->afterLoad(); /** * quote does not meet rule's conditions */ if (!$rule->validate($address)) { $rule->setIsValid(false); continue; } /** * passed all validations, remember to be valid */ $rule->setIsValid(true); } /** * although the rule is valid, this item is not marked for action */ if (!$rule->getActions()->validate($item)) { continue; } $qty = $rule->getDiscountQty() ? min($item->getQty(), $rule->getDiscountQty()) : $item->getQty(); $rulePercent = $rule->getDiscountAmount(); switch ($rule->getSimpleAction()) { case 'to_percent': $rulePercent = max(0, 100 - $rule->getDiscountAmount()); //no break; //no break; case 'by_percent': $discountAmount = $qty * $item->getCalculationPrice() * $rulePercent / 100; $baseDiscountAmount = $qty * $item->getBaseCalculationPrice() * $rulePercent / 100; if (!$rule->getDiscountQty()) { $discountPercent = min(100, $item->getDiscountPercent() + $rulePercent); $item->setDiscountPercent($discountPercent); } break; case 'to_fixed': $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount()); $discountAmount = $qty * ($item->getCalculationPrice() - $quoteAmount); $baseDiscountAmount = $qty * ($item->getBaseCalculationPrice() - $rule->getDiscountAmount()); break; case 'by_fixed': $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount()); $discountAmount = $qty * $quoteAmount; $baseDiscountAmount = $qty * $rule->getDiscountAmount(); break; } $discountAmount = $quote->getStore()->roundPrice($discountAmount); $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount); $discountAmount = min($discountAmount, $item->getRowTotal()); $baseDiscountAmount = min($baseDiscountAmount, $item->getBaseRowTotal()); $item->setDiscountAmount($discountAmount); $item->setBaseDiscountAmount($baseDiscountAmount); switch ($rule->getSimpleFreeShipping()) { case Mage_SalesRule_Model_Rule::FREE_SHIPPING_ITEM: $item->setFreeShipping($rule->getDiscountQty() ? $rule->getDiscountQty() : true); break; case Mage_SalesRule_Model_Rule::FREE_SHIPPING_ADDRESS: $address->setFreeShipping(true); break; } $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId(); if ($rule->getStopRulesProcessing()) { break; } if ($rule->getCouponCode() && $rule->getCouponCode() == $this->getCouponCode()) { $address->setCouponCode($this->getCouponCode()); } } $item->setAppliedRuleIds(join(',', $appliedRuleIds)); $address->setAppliedRuleIds($this->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds)); $quote->setAppliedRuleIds($this->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds)); return $this; }
/** * Get address object which can be used for discount calculation * * @param Mage_Sales_Model_Quote_Item_Abstract $item * @return Mage_Sales_Model_Quote_Address */ protected function _getAddress(Mage_Sales_Model_Quote_Item_Abstract $item) { if ($item instanceof Mage_Sales_Model_Quote_Address_Item) { $address = $item->getAddress(); } elseif ($item->getQuote()->isVirtual()) { $address = $item->getQuote()->getBillingAddress(); } else { $address = $item->getQuote()->getShippingAddress(); } $address->setBaseSubtotal($address->getSubtotal() + $address->getTaxAmount() - $address->getShippingTaxAmount()); return $address; }
/** * Quote item discount calculation process * * @param Mage_Sales_Model_Quote_Item_Abstract $item * @return Mage_SalesRule_Model_Validator */ public function process(Mage_Sales_Model_Quote_Item_Abstract $item) { $item->setDiscountAmount(0); $item->setBaseDiscountAmount(0); $item->setDiscountPercent(0); $quote = $item->getQuote(); $address = $item->getAddress(); $itemPrice = $this->_getItemPrice($item); $baseItemPrice = $this->_getItemBasePrice($item); $itemOriginalPrice = $this->_getItemOriginalPrice($item); $baseItemOriginalPrice = $this->_getItemBaseOriginalPrice($item); if ($itemPrice < 0) { return $this; } $appliedRuleIds = array(); foreach ($this->_getRules() as $rule) { /* @var $rule Mage_SalesRule_Model_Rule */ if (!$this->_canProcessRule($rule, $address)) { continue; } if (!$this->_skipActionsValidation && !$rule->getActions()->validate($item)) { continue; } $qty = $this->_getItemQty($item, $rule); $rulePercent = min(100, $rule->getDiscountAmount()); $discountAmount = 0; $baseDiscountAmount = 0; //discount for original price $originalDiscountAmount = 0; $baseOriginalDiscountAmount = 0; switch ($rule->getSimpleAction()) { case Mage_SalesRule_Model_Rule::TO_PERCENT_ACTION: $rulePercent = max(0, 100 - $rule->getDiscountAmount()); //no break; //no break; //no break; //no break; case Mage_SalesRule_Model_Rule::BY_PERCENT_ACTION: $step = $rule->getDiscountStep(); if ($step) { $qty = floor($qty / $step) * $step; } $_rulePct = $rulePercent / 100; $discountAmount = ($qty * $itemPrice - $item->getDiscountAmount()) * $_rulePct; $baseDiscountAmount = ($qty * $baseItemPrice - $item->getBaseDiscountAmount()) * $_rulePct; //get discount for original price $originalDiscountAmount = ($qty * $itemOriginalPrice - $item->getDiscountAmount()) * $_rulePct; $baseOriginalDiscountAmount = ($qty * $baseItemOriginalPrice - $item->getDiscountAmount()) * $_rulePct; if (!$rule->getDiscountQty() || $rule->getDiscountQty() > $qty) { $discountPercent = min(100, $item->getDiscountPercent() + $rulePercent); $item->setDiscountPercent($discountPercent); } break; case Mage_SalesRule_Model_Rule::TO_FIXED_ACTION: $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount()); $discountAmount = $qty * ($itemPrice - $quoteAmount); $baseDiscountAmount = $qty * ($baseItemPrice - $rule->getDiscountAmount()); //get discount for original price $originalDiscountAmount = $qty * ($itemOriginalPrice - $quoteAmount); $baseOriginalDiscountAmount = $qty * ($baseItemOriginalPrice - $rule->getDiscountAmount()); break; case Mage_SalesRule_Model_Rule::BY_FIXED_ACTION: $step = $rule->getDiscountStep(); if ($step) { $qty = floor($qty / $step) * $step; } $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount()); $discountAmount = $qty * $quoteAmount; $baseDiscountAmount = $qty * $rule->getDiscountAmount(); break; case Mage_SalesRule_Model_Rule::CART_FIXED_ACTION: if (empty($this->_rulesItemTotals[$rule->getId()])) { Mage::throwException(Mage::helper('Mage_SalesRule_Helper_Data')->__('Item totals are not set for rule.')); } /** * 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()) { break; } 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) { if ($this->_rulesItemTotals[$rule->getId()]['items_count'] <= 1) { $quoteAmount = $quote->getStore()->convertPrice($cartRules[$rule->getId()]); $baseDiscountAmount = min($baseItemPrice * $qty, $cartRules[$rule->getId()]); } else { $discountRate = $baseItemPrice * $qty / $this->_rulesItemTotals[$rule->getId()]['base_items_price']; $maximumItemDiscount = $rule->getDiscountAmount() * $discountRate; $quoteAmount = $quote->getStore()->convertPrice($maximumItemDiscount); $baseDiscountAmount = min($baseItemPrice * $qty, $maximumItemDiscount); $this->_rulesItemTotals[$rule->getId()]['items_count']--; } $discountAmount = min($itemPrice * $qty, $quoteAmount); $discountAmount = $quote->getStore()->roundPrice($discountAmount); $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount); //get discount for original price $originalDiscountAmount = min($itemOriginalPrice * $qty, $quoteAmount); $baseOriginalDiscountAmount = $quote->getStore()->roundPrice($baseItemOriginalPrice); $cartRules[$rule->getId()] -= $baseDiscountAmount; } $address->setCartFixedRules($cartRules); break; case Mage_SalesRule_Model_Rule::BUY_X_GET_Y_ACTION: $x = $rule->getDiscountStep(); $y = $rule->getDiscountAmount(); if (!$x || $y > $x) { break; } $buyAndDiscountQty = $x + $y; $fullRuleQtyPeriod = floor($qty / $buyAndDiscountQty); $freeQty = $qty - $fullRuleQtyPeriod * $buyAndDiscountQty; $discountQty = $fullRuleQtyPeriod * $y; if ($freeQty > $x) { $discountQty += $freeQty - $x; } $discountAmount = $discountQty * $itemPrice; $baseDiscountAmount = $discountQty * $baseItemPrice; //get discount for original price $originalDiscountAmount = $discountQty * $itemOriginalPrice; $baseOriginalDiscountAmount = $discountQty * $baseItemOriginalPrice; break; } $result = new Varien_Object(array('discount_amount' => $discountAmount, 'base_discount_amount' => $baseDiscountAmount)); Mage::dispatchEvent('salesrule_validator_process', array('rule' => $rule, 'item' => $item, 'address' => $address, 'quote' => $quote, 'qty' => $qty, 'result' => $result)); $discountAmount = $result->getDiscountAmount(); $baseDiscountAmount = $result->getBaseDiscountAmount(); $percentKey = $item->getDiscountPercent(); /** * Process "delta" rounding */ if ($percentKey) { $delta = isset($this->_roundingDeltas[$percentKey]) ? $this->_roundingDeltas[$percentKey] : 0; $baseDelta = isset($this->_baseRoundingDeltas[$percentKey]) ? $this->_baseRoundingDeltas[$percentKey] : 0; $discountAmount += $delta; $baseDiscountAmount += $baseDelta; $this->_roundingDeltas[$percentKey] = $discountAmount - $quote->getStore()->roundPrice($discountAmount); $this->_baseRoundingDeltas[$percentKey] = $baseDiscountAmount - $quote->getStore()->roundPrice($baseDiscountAmount); $discountAmount = $quote->getStore()->roundPrice($discountAmount); $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount); } else { $discountAmount = $quote->getStore()->roundPrice($discountAmount); $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount); } /** * We can't use row total here because row total not include tax * Discount can be applied on price included tax */ $itemDiscountAmount = $item->getDiscountAmount(); $itemBaseDiscountAmount = $item->getBaseDiscountAmount(); $discountAmount = min($itemDiscountAmount + $discountAmount, $itemPrice * $qty); $baseDiscountAmount = min($itemBaseDiscountAmount + $baseDiscountAmount, $baseItemPrice * $qty); $item->setDiscountAmount($discountAmount); $item->setBaseDiscountAmount($baseDiscountAmount); $item->setOriginalDiscountAmount($originalDiscountAmount); $item->setBaseOriginalDiscountAmount($baseOriginalDiscountAmount); $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId(); $this->_maintainAddressCouponCode($address, $rule); $this->_addDiscountDescription($address, $rule); if ($rule->getStopRulesProcessing()) { break; } } $item->setAppliedRuleIds(join(',', $appliedRuleIds)); $address->setAppliedRuleIds($this->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds)); $quote->setAppliedRuleIds($this->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds)); return $this; }
public function process(Mage_Sales_Model_Quote_Item_Abstract $item) { $item->setFreeShipping(false); $item->setDiscountAmount(0); $item->setBaseDiscountAmount(0); $item->setDiscountPercent(0); $quote = $item->getQuote(); if ($item instanceof Mage_Sales_Model_Quote_Address_Item) { $address = $item->getAddress(); } elseif ($quote->isVirtual()) { $address = $quote->getBillingAddress(); } else { $address = $quote->getShippingAddress(); } $customerId = $quote->getCustomerId(); $ruleCustomer = Mage::getModel('salesrule/rule_customer'); $appliedRuleIds = array(); foreach ($this->_rules as $rule) { /* @var $rule Mage_SalesRule_Model_Rule */ /** * already tried to validate and failed */ if ($rule->getIsValid() === false) { continue; } if ($rule->getIsValid() !== true) { /** * too many times used in general */ if ($rule->getUsesPerCoupon() && $rule->getTimesUsed() >= $rule->getUsesPerCoupon()) { $rule->setIsValid(false); continue; } /** * too many times used for this customer */ $ruleId = $rule->getId(); if ($ruleId && $rule->getUsesPerCustomer()) { $ruleCustomer->loadByCustomerRule($customerId, $ruleId); if ($ruleCustomer->getId()) { if ($ruleCustomer->getTimesUsed() >= $rule->getUsesPerCustomer()) { continue; } } } $rule->afterLoad(); /** * quote does not meet rule's conditions */ if (!$rule->validate($address)) { $rule->setIsValid(false); continue; } /** * passed all validations, remember to be valid */ $rule->setIsValid(true); } /** * although the rule is valid, this item is not marked for action */ if (!$rule->getActions()->validate($item)) { continue; } $qty = $item->getQty(); if ($item->getParentItem()) { $qty *= $item->getParentItem()->getQty(); } $qty = $rule->getDiscountQty() ? min($qty, $rule->getDiscountQty()) : $qty; $rulePercent = min(100, $rule->getDiscountAmount()); $discountAmount = 0; $baseDiscountAmount = 0; switch ($rule->getSimpleAction()) { case 'to_percent': $rulePercent = max(0, 100 - $rule->getDiscountAmount()); //no break; //no break; case 'by_percent': if ($step = $rule->getDiscountStep()) { $qty = floor($qty / $step) * $step; } $discountAmount = ($qty * $item->getCalculationPrice() - $item->getDiscountAmount()) * $rulePercent / 100; $baseDiscountAmount = ($qty * $item->getBaseCalculationPrice() - $item->getBaseDiscountAmount()) * $rulePercent / 100; if (!$rule->getDiscountQty() || $rule->getDiscountQty() > $qty) { $discountPercent = min(100, $item->getDiscountPercent() + $rulePercent); $item->setDiscountPercent($discountPercent); } break; case 'to_fixed': $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount()); $discountAmount = $qty * ($item->getCalculationPrice() - $quoteAmount); $baseDiscountAmount = $qty * ($item->getBaseCalculationPrice() - $rule->getDiscountAmount()); break; case 'by_fixed': if ($step = $rule->getDiscountStep()) { $qty = floor($qty / $step) * $step; } $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount()); $discountAmount = $qty * $quoteAmount; $baseDiscountAmount = $qty * $rule->getDiscountAmount(); break; case 'cart_fixed': $cartRules = $address->getCartFixedRules(); if (!isset($cartRules[$rule->getId()])) { $cartRules[$rule->getId()] = $rule->getDiscountAmount(); } if ($cartRules[$rule->getId()] > 0) { $quoteAmount = $quote->getStore()->convertPrice($cartRules[$rule->getId()]); $discountAmount = min($item->getRowTotal(), $quoteAmount); $baseDiscountAmount = min($item->getBaseRowTotal(), $cartRules[$rule->getId()]); $cartRules[$rule->getId()] -= $baseDiscountAmount; } $address->setCartFixedRules($cartRules); break; case 'buy_x_get_y': $x = $rule->getDiscountStep(); $y = $rule->getDiscountAmount(); if (!$x || $y >= $x) { break; } $buy = 0; $free = 0; while ($buy + $free < $qty) { $buy += $x; if ($buy + $free >= $qty) { break; } $free += min($y, $qty - $buy - $free); if ($buy + $free >= $qty) { break; } } $discountAmount = $free * $item->getCalculationPrice(); $baseDiscountAmount = $free * $item->getBaseCalculationPrice(); break; } $result = new Varien_Object(array('discount_amount' => $discountAmount, 'base_discount_amount' => $baseDiscountAmount)); Mage::dispatchEvent('salesrule_validator_process', array('rule' => $rule, 'item' => $item, 'address' => $address, 'quote' => $quote, 'qty' => $qty, 'result' => $result)); $discountAmount = $result->getDiscountAmount(); $baseDiscountAmount = $result->getBaseDiscountAmount(); $discountAmount = $quote->getStore()->roundPrice($discountAmount); $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount); $discountAmount = min($item->getDiscountAmount() + $discountAmount, $item->getRowTotal()); $baseDiscountAmount = min($item->getBaseDiscountAmount() + $baseDiscountAmount, $item->getBaseRowTotal()); $item->setDiscountAmount($discountAmount); $item->setBaseDiscountAmount($baseDiscountAmount); switch ($rule->getSimpleFreeShipping()) { case Mage_SalesRule_Model_Rule::FREE_SHIPPING_ITEM: $item->setFreeShipping($rule->getDiscountQty() ? $rule->getDiscountQty() : true); break; case Mage_SalesRule_Model_Rule::FREE_SHIPPING_ADDRESS: $address->setFreeShipping(true); break; } $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId(); if ($rule->getCouponCode() && strtolower($rule->getCouponCode()) == strtolower($this->getCouponCode())) { $address->setCouponCode($this->getCouponCode()); } if ($rule->getStopRulesProcessing()) { break; } } $item->setAppliedRuleIds(join(',', $appliedRuleIds)); $address->setAppliedRuleIds($this->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds)); $quote->setAppliedRuleIds($this->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds)); return $this; }