Commit 2c21c8af authored by Reinhold Kainhofer's avatar Reinhold Kainhofer
Browse files

V6.1.4: Fix multiple tax rules

- Update setCartPrices from the latest VM version. This fixes multiple taxes.
  We now also call the original function, unless ShippingWithTax is used.
  This should be more robust than always using a copied/modified function.
- Ignore empty lines in the rules
parent f70b7cd2
......@@ -2,7 +2,7 @@ BASE=rules_shipping
BASE_ADV=rules_shipping_advanced
PLUGINTYPE=vmshipment
ZIPBASE=opentools_vm
VERSION=6.1.3
VERSION=6.1.4
PLUGINFILES=$(BASE).php $(BASE)_base.php $(BASE)_framework_joomla.php $(BASE).script.php $(BASE).xml index.html
PLUGINFILES_ADV=$(BASE_ADV).php $(BASE)_base.php $(BASE)_framework_joomla.php $(BASE_ADV).script.php $(BASE_ADV).xml index.html
......
......@@ -558,7 +558,7 @@ class RulesShippingFramework {
$rules1 = preg_split("/(\r\n|\n|\r)/", $rulestring);
foreach ($rules1 as $r) {
// Ignore empty lines
if (empty($r)) continue;
if (empty($r) || trim($r)=='') continue;
$result[] = $this->createMethodRule ($r, $countries, $ruleinfo);
}
return $result;
......
......@@ -6,7 +6,7 @@
<authorUrl>http://www.open-tools.net</authorUrl>
<copyright>Copyright (C) 2013-2014, Reinhold Kainhofer</copyright>
<license>GPL v3+</license>
<version>6.1.3</version>
<version>6.1.4</version>
<description>OTSHIPMENT_RULES_DESC</description>
<files>
<filename plugin="rules_shipping">rules_shipping.php</filename>
......
......@@ -6,7 +6,7 @@
<authorUrl>http://www.open-tools.net</authorUrl>
<copyright>Copyright (C) 2013-2014, Reinhold Kainhofer</copyright>
<license>GPL v3+</license>
<version>6.1.3</version>
<version>6.1.4</version>
<description>OTSHIPMENT_RULES_ADV_DESC</description>
<files>
<filename plugin="rules_shipping_advanced">rules_shipping_advanced.php</filename>
......
......@@ -246,31 +246,56 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
* @param $tax_id : tax id
*/
function setCartPrices (VirtueMartCart $cart, &$cart_prices, $method, $progressive = true) {
// Copied and adjusted from VirtueMart 2.6.2
// Lines 984ff, File administrator/components/com_virtuemart/plugins/vmpsplugin.php
// BEGIN_RK_CHANGES
$includes_tax = isset($method->includes_tax) && $method->includes_tax;
if (!$includes_tax) {
// Use the default from the parent class, so any changes done in future versions apply directly
return parent::setCartPrices($cart, $cart_prices, $method, $progressive);
}
// if ($includes_tax==true) => We need to modify the code to remove all taxes from the calculations
// CAUTION: Need to keep this code in sync with the VM core code, in particular the
// setCartPrices in Lines 984ff, File administrator/components/com_virtuemart/plugins/vmpsplugin.php
// END_RK_CHANGES
$idN = 'virtuemart_'.$this->_psType.'method_id';
$_psType = ucfirst ($this->_psType);
if (!class_exists ('calculationHelper')) {
// BEGIN_RK_CHANGES
if(!defined('VM_VERSION') or VM_VERSION < 3){ // VM2:
require(JPATH_VM_ADMINISTRATOR . DS . 'helpers' . DS . 'calculationh.php');
} else { // VM 3:
require(VMPATH_ADMIN . DS . 'helpers' . DS . 'calculationh.php');
}
// END_RK_CHANGES
}
$_psType = ucfirst ($this->_psType);
$calculator = calculationHelper::getInstance ();
$cart_prices[$this->_psType . 'Value'] = $calculator->roundInternal ($this->getCosts ($cart, $method, $cart_prices), 'salesPrice');
// BEGIN_RK_CHANGES
$includes_tax = isset($method->includes_tax) && $method->includes_tax;
if ($includes_tax) {
$cart_prices['salesPrice' . $_psType] = $cart_prices[$this->_psType . 'Value'];
if($this->_toConvert){
$calculator = calculationHelper::getInstance ();
foreach($this->_toConvert as $c){
if(isset($method->$c)){
$method->$c = $calculator->_currencyDisplay->convertCurrencyTo($method->currency_id,$method->$c,true);
} else {
$method->$c = 0.0;
}
}
}
// END_RK_CHANGES
$cart_prices[$this->_psType . 'Value'] = $calculator->roundInternal ($this->getCosts ($cart, $method, $cart_prices), 'salesPrice');
if(!isset($cart_prices[$this->_psType . 'Value'])) $cart_prices[$this->_psType . 'Value'] = 0.0;
if(!isset($cart_prices[$this->_psType . 'Tax'])) $cart_prices[$this->_psType . 'Tax'] = 0.0;
if($this->_psType=='payment'){
$cartTotalAmountOrig=$this->getCartAmount($cart_prices);
$cartTotalAmountOrig = $this->getCartAmount($cart_prices);
if(!isset($method->cost_percent_total)) $method->cost_percent_total = 0.0;
if(!isset($method->cost_per_transaction)) $method->cost_per_transaction = 0.0;
if(!$progressive){
//Simple
$cartTotalAmount=($cartTotalAmountOrig + $method->cost_per_transaction) * (1 +($method->cost_percent_total * 0.01));
......@@ -282,11 +307,23 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
//vmdebug('Progressive $cartTotalAmount = ('.$cartTotalAmountOrig.' + '.$method->cost_per_transaction.') / (1 - ('.$method->cost_percent_total.' * 0.01)) = '.$cartTotalAmount );
//vmdebug('Progressive $cartTotalAmount = '.($cartTotalAmountOrig + $method->cost_per_transaction) .' / '. (1 - $method->cost_percent_total * 0.01) .' = '.$cartTotalAmount );
}
$cart_prices[$this->_psType . 'Value'] = $cartTotalAmount - $cartTotalAmountOrig;
if(!empty($method->cost_min_transaction) and $method->cost_min_transaction!='' and $cart_prices[$this->_psType . 'Value'] < $method->cost_min_transaction){
$cart_prices[$this->_psType . 'Value'] = $method->cost_min_transaction;
}
}
if(!isset($cart_prices['salesPrice' . $_psType])) $cart_prices['salesPrice' . $_psType] = $cart_prices[$this->_psType . 'Value'];
// BEGIN_RK_CHANGES
// If the given shipping cost includes the tax, set the final sales price to that value beforehand!
if ($includes_tax) {
$cart_prices['salesPrice' . $_psType] = $cart_prices[$this->_psType . 'Value'];
}
// END_RK_CHANGES
$taxrules = array();
if(isset($method->tax_id) and (int)$method->tax_id === -1){
......@@ -305,18 +342,16 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
$rule['subTotalOld'] = $rule['subTotal'];
$rule['taxAmountOld'] = $rule['taxAmount'];
$rule['taxAmount'] = 0;
$rule['subTotal'] = $cart_prices[$this->_psType . 'Value'];
// BEGIN_RK_CHANGES
if ($includes_tax) {
$calculator->setRevert (true);
$rule['subTotal'] = $cart_prices[$this->_psType . 'Value'];
$valueWithoutTax = $calculator->roundInternal ($calculator->interpreteMathOp($rule, $rule['subTotal']));
$cart_prices[$this->_psType . 'TaxPerID'][$rule['virtuemart_calc_id']] = $calculator->roundInternal($rule['subTotal'] - $valueWithoutTax, 'salesPrice');
$calculator->setRevert (false);
// $rule['subTotal'] = $valueWithoutTax;
} else {
// END_RK_CHANGES
$rule['subTotal'] = $cart_prices[$this->_psType . 'Value'];
$cart_prices[$this->_psType . 'TaxPerID'][$rule['virtuemart_calc_id']] = $calculator->roundInternal($calculator->roundInternal($calculator->interpreteMathOp($rule, $rule['subTotal'])) - $rule['subTotal'], 'salesPrice');
// BEGIN_RK_CHANGES
}
// END_RK_CHANGES
$cart_prices[$this->_psType . 'Tax'] += $cart_prices[$this->_psType . 'TaxPerID'][$rule['virtuemart_calc_id']];
......@@ -330,58 +365,54 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
$taxrules = array_merge($cart->cartData['VatTax'],$cart->cartData['taxRulesBill']);
}
// END_RK_CHANGES
$cartdiscountBeforeTax = $calculator->roundInternal($calculator->cartRuleCalculation($cart->cartData['DBTaxRulesBill'], $cart->cartPrices['salesPrice']));
if(!empty($taxrules) ){
$denominator = 0.0;
foreach($taxrules as &$rule){
//$rule['numerator'] = $rule['calc_value']/100.0 * $rule['subTotal'];
$this->helper->warning("<pre>inside taxrules, includes_tax=$includes_tax</pre>");
$this->helper->warning("<pre>cartPrices: ".print_r($cart->cartPrices,1).", rules: ".print_r($rule,1). "</pre>");
//Quickn dirty
if(!isset($rule['calc_kind'])) $rule = (array)VmModel::getModel('calc')->getCalc($rule['virtuemart_calc_id']);
if(!isset($rule['subTotal'])) $rule['subTotal'] = 0;
if(!isset($rule['taxAmount'])) $rule['taxAmount'] = 0;
// BEGIN_RK_CHANGES
if ($includes_tax) {
$denominator += $rule['subTotal'];
} else {
if(!isset($rule['DBTax'])) $rule['DBTax'] = 0;
// BEGIN_RK_CHANGES: If shipping includes tax, the distribution of the shipping cost to the tax rules needs to be determined after taxes. Otherwise the distribution should be calculated before taxes
if(!isset($rule['percentage'])/* && $rule['subTotal'] < $cart->cartPrices['salesPrice']*/) {
// END_RK_CHANGES
$denominator += ($rule['subTotal']-$rule['taxAmount']);
// BEGIN_RK_CHANGES
$rule['percentage'] = ($rule['subTotal'] + $rule['DBTax']) / ($cart->cartPrices['salesPrice'] + $cartdiscountBeforeTax);
} else if(!isset($rule['percentage'])) {
$rule['percentage'] = 1;
}
// END_RK_CHANGES
$rule['subTotalOld'] = $rule['subTotal'];
$rule['subTotal'] = 0;
$rule['taxAmountOld'] = $rule['taxAmount'];
$rule['taxAmount'] = 0;
//$rule['subTotal'] = $cart_prices[$this->_psType . 'Value'];
}
if(empty($denominator)){
$denominator = 1;
}
foreach($taxrules as &$rule){
$rule['subTotal'] = $cart_prices[$this->_psType . 'Value'] * $rule['percentage'];
if(!isset($cart_prices[$this->_psType . 'Tax'])) $cart_prices[$this->_psType . 'Tax'] = 0.0;
// BEGIN_RK_CHANGES
if ($includes_tax) {
$calculator->setRevert (true);
$frac = $rule['subTotalOld']/$denominator;
$rule['subTotal'] = $cart_prices[$this->_psType . 'Value'] * $frac;
$valueWithoutTax = $calculator->roundInternal ($calculator->interpreteMathOp($rule, $rule['subTotal']));
$cart_prices[$this->_psType . 'TaxPerID'][$rule['virtuemart_calc_id']] = $calculator->roundInternal($rule['subTotal'] - $valueWithoutTax, 'salesPrice');
$calculator->setRevert (false);
// $rule['subTotal'] = $valueWithoutTax;
} else {
// END_RK_CHANGES
$frac = ($rule['subTotalOld']-$rule['taxAmountOld'])/$denominator;
$rule['subTotal'] = $cart_prices[$this->_psType . 'Value'] * $frac;
//vmdebug('Part $denominator '.$denominator.' $frac '.$frac,$rule['subTotal']);
$cart_prices[$this->_psType . 'TaxPerID'][$rule['virtuemart_calc_id']] = $calculator->roundInternal($calculator->roundInternal($calculator->interpreteMathOp($rule, $rule['subTotal'])) - $rule['subTotal'], 'salesPrice');
// BEGIN_RK_CHANGES
}
if(!isset($cart_prices[$this->_psType . 'Tax'])) $cart_prices[$this->_psType . 'Tax'] = 0.0;
// END_RK_CHANGES
$cart_prices[$this->_psType . 'Tax'] += $cart_prices[$this->_psType . 'TaxPerID'][$rule['virtuemart_calc_id']];
}
}
}
if(empty($method->cost_per_transaction)) $method->cost_per_transaction = 0.0;
if(empty($method->cost_min_transaction)) $method->cost_min_transaction = 0.0;
if(empty($method->cost_percent_total)) $method->cost_percent_total = 0.0;
if (count ($taxrules) > 0 ) {
......@@ -393,30 +424,28 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
$cart_prices[$this->_psType . 'Value'] = $calculator->roundInternal ($calculator->executeCalculation($taxrules, $cart_prices[$this->_psType . 'Value'], true), 'salesPrice');
$calculator->setRevert (false);
} else {
// END_RK_CHANGES
$cart_prices['salesPrice' . $_psType] = $calculator->roundInternal ($calculator->executeCalculation ($taxrules, $cart_prices[$this->_psType . 'Value'],true,false), 'salesPrice');
//vmdebug('I am in '.get_class($this).' and have this rules now',$taxrules,$cart_prices[$this->_psType . 'Value'],$cart_prices['salesPrice' . $_psType]);
// $cart_prices[$this->_psType . 'Tax'] = $calculator->roundInternal (($cart_prices['salesPrice' . $_psType] - $cart_prices[$this->_psType . 'Value']), 'salesPrice');
// BEGIN_RK_CHANGES
}
// END_RK_CHANGES
reset($taxrules);
// $taxrule = current($taxrules);
// $cart_prices[$this->_psType . '_calc_id'] = $taxrule['virtuemart_calc_id'];
foreach($taxrules as &$rule){
if(!isset($cart_prices[$this->_psType . '_calc_id']) or !is_array($cart_prices[$this->_psType . '_calc_id'])) $cart_prices[$this->_psType . '_calc_id'] = array();
$cart_prices[$this->_psType . '_calc_id'][] = $rule['virtuemart_calc_id'];
if(isset($rule['subTotalOld'])) $rule['subTotal'] += $rule['subTotalOld'];
if(isset($rule['taxAmountOld'])) $rule['taxAmount'] += $rule['taxAmountOld'];
}
} else {
$cart_prices['salesPrice' . $_psType] = $cart_prices[$this->_psType . 'Value'];
$cart_prices[$this->_psType . 'Tax'] = 0;
$cart_prices[$this->_psType . '_calc_id'] = 0;
}
//$c[$this->_psType][$method->$idN] =& $cart_prices;
//if($_psType='Shipment')vmTrace('setCartPrices '.$cart_prices['salesPrice' . $_psType]);
return $cart_prices['salesPrice' . $_psType];
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment