After looking over the current implementation of tax handling, I'm blind! (Ok, just kidding)

I started off wanting to adjust paypal.module to send the tax amount per transaction to the paypal payment screen. That's when I noticed the tax amount doesn't seem to get stored anywhere (as this thread also mentions). Since all the other costs & price adjustments (i.e. shipping cost, coupon) are in ec_transaction, couldn't the tax amount have a field in that table as well?

As the current tax situation stands, the tax amount is neither sent to paypal's payment screen nor able to be recalled by looking at order history; hence, the 'critical' flag on this post.

Also, I recommend that in tax.module, around line 57 the if(product_is_shippable) condition should probably be removed (see below). In the U.S., at least, there are actually service items that are taxable, even if billed online.

        /** if (product_is_shippable($item->nid)) { */
          $taxable_amount += product_adjust_price($item) * $item->qty;
        /** } */

Comments

gordon’s picture

Yes I know that the tax module is like this, and I am planning a new development called miscellaneous transactions which will allow for any type of transaction that doesn't relate to the product, like tax, shipping, discounts, handling, etc to be recorded in a single place.

This will also mean that altering the txn->gross will not be allow, and all invoices will balance. This will also make it easier to work out exactly how the system created the invoice.

Lastly it means that you will be able to create a General Ledger interface so that all the sales information can be exported to quickbooks or MyOB.

rszrama’s picture

Guckie raised a good point with some items being taxable and others not. A simple solution in the case of an E-Commerce package like this with many different types of "products" for sale is to store for each product its "taxability" and create a simple is_taxable function instead of using is_shippable. This function could also be the one to check the delivery address to see if taxes even need to be applied to the transaction and perhaps return a percent or dollar value if true or 0 if false.

ñull’s picture

Yes I know that the tax module is like this, and I am planning a new development called miscellaneous transactions which will allow for any type of transaction that doesn't relate to the product, like tax, shipping, discounts, handling, etc to be recorded in a single place.

Just adding my grain of sand. These things may be don't directly relate to the product, but they do relate indirectly.

  • Although they attempt to simplify it, in quite some European countries there are still different VAT cathegories, with each their own rate (in Spain for instance: education 0%, Food, books 4%, other 16%). So there are product groups that can have different Tax rates. May tax should not relate to the product but to taxonomy? I could imagine a TAX configuration that would allow to choose taxonomies and set a rate for them.
  • VAT relates to billing address and VAT registation. No VAT when ordered outside E.U. or when a valid VAT registration exists.
  • This is off topic, but still the same shipping cost relates often to the weight of a product. Again it somehow relates to the product, isn't it?
  • Again off-topic. To make Discount more flexible it would be good to relate it to taxonomy as well. This way you can have different discount groups, without having to add another special database table.
guckie’s picture

@gordon -- Yay! Glad to hear that the plans you mention are in the works =) Seems to me the tax handling, as it is, would prevent many folks from taking the e-commerce package seriously. (And that'd be a shame, since it's really been a tremendous effort!) ... and reporting functionality will certainly be a treat!

@rszrama -- You make a much better (and more thorough) point than I did.

Here's another thought: maybe for maximum granularity, there could be a field called 'Apply Tax Rules?' (with a multiple-select) to populate during product creation, allowing the product creator to specify exactly which tax rule(s) apply on a per-product level. It would then be easy to tie each product to appropriate tax calculations (even if not an exact tax amount per transaction) in order history. (i.e. product "widget" is subject to tax rules #1, 2, & 5.)

A couple of possible 'downsides' to this:
- Tax Rules probably shouldn't be allowed to be changed or deleted (once associated with a transaction in history). A tax rule could only be 'disabled' (and a new rule added to take its place).
- On large e-commerce sites, re-calculating a tax amount (based on a 'tax rule' field value) to display order history would result in far more cpu time than storing a precise 'total tax' amount field with each transaction.

Perhaps both (associating specific tax rules to a product AND storing an overall tax amount per transaction) would be in order?

Please forgive me for thinking out loud here... but this does seem like important discussion could be had in order to determine the broadest cross-section of community needs that coud be met (with regard to tax functionality).

ñull’s picture

guckie: Perhaps both (associating specific tax rules to a product AND storing an overall tax amount per transaction) would be in order?

