/** * Add pricing data for the item to the item payload. * * @return self */ protected function _injectPricingData() { $merchandisePricing = $this->_orderItem->getEmptyMerchandisePriceGroup()->setUnitPrice($this->_item->getPrice())->setAmount($this->_item->getRowTotal())->setTaxClass($this->_itemProduct->getTaxCode()); $this->_discountHelper->transferTaxDiscounts($this->_item, $merchandisePricing); $this->_orderItem->setMerchandisePricing($merchandisePricing); // This will be set by the parent address when initially creating the // item request builder. Each ship group should include shipping on // only one item in the ship group for address level shipping totals. if ($this->_item->getIncludeShippingTotals()) { $shippingPricing = $this->_orderItem->getEmptyShippingPriceGroup()->setAmount($this->_address->getShippingAmount())->setTaxClass($this->_taxConfig->shippingTaxClass); $this->_addShippingDiscount($shippingPricing); $this->_orderItem->setShippingPricing($shippingPricing); } return $this; }
protected function resetItem(Mage_Sales_Model_Quote_Item_Abstract $item) { $item->setDiscountAmount(0.0); $item->setBaseDiscountAmount(0.0); $item->setRowTotalWithDiscount($item->getRowTotal()); $item->setBaseRowTotalWithDiscount($item->getBaseRowTotal()); $item->setDiscountPercent(0); $item->setAppliedRuleIds(''); $item->setFreeShipping(false); }
/** * Aggregate row totals per tax rate in array * * @param Mage_Sales_Model_Quote_Item_Abstract $item * @param float $rate * @param array $taxGroups * @return Mage_Tax_Model_Sales_Total_Quote */ protected function _aggregateTaxPerRate($item, $rate, &$taxGroups) { $inclTax = $item->getIsPriceInclTax(); $rateKey = (string) $rate; $subtotal = $item->getTaxableAmount() + $item->getExtraRowTaxableAmount(); $baseSubtotal = $item->getBaseTaxableAmount() + $item->getBaseExtraRowTaxableAmount(); $item->setTaxPercent($rate); if (!isset($taxGroups[$rateKey]['totals'])) { $taxGroups[$rateKey]['totals'] = array(); $taxGroups[$rateKey]['base_totals'] = array(); } $hiddenTax = null; $baseHiddenTax = null; switch ($this->_helper->getCalculationSequence($this->_store)) { case Mage_Tax_Model_Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: case Mage_Tax_Model_Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false); $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax, false); break; case Mage_Tax_Model_Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: case Mage_Tax_Model_Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: $discount = $item->getDiscountAmount(); $baseDiscount = $item->getBaseDiscountAmount(); $subtotal -= $discount; $baseSubtotal -= $baseDiscount; $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false); $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax, false); break; } $rowTax = $this->_deltaRound($rowTax, $rateKey, $inclTax); $baseRowTax = $this->_deltaRound($baseRowTax, $rateKey, $inclTax, 'base'); if ($inclTax && !empty($discount)) { $hiddenTax = $item->getRowTotalInclTax() - $item->getRowTotal() - $rowTax; $baseHiddenTax = $item->getBaseRowTotalInclTax() - $item->getBaseRowTotal() - $baseRowTax; } $item->setTaxAmount(max(0, $rowTax)); $item->setBaseTaxAmount(max(0, $baseRowTax)); $item->setHiddenTaxAmount(max(0, $hiddenTax)); $item->setBaseHiddenTaxAmount(max(0, $baseHiddenTax)); $taxGroups[$rateKey]['totals'][] = max(0, $subtotal); $taxGroups[$rateKey]['base_totals'][] = max(0, $baseSubtotal); return $this; }
/** * Recollect item price and row total using after taxes subtract. * Declare item price including tax attributes * * @deprecated after 1.4.1 * * @param Mage_Sales_Model_Quote_Address $address * @param Mage_Sales_Model_Quote_Item_Abstract $item * * @return Mage_Tax_Model_Sales_Total_Quote_Subtotal */ protected function _recollectItem($address, Mage_Sales_Model_Quote_Item_Abstract $item) { $store = $address->getQuote()->getStore(); $request = $this->_getStoreTaxRequest($address); $request->setProductClassId($item->getProduct()->getTaxClassId()); $rate = $this->_calculator->getRate($request); $qty = $item->getTotalQty(); $price = $taxPrice = $item->getCalculationPriceOriginal(); $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal(); $subtotal = $taxSubtotal = $item->getRowTotal(); $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal(); if ($this->_config->discountTax($store)) { $item->setDiscountCalculationPrice($price); $item->setBaseDiscountCalculationPrice($basePrice); } /** * Use original price for tax calculation */ if ($item->hasCustomPrice() && !$this->_helper->applyTaxOnCustomPrice($store)) { $taxPrice = $item->getOriginalPrice(); $baseTaxPrice = $item->getBaseOriginalPrice(); $taxSubtotal = $taxPrice * $qty; $baseTaxSubtotal = $baseTaxPrice * $qty; } if ($this->_areTaxRequestsSimilar) { $item->setRowTotalInclTax($subtotal); $item->setBaseRowTotalInclTax($baseSubtotal); $item->setPriceInclTax($price); $item->setBasePriceInclTax($basePrice); $item->setTaxCalcPrice($taxPrice); $item->setBaseTaxCalcPrice($baseTaxPrice); $item->setTaxCalcRowTotal($taxSubtotal); $item->setBaseTaxCalcRowTotal($baseTaxSubtotal); } $this->_subtotalInclTax += $subtotal; $this->_baseSubtotalInclTax += $baseSubtotal; if ($this->_config->getAlgorithm($store) == Mage_Tax_Model_Calculation::CALC_UNIT_BASE) { $taxAmount = $this->_calculator->calcTaxAmount($taxPrice, $rate, true); $baseTaxAmount = $this->_calculator->calcTaxAmount($baseTaxPrice, $rate, true); $unitPrice = $this->_calculator->round($price - $taxAmount); $baseUnitPrice = $this->_calculator->round($basePrice - $baseTaxAmount); $subtotal = $this->_calculator->round($unitPrice * $qty); $baseSubtotal = $this->_calculator->round($baseUnitPrice * $qty); } else { $taxAmount = $this->_calculator->calcTaxAmount($taxSubtotal, $rate, true, false); $baseTaxAmount = $this->_calculator->calcTaxAmount($baseTaxSubtotal, $rate, true, false); $unitPrice = ($subtotal - $taxAmount) / $qty; $baseUnitPrice = ($baseSubtotal - $baseTaxAmount) / $qty; $subtotal = $this->_calculator->round($subtotal - $taxAmount); $baseSubtotal = $this->_calculator->round($baseSubtotal - $baseTaxAmount); } if ($item->hasCustomPrice()) { $item->setCustomPrice($unitPrice); $item->setBaseCustomPrice($baseUnitPrice); } $item->setPrice($baseUnitPrice); $item->setOriginalPrice($unitPrice); $item->setBasePrice($baseUnitPrice); $item->setRowTotal($subtotal); $item->setBaseRowTotal($baseSubtotal); return $this; }
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; }
/** * Aggregate row totals per tax rate in array * * @param Mage_Sales_Model_Quote_Item_Abstract $item * @param float $rate * @param array $taxGroups * @return Mage_Tax_Model_Sales_Total_Quote */ protected function _aggregateTaxPerRate($item, $rate, &$taxGroups) { $store = $item->getStore(); $inclTax = $this->_usePriceIncludeTax($store); if ($inclTax) { $subtotal = $item->getTaxCalcRowTotal(); $baseSubtotal = $item->getBaseTaxCalcRowTotal(); } else { if ($item->hasCustomPrice() && $this->_helper->applyTaxOnCustomPrice($store)) { $subtotal = $item->getRowTotal(); $baseSubtotal = $item->getBaseRowTotal(); } else { $subtotal = $item->getTotalQty() * $item->getOriginalPrice(); $baseSubtotal = $item->getTotalQty() * $item->getBaseOriginalPrice(); } } $discountAmount = $item->getDiscountAmount(); $baseDiscountAmount = $item->getBaseDiscountAmount(); $qty = $item->getTotalQty(); $rateKey = (string) $rate; /** * Add extra amounts which can be taxable too */ $calcTotal = $subtotal + $item->getExtraRowTaxableAmount(); $baseCalcTotal = $baseSubtotal + $item->getBaseExtraRowTaxableAmount(); $item->setTaxPercent($rate); if (!isset($taxGroups[$rateKey]['totals'])) { $taxGroups[$rateKey]['totals'] = array(); } if (!isset($taxGroups[$rateKey]['totals'])) { $taxGroups[$rateKey]['base_totals'] = array(); } $calculationSequence = $this->_helper->getCalculationSequence($store); switch ($calculationSequence) { case Mage_Tax_Model_Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: $rowTax = $this->_calculator->calcTaxAmount($calcTotal, $rate, $inclTax, false); $baseRowTax = $this->_calculator->calcTaxAmount($baseCalcTotal, $rate, $inclTax, false); break; case Mage_Tax_Model_Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: $rowTax = $this->_calculator->calcTaxAmount($calcTotal, $rate, $inclTax, false); $baseRowTax = $this->_calculator->calcTaxAmount($baseCalcTotal, $rate, $inclTax, false); $discountPrice = $inclTax ? $subtotal / $qty : ($subtotal + $rowTax) / $qty; $baseDiscountPrice = $inclTax ? $baseSubtotal / $qty : ($baseSubtotal + $baseRowTax) / $qty; $item->setDiscountCalculationPrice($discountPrice); $item->setBaseDiscountCalculationPrice($baseDiscountPrice); break; case Mage_Tax_Model_Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: case Mage_Tax_Model_Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: $calcTotal = $calcTotal - $discountAmount; $baseCalcTotal = $baseCalcTotal - $baseDiscountAmount; $rowTax = $this->_calculator->calcTaxAmount($calcTotal, $rate, $inclTax, false); $baseRowTax = $this->_calculator->calcTaxAmount($baseCalcTotal, $rate, $inclTax, false); break; } /** * "Delta" rounding */ $delta = isset($this->_roundingDeltas[$rateKey]) ? $this->_roundingDeltas[$rateKey] : 0; $baseDelta = isset($this->_baseRoundingDeltas[$rateKey]) ? $this->_baseRoundingDeltas[$rateKey] : 0; $rowTax += $delta; $baseRowTax += $baseDelta; $this->_roundingDeltas[$rateKey] = $rowTax - $this->_calculator->round($rowTax); $this->_baseRoundingDeltas[$rateKey] = $baseRowTax - $this->_calculator->round($baseRowTax); $rowTax = $this->_calculator->round($rowTax); $baseRowTax = $this->_calculator->round($baseRowTax); /** * Renew item amounts in case if we are working with price include tax */ if ($inclTax) { $unitTax = $this->_calculator->round($rowTax / $qty); $baseUnitTax = $this->_calculator->round($baseRowTax / $qty); if ($item->hasCustomPrice()) { $item->setCustomPrice($item->getPriceInclTax() - $unitTax); $item->setBaseCustomPrice($item->getBasePriceInclTax() - $baseUnitTax); } else { $item->setOriginalPrice($item->getPriceInclTax() - $unitTax); $item->setPrice($item->getBasePriceInclTax() - $baseUnitTax); $item->setBasePrice($item->getBasePriceInclTax() - $baseUnitTax); } $item->setRowTotal($item->getRowTotalInclTax() - $rowTax); $item->setBaseRowTotal($item->getBaseRowTotalInclTax() - $baseRowTax); } $item->setTaxAmount($rowTax); $item->setBaseTaxAmount($baseRowTax); $taxGroups[$rateKey]['totals'][] = $calcTotal; $taxGroups[$rateKey]['base_totals'][] = $baseCalcTotal; return $this; }
/** * Add row total item amount to subtotal * * @param Mage_Sales_Model_Quote_Address $address * @param Mage_Sales_Model_Quote_Item_Abstract $item * @return Mage_Tax_Model_Sales_Total_Quote_Subtotal */ protected function _addSubtotalAmount(Mage_Sales_Model_Quote_Address $address, $item) { $address->setTotalAmount('subtotal', $address->getTotalAmount('subtotal') + $item->getRowTotal()); $address->setBaseTotalAmount('subtotal', $address->getBaseTotalAmount('subtotal') + $item->getBaseRowTotal()); $address->setSubtotalInclTax($address->getSubtotalInclTax() + $item->getRowTotalInclTax()); $address->setBaseSubtotalInclTax($address->getBaseSubtotalInclTax() + $item->getBaseRowTotalInclTax()); return $this; }
/** * Convert quote item to order item * * @param Mage_Sales_Model_Quote_Item_Abstract $item * @return Mage_Sales_Model_Order_Item */ public function itemToOrderItem(Mage_Sales_Model_Quote_Item_Abstract $item) { $orderItem = Mage::getModel('sales/order_item')->setStoreId($item->getStoreId())->setQuoteItemId($item->getId())->setProductId($item->getProductId())->setSuperProductId($item->getSuperProductId())->setParentProductId($item->getParentProductId())->setSku($item->getSku())->setName($item->getName())->setDescription($item->getDescription())->setWeight($item->getWeight())->setIsQtyDecimal($item->getIsQtyDecimal())->setQtyOrdered($item->getQty())->setOriginalPrice($item->getOriginalPrice())->setAppliedRuleIds($item->getAppliedRuleIds())->setAdditionalData($item->getAdditionalData())->setPrice($item->getCalculationPrice())->setTaxPercent($item->getTaxPercent())->setTaxAmount($item->getTaxAmount())->setRowWeight($item->getRowWeight())->setRowTotal($item->getRowTotal())->setBasePrice($item->getBaseCalculationPrice())->setBaseOriginalPrice($item->getPrice())->setBaseTaxAmount($item->getBaseTaxAmount())->setBaseRowTotal($item->getBaseRowTotal()); if (!$item->getNoDiscount()) { $orderItem->setDiscountPercent($item->getDiscountPercent())->setDiscountAmount($item->getDiscountAmount())->setBaseDiscountAmount($item->getBaseDiscountAmount()); } Mage::dispatchEvent('sales_convert_quote_item_to_order_item', array('order_item' => $orderItem, 'item' => $item)); return $orderItem; }
/** * Calculate item tax amount based on row total * * @param Mage_Sales_Model_Quote_Item_Abstract $item * @param float $rate * @return Mage_Tax_Model_Sales_Total_Quote */ protected function _calcRowTaxAmount($item, $rate) { $inclTax = $item->getIsPriceInclTax(); $subtotal = $item->getTaxableAmount() + $item->getExtraRowTaxableAmount(); $baseSubtotal = $item->getBaseTaxableAmount() + $item->getBaseExtraRowTaxableAmount(); $item->setTaxPercent($rate); $hiddenTax = null; $baseHiddenTax = null; switch ($this->_helper->getCalculationSequence($this->_store)) { case Mage_Tax_Model_Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: case Mage_Tax_Model_Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax); $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax); break; case Mage_Tax_Model_Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: case Mage_Tax_Model_Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: $discountAmount = $item->getDiscountAmount(); $baseDiscountAmount = $item->getBaseDiscountAmount(); $rowTax = $this->_calculator->calcTaxAmount(max($subtotal - $discountAmount, 0), $rate, $inclTax); $baseRowTax = $this->_calculator->calcTaxAmount(max($baseSubtotal - $baseDiscountAmount, 0), $rate, $inclTax); if ($inclTax && $discountAmount > 0) { $hiddenTax = $subtotal - $rowTax - $item->getRowTotal(); $baseHiddenTax = $baseSubtotal - $baseRowTax - $item->getBaseRowTotal(); } elseif ($discountAmount > $subtotal) { // case with 100% discount on price incl. tax $hiddenTax = $discountAmount - $subtotal; $baseHiddenTax = $baseDiscountAmount - $baseSubtotal; } break; } $item->setTaxAmount(max(0, $rowTax)); $item->setBaseTaxAmount(max(0, $baseRowTax)); $item->setHiddenTaxAmount(max(0, $hiddenTax)); $item->setBaseHiddenTaxAmount(max(0, $baseHiddenTax)); return $this; }