/** * Collect address discount amount * * @param Mage_Sales_Model_Quote_Address $address * @return Mage_SalesRule_Model_Quote_Discount */ public function collect(Mage_Sales_Model_Quote_Address $address) { parent::collect($address); $quote = $address->getQuote(); $store = Mage::app()->getStore($quote->getStoreId()); $this->_calculator->reset($address); $items = $this->_getAddressItems($address); if (!count($items)) { return $this; } $eventArgs = array('website_id' => $store->getWebsiteId(), 'customer_group_id' => $quote->getCustomerGroupId(), 'coupon_code' => $quote->getCouponCode()); $this->_calculator->init($store->getWebsiteId(), $quote->getCustomerGroupId(), $quote->getCouponCode()); $this->_calculator->initTotals($items, $address); $address->setDiscountDescription(array()); $items = $this->_calculator->sortItemsByPriority($items); foreach ($items as $item) { if ($item->getNoDiscount()) { $item->setDiscountAmount(0); $item->setBaseDiscountAmount(0); } else { /** * Child item discount we calculate for parent */ if ($item->getParentItemId()) { continue; } $eventArgs['item'] = $item; Mage::dispatchEvent('sales_quote_address_discount_item', $eventArgs); if ($item->getHasChildren() && $item->isChildrenCalculated()) { foreach ($item->getChildren() as $child) { $this->_calculator->process($child); $eventArgs['item'] = $child; Mage::dispatchEvent('sales_quote_address_discount_item', $eventArgs); $this->_aggregateItemDiscount($child); } } else { $this->_calculator->process($item); $this->_aggregateItemDiscount($item); } } } /** * process weee amount */ if (Mage::helper('weee')->isEnabled() && Mage::helper('weee')->isDiscounted($store)) { $this->_calculator->processWeeeAmount($address, $items); } /** * Process shipping amount discount */ $address->setShippingDiscountAmount(0); $address->setBaseShippingDiscountAmount(0); if ($address->getShippingAmount()) { $this->_calculator->processShippingAmount($address); $this->_addAmount(-$address->getShippingDiscountAmount()); $this->_addBaseAmount(-$address->getBaseShippingDiscountAmount()); } $this->_calculator->prepareDescription($address); return $this; }
public function process(Mage_Sales_Model_Quote_Item_Abstract $item) { parent::process($item); try { $customer = Mage::getSingleton('customer/session'); if ($customer->isLoggedIn()) { $customerId = Mage::getModel('customer/session')->getCustomerId(); $auto_use = Mage::getStoreConfig('rewardpoints/default/auto_use', Mage::app()->getStore()->getId()); if ($auto_use) { if (Mage::getStoreConfig('rewardpoints/default/flatstats', Mage::app()->getStore()->getId())) { $reward_model = Mage::getModel('rewardpoints/flatstats'); $customer_points = $reward_model->collectPointsCurrent($customerId, Mage::app()->getStore()->getId()); } else { $reward_model = Mage::getModel('rewardpoints/stats'); $customer_points = $reward_model->getPointsCurrent($customerId, Mage::app()->getStore()->getId()); } if ($customer_points && $customer_points > Mage::helper('rewardpoints/event')->getCreditPoints()) { //J2T MOD. getCartAmount $cart_amount = Mage::getModel('rewardpoints/discount')->getCartAmount($item->getQuote()); $cart_amount = Mage::helper('rewardpoints/data')->processMathValue($cart_amount); $points_value = min(Mage::helper('rewardpoints/data')->convertMoneyToPoints($cart_amount), (int) $customer_points); Mage::getSingleton('customer/session')->setProductChecked(0); Mage::helper('rewardpoints/event')->setCreditPoints($points_value); } } Mage::getModel('rewardpoints/discount')->apply($item); } } catch (Mage_Core_Exception $e) { Mage::getSingleton('checkout/session')->addError($e->getMessage()); } catch (Exception $e) { Mage::getSingleton('checkout/session')->addError($e); } return $this; }
public function testProcess() { $item = $this->getMock('Mage_Sales_Model_Quote_Item', array('getAddress'), array(), '', false); $item->expects($this->once())->method('getAddress')->will($this->returnValue(true)); $item->setDiscountCalculationPrice(-1); $item->setCalculationPrice(1); $quote = $this->getMock('Mage_Sales_Model_Quote', null, array(), '', false); $item->setQuote($quote); $this->assertInstanceOf('Mage_SalesRule_Model_Validator', $this->_model->process($item)); return true; }
/** * 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) { $address = $this->_getAddress($item); /** * check coupon count limit */ $this->validateCouponCount($address); /** * check coupon usage */ $this->validateCouponUsage($address); parent::process($item); }
public function process(Mage_Sales_Model_Quote_Item_Abstract $item) { parent::process($item); if (Mage::helper('referafriend')->checkVersion('1.4.0.0')) { if (!$this->_discount) { $this->_discount = Mage::getModel('referafriend/discount'); } if ($this->_discount) { $this->_discount->apply($item); } } return $this; }
public function process(Mage_Sales_Model_Quote_Item_Abstract $item) { if (version_compare(Mage::getVersion(), '1.4.1.0', '>=')) { return parent::process($item); } // copying from base class, doing some modifications $item->setDiscountAmount(0); $item->setBaseDiscountAmount(0); $item->setDiscountPercent(0); $quote = $item->getQuote(); $address = $this->_getAddress($item); //Clearing applied rule ids for quote and address if ($this->_isFirstTimeProcessRun !== true) { $this->_isFirstTimeProcessRun = true; $quote->setAppliedRuleIds(''); $address->setAppliedRuleIds(''); } $itemPrice = $item->getDiscountCalculationPrice(); if ($itemPrice !== null) { $baseItemPrice = $item->getBaseDiscountCalculationPrice(); } else { $itemPrice = $item->getCalculationPrice(); $baseItemPrice = $item->getBaseCalculationPrice(); } $appliedRuleIds = array(); foreach ($this->_getRules() as $rule) { /* @var $rule Mage_SalesRule_Model_Rule */ if (!$this->_canProcessRule($rule, $address)) { continue; } if (!$rule->getActions()->validate($item)) { continue; } $qty = $item->getTotalQty(); $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': $step = $rule->getDiscountStep(); if ($step) { $qty = floor($qty / $step) * $step; } $discountAmount = ($qty * $itemPrice - $item->getDiscountAmount()) * $rulePercent / 100; $baseDiscountAmount = ($qty * $baseItemPrice - $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 * ($itemPrice - $quoteAmount); $baseDiscountAmount = $qty * ($baseItemPrice - $rule->getDiscountAmount()); break; case 'by_fixed': $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 '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()]); /** * We can't use row total here because row total not include tax */ $discountAmount = min($itemPrice * $qty - $item->getDiscountAmount(), $quoteAmount); $baseDiscountAmount = min($baseItemPrice * $qty - $item->getBaseDiscountAmount(), $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 * $itemPrice; $baseDiscountAmount = $free * $baseItemPrice; 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 */ $discountAmount = min($item->getDiscountAmount() + $discountAmount, $itemPrice * $qty); $baseDiscountAmount = min($item->getBaseDiscountAmount() + $baseDiscountAmount, $baseItemPrice * $qty); $item->setDiscountAmount($discountAmount); $item->setBaseDiscountAmount($baseDiscountAmount); $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId(); // MODIFICATION BY AMASTY $currentCouponCode = explode(',', $this->getCouponCode()); if ($currentCouponCode && $rule->getCouponCode() && in_array($rule->getCouponCode(), $currentCouponCode)) { $address->setCouponCode($this->getCouponCode()); } // MODIFICATION BY AMASTY END if ($rule->getCouponCode() && strtolower($rule->getCouponCode()) == strtolower($this->getCouponCode())) { $address->setCouponCode($this->getCouponCode()); } $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; }
/** * 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 = $this->_getAddress($item); $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 (!$rule->getActions()->validate($item)) { continue; } $qty = $this->_getItemQty($item, $rule); $discountAmount = 0; $baseDiscountAmount = 0; //discount for original price $originalDiscountAmount = 0; $baseOriginalDiscountAmount = 0; if ($rule->getSimpleAction() != Mage_SalesRule_Model_Rule::BUY_X_GET_Y_ACTION) { return parent::process($item); } switch ($rule->getSimpleAction()) { 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; } /** * This is the only needed part to get/apply the discount, if you have any issues or different * Different version of @see Mage_SalesRule_Model_Validator you can take this code and update this file * With your version of @see Mage_SalesRule_Model_Validator */ if ($address->getByXGetY()) { $arrItems = Mage::helper('web_rules')->getItemsToDiscount($rule, $address, $item); if (isset($arrItems[$item->getId()])) { $discountQty = $arrItems[$item->getId()]; } else { $discountQty = 0; } } /** The modifications end here */ $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; }
/** * (non-PHPdoc) * @see Mage_SalesRule_Model_Validator::process($item) */ public function process(Mage_Sales_Model_Quote_Item_Abstract $item) { return parent::process($item); if (Mage::helper('rewards')->isBaseMageVersionAtLeast('1.4.2')) { $v = Mage::registry('assex'); $v = !is_array($v) ? array() : $v; if (isset($v[$item->getId()])) { return $this; } else { $v[$item->getId()] = 1; Mage::unregister('assex'); Mage::register('assex', $v); } } Varien_Profiler::start("TBT_REWARDS: Salesrule Validator"); if ($this->num_items_validated == 0) { $item->getQuote()->setAppliedRuleIds(array()); } $this->num_items_validated++; //@nelkaake -a 28/11/10: Run magento's orgiinal process method. $this->originalProcess($item); $quote = $item->getQuote(); $address = $this->_extractAddress($item); if (Mage::helper('rewards')->isBaseMageVersionAtLeast('1.4.2')) { $itemPrice = $this->_getItemPrice($item); $baseItemPrice = $this->_getItemBasePrice($item); if ($itemPrice <= 0) { return $this; } } //Clearing applied rule ids for quote and address if ($this->_isFirstTimeProcessRun !== true) { $this->_isFirstTimeProcessRun = true; $quote->setAppliedRuleIds(''); $address->setAppliedRuleIds(''); } $applicable_redemptions = explode(',', $quote->getCartRedemptions()); $applied_redemptions = explode(',', $quote->getAppliedRedemptions()); //@nelkaake -a 28/11/10: Get all the rule ids that were validated by Magento $all_rule_ids = $this->_getQuoteRewardsRuleIds($quote); $validated_applicable_rule_ids = array(); $validated_applied_rule_ids = array(); $item->setDiscountAmount(0); $item->setBaseDiscountAmount(0); $item->setDiscountPercent(0); //@nelkaake -a 28/11/10: Revalidate the ones according to Sweet Tooth redemption validation and populate lists. $this->_validateAppliedRules($all_rule_ids, $address, $applicable_redemptions, $applied_redemptions, $validated_applicable_rule_ids, $validated_applied_rule_ids); //@nelkaake -a 28/11/10: $this->_cleanApplicableAndApplied($applicable_redemptions, $applied_redemptions, $validated_applicable_rule_ids, $validated_applied_rule_ids); //@nelkaake -a 28/11/10: $this->_validateStopProcessingCondition($applicable_redemptions, $applied_redemptions, $validated_applied_rule_ids); //@nelkaake -a 28/11/10: $this->_validateBySpentRules($applicable_redemptions, $applied_redemptions, $validated_applied_rule_ids); //@nelkaake -a 3/03/11: uniqify just in case the above functions weren't meticulous enough. $validated_applied_rule_ids = array_unique($validated_applied_rule_ids); $applied_redemptions = array_unique($applied_redemptions); $applicable_redemptions = array_unique($applicable_redemptions); foreach ($validated_applied_rule_ids as $rule_id) { $this->recalculateDiscounts($quote, $address, $item, $rule_id); } // No support for multi-shipping if (Mage::helper('rewards')->isMultishipMode($quote)) { $applicable_redemptions = array(); $applied_redemptions = array(); $validated_applied_rule_ids = array(); } $this->recalculateShippingDiscounts($address, $item, $applied_redemptions); //@nelkaake -a 28/11/10: Save redemption info into item address and quote $this->_saveRedemptions($applicable_redemptions, $applied_redemptions, $validated_applied_rule_ids, $item, $address, $quote); $this->total_discount_reversed = 0; $this->total_base_discount_reversed = 0; Varien_Profiler::stop("TBT_REWARDS: Salesrule Validator"); return $this; }