Error applying VAT when using general discount

  • Posts: 187
  • Thank you received: 10
9 years 10 months ago #185026

-- HikaShop version -- : 2,3,5
-- Joomla version -- : 3.3.5
-- PHP version -- : 5,4

Just setup the new VAT rules (thanks for the easy way to do this) and found something that seems an bug.

we had one product that had a 10% discount applied. For my country (NL) all 3 rates are set to charge 21% VAT.
VAT system set to FLOAT.

That works fine but if I enable the discount I get funny issues: companies with VAT suddenly need to pay an extra 21%
Individuals don't pay VAT etc.

Seems the general discount is interfering with the prices and how VAT is calculated.

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
9 years 10 months ago #185079

Hi,

No one reported such issue and we cannot reproduce the problem.
So I can only deduce that the problem comes from how you configured your tax rules.
Please edit each tax rule for your country and provide a screenshot of the option screen of each one.
Also, please provide a screenshot of the issue with the price before/after discount being displayed on the checkout with the address displayed.

Please Log in or Create an account to join the conversation.

  • Posts: 187
  • Thank you received: 10
9 years 10 months ago #185824

Of course could be a wrong setting somewhere but it keeps coming back:

Setting: standard customer in the Netherlands:
VAT 21%:



The customer order 2 identical products, (made a copy). One with 10% discount the other not:



As you can see, one gets VAT applied, the other not.

Tax settings in config:



Curious whats going on.

Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
9 years 10 months ago #185941

It could come from the floating tax prices option.
That is a new option we introduced in the 2.3.5 and I wouldn't be surprised that it would have some issue with discounts.
How did you configure your discount ? Could you do a screenshot ?
Could you try to turn off the "floating tax prices" option and see if that helps ?

Please Log in or Create an account to join the conversation.

  • Posts: 187
  • Thank you received: 10
9 years 10 months ago #185944

Hi Nicolas,

Not the only one working late.....
Yes it seems to come from the FLOAT tax. Switched it off and at least the VAT issue seem less.
Have done a few combination tests, als going back to 'default' tax system etc but that wasn't changing much.

Discount is pretty simple. just 10% on that specific product.




Removing FLOAT seems to help but there are still a few more calculations that don't add up exactly when I use two discount and one overriding.
Time to stop and work on it tomorrow.

Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
9 years 10 months ago #186361

Hi,

I think that I've found the issue with the "Floating tax prices" option and the discount calculations.
Add the code:

$config = hikashop_config();
		if($config->get('floating_tax_prices',0)){
			$price->price_value = $price->price_value_with_tax;
		}
