Post by TNCP » Mon Oct 13, 2008 5:16 am

Hello,

I've been reading numerous threads about this, but have been unable to find a thread that actually solves my specific issue. I am using OpenCart for a small business that sells products in Florida, USA. I am having an issue with the sales tax. For Florida, we only need to charge sales tax to customers within Florida. Anywhere in the USA outside of Florida, no sales tax needs to be applied.

Under admin, I have set up a "Taxable Goods" category, set up a Geo Zone with only Florida, USA in it, applied the "Taxable Goods" category to my products, etc. and so on. I'm fairly certain I've set up everything correctly there.

I've made a test login to make sure that the sales tax setup is working right. First, I made an address with Florida as the state. As expected, the sales tax showed up. Good so far...

Then I made an address with another random state in the USA and went to check out and... uh oh, there's the sales tax. I tried changing the address to another country; sales tax still showed up. I started digging and debugging in the code and it appears the issue stems from 'tax.php' under the 'cart' directory in the 'library' directory:

Code: Select all

<?php
class Tax {
	var $taxes = array();
	
	function __construct(&$locator) {
		$this->config   =& $locator->get('config');
		$this->database =& $locator->get('database');
		$this->session  =& $locator->get('session');

// ***Issue is here***
		$address_info = $this->database->getRow("select country_id, zone_id from address where address_id = '" . (int)$this->session->get('shipping_address_id') . "' and customer_id = '" . (int)$this->session->get('customer_id') . "'");
// ***Issue ends here***

                if ($address_info) {
			$country_id = $address_info['country_id'];
			$zone_id    = $address_info['zone_id'];
		} else {
			$country_id = $this->config->get('config_country_id');
			$zone_id    = $this->config->get('config_zone_id');
		}

		$results = $this->database->getRows("select tr.tax_class_id, sum(tr.rate) as rate, tr.description from tax_rate tr left join zone_to_geo_zone z2gz on (tr.geo_zone_id = z2gz.geo_zone_id) left join geo_zone gz on (tr.geo_zone_id = gz.geo_zone_id) where (z2gz.country_id = '0' or z2gz.country_id = '" . (int)$country_id . "') and (z2gz.zone_id = '0' or z2gz.zone_id = '" . (int)$zone_id . "') group by tr.tax_class_id");
	
		foreach ($results as $result) {
      		$this->taxes[$result['tax_class_id']] = array(
        		'rate'        => $result['rate'],
        		'description' => $result['description']
      		);
    	}	
  	}
	
  	function calculate($value, $tax_class_id, $calculate = TRUE) {	
		if (($calculate) && (isset($this->taxes[$tax_class_id])))  {
      		return $value + ($value * $this->taxes[$tax_class_id]['rate'] / 100);
    	} else {
      		return $value;
    	}
  	}
        
  	function getRate($tax_class_id) {
    	return (isset($this->taxes[$tax_class_id]) ? $this->taxes[$tax_class_id]['rate'] : NULL);
  	}
  
  	function getDescription($tax_class_id) {
		return (isset($this->taxes[$tax_class_id]) ? $this->taxes[$tax_class_id]['description'] : NULL);
  	}
  
  	function has($tax_class_id) {
		return isset($this->taxes[$tax_class_id]);
  	}
}
?>
Between my comments ("Issue is here"), that appears to be where the problem is. When I print out the variables it places into the SQL code, '(int)$this->session->get('shipping_address_id')' seems to always return 0, which I'm guessing is PHP's int representation of null. Here is the get() function inside the Session class:

Code: Select all

	function get($key) {
		return (isset($_SESSION[$key]) ? $_SESSION[$key] : NULL);
	}
As you can see, it returns null if $_SESSION[$key] is not set. Thus, it is my guess that $_SESSION['shipping_address_id'] is not set in the code.

Since there are no records in the address table with 0 as the address_id, the SQL query returns nothing. If you follow the original code past my comments a little more:

Code: Select all

                if ($address_info) {
			$country_id = $address_info['country_id'];
			$zone_id    = $address_info['zone_id'];
		} else {
			$country_id = $this->config->get('config_country_id');
			$zone_id    = $this->config->get('config_zone_id');
		}
you will see that the code defaults to the default settings of the store if no records are queried. This is my best deduction as to what causes the sales tax to always appear on my transactions, because the store's default location is Florida, USA.

