Problem:
when using EUR as vendor currency and CZK as customer selected currency, the shipping value of 3.30 eur gets rounded to 3 eur and further calculated to CZK which is an obviously wrong calculation.
VM3.0.12 + Joomla 3.x
Configuration:
- EUR (2 decimal rounding)
- CZK (0 decimal rounding)
- price config is all to "-1" (follow currency config)
- checkout "use swiss rounding" (but doesn't play a role here)
Shipping price 3.30 euro (weight countries)
Quick fix:
- remove all roundinternal from vmpsplugin.php:
this is a "quick fix" and we are still working on a better "real world fix":
function setCartPrices (VirtueMartCart $cart, &$cart_prices, $method, $progressive = true) {
$c = array();
$idN = 'virtuemart_'.$this->_psType.'method_id';
$_psType = ucfirst ($this->_psType);
/*if(isset($c[$this->_psType][$method->$idN])){
$cart_prices = array_merge($cart_prices,$c[$this->_psType][$method->$idN]);
return $cart_prices['salesPrice' . $_psType];
}*/
if (!class_exists ('calculationHelper')) {
require(VMPATH_ADMIN . DS . 'helpers' . DS . 'calculationh.php');
}
$calculator = calculationHelper::getInstance ();
$cart_prices[$this->_psType . 'Value'] = $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);
if(!$progressive){
//Simple
$cartTotalAmount=($cartTotalAmountOrig + $method->cost_per_transaction) * (1 +($method->cost_percent_total * 0.01));
//vmdebug('Simple $cartTotalAmount = ('.$cartTotalAmountOrig.' + '.$method->cost_per_transaction.') * (1 + ('.$method->cost_percent_total.' * 0.01)) = '.$cartTotalAmount );
//vmdebug('Simple $cartTotalAmount = '.($cartTotalAmountOrig + $method->cost_per_transaction).' * '. (1 + $method->cost_percent_total * 0.01) .' = '.$cartTotalAmount );
} else {
//progressive
$cartTotalAmount = ($cartTotalAmountOrig + $method->cost_per_transaction) / (1 -($method->cost_percent_total * 0.01));
//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'];
$taxrules = array();
if(isset($method->tax_id) and (int)$method->tax_id === -1){
} else if (!empty($method->tax_id)) {
$cart_prices[$this->_psType . '_calc_id'] = $method->tax_id;
$db = JFactory::getDBO ();
$q = 'SELECT * FROM #__virtuemart_calcs WHERE `virtuemart_calc_id`="' . $method->tax_id . '" ';
$db->setQuery ($q);
$taxrules = $db->loadAssocList ();
if(!empty($taxrules) ){
foreach($taxrules as &$rule){
if(!isset($rule['subTotal'])) $rule['subTotal'] = 0;
if(!isset($rule['taxAmount'])) $rule['taxAmount'] = 0;
$rule['subTotalOld'] = $rule['subTotal'];
$rule['taxAmountOld'] = $rule['taxAmount'];
$rule['taxAmount'] = 0;
$rule['subTotal'] = $cart_prices[$this->_psType . 'Value'];
$cart_prices[$this->_psType . 'TaxPerID'][$rule['virtuemart_calc_id']] = $calculator->interpreteMathOp($rule, $rule['subTotal']) - $rule['subTotal']; //, 'salesPrice');
$cart_prices[$this->_psType . 'Tax'] += $cart_prices[$this->_psType . 'TaxPerID'][$rule['virtuemart_calc_id']];
}
}
} else {
$taxrules = array_merge($cart->cartData['VatTax'],$cart->cartData['taxRulesBill']);
$cartdiscountBeforeTax = $calculator->cartRuleCalculation($cart->cartData['DBTaxRulesBill']); //, $cart->cartPrices['salesPrice']));
if(!empty($taxrules) ){
foreach($taxrules as &$rule){
//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;
if(!isset($rule['DBTax'])) $rule['DBTax'] = 0;
if(!isset($rule['percentage']) && $rule['subTotal'] < $cart->cartPrices['salesPrice']) {
$rule['percentage'] = ($rule['subTotal'] + $rule['DBTax']) / ($cart->cartPrices['salesPrice'] + $cartdiscountBeforeTax);
} else if(!isset($rule['percentage'])) {
$rule['percentage'] = 1;
}
$rule['subTotalOld'] = $rule['subTotal'];
$rule['subTotal'] = 0;
$rule['taxAmountOld'] = $rule['taxAmount'];
$rule['taxAmount'] = 0;
}
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;
$cart_prices[$this->_psType . 'TaxPerID'][$rule['virtuemart_calc_id']] = $calculator->interpreteMathOp($rule, $rule['subTotal']) - $rule['subTotal']; //, 'salesPrice');
$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 ) {
$cart_prices['salesPrice' . $_psType] = $calculator->executeCalculation ($taxrules, $cart_prices[$this->_psType . 'Value'],true,false); //, 'salesPrice');
// $cart_prices[$this->_psType . 'Tax'] = $calculator->roundInternal (($cart_prices['salesPrice' . $_psType] - $cart_prices[$this->_psType . 'Value']), 'salesPrice');
reset($taxrules);
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];
}
the above code is from vm3.0.12 and it suffers from more issues then just this one:
- if "default tax rules" are used, the foreach loop uses ALL calculation rules instead of just picking one and exiting... OR checking the rules agains the products in the cart OR other logic
- since this is quite core calculation, i believe it should be all located in calculationh.php
best regards, stan
Please enter the value with a DOT, not comma, then it works correctly