after the line:
function addDiscount(&$price,&$discount,$discount_before_tax,$zone_id,$product_tax_id){
in the file administrator/components/com_hikashop/classes/currency.php and that should fix the issue with the price calculations when both the floating tax prices option is turned on and that the prices have a discount.
It fixes the issue on my end in the few tests I did.

Please Log in or Create an account to join the conversation.

  • Posts: 187
  • Thank you received: 10
9 years 10 months ago #186383

Did not fix it for me. still applying discount to product then messing up VAT on top of price with VAT.

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
9 years 10 months ago #186392

Hi,

Do you have the "Floating tax prices" option activated ?
If you switch the "Apply discount" option of the HikaShop configuration, does it work ? I have it set to "Before taxes" on my end.

Please Log in or Create an account to join the conversation.

  • Posts: 187
  • Thank you received: 10
9 years 10 months ago #186537

Nicolas, we need to apply after taxes, this is a consumer site and 50 euro discount should end up as 50 euro of the total.
So for testing: floating set and taxes before:
When I have no discount, it show inc and excl taxes ok
When I set a discount, taxes before, it seems ok
I get the same incl and excl prices when I switch back to after taxes.
So the issues is indeed when set to discount after tax

Coupons seem to work OK. (although we had to change them all and give them a VAT select to get the same prices back again.)

Bastiaan

Please Log in or Create an account to join the conversation.

  • Posts: 26158
  • Thank you received: 4028
  • MODERATOR
9 years 10 months ago #186736

Hi,

I'm trying to continue this thread and I'm a little bit confused.
Would it be possible to have a description of the configuration which provide a wrong result ?
So I will be able to set a sample store using that and fix the issue directly in the code (and then, provide you a fix).

Thanks !


Jerome - Obsidev.com
HikaMarket & HikaSerial developer / HikaShop core dev team.

Also helping the HikaShop support team when having some time or couldn't sleep.
By the way, do not send me private message, use the "contact us" form instead.

Please Log in or Create an account to join the conversation.

  • Posts: 187
  • Thank you received: 10
9 years 10 months ago #186744

Hi Jerome, login in your PM. Easier for both.

Setting: VAT set to FLOAT, apply discount after TAX. That seems to mess up the VAT calculation when using an overal discount. (not coupon)

Please Log in or Create an account to join the conversation.

  • Posts: 187
  • Thank you received: 10
9 years 10 months ago #186805

Just to add to the misery: I get clients that are confronted with wrong prices:

Shop is using prices included VAT but see this invoice when someone enters his VAT number while in a country without exempt:
(Dutch company buying in NL from our Dutch shops)



Some crooked calculation pops up. Instead of the proper 347, he has to pay a strange amount. We are now serious in trouble with a bunch of clients and overloaded helpdesk..

We have set the VAT amount for companies in the Netherlands equal to consumer amount. With or without VAT number:

Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 26158
  • Thank you received: 4028
  • MODERATOR
9 years 10 months ago #186831

Hi,

When Nicolas implemented the floating tax mode ; some users has test it in order to validate it.
Nicolas also made a bunch of tests in order to be sure that it is working properly.
Unfortunately, some elements have not been tested and the problem you are seeing now are, I think, all links to the floating tax option.

Regards,


Jerome - Obsidev.com
HikaMarket & HikaSerial developer / HikaShop core dev team.

Also helping the HikaShop support team when having some time or couldn't sleep.
By the way, do not send me private message, use the "contact us" form instead.

Please Log in or Create an account to join the conversation.

  • Posts: 26158
  • Thank you received: 4028
  • MODERATOR
9 years 10 months ago #186925

Hi,

I finally got it !
So, please edit the file "administrator/components/classes/currency.php" and replace

	function getUntaxedPrice(&$price,$zone_id,$tax_category_id,$round=2){
		$this->taxRates=array();
		$tax = (float)$this->getTax($zone_id,$tax_category_id);
		if(empty($tax)) return $this->_round($price,$round);
		$config =& hikashop_config();
		if(!$config->get('floating_tax_prices',0)){
			$float_price=(float)$price;
			$untaxedPrice = $this->_round($float_price/(1.00000+$tax),$round);
			if(!empty($this->taxRates)){
				foreach($this->taxRates as $k => $rate){
					$this->taxRates[$k]->tax_amount = $this->_round($float_price*floatval($rate->tax_rate)/(1.00000+floatval($rate->tax_rate)),$round);
				}
			}
		}else{
			$untaxedPrice=(float)$price;
			$taxedPrice=$this->_round($untaxedPrice+$untaxedPrice*$tax,$round);
			if(!empty($this->taxRates)){
				foreach($this->taxRates as $k => $rate){
					$this->taxRates[$k]->tax_amount = $this->_round($untaxedPrice*floatval($rate->tax_rate),$round);
				}
			}
		}
		return $untaxedPrice;
	}
By
	function getUntaxedPrice(&$price, $zone_id, $tax_category_id, $round = 2) {
		$this->taxRates = array();
		$tax = (float)$this->getTax($zone_id, $tax_category_id);
		if(empty($tax))
			return $this->_round($price, $round);
		$float_price = (float)$price;
		$untaxedPrice = $this->_round($float_price / (1.00000 + $tax), $round);
		if(!empty($this->taxRates)) {
			foreach($this->taxRates as $k => $rate) {
				$this->taxRates[$k]->tax_amount = $this->_round($float_price * floatval($rate->tax_rate) / (1.00000 + floatval($rate->tax_rate)), $round);
			}
		}
		return $untaxedPrice;
	}
And it will fix the issue with the floating taxes and the discount after taxes.
I made some tests and some checks ; the modifications does not seems to have bad side effects.

Let me know if you have any feedback on that patch.

Regards,


Jerome - Obsidev.com
HikaMarket & HikaSerial developer / HikaShop core dev team.

Also helping the HikaShop support team when having some time or couldn't sleep.
By the way, do not send me private message, use the "contact us" form instead.

Please Log in or Create an account to join the conversation.

  • Posts: 187
  • Thank you received: 10
9 years 10 months ago #186928

Hi Jerome,

Yes it works now for a general discount and VAT seems ok, although I will have to test a bit more tomorrow with and without VAT number.
but coupons still don't work right. My settings is still apply discount after tax but the coupon code still takes discount before tax.

Of course I have a complicate example: product receives 10% discount and then people can add a 50% discount coupon that should override. 50% of 1388 = 694. Not whats on the sheet now:


Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 26158
  • Thank you received: 4028
  • MODERATOR
9 years 10 months ago #186939

Hi,

I was focused on the discounts for my tests and I didn't test the coupons.
It is for coupons or just when there is a "discount + coupon" ?

I'll perform some new tests for that.

Don't hesitate to send me more information if you find other problems.

Regards,


Jerome - Obsidev.com
HikaMarket & HikaSerial developer / HikaShop core dev team.

Also helping the HikaShop support team when having some time or couldn't sleep.
By the way, do not send me private message, use the "contact us" form instead.

Please Log in or Create an account to join the conversation.

  • Posts: 187
  • Thank you received: 10
9 years 10 months ago #186969

It happens with 'clean' coupons and with the combination.
Without Float setting it seems ok.

Please Log in or Create an account to join the conversation.

  • Posts: 26158
  • Thank you received: 4028
  • MODERATOR
9 years 10 months ago #187080

Hi,

I performed several tests using floating taxes and coupons (apply on products or not, fixed and percentage...)
Thanks to these tests (and some aspirins), I made some patches for the coupons and I got know good results.

So here the new version of the function "addCoupon" in the currency class

function addCoupon(&$prices, &$discount, $products = null, $id = array()) {
	$config =& hikashop_config();
	$discount_before_tax = $config->get('discount_before_tax');

	$config = hikashop_config();
	$floating_tax = (int)$config->get('floating_tax_prices', 0);

	foreach($prices->prices as $k => $price) {
		if(isset($prices->prices[$k]->price_value_without_discount_with_tax) && $prices->prices[$k]->price_value_without_discount_with_tax > 0)
			continue;

		if(isset($price->taxes)) {
			$price->taxes_without_discount = array();
			foreach($price->taxes as $namekey => $tax) {
				$price->taxes_without_discount[$namekey] = clone($tax);
			}
		}

		$prices->prices[$k]->price_value_without_discount_with_tax = $price->price_value_with_tax;

		$round = $this->getRounding(@$prices->prices[$k]->price_currency_id);
		$zone_id = hikashop_getZone();
		if(bccomp($discount->discount_flat_amount, 0, 5) !== 0) {
			$discount->discount_value_without_tax = $discount->discount_flat_amount_without_tax = $discount->discount_flat_amount;
			$untaxed = null;
			if($discount_before_tax) {
				$untaxed = $discount->discount_flat_amount;
				$discount->discount_flat_amount = $this->getTaxedPrice($discount->discount_flat_amount, $zone_id, $discount->discount_tax_id, $round);
			} else if($floating_tax) {
				$untaxed = $discount->discount_flat_amount;
			}
			if($untaxed !== null) {
				$discount->taxes = array();
				foreach($price->taxes as $namekey => $tax) {
					$discount->taxes[$namekey] = clone($tax);
					$discount->taxes[$namekey]->tax_amount = $untaxed * $tax->tax_rate;
					$price->taxes[$namekey]->tax_amount = $tax->tax_amount - $discount->taxes[$namekey]->tax_amount;
				}
			}
			$prices->prices[$k]->price_value_with_tax = $price->price_value_with_tax - floatval($discount->discount_flat_amount);
		} elseif(bccomp($discount->discount_percent_amount, 0, 5) !== 0) {
			if($discount_before_tax) {
				$discount->discount_value_without_tax = $discount->discount_percent_amount_calculated_without_tax = $discount->discount_percent_amount_calculated = ($price->price_value*floatval($discount->discount_percent_amount)/100.0);
				$discount->discount_percent_amount_calculated = 0.0;
				if($price->price_value_with_tax != 0.0)
					$discount->discount_percent_amount_calculated = $price->price_value_with_tax * $discount->discount_percent_amount_calculated_without_tax / $price->price_value_with_tax;
			} else {
				if(!$floating_tax)
					$price_value = $price->price_value_with_tax;
				else
					$price_value = $price->price_value;
				$discount->discount_value_without_tax = $discount->discount_percent_amount_calculated_without_tax = $discount->discount_percent_amount_calculated = ($price_value * floatval($discount->discount_percent_amount) / 100.0);
			}
			$discount->discount_percent_amount_calculated = $this->getTaxedPrice($discount->discount_percent_amount_calculated, $zone_id, $discount->discount_tax_id, $round);
			$discount->taxes = array();
			foreach($price->taxes as $namekey => $tax) {
				$discount->taxes[$namekey] = clone($tax);
				$discount->taxes[$namekey]->tax_amount = $discount->taxes[$namekey]->tax_amount * floatval($discount->discount_percent_amount) / 100.0;
				$price->taxes[$namekey]->tax_amount = $price->taxes[$namekey]->tax_amount - $discount->taxes[$namekey]->tax_amount;
			}
			$prices->prices[$k]->price_value_with_tax = $price->price_value_with_tax - $discount->discount_percent_amount_calculated;
			if(isset($price->price_orig_value_with_tax)) {
				$prices->prices[$k]->price_orig_value_without_discount_with_tax = $price->price_orig_value_with_tax;
				$discount->discount_orig_percent_amount_calculated_without_tax = $discount->discount_orig_percent_amount_calculated = ($price->price_orig_value_with_tax * floatval($discount->discount_percent_amount) / 100.0);
				$discount->discount_orig_percent_amount_calculated = $this->getTaxedPrice($discount->discount_orig_percent_amount_calculated, $zone_id, $discount->discount_tax_id, $round);
				$prices->prices[$k]->price_orig_value_with_tax = $price->price_orig_value_with_tax - $discount->discount_orig_percent_amount_calculated;
			}
		} else {
			$discount->discount_value_without_tax = 0;
		}
		$discount->discount_value = $prices->prices[$k]->price_value_without_discount_with_tax - $prices->prices[$k]->price_value_with_tax;

		$prices->prices[$k]->price_value_without_discount = $price->price_value;
		$prices->prices[$k]->price_value = $price->price_value - $discount->discount_value_without_tax;
	}
}
I also made some modification in the class discount for other improvements.

Regards,


Jerome - Obsidev.com
HikaMarket & HikaSerial developer / HikaShop core dev team.

Also helping the HikaShop support team when having some time or couldn't sleep.
By the way, do not send me private message, use the "contact us" form instead.

Please Log in or Create an account to join the conversation.

  • Posts: 187
  • Thank you received: 10
9 years 10 months ago #187116

Hope your headache is better, mine is not :-)

Replaced the class but discount is still applied before taxes. Switching that option in the config does not change the numbers.
Checked it only with a very basic product (ID=1) and a coupon.

Also switching tax category in the coupon setting does not change the amounts so it seems to miss those values completely.

For security of testing it might be safer to attach or email the full currency.php file.

Please Log in or Create an account to join the conversation.

  • Posts: 26158
  • Thank you received: 4028
  • MODERATOR
9 years 10 months ago #187181

Hi,

I'll need more details about your coupon in order to reproduce it.
My tests looks good so it will be difficult to know what I have to fix now !

Regards,


Jerome - Obsidev.com
HikaMarket & HikaSerial developer / HikaShop core dev team.

Also helping the HikaShop support team when having some time or couldn't sleep.
By the way, do not send me private message, use the "contact us" form instead.

Please Log in or Create an account to join the conversation.

Time to create page: 0.111 seconds
Powered by Kunena Forum