/** * Correct quantity list price calculations by cart item. * * Basically, calculate the price of the item's options (ie. item price - base * product price). * * @param array $list * @param Mage_Sales_Model_Quote_Item $item * @return array */ public function correctPriceCalculationsByCartItem(array $list, Mage_Sales_Model_Quote_Item $item) { if (count($list) && $item) { $qty = (double) $item->getQty(); $qtyKey = $this->getQtyKey($qty); $optionsPrice = null; $optionsPriceInclTax = null; // if we have applied an overriding price on the item we can run an easier calculation method, se the else block for that if (!$item->hasCustomPrice()) { /* @var Mage_Catalog_Model_Product_Type_Price $priceModel */ $priceModel = $this->getProductPriceModel($item->getProduct(), true); /* @var Mage_Catalog_Model_Product $product */ $product = Mage::getModel('catalog/product')->load($item->getProduct()->getId()); // calculate normal product price based on item quantity $productPrice = Mage::helper('core')->currency($priceModel->getFinalPrice($qty, $product), false, false); $productPriceInclTax = Mage::helper('tax')->getPrice($product, $productPrice, true, null, null, null, null, null, false); // calculate option prices (item price - product base price) $optionsPrice = $item->getConvertedPrice() - $productPrice; $optionsPriceInclTax = $item->getPriceInclTax() - $productPriceInclTax; } else { // just fetch the overriding price which has been used from the quantity option list // and calculate the options price as item price - overriding price, that's it. if (isset($list[$qtyKey]) && isset($list[$qtyKey]['p']) && isset($list[$qtyKey]['p']['pu'])) { $optionsPrice = $item->getConvertedPrice() - (double) $list[$qtyKey]['p']['pu']; } if (isset($list[$qtyKey]) && isset($list[$qtyKey]['p']) && isset($list[$qtyKey]['p']['iu'])) { $optionsPriceInclTax = $item->getPriceInclTax() - (double) $list[$qtyKey]['p']['iu']; } } // if there was an additional option based price on the item, add that additional price to all quantity options, correcting their initial calculations if (!is_null($optionsPrice) && $optionsPrice > 0) { foreach ($list as $key => $option) { $list[$key]['p']['p'] += $optionsPrice * $option['qty']; $list[$key]['p']['pu'] += $optionsPrice; if (isset($list[$key]['p']['o'])) { $list[$key]['p']['o'] += $optionsPrice * $option['qty']; $list[$key]['p']['ou'] += $optionsPrice; } if (isset($list[$key]['p']['e'])) { $list[$key]['p']['e'] += $optionsPrice * $option['qty']; $list[$key]['p']['eu'] += $optionsPrice; } if (isset($list[$key]['p']['i']) && !is_null($optionsPriceInclTax) && $optionsPriceInclTax > 0) { $list[$key]['p']['i'] += $optionsPriceInclTax * $option['qty']; $list[$key]['p']['iu'] += $optionsPriceInclTax; } } } } return $list; }
/** * Returns the item's original editable price * * @param Mage_Sales_Model_Quote_Item $item * @return float */ public function getOriginalEditablePrice($item) { if ($item->hasOriginalCustomPrice()) { $result = $item->getOriginalCustomPrice() * 1; } elseif ($item->hasCustomPrice()) { $result = $item->getCustomPrice() * 1; } else { if (Mage::helper('tax')->priceIncludesTax($this->getStore())) { $result = $item->getPriceInclTax() * 1; } else { $result = $item->getOriginalPrice() * 1; } } return $result; }
/** * Retenders the item's redemption rules and final row total and returns it. * @param Mage_Sales_Model_Quote_Item $item * @return array a map of the new item redemption data: * array('redemptions_data'=>{...}, 'row_total'=>float) */ protected function getUpdatedRedemptionData($item, $do_incl_tax = true) { // Step 1: Create a map of usability for all applied redemptions //echo "$item->getRedeemedPointsHash()"; $redeemed_points = Mage::helper('rewards')->unhashIt($item->getRedeemedPointsHash()); // Prepare data from item and initalize counters if ($item->getQuote()) { $store_currency = round($item->getQuote()->getStoreToQuoteRate(), 4); } if ($item->getOrder()) { $store_currency = round($item->getOrder()->getStoreToQuoteRate(), 4); } if ($item->hasCustomPrice()) { $product_price = (double) $item->getCustomPrice() * $store_currency; } else { //@nelkaake -a 17/02/11: We need to use our own calculation because the one that was set by the // rest of the Magento system is rounded. if (Mage::helper('tax')->priceIncludesTax() && $item->getPriceInclTax()) { $product_price = $item->getPriceInclTax() / (1 + $item->getTaxPercent() / 100); } else { $product_price = (double) $item->getPrice() * $store_currency; } } if ($item->getParentItem() || sizeof($redeemed_points) == 0) { return array('redemptions_data' => array(), 'row_total_incl_tax' => $item->getRowTotalInclTax(), 'row_total' => $item->getRowTotal()); } $total_qty = $item->getQty(); $total_qty_redeemed = 0.0; $row_total = 0.0; $new_redeemed_points = array(); $ret = array(); // Loop through and apply all our rules. foreach ($redeemed_points as $key => &$redemption_instance) { $redemption_instance = (array) $redemption_instance; $applic_qty = $redemption_instance[self::POINTS_APPLICABLE_QTY]; $rule_id = $redemption_instance[self::POINTS_RULE_ID]; $effect = $redemption_instance[self::POINTS_EFFECT]; $uses = isset($redemption_instance[self::POINTS_USES]) ? (int) $redemption_instance[self::POINTS_USES] : 1; $rule = Mage::helper('rewards/rule')->getCatalogRule($rule_id); // If a rule was turned off at some point in the back-end it should be removed and not calculated in the cart anymore. if (!$rule->getIsActive()) { $this->removeCatalogRedemptionsFromItem($item, array($rule_id)); $effect = ""; } $total_qty_remain = $total_qty - $total_qty_redeemed; if ($total_qty_remain > 0) { if ($total_qty_remain < $applic_qty) { $applic_qty = $total_qty_remain; $redemption_instance[TBT_Rewards_Model_Redeem::POINTS_APPLICABLE_QTY] = $applic_qty; } $price_after_redem = $this->getPriceAfterEffect($product_price, $effect, $item); $row_total += $applic_qty * (double) $price_after_redem; $total_qty_redeemed += $applic_qty; $new_redeemed_points[] = $redemption_instance; } else { $redemption_instance[TBT_Rewards_Model_Catalogrule_Rule::POINTS_APPLICABLE_QTY] = 0; $redemption_instance[TBT_Rewards_Model_Catalogrule_Rule::POINTS_USES] = 1; // used once by default unset($redeemed_points[$key]); } } $ret['redemptions_data'] = $new_redeemed_points; // Add in the left over products that perhaps weren't affected by qty adjustment. $total_qty_remain = $total_qty - $total_qty_redeemed; if ($total_qty_remain < 0) { $total_qty_remain = 0; $total_qty_redeemed = $total_qty; //throw new Exception("Redemption rules may be overlapping. Please notify the store administrator of this error."); } $row_total += $total_qty_remain * (double) $product_price; $ret['row_total'] = $row_total; $ret['row_total_incl_tax'] = $row_total * (1 + $item->getTaxPercent() / 100); return $ret; }