Skip to content

Commit

Permalink
Issue firegento#13: Proportional shipping tax calculation (needs test…
Browse files Browse the repository at this point in the history
…ing!)
  • Loading branch information
Alexander Menk committed Mar 14, 2013
1 parent 6be1d51 commit 4c1c421
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@ public function toOptionArray()
return array(
array(
'value' => 0,
'label' => $helper->__('No dynamic shipping tax caluclation')
'label' => $helper->__('Off (Use above tax class)')
),
array(
'value' => FireGento_GermanSetup_Model_Tax_Config::USE_HIGHTES_TAX_ON_PRODUCTS,
'value' => FireGento_GermanSetup_Model_Tax_Config::USE_HIGHEST_TAX_ON_PRODUCTS,
'label' => $helper->__('Use the highest product tax')
),
array(
'value' => FireGento_GermanSetup_Model_Tax_Config::USE_TAX_DEPENDING_ON_PRODUCT_VALUES,
'label' => $helper->__('Use the tax rate of products that make up the biggest amount')
),
array(
'value' => FireGento_GermanSetup_Model_Tax_Config::USE_PROPORTIONALLY_MIXED_TAX,
'label' => $helper->__('Use mixed tax rates (in proportion to product value)')
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,21 @@ class FireGento_GermanSetup_Model_Tax_Config extends Mage_Tax_Model_Config
{
const XML_PATH_SHIPPING_TAX_ON_PRODUCT_TAX = 'tax/classes/shipping_tax_on_product_tax';

const USE_HIGHTES_TAX_ON_PRODUCTS = 1;
const USE_HIGHEST_TAX_ON_PRODUCTS = 1;
const USE_TAX_DEPENDING_ON_PRODUCT_VALUES = 2;
const USE_PROPORTIONALLY_MIXED_TAX = 3;

protected $_simulateClass = null;

public function setSimulateClass($simulateClass)
{
$this->_simulateClass = $simulateClass;
}

public function getSimulateClass()
{
return $this->_simulateClass;
}

/**
* Get tax class id specified for shipping tax estimation based on highest product
Expand All @@ -48,6 +61,9 @@ class FireGento_GermanSetup_Model_Tax_Config extends Mage_Tax_Model_Config
*/
public function getShippingTaxClass($store = null)
{
if ($this->_simulateClass != null) {
return $this->_simulateClass;
}

/* @var $session Mage_Checkout_Model_Session */
$session = Mage::getSingleton('checkout/session');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php
/**
* netz98 magento module
*
* LICENSE
*
* This source file is subject of netz98.
* You may be not allowed to change the sources
* without authorization of netz98 new media GmbH.
*
* @copyright Copyright (c) 1999-2013 netz98 new media GmbH (http://www.netz98.de)
* @author netz98 new media GmbH <info@netz98.de>
* @category N98
* @package N98_XXXXXXXX
*/

/**
* CLASS DESCRIPTION
*
* @category N98
* @package N98_XXXXXXXX
*/

class FireGento_GermanSetup_Model_Tax_Sales_Total_Quote_Tax extends Mage_Tax_Model_Sales_Total_Quote_Tax {


protected function _getQuoteItems()
{
/* @var $session Mage_Checkout_Model_Session */
$session = Mage::getSingleton('checkout/session');

if ($session->hasQuote()) {
$quoteItems = $session->getQuote()->getAllItems();
} else {
$quoteItems = array();
}
return $quoteItems;
}

/**
* Calculates the portions of a quote with a specifc tax class
* The price incl tax is used for the calculation
*
* @param $quoteItems
* @return array (taxClassId -> percentage in quote)
*/
protected function _collectTaxClassPortions($quoteItems)
{
$taxClassIds = array();

// Fetch the tax rates from the quote items
$taxClassSums = array();
$total = 0;
foreach ($quoteItems as $item) {
/** @var $item Mage_Sales_Model_Quote_Item */
if ($item->getParentItem()) {
continue;
}
// sum up all product values grouped by the tax class id
if (!isset($taxClassSums[$item->getTaxClassId()])) {
$taxClassSums[$item->getTaxClassId()] = 0;
}
$rowSum = $item->getPriceInclTax() * $item->getQty();
$taxClassSums[$item->getTaxClassId()] += $rowSum;
$total += $rowSum;
}

$portions = array();
foreach($taxClassSums as $taxClassId=>$sum) {
$portions[$taxClassId] = $sum/$total;
}
return $portions;
}

/**
*
* Calculate proportional mixed tax
*
* TODO Works only for "Shipping cost incl Tax"
*
* @param Mage_Sales_Model_Quote_Address $address
* @param Varien_Object $taxRateRequest
*
* @return $this|Mage_Tax_Model_Sales_Total_Quote
*/
protected function _calculateShippingTax(Mage_Sales_Model_Quote_Address $address, $taxRateRequest)
{
if (Mage::getStoreConfigFlag(FireGento_GermanSetup_Model_Tax_Config::XML_PATH_SHIPPING_TAX_ON_PRODUCT_TAX)
!= FireGento_GermanSetup_Model_Tax_Config::USE_PROPORTIONALLY_MIXED_TAX) {
return parent::_calculateShippingTax($address, $taxRateRequest);
}

if (!$address->getIsShippingInclTax()) {
throw Exception('Not implemented');
}
$portions = $this->_collectTaxClassPortions($this->_getQuoteItems());

$totalTaxable = $address->getShippingTaxable();
$totalBaseTaxable = $address->getBaseShippingTaxable();
$totalShippingTaxAmount = 0;
$totalBaseShippingTaxAmount = 0;
foreach($portions as $taxClassId=>$portion) {
$address->setShippingTaxable($totalTaxable * $portion);
$address->setBaseShippingTaxable($totalBaseTaxable * $portion);
$this->_config->setSimulateClass($taxClassId);
parent::_calculateShippingTax($address, $taxRateRequest);
$this->_config->setSimulateClass(null);
$totalShippingTaxAmount += $address->getShippingTaxAmount();
$totalBaseShippingTaxAmount += $address->getBaseShippingTaxAmount();
}
$address->setShippingTaxAmount($totalShippingTaxAmount);
$address->setBaseShippingTaxAmount($totalBaseShippingTaxAmount);

// now we have to adjust the actual shipping cost
// we just set it to brutto minus tax
$address->setTotalAmount('shipping', $address->getShippingInclTax() - $totalShippingTaxAmount);
$address->setBaseTotalAmount('shipping', $address->getBaseShippingInclTax() - $totalBaseShippingTaxAmount);

$address->setShippingTaxable($totalTaxable);
$address->setBaseShippingTaxable($totalBaseTaxable);

$address->setShippingAmount($address->getTotalAmount('shipping'));
$address->setBaseShippingAmount($address->getBaseTotalAmount('shipping'));

return $this;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
<tax>
<rewrite>
<config>FireGento_GermanSetup_Model_Tax_Config</config>
<sales_total_quote_tax>FireGento_GermanSetup_Model_Tax_Sales_Total_Quote_Tax</sales_total_quote_tax>
</rewrite>
</tax>
</models>
Expand Down
6 changes: 5 additions & 1 deletion src/app/code/community/FireGento/GermanSetup/etc/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,13 @@
<groups>
<classes>
<fields>
<shipping_tax_class>
<depends>
<shipping_tax_on_product_tax>0</shipping_tax_on_product_tax>
</depends>
</shipping_tax_class>
<shipping_tax_on_product_tax translate="label,comment" module="germansetup">
<label>Dynamic Shipping Tax Class Calculation</label>
<comment><![CDATA[Set to "yes" if you want to calculate the shipping tax rate based on the highest product tax rate or according to the tax rate of products that make up the biggest amount in cart.<br /><b>ATTENTION:</b> This setting overwrites the "Tax Class for Shipping" setting above!]]></comment>
<frontend_type>select</frontend_type>
<source_model>germansetup/source_tax_dynamicType</source_model>
<sort_order>11</sort_order>
Expand Down
7 changes: 6 additions & 1 deletion src/app/locale/de_DE/FireGento_GermanSetup.csv
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,9 @@
"Configuration Settings","Konfigurations-Einstellungen"
"CMS Settings","CMS-Einstellungen"
"Email Settings","Email-Einstellungen"
"Tax Settings","Steuer-Einstellungen"
"Tax Settings","Steuer-Einstellungen"

"Off (Use above tax class)","Aus (verwende o.a. Steuerklasse)"
"Use the highest product tax","Verwende den höchsten Produktsteuersatz des Warenkorbs"
"Use the tax rate of products that make up the biggest amount","Verwende den Steuersatz des größten Produktanteils"
"Use mixed tax rates (in proportion to product value)","Gemischte Besteuerung anhand der Produktanteile"

0 comments on commit 4c1c421

Please sign in to comment.