예제 #1
0
 /**
  * Collect address subtotal
  *
  * @param   Mage_Sales_Model_Quote_Address $address
  * @return  Mage_Sales_Model_Quote_Address_Total_Subtotal
  */
 public function collect(Mage_Sales_Model_Quote_Address $address)
 {
     if ($address->getAddressType() == 'billing') {
         return $this;
     }
     $juros = Mage::getSingleton('checkout/session')->getJuros();
     $address->setBaseJurosAmount($juros);
     $address->setJurosAmount($juros);
     $address->setBaseTotalAmount($this->getCode(), $juros);
     $address->setTotalAmount($this->getCode(), $juros);
     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)
 {
     if ($this->_config->priceIncludesTax($this->_store)) {
         $subTotal = $item->getRowTotalInclTax() - $item->getRowTax();
         $baseSubTotal = $item->getBaseRowTotalInclTax() - $item->getBaseRowTax();
         $address->setTotalAmount('subtotal', $address->getTotalAmount('subtotal') + $subTotal);
         $address->setBaseTotalAmount('subtotal', $address->getBaseTotalAmount('subtotal') + $baseSubTotal);
     } else {
         $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;
 }
예제 #3
0
 /**
  * Calculate item price including/excluding tax, row total including/excluding tax
  * and subtotal including/excluding tax.
  * Determine discount price if needed
  *
  * @param   Mage_Sales_Model_Quote_Address $address
  * @return  Mage_Tax_Model_Sales_Total_Quote_Subtotal
  */
 public function collect(Mage_Sales_Model_Quote_Address $address)
 {
     $this->_store = $address->getQuote()->getStore();
     $this->_address = $address;
     $this->_subtotalInclTax = 0;
     $this->_baseSubtotalInclTax = 0;
     $this->_subtotal = 0;
     $this->_baseSubtotal = 0;
     $this->_roundingDeltas = array();
     $address->setSubtotalInclTax(0);
     $address->setBaseSubtotalInclTax(0);
     $address->setTotalAmount('subtotal', 0);
     $address->setBaseTotalAmount('subtotal', 0);
     $items = $this->_getAddressItems($address);
     if (!$items) {
         return $this;
     }
     $addressRequest = $this->_getAddressTaxRequest($address);
     $storeRequest = $this->_getStoreTaxRequest($address);
     $this->_calculator->setCustomer($address->getQuote()->getCustomer());
     if ($this->_config->priceIncludesTax($this->_store)) {
         $classIds = array();
         foreach ($items as $item) {
             $classIds[] = $item->getProduct()->getTaxClassId();
             if ($item->getHasChildren()) {
                 foreach ($item->getChildren() as $child) {
                     $classIds[] = $child->getProduct()->getTaxClassId();
                 }
             }
         }
         $classIds = array_unique($classIds);
         $storeRequest->setProductClassId($classIds);
         $addressRequest->setProductClassId($classIds);
         $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests($storeRequest, $addressRequest);
     }
     foreach ($items as $item) {
         if ($item->getParentItem()) {
             continue;
         }
         $origItem = clone $item;
         if ($item->getHasChildren() && $item->isChildrenCalculated()) {
             foreach ($item->getChildren() as $child) {
                 $this->_processItem($child, $addressRequest);
                 if ($child->getTaxPercent() > 0) {
                     $item->setTaxPercent($child->getTaxPercent());
                 }
             }
             $this->_recalculateParent($item);
         } else {
             $this->_processItem($item, $addressRequest);
         }
         if ($origItem->getCustomPrice()) {
             $taxPercent = $item->getTaxPercent();
             $customPrice = $origItem->getCustomPrice();
             $price = $customPrice;
             $taxAmount = $customPrice * ($taxPercent / 100);
             $baseTaxAmount = $customPrice * ($taxPercent / 100);
             $basePrice = $customPrice;
             $rowTotal = $customPrice * $item->getQty();
             $baseRowTotal = $customPrice * $item->getQty();
             $priceInclTax = $customPrice + $taxAmount;
             $basePriceInclTax = $customPrice + $baseTaxAmount;
             $rowTotalInclTax = $priceInclTax * $item->getQty();
             $baseRowTotalInclTax = $basePriceInclTax * $item->getQty();
             $item->setCustomPrice($origItem->getCustomPrice());
             $item->setConvertedPrice($price);
             $item->setPrice($basePrice);
             $item->setRowTotal($rowTotal);
             $item->setBaseRowTotal($baseRowTotal);
             $item->setTaxableAmount($rowTotal);
             $item->setBaseTaxableAmount($baseRowTotal);
             $item->setPriceInclTax($priceInclTax);
             $item->setBasePriceInclTax($basePriceInclTax);
             $item->setRowTotalInclTax($rowTotalInclTax);
             $item->setBaseRowTotalInclTax($baseRowTotalInclTax);
             $count = 0;
             if ($item->getHasChildren()) {
                 foreach ($item->getChildren() as $child) {
                     if ($count === 0) {
                         $child->setTaxableAmount($rowTotal);
                         $child->setBaseTaxableAmount($baseRowTotal);
                     } else {
                         $child->setTaxableAmount(0);
                         $child->setBaseTaxableAmount(0);
                     }
                     $count++;
                 }
             }
         }
         $this->_addSubtotalAmount($address, $item);
     }
     $address->setRoundingDeltas($this->_roundingDeltas);
     return $this;
 }
예제 #4
0
 /**
  * Round the total amounts in address
  *
  * @param Mage_Sales_Model_Quote_Address $address
  * @return Mage_Tax_Model_Sales_Total_Quote_Tax
  */
 protected function _roundTotals(Mage_Sales_Model_Quote_Address $address)
 {
     // initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5
     $totalDelta = 1.0E-6;
     $baseTotalDelta = 1.0E-6;
     /*
      * The order of rounding is import here.
      * Tax is rounded first, to be consistent with unit based calculation.
      * Hidden tax and shipping_hidden_tax are rounded next, which are really part of tax.
      * Shipping is rounded before subtotal to minimize the chance that subtotal is
      * rounded differently because of the delta.
      * Here is an example: 19.2% tax rate, subtotal = 49.95, shipping = 9.99, discount = 20%
      * subtotalExclTax = 41.90436, tax = 7.7238, hidden_tax = 1.609128, shippingPriceExclTax = 8.38087
      * shipping_hidden_tax = 0.321826, discount = -11.988
      * The grand total is 47.952 ~= 47.95
      * The rounded values are:
      * tax = 7.72, hidden_tax = 1.61, shipping_hidden_tax = 0.32,
      * shipping = 8.39 (instead of 8.38 from simple rounding), subtotal = 41.9, discount = -11.99
      * The grand total calculated from the rounded value is 47.95
      * If we simply round each value and add them up, the result is 47.94, which is one penny off
      */
     $totalCodes = array('tax', 'hidden_tax', 'shipping_hidden_tax', 'shipping', 'subtotal', 'weee', 'discount');
     foreach ($totalCodes as $totalCode) {
         $exactAmount = $address->getTotalAmount($totalCode);
         $baseExactAmount = $address->getBaseTotalAmount($totalCode);
         if (!$exactAmount && !$baseExactAmount) {
             continue;
         }
         $roundedAmount = $this->_calculator->round($exactAmount + $totalDelta);
         $baseRoundedAmount = $this->_calculator->round($baseExactAmount + $baseTotalDelta);
         $address->setTotalAmount($totalCode, $roundedAmount);
         $address->setBaseTotalAmount($totalCode, $baseRoundedAmount);
         $totalDelta = $exactAmount + $totalDelta - $roundedAmount;
         $baseTotalDelta = $baseExactAmount + $baseTotalDelta - $baseRoundedAmount;
     }
     return $this;
 }
예제 #5
0
 /**
  * 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;
 }
 /**
  * Tax caclulation for shipping price
  *
  * @param   Mage_Sales_Model_Quote_Address $address
  * @param   Varien_Object $taxRateRequest
  * @return  Mage_Tax_Model_Sales_Total_Quote
  */
 protected function _calculateShippingTax(Mage_Sales_Model_Quote_Address $address, $taxRateRequest)
 {
     $store = $address->getQuote()->getStore();
     $shippingTaxClass = $this->_config->getShippingTaxClass($store);
     $shippingAmount = $address->getShippingAmount();
     $baseShippingAmount = $address->getBaseShippingAmount();
     $shippingDiscountAmount = $address->getShippingDiscountAmount();
     $baseShippingDiscountAmount = $address->getBaseShippingDiscountAmount();
     /**
      * Subtract discount before calculate tax amount
      */
     if ($this->_config->applyTaxAfterDiscount($store)) {
         $calcAmount = $shippingAmount - $shippingDiscountAmount;
         $baseCalcAmount = $baseShippingAmount - $baseShippingDiscountAmount;
     } else {
         $calcAmount = $shippingAmount;
         $baseCalcAmount = $baseShippingAmount;
     }
     $shippingTax = 0;
     $shippingBaseTax = 0;
     if ($shippingTaxClass) {
         $taxRateRequest->setProductClassId($shippingTaxClass);
         $rate = $this->_calculator->getRate($taxRateRequest);
         if ($rate) {
             if ($this->_config->shippingPriceIncludesTax($store) && $this->_areTaxRequestsSimilar) {
                 $shippingTax = $this->_calculator->calcTaxAmount($calcAmount, $rate, true, false);
                 $shippingBaseTax = $this->_calculator->calcTaxAmount($baseCalcAmount, $rate, true, false);
                 $shippingAmount -= $shippingTax;
                 $baseShippingAmount -= $shippingBaseTax;
             } else {
                 $shippingTax = $this->_calculator->calcTaxAmount($calcAmount, $rate, false, false);
                 $shippingBaseTax = $this->_calculator->calcTaxAmount($baseCalcAmount, $rate, false, false);
             }
             $rateKey = (string) $rate;
             if (isset($this->_roundingDeltas[$rateKey])) {
                 $shippingTax += $this->_roundingDeltas[$rateKey];
             }
             if (isset($this->_baseRoundingDeltas[$rateKey])) {
                 $shippingBaseTax += $this->_baseRoundingDeltas[$rateKey];
             }
             $shippingTax = $this->_calculator->round($shippingTax);
             $shippingBaseTax = $this->_calculator->round($shippingBaseTax);
             $address->setTotalAmount('shipping', $shippingAmount);
             $address->setBaseTotalAmount('shipping', $baseShippingAmount);
             /**
              * Provide additional attributes for apply discount on price include tax
              */
             if ($this->_config->discountTax($store)) {
                 $address->setShippingAmountForDiscount($shippingAmount + $shippingTax);
                 $address->setBaseShippingAmountForDiscount($baseShippingAmount + $shippingBaseTax);
             }
             $this->_addAmount($shippingTax);
             $this->_addBaseAmount($shippingBaseTax);
             $applied = $this->_calculator->getAppliedRates($taxRateRequest);
             $this->_saveAppliedTaxes($address, $applied, $shippingTax, $shippingBaseTax, $rate);
         }
     }
     $address->setShippingTaxAmount($shippingTax);
     $address->setBaseShippingTaxAmount($shippingBaseTax);
     return $this;
 }