diff --git a/rules_shipping_base.php b/rules_shipping_base.php index ff4eb80a39b5b0222993ad1a6cea2271aa5212c1..20f8427a9910963f8c94fa0f5e9678b06e62fbdd 100644 --- a/rules_shipping_base.php +++ b/rules_shipping_base.php @@ -296,8 +296,7 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin { $result[$rtype][] = $r; break; case 'definition': // A definition updates the $cartvals, but has no other effects - $cartvals[strtolower($r->getRuleName())] = $r->getShippingCosts(); - // TODO + $cartvals[strtolower($r->getRuleName())] = $r->getValue(); break; default: $this->printWarning(JText::sprintf('VMSHIPMENT_RULES_UNKNOWN_TYPE', $r->getType(), $r->rulestring)); @@ -363,10 +362,10 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin { // with possibly multiple modifiers $method->cost = $r->getShippingCosts(); foreach ($match['modifiers_multiply'] as $modifier) { - $method->cost *= $modifier->getShippingCosts(); + $method->cost *= $modifier->getValue(); } foreach ($match['modifiers_add'] as $modifier) { - $method->cost += $modifier->getShippingCosts(); + $method->cost += $modifier->getValue(); } $method->includes_tax = $r->includes_tax; return $method->cost; @@ -376,8 +375,13 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin { return 0; } + /** - * update the plugin cart_prices ( + * update the plugin cart_prices + * + * Override the plugin's setCartPrices to allow reverse tax calculation (i.e. shipping costs are + * given with taxes, the net price and the tax is calculated from the gross shipping costs)- + * We need separate versions for VM2 and VM3. * * @author Valérie Isaksen (original), Reinhold Kainhofer (tax calculations from shippingWithTax) * @@ -385,24 +389,47 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin { * @param $value : fee * @param $tax_id : tax id */ - - function setCartPrices (VirtueMartCart $cart, &$cart_prices, $method) { - + 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 if (!class_exists ('calculationHelper')) { - require(JPATH_VM_ADMINISTRATOR . DS . 'helpers' . DS . 'calculationh.php'); + 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'); + } } $_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 = $method->includes_tax; + if ($includes_tax) { + $cart_prices['salesPrice' . $_psType] = $cart_prices[$this->_psType . 'Value']; + } + // END_RK_CHANGES + 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); - $cartTotalAmount=($cartTotalAmountOrig + $method->cost_per_transaction) / (1 -($method->cost_percent_total * 0.01)); + 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(!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){ @@ -422,11 +449,29 @@ 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); + } 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']]; } } } else { - $taxrules = array_merge($calculator->_cartData['VatTax'],$calculator->_cartData['taxRulesBill']); + if(!defined('VM_VERSION') or VM_VERSION < 3){ // VM2: + $taxrules = array_merge($calculator->_cartData['VatTax'],$calculator->_cartData['taxRulesBill']); + } else { // VM3: + $taxrules = array_merge($cart->cartData['VatTax'],$cart->cartData['taxRulesBill']); + } if(!empty($taxrules) ){ $denominator = 0.0; @@ -434,7 +479,15 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin { //$rule['numerator'] = $rule['calc_value']/100.0 * $rule['subTotal']; if(!isset($rule['subTotal'])) $rule['subTotal'] = 0; if(!isset($rule['taxAmount'])) $rule['taxAmount'] = 0; - $denominator += ($rule['subTotal']-$rule['taxAmount']); + // BEGIN_RK_CHANGES + if ($includes_tax) { + $denominator += $rule['subTotal']; + } else { + // END_RK_CHANGES + $denominator += ($rule['subTotal']-$rule['taxAmount']); + // BEGIN_RK_CHANGES + } + // END_RK_CHANGES $rule['subTotalOld'] = $rule['subTotal']; $rule['subTotal'] = 0; $rule['taxAmountOld'] = $rule['taxAmount']; @@ -446,9 +499,25 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin { } foreach($taxrules as &$rule){ - $frac = ($rule['subTotalOld']-$rule['taxAmountOld'])/$denominator; - $rule['subTotal'] = $cart_prices[$this->_psType . 'Value'] * $frac; - vmdebug('Part $denominator '.$denominator.' $frac '.$frac,$rule['subTotal']); + // 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); + } 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']]; } } } @@ -460,27 +529,26 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin { if (count ($taxrules) > 0 ) { // BEGIN_RK_CHANGES - if ($method->includes_tax) { - - $cart_prices['salesPrice' . $_psType] = $calculator->roundInternal ($cart_prices[$this->_psType . 'Value'], 'salesPrice'); - // Calculate the tax from the final sales price: + if ($includes_tax) { + // Calculate the net shipping cost by removing all taxes: $calculator->setRevert (true); - $cart_prices[$this->_psType . 'Value'] = $calculator->roundInternal ($calculator->executeCalculation($taxrules, $cart_prices[$this->_psType . 'Value'], true)); - $cart_prices[$this->_psType . 'Tax'] = $cart_prices['salesPrice' . $_psType] - $cart_prices[$this->_psType . 'Value']; + $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'); + $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']; +// $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']; } @@ -491,7 +559,6 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin { $cart_prices[$this->_psType . '_calc_id'] = 0; } - return $cart_prices['salesPrice' . $_psType]; } @@ -1369,10 +1436,6 @@ class ShippingRule { $this->match = True; // Calculate the value (i.e. shipping cost or modifier) $this->value = $this->calculateShipping($vals, $products, $cartvals_callback); - // For definitions add the variable to the vals - if ($this->ruletype=='definition') { - $vals[strtolower($this->name)] = $this->value; - } // Evaluate the rule name as a translatable string with variables inserted: // Replace all {variable} tags in the name by the variables from $vals $matches=array(); @@ -1403,11 +1466,14 @@ class ShippingRule { return $this->rulename; } - function getShippingCosts() { + function getValue() { if (!$this->evaluated) - vmDebug('WARNING: getShippingCosts called without prior evaluation of the rule, e.g. by calling rule->matches(...)'); + vmDebug('WARNING: getValue called without prior evaluation of the rule, e.g. by calling rule->matches(...)'); return $this->value; } + function getShippingCosts() { + return $this->getValue(); + } function isNoShipping() { // NoShipping is set, so if the rule matches, this method should not offer any shipping at all