Author Topic: Modification to the way ps_checkout->calc_order_taxable function works  (Read 18188 times)

BrianCockle

  • Beginner
  • *
  • Posts: 20
I have come up with a modification to the way the calc_order_taxable function works to use something other than the weight of an item to determine if it is taxable or not.

I was hoping some of you who are a little more knowledgeable of PHP and the inner workings of developing in VirtueMart could look over what I have done and offer any suggestions.  Knock on wood, but so far it is working great on my test system.

The goal of the hack is to be able to charge sales tax to customers on certain items (food) for orders shipped to the same state where the business is setup in.  This is a pretty common scenario in the United States.  I found that the zero weight function works properly in that if you set its shipping weight to zero, a customer in your state will not be charged the sales tax, but this presented a few problems when it comes to calculating the shipping cost for the customer.

To get around that, but use the logic already in VirtueMart, I changed the way the ps_checkout.php->calc_order_taxable function works.  Instead of using an item with zero weight to determine if the tax should be calculated, it adds a field to the product database and the function looks at that field to determine if the tax should be calculated.  That way you can still utilize the real time shipping calculators that rely on the weight of the cart for calculating the shipping accurately.

There are four PHP files that need to be modified and one SQL statement that needs to be ran to extend the product table.

Modifications to the files are detailed in the readme.txt file.

That should be it.  Any comments and suggestions are appreciated.  I have also attached the modified files.  Like anything new though, please check it on a test system and backup your original files so you can roll back.  Maybe someone has a better solution or a way to make it a little cleaner, or maybe we can come up with a way to get this functionality into the core of the program.

Update 01/09/2007: I have fixed a couple of bugs and updated the files to work with 1.0.9.  As mentioned in the thread, there were some problems when adding a new product.  There was one other issue relating to adding a product where if you created a new item and marked it taxable, it wasn't saving.  That is now fixed.

[attachment cleanup by admin]

Bruce Morgan

  • Full Member
  • ***
  • Posts: 672
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #1 on: September 18, 2006, 17:49:39 pm »
Have you updated this hack to work with the latest VBM 1.0.7?

BrianCockle

  • Beginner
  • *
  • Posts: 20
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #2 on: September 19, 2006, 05:42:24 am »
Have you updated this hack to work with the latest VBM 1.0.7?
Not yet.  I'll work on it this week and post an update.  I had just fixed a couple little things under 1.0.6 and was going to post an update to the thread when 1.0.7 came out.  All in all though in my testing it has been working great.

jsnyde

  • Beginner
  • *
  • Posts: 37
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #3 on: November 02, 2006, 00:17:36 am »
I'm using 1.0.7.  The problem I'm having is that I need to add a function to the ps_product file that gets the value of "product_taxable" in order to get rid of a "call to undefined function" error when I try to use this method.

So far I have:

   
Code: [Select]
  function get_product_taxable($prod_id) {

$db = new ps_DB;

$q = "SELECT product_taxable FROM #__{vm}_product WHERE product_id='". $prod_id ."'";
$db->query($q);
$db->next_record();
if (product_taxable !="Y") {
return false;
} else {
return true;
}

}