In Spain, as far as I can tell, you would need to know per product, what tax rule (guckie's term) was applied. The invoice at the moment does not include Tax calculation, but in a legally correct invoice the totals per tax rule should be visible or at least calculable. This impies that the transaction (history) should also contain the tax rule label and the amount.. Transaction table is history and should store amounts and text labels, not relational id. Who cares about the extra needed disk space nowadays? Much better would be a facility to download and backup old transactions, to clean up that table periodically.

guckie:It would then
be easy to tie each product to appropriate tax calculations (even if
not an exact tax amount per transaction) in order history. (i.e.
product "widget" is subject to tax rules #1, 2, & 5.)

The same could be done by selecting a term of a taxonomy vocabulary. Each tax rule could have various Taxonomy terms that apply (for instance books and food that have the same tax rule here).

guckie’s picture

@com2: Good comments - thanks for sharing your insight! I have a lot of interruptions here today, so I had started my last post before your seeing your post - but finished it after you had posted. Maybe some of my thoughts weren't too far off the mark, considering? I don't have any solid technical (programming/development) skills to apply here... but I hope some dialogue about needs/requirements might help this project. And you've elaborated on some important concerns, so thank you!

gordon’s picture

The current tax module is a bit limited, but does meet most peoples needs.

The biggest problem ATM is the reporting, you just can't.

Following is the way I am going to be laying out the miscellaneous transactions.

mysql> describe ec_transaction_misc;
+-------------+---------------+------+-----+---------+-------+
| Field       | Type          | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+-------+
| txnid       | int(10)       |      | PRI | 0       |       |
| type        | varchar(10)   |      | PRI |         |       |
| nid         | int(10)       |      | PRI | 0       |       |
| description | varchar(255)  |      |     |         |       |
| invisible   | int(2)        |      |     | 0       |       |
| price       | decimal(10,2) |      |     | 0.00    |       |
+-------------+---------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

You will be able to attach a transaction to an individual product, or globally by setting nid = 0. So in the case of tax you will be able to set the following something like

123,TAX,123,GST,0,5.00

I am thinking that in the miscapi I will be able to get the module to accumulate entries or something like this.

Also this method gives complete reporting, and the ballancing of an invoice will be easy, ec_transaction_product + ec_transaction_misc = gross.

Also for things like paypal, we can seach the array for all the tax and shipping transaction to pass.

sime’s picture

Category: bug » feature

removing the bug status seems appropriate. (??)

guckie’s picture

Hey Gordon,

Thanks for outlining this =) Now that I understand this better, I see the value in your planned structure.

Couple of small questions...

Also this method gives complete reporting, and the ballancing of an invoice will be easy, ec_transaction_product + ec_transaction_misc = gross.

I guess this actually means 'ec_transaction_product + (the sum of all) ec_transaction_misc (for the given txn) = gross'? I gather 'misc' will encompass all charges or credits that affect the bottom line for a given product and/or transaction (i.e. shipping, tax, coupon, discount by role, etc.)?

Will tax rules remain globally configurable per region only? Or will there be any provision for specifying tax rules per taxonomy or per product?

Sorry to be so pesky with questions. I'm just embarking on the process of determining shopping cart solutions for two clients.

In one case, e-commerce on drupal simply will not work due to limitations in the tax module. (Client needs to be able to differentiate tax exempt customers, as well as tax exempt products within a given tax class.) I don't think I'll convince this client to invest in their own rewrite of tax.module to do this - not when cubecart (& others) already handle this effectively.

In the other case, I'm secretly hoping that drupal w/ e-commerce will meet their needs, but still have evaluation to do. Their tax purposes are much simpler, but it will be imperative (for them) that they can actually invoice & collect the tax amounts via paypal (currently a show-stopper).

I really am rooting for drupal with e-commerce package to reach 'contender' status among cart applications. It's just not quite there yet (bugs aside). I don't mean to offend. I fully recognize how much energy is/has been going into this collection of modules.

gordon’s picture

I guess this actually means 'ec_transaction_product + (the sum of all) ec_transaction_misc (for the given txn) = gross'? I gather 'misc' will encompass all charges or credits that affect the bottom line for a given product and/or transaction (i.e. shipping, tax, coupon, discount by role, etc.)?

Yes this is correct.

Will tax rules remain globally configurable per region only? Or will there be any provision for specifying tax rules per taxonomy or per product?

At this stage unless someone is going to be developing something. ATM for the tax module doesn't even work properly for Australia, or New Zealand. Currently it only works on products, and not miscelleous transactions such as shipping and shipping which do attract GST.

The tax module actually needs to be the last thing to run when calculating the tax for products and misc transactions. I will be pushing to have the tax flags on each product with a global setting which gives the default.

Tax is a small part of ecommerce, and most of what you want could be put together pretty quickly and look very tidy esp with the new formapi that is comming with 4.7.

I also have some things in the works which will speed up the ecommerce development and collaboration a lot easier, I hope that this will be annouced over the weekend.

Gordon.

solipsist’s picture

I've set up the e-commerce components and after some fiddling and tweaking made it work with my PayPal sandbox accounts. However when the user gets to the checkout screen no tax is calculated despite there being rules for it. With the aforementioned regarding taxes in the EU, I need to be able to add VAT when selling to other Europeans. I have configured the tax rules to add 25% to all payments made by members of other EU countries but like I said, it doesn't calculate it.

Anyhow, is there a working tax module anywhere I can use?

solipsist’s picture

<?php

        //if (product_is_shippable($item->nid)) { */
          $taxable_amount += product_adjust_price($item) * $item->qty;
        // }
?>

Commented that out, like guckie noted, worked. I need to be able to charge tax on file downloads. In the EU, or in Sweden at least, electronic goods are considered services and are subject to VAT.

solipsist’s picture

Actually, that just solved the problem with the checkout screen, the tax is still not sent to PayPal so it's never charged. Does anyone know of a way to do this?

neclimdul’s picture

@gordon Could we have an api or hook that would affect/overide the taxability of an item. For the sake of arguement I'm going to call it an api. For example, we have a product that is know to be globally taxable, but we call the api and module X wants to handle taxing based on the user or the country or whatever. So it handles it and returns false or something.

As for the paypal problem(not passing tax info), I'd say this might be able to handle that too. We could pass the taxable amount as part of the api call and then modules like paypal can grab the information and hold it, use it as needed. This will probably require passing the txn variable by reference similar to the other ec api's.

This is just a brainstorm but it seems to add the flexibility and functionality a lot of people seem to want.

Also, from a curiosity stand point, whats the invisible field do in the db schema you gave.

solipsist’s picture

The PayPal tax issue can be resolved however, and quite simply so, I simply set up regional taxes in my PayPal profile and they get calculated automatically. It works great for my needs. PayPal will also store a record of the transaction including the VAT amount.

ñull’s picture

I would like to add my thoughts about letting Paypal handle Tax:

  • Should the Tax module be written only for Paypal, with their features or should it work with all (future) means of payment? For instance COD module has no tax handling build in and the Paypal module neither. Do you want to rewrite all payment processor module so they will work the same like Paypal?
  • Can you count on Paypal always having this feature?
  • For my situation in Spain, Paypal's Tax handling falls short, since it cannot handle the different Tax groups I mentioned before in this thread and it will not check VAT registration. What might work for you using their tax handling, will not work for others. Paypal's tax feature was made for the US, not for Europe.
  • The whole idea of the Tax module is that it makes us independent of features that might or might not be there in our payment processor. In most means of payment there will be no build-in tax feature or when it is there, it will be insufficiently developed for some of us.
paddywwoof’s picture

Category: feature » bug

I'm not sure what has happened since the above comments in March however I have installed the tax module within the last few weeks and it still seems to have this (line 57) bug in it. At the top of the file it says:
// $Id: tax.module,v 1.16.2.3 2006/06/08 01:27:39 gordon Exp $

It's not easy to find this page using drupal.org search. I had to spend an hour or so figuring out what wasn't working, edit the code so it worked then search for "$taxable_amount" to check if the issue had been raised before!

It is certainly a bug because if you define a tax for all Germans (say) of 1.5 Euros and 15% they only get charge the 1.5 Euros if the sale is for a service. I am not aware of anywhere that defines ALL services as non taxed and ALL goods as taxed!

paddywwoof’s picture

At the final "pay" button PayPal seems to do the right thing with the tax at their end and, although it would be easier to have is listed as a field in the transactions (or better in another table of transactions_tax), it will be possible to generate something from joined transaction-address-tax table to reconstruct what the tax must have been!

However I am more concerned that it seems to be very easy (and obvious even to a non technical user) to change the price and tax on the url as sent to PayPal. I have read some discussion about this somewhere else but can't find it now. Surely it would be better to use POST variables.

deadmalc’s picture

I have to mention this, but it is a common misconseption that using a post is somehow more secure, it is not - plain and simple.
Paypal should provide a mechanism to check that the data being sent has not been modified in transit, if they do not then that is scary.

sime’s picture

Component: tax.module » tax

fixed component

brmassa’s picture

Status: Active » Closed (fixed)

too old issue. feel free to reopen it