I haven't had time to dig deeper and figure out why $_SESSION['shipping_address_id'] is never set in the code, but I figured I'd post it here to see if anyone else has had a similar issue or it if has been fixed already.

Newbie

Posts

Joined
Mon Oct 13, 2008 4:58 am

Post by Qphoria » Mon Oct 13, 2008 5:49 am

I have just tried this in 0.7.8 and 0.7.9RC1 and cannot confirm what you are seeing. I see it working correctly for me.

shipping zone 1 = Florida
Address 1 = Florida = Tax
Address 2 = Texas = No Tax

What version are you running?
Last edited by Qphoria on Mon Oct 13, 2008 5:57 am, edited 1 time in total.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by bruce » Mon Oct 13, 2008 8:29 am

Did you follow the steps in the howto document in contributions? If the download does not have the .zip extension, simply rename it.

I think the only step you have missed is to turn off tax in your store admin. Only then will the taxes be calculated on the shipping destination. Otherwise it is calculated on the store address.

All products must be set in admin to require shipping also.

Active Member

Posts

Joined
Wed Dec 12, 2007 2:26 pm

Post by Qphoria » Mon Oct 13, 2008 9:35 am

bruce wrote: Did you follow the steps in the howto document in contributions? If the download does not have the .zip extension, simply rename it.
heh didn't even know there was a contrib involved. Also not sure why that applies here tho, this is core functionality
bruce wrote: I think the only step you have missed is to turn off tax in your store admin. Only then will the taxes be calculated on the shipping destination. Otherwise it is calculated on the store address.

All products must be set in admin to require shipping also.
This is a good point. I've never checked into how that works
Last edited by Qphoria on Mon Oct 13, 2008 9:42 am, edited 1 time in total.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by bruce » Mon Oct 13, 2008 9:41 am

More like a discovery of how to make it behave. How to do it is very unintuitive... hence the document.

Active Member

Posts

Joined
Wed Dec 12, 2007 2:26 pm

Post by Qphoria » Mon Oct 13, 2008 9:47 am

ah i see. I didn't need no document. I guess i'm just a genius :P (j/k)

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by bruce » Mon Oct 13, 2008 9:51 am

LOL... lucky more like  ;)

Active Member

Posts

Joined
Wed Dec 12, 2007 2:26 pm

Post by TNCP » Mon Oct 13, 2008 1:38 pm

Wow, the problem was much simpler than I thought. I simply hadn't set up shipping yet... ;D

Thanks for linking the howto document, bruce. I had found that document in my forum searches, but was confused by it not having an extension. It'd be great if we could get that howto document put into the official documentation for OpenCart. :)

Newbie

Posts

Joined
Mon Oct 13, 2008 4:58 am

Post by dvfd9 » Mon Dec 15, 2008 12:34 pm

Thank you for posting this thread, as it helped me fix my issue

The issue I'm having (version .7.7) is when I want people in Connecticut ONLY to be charged Tax - anywhere else I could care less about

the code snippet the OP made in the tax.php file

Code: Select all

// ***Issue is here***
		$address_info = $this->database->getRow("select country_id, zone_id from address where address_id = '" . (int)$this->session->get('shipping_address_id') . "' and customer_id = '" . (int)$this->session->get('customer_id') . "'");
// ***Issue ends here***
needs to be modified to

Code: Select all

// ***Issue is here***
		$address_info = $this->database->getRow("select country_id, zone_id from address where customer_id = '" . (int)$this->session->get('customer_id') . "'");
// ***Issue ends here***
This is what fixed it for me, tax is now correctly working for any other state not getting charged and people in my state only being charged.

Thanks!!!!!!!!!!!!

Newbie

Posts

Joined
Mon Apr 07, 2008 2:43 am

Post by dvfd9 » Mon Dec 15, 2008 12:35 pm

I also wanted to add that it may only work for Weight Based shipping which is what I need to use, so it may or may not work for people using different shipping methods


Love this product though, thanks all.

Newbie

Posts

Joined
Mon Apr 07, 2008 2:43 am

Post by smokingstar » Sat Jan 31, 2009 11:50 am

I followed the How To from the contributions, but I'm still having trouble having my cart only do sales tax when the item ships to TX.

Newbie

Posts

Joined
Tue Jan 27, 2009 11:47 am
Who is online

Users browsing this forum: No registered users and 3 guests