but it disrupts the add new product process and causes an error that reads "ERROR: A product ID is missing." but then reports that " a product was successfully added"  (when it wasn't).

Can anyone help me with this?  I really need this function to work, even if it means I have to add products directly into the Db.

Jeff


BrianCockle

  • Beginner
  • *
  • Posts: 20
Re: Modification to the way ps_checkout->calc_orde
« Reply #4 on: November 02, 2006, 02:39:56 am »
I'm using 1.0.7.  The problem I'm having is that I need to add a function to the ps_product file that gets the value of "product_taxable" in order to get rid of a "call to undefined function" error when I try to use this method.

So far I have:

   
Code: [Select]
  function get_product_taxable($prod_id) {

$db = new ps_DB;

$q = "SELECT product_taxable FROM #__{vm}_product WHERE product_id='". $prod_id ."'";
$db->query($q);
$db->next_record();
if (product_taxable !="Y") {
return false;
} else {
return true;
}

}

but it disrupts the add new product process and causes an error that reads "ERROR: A product ID is missing." but then reports that " a product was successfully added"  (when it wasn't).

Can anyone help me with this?  I really need this function to work, even if it means I have to add products directly into the Db.

Jeff

I'm not quite sure I understand what you are trying to do with the additional function.  Are you using this as a customization for something else or are you just trying to get it setup as-is and it's not working?  Did you use the files in the zip or are you manually modifying them?

jsnyde

  • Beginner
  • *
  • Posts: 37
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #5 on: November 04, 2006, 17:12:14 pm »
I've tried both editing manually and using the zip files.  With both, I received an error regarding a call to an undefined function get_product_taxable() in ps_product.

I assumed this might have to do with the modification not being developed for 1.0.7.  I decided to try to add the function myself (I'm obviously not much of a coder).  And that's as far as I've gotten. 

I haven't tested a mix of taxable and non-taxable products on an order yet to see if the modification is working except for the problem adding new products mentioned above.

Do you have it working on 1.0.7?

Thanks,

Jeff


jsnyde

  • Beginner
  • *
  • Posts: 37
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #6 on: November 04, 2006, 17:42:13 pm »
I must have gotten files mixed up because now I see the get_product_taxable function in the zip, but if I use that and the ps_checkout from the zip I get:

Fatal error: Call to undefined function: tax_based_on_vendor_address() in /home/xxx/xxx/xxx/administrator/components/com_virtuemart/html/basket.php on line 199 (A function I'm not using BTW, I'm basing shipping on shipping address)

So, I added that function back in from the original ps_checkout.

That got rid of calls to undefined functions and placed me back at the original problem - can't add new products.
"ERROR: A product ID is missing."

Thanks,

Jeff


jsnyde

  • Beginner
  • *
  • Posts: 37
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #7 on: November 04, 2006, 18:29:31 pm »
OK, I think I may have found the problem:

in the original ps_product, the INSERT line of the query for adding new products reads on line 252
Code: [Select]
$q .= "cdate,mdate,product_tax_id) ";
This was modified to also add the product taxable value:
Code: [Select]
$q .= "cdate,mdate,product_tax_id,product_taxable) ";
HOWEVER,

The corresponding list of variables in the VALUES statement of the query the list was not amended to account for the additional variable to be inserted - this code is the same in both the original and modified files:

Code: [Select]
$q .= "VALUES ('";
$q .= $d['vendor_id'] . "','" . $d["product_parent_id"] . "','";
$q .= $d["product_sku"] . "','" . $d["product_name"] . "','";
$q .= $d["product_desc"] . "','" . $d["product_s_desc"] . "','";
$q .= $d["product_thumb_image"] . "','";
$q .= $d["product_full_image"] . "','" . $d["product_publish"] . "','";
$q .= $d["product_weight"] . "','" . $d["product_weight_uom"] . "','";
$q .= $d["product_length"] . "','" . $d["product_width"] . "','";
$q .= $d["product_height"] . "','" . $d["product_lwh_uom"] . "','";
$q .= $d["product_unit"] . "','" . (($d["product_box"] << 16) | ($d["product_packaging"]&0xFFFF)) . "','"; // Changed Packaging - Added
$q .= $d["product_url"] . "','" . $d["product_in_stock"] . "','";
$q .= $d["product_advanced_attribute"]."','";
$q .= $d["product_custom_attribute"]."','";
$q .= $d["product_available_date_timestamp"] . "','";
$q .= $d["product_availability"] . "','";
$q .= $d["product_special"] . "','";
$q .= $d["product_discount_id"] . "','$timestamp','$timestamp','".$d["product_tax_id"]."')";

$db->setQuery($q); $db->query();

$d["product_id"] = $db->last_insert_id();

Could this be it? 

TESTED IT.  PROBLEM SOLVED.  CHANGE LAST LINE OF QUERY TO:

Code: [Select]
$q .= $d["product_discount_id"] . "','$timestamp','$timestamp','".$d["product_tax_id"]."','".$d["product_taxable"]."')";
Hope this helps someone else.

Jeff

Bruce Morgan

  • Full Member
  • ***
  • Posts: 672
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #8 on: November 04, 2006, 18:47:50 pm »
Just to make sure I do not screw this up could you give a quick summary of what needs to be done or post a revised zip file?

Bruce

jsnyde

  • Beginner
  • *
  • Posts: 37
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #9 on: November 04, 2006, 18:59:24 pm »
I'm addressing multiple problems here - some of which I caused myself.  Which one are you having so I can help you better?

Jeff

Bruce Morgan

  • Full Member
  • ***
  • Posts: 672
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #10 on: November 04, 2006, 19:07:58 pm »
I see your point.  Ther are a lot of small changes to make in many places and this does not lend itself to modding one file and uploading.  I am starting to accumulate enough hacks on my web site that each time Joomla or VM is updated I have a bigger and bigger headache trying to add back all of these mods without crashing the site. 

A mod like this has been overdue for a long time.  I would like to see it added to the next release.  Hopefully Soeren will see fit to work it in.

Bruce

jsnyde

  • Beginner
  • *
  • Posts: 37
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #11 on: November 04, 2006, 19:30:31 pm »
Yeah, I comment all my hacks and label them "HACK" religiously.  Then when there is an update, I can search in all the files for case sensitive "HACK" and locate them all.

Didn't mean to put you off,  I'll be happy to help you with this one.

First get the first zip from above and install it.  (after you back up the necessary files of course).
Let me know if you receive any errors (some of the ones I got, I caused in the process, so you might not get them).

If you get a Call to undefined function: tax_based_on_vendor_address() its because that function isn't in the ps_checkout included in the zip.

HERE IT IS:
Code: [Select]
/**
* If the customer is in the EU then tax should be charged according to the
*  vendor's address, and this function will return true.
*/
function tax_based_on_vendor_address () {
global $__tax_based_on_vendor_address;
global $vmLogger;

if (!isset ($__tax_based_on_vendor_address)) {
$__tax_based_on_vendor_address = ps_checkout::_tax_based_on_vendor_address ();
if ($__tax_based_on_vendor_address)
$vmLogger->debug ('calculating tax based on vendor address');
else
$vmLogger->debug ('calculating tax based on shipping address');
}
return $__tax_based_on_vendor_address;
}

function _tax_based_on_vendor_address () {
global $auth;
global $vmLogger;

switch (TAX_MODE) {
case '0':
return false;

case '1':
return true;

case '17749':
if (! array_key_exists ('country', $auth)) {
$vmLogger->debug ('shopper\'s country is not known; defaulting to vendor-based tax');
return true;
}

$vmLogger->debug ('shopper is in ' . $auth['country']);
return ps_checkout::country_in_eu_common_vat_zone ($auth['country']);

default:
$vmLogger->warning ('unknown TAX_MODE "' . TAX_MODE . '"');
return true;
}
}

function country_in_eu_common_vat_zone ($country) {
$eu_countries = array ('AUT', 'BEL', 'CYP', 'CZE', 'DNK', 'EST', 'FIN', 'FRA', 'DEU', 'GRC', 'HUN', 'IRL', 'ITA', 'LVA', 'LTU', 'LUX', 'MLT', 'POL', 'PRT', 'SVK', 'SVN', 'ESP', 'SWE', 'NLD', 'GBR');
return in_array ($country, $eu_countries);
}

paste it in AFTER THE LAST FUNCTION "approx()" which ends around line 2128 and looks like this:
Code: [Select]
/*
* @abstract This function is very useful to round totals with definite decimals.
*
* @param float   $value
* @param integer $dec
* @return float
*/
function approx( $value, $dec = 2 ) {
$value += 0.0;
$unit  = floor( $value * pow( 10, $dec + 1 ) ) / 10;
$round = round( $unit );
return $round / pow( 10, $dec );
}

AND BEFORE THE CLOSING BRACE AND PHP TAG
Code: [Select]
}
?>

See if you can add new products. 

If you get ERROR: Product ID missing

You need to replace the line around 269 in ps_product that reads:
Code: [Select]
$q .= $d["product_discount_id"] . "','$timestamp','$timestamp','".$d["product_tax_id"]."')";
with:
Code: [Select]
$q .= $d["product_discount_id"] . "','$timestamp','$timestamp','".$d["product_tax_id"]."','".$d["product_taxable"]."')";
These are the 2 major issues I ran into.  Let me know if you have any more questions.  I'll try to help.

Jeff

BrianCockle

  • Beginner
  • *
  • Posts: 20
Re: Modification to the way ps_checkout->calc_orde
« Reply #12 on: January 09, 2007, 22:47:32 pm »
To make it a little easier, I have updated the files to work with 1.0.9 and fixed the issues above.  It is in the initial message in the thread.

If anyone has a chance and could test it out, that would be great.  It would be nice if this functionality could get incorporated into the official version in one form or another.

Anthony C.

  • Jr. Member
  • **
  • Posts: 286
Re: Modification to the way ps_checkout->calc_order_taxable function works
« Reply #13 on: March 15, 2007, 00:49:38 am »
Hi,

Nice hack. I really need this too.

However, in your file: product.product.form  line: 241
-->
echo "<input type=\"checkbox\" name=\"product_taxable\" value=\"Y\" />";

should the value be  :   N
like this -->
echo "<input type=\"checkbox\" name=\"product_taxable\" value=\"N\" />";

Or there will be no difference if you set it tax exempt.
I am not sure if this is right .. please tell me..

Anthony

BrianCockle

  • Beginner
  • *
  • Posts: 20
Re: Modification to the way ps_checkout->calc_orde
« Reply #14 on: March 15, 2007, 01:05:34 am »
Anthony,

I don't have my notes in front of me, but I seem to recall doing that initially (as it seemed logical) and it didn't work.  As it has been several months since I first did the hack, I don't remember exactly why off hand, I just remember that it turned out that by doing the opposite logically of what it seemed you should do resolved it.

I have been using the hack on my production server for several months and it has been working great for me.  The only problem is every time an update comes out is it has to be re-implemented.

--Brian