There are two ways of applying discounts: pre-tax (sales tax) and post-tax (vat).
If the discount is applied pre-tax, then discount the base price is usually good enough.
But if the discount is applied post-tax, then it needs to take into account all price components.

Right now there is no way to apply discounts to prices w/ VAT directly from rules.
We only ship with a "apply discount to base price" action, there is no action for applying a discount to all components of a price.

Imagine a 12eur product with a VAT 20% tax rate.
12eur = 10eur (base) + 2eur (vat)

You desire to apply a 50% (== 6eur) discount to that price.

Right now, using the existing action, you'd discount the base price only, getting:
6eur = 4eur + 2eur.
The end amount is correct, but the item suddenly has a 50% tax rate :)

The correct way to apply the discount is:
1) If the discount is a percentage, the percentage is applied to each component.
So, 6eur = 10eur (base) + 2eur (vat) - 5eur (base) - 1eur (vat).

2) If the discount is a flat amount, it needs to have the VAT component reverse-calculated
A 6eur discount is 5eur (base) + 1eur (vat).

And then the result is the same as in #1.

So, we need one action for adding a percentage based discount to a price, and another for adding a fixed amount discount to a price.
No need to mention VAT in the action names, it can just be "Apply percentage discount to price" and "Apply fixed amount discount to price"
and it will work normally with sales tax as well (since the sales tax is applied after the discount).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

vasike’s picture

isn't this Commerce Discount 's business?

i think can be achieved easily by changing the weight of the TAX Rules - greater than Discount Rules (which are 0) as they are code defined rules (in commerce_discount.rules_defaults.inc)

other solution is to specify the weight of Discounts Rules in "commerce_discount.rules_defaults.inc"
let's say :

$rule->weight = -10;

What about having for Taxes a Rules approach as for Discounts?
In that way maybe we can control de Pricing Rules Order?

matsjacobsson’s picture

I have the same problem as well. Haven't tried the discount module yet but it would definetely be great if this could be done with rules in some way. Setting the weight for the VAT in the product pricing rules doesn't do the trick unfortunate...

GiorgosK’s picture

I came here from #1784908: Add a setting to use base price or full price for all percentage offers discount types
anybody has any progress on such rules

any planned date for this (discounts are really not usable in this state)

EDIT: this issue comment #8 offers a solution that might be useful #1819782: Discounted price not used in tax calculation

bojanz’s picture

For reference, there's a sandbox that seems to have the same goals:
http://drupal.org/sandbox/iMiksu/1871090

So that code could at least be used as a reference for fixing this issue.

GiorgosK’s picture

so far iMiksu's project is unusable (only has an .info file), will wait for update to test it

iMiksu’s picture

Checkout the 7.x-1.x branch, which should contain the module.

iMiksu’s picture

My idea for the sandbox came from a though that what if the percentage discount would affect on base_price + tax rate at the same time. Does it make any sense to you guys?

The sandbox project however deals with tax rate only and then uses the difference amount again to put the price back in place as "VAT discount regression"..

pcambra’s picture

Assigned: Unassigned » pcambra
Status: Active » Needs review
FileSize
9.25 KB

Clarifying comment in #1 you can actually set the discount (all of them) to a lower weight than the taxes calculation if you're not using including VAT feature, that would give you the right results, but for including VAT, that's simply not ok as the tax is already there.

The patch attached adds two actions (maybe line item module is not the perfect location for it):

  • commerce_line_item_apply_percentage_discount: Accepts a percentage and applies it to the line item, in the line of iMiksu one, but instead of creating a new price component that is listed, it adds a negative amount to the taxes reusing the same taxes component.
  • commerce_line_item_apply_fixed_discount: This one is a little more tricky, as for what taxes is worth for a fixed discount, it can be applied before taxes (excluding) or after taxes (including) giving two different results. In the end this is translated in a percentage that reuses the logic of the first action and adds the same component.

What I don't know is if we should update weights on our default rules to somehow force taxes to happen always before discounts as they might happen afterwards occasionally, as Rules might chose one or the other as all have weight 0.

_paul’s picture

pcambra's fix works perfectly for me.

I override my own discount rule with one of those created by #8 patch and my discount problem is now fixed.

Thanks again ! <3

rszrama’s picture

Category: task » feature
Status: Needs review » Needs work

I haven't fully tested everything in this, but I've hit enough to hold off further review. We'll just have to go for this after the Commerce 1.6 release.

  1. I think using the Commerce Line Item group is fine, but we should stick with specifying the "unit price" not just the "price" as the target of the action (e.g. "Apply a percentage discount to the unit price"). We might even go so far as to indicate this is happening to all price components (e.g. "Apply a percentage discount to unit price components")... but that may be too much information.
  2. Instead of accepting input in percentage format, this action should accept input in decimal format like the tax rate form does. It won't do us any favors to have two different input methods for percentages.
  3. If you use the percentage discount on a product with sales tax - i.e. the tax type that does not include its components in the price amount value, just in the components array - the action creates the negative tax component marked as included in the price amount already. This is incorrect - I went from a $10 product with tax as a hidden .60 price component to a 50% discounted product at $5.30. The function that creates new price components for these discounts ought to use the same "included" value for the new components.
  4. Additionally, this function should be a "public" API function - no underscore prefix needed. It's the real meat of the operation and should be dependable for anyone wanting to use it in their module code.
pcambra’s picture

Priority: Major » Normal
Status: Needs work » Needs review
FileSize
9.56 KB

Here's another take, I've reworded a little the event names and "upgraded" the function to apply a discount rate to the main module, also changed the format to accept decimals. (points 1,2,4).

About 3, not sure what's the issue there, some screenshots/examples would help, I changed the included setting to match the original component one though.

rszrama’s picture

I don't have a screenie handy, but if you updated it like you said, then you've fixed the issue. The idea was with sales tax, the product page would show me the price excluding tax. But if I used a discount action from the previous patch, the page would suddenly start showing me prices including tax.

Horroshow’s picture

Tried it but there's no data selector I can use.

Kiampp’s picture

The patch from #11 works for me. Taxes are displayed correctly for the couple of items that I tried it with.
It also showed the amount of discount that I got in checkout screen, but that number was not correct. It was lower then it should be and that probably also has something to do with taxes. But I just turned it off (selected base amount instead of discount) and then everything that it shows is fine.

jkuma’s picture

zambrey’s picture

I tested only using direct call to commerce_line_item_apply_discount_rate() function and it works fine for included tax. Thanks.
There is one problem though. There is no easy way to delete discounted price because one should also delete taxed discount and they are not connected in component array.

dwkitchen’s picture

Status: Needs review » Needs work

This function has a dependency on Commerce Tax which has not been added.

Specifically this is only needed to apply a fixed price discount to a line item when the price has been entered including tax. This is directly only related to anyone using Commerce Tax for VAT and perhaps belongs in that module rather than in line item.

As has been said when entering the price excluding VAT and using rules to calculate the VAT there is no need for this functionality. This does however mean the merchant has to enter the discount as an excluding VAT amount which could be confusing.

I would also be worried about rounding issues as after rounding the individual components they may not ad up to the original total.

pcambra’s picture

Assigned: pcambra » Unassigned
amillionmonkeys’s picture

Hi there,
Can I just clarify, should I need to do anything to make this patch work? Or should it simply replace the way the discount module currently works?

I've tried just applying the patch, but it doesn't seem to be making any difference.

Thanks

Phil

amillionmonkeys’s picture

I need this to work for a client so, in case anyone is in the same bag I just want to let you know how I've resolved I'm going to build a workaround while people much cleverer than I make this work as it should. I've tested locally and it seems to be working. Essentially I've disabled the tax module and removed any tax configuration options. Each product now has a boolean value associated with it indicated whether or not the product is taxable. Each line up item type has a new field added labeled tax due. I've set up a rule that, on completion of the checkout process loops through lineup items, checks whether the associated product is taxable and if so multiplies the total of the line item by the standard tax rate.

I've had to adjust a few views, but this seems to be working. Hope this helps someone. Happy to post more details if anyone else is struggling with the same issue.

L5’s picture

Hi amillionmonkeys, I'm interested in your solution. Can you post more details?

marktheshark’s picture

Same issue here, any plans to incorporate this option (pre / post sale as base for discount) into the module?

sibiru’s picture

I have custom discount pricing rule here

{ "rules_discount_from_field" : {
    "LABEL" : "Discount from Field",
    "PLUGIN" : "reaction rule",
    "WEIGHT" : "2",
    "REQUIRES" : [ "rules", "commerce_line_item", "commerce_product_reference" ],
    "ON" : [ "commerce_product_calculate_sell_price" ],
    "IF" : [
      { "entity_has_field" : { "entity" : [ "commerce-line-item" ], "field" : "commerce_product" } },
      { "entity_has_field" : {
          "entity" : [ "commerce-line-item:commerce-product" ],
          "field" : "field_discount"
        }
      },
      { "NOT data_is_empty" : { "data" : [ "commerce-line-item:commerce-product:field-discount" ] } }
    ],
    "DO" : [
      { "variable_add" : {
          "USING" : { "type" : "decimal", "value" : "1" },
          "PROVIDE" : { "variable_added" : { "max_discount" : "Max Discount" } }
        }
      },
      { "data_calc" : {
          "USING" : {
            "input_1" : [ "max-discount" ],
            "op" : "-",
            "input_2" : [ "commerce-line-item:commerce-product:field-discount" ]
          },
          "PROVIDE" : { "result" : { "discount_multiplier" : "Discount Multiplier" } }
        }
      },
      { "commerce_line_item_unit_price_multiply" : {
          "commerce_line_item" : [ "commerce_line_item" ],
          "amount" : [ "discount-multiplier" ],
          "component_name" : "discount",
          "round_mode" : "0"
        }
      }
    ]
  }
}

Default VAT pricing rule, weight 0

{ "commerce_tax_type_vat" : {
    "LABEL" : "Calculate taxes: VAT",
    "PLUGIN" : "reaction rule",
    "TAGS" : [ "Commerce Tax" ],
    "REQUIRES" : [ "commerce_tax", "commerce_product_reference" ],
    "ON" : [ "commerce_product_calculate_sell_price" ],
    "DO" : [
      { "commerce_tax_calculate_by_type" : {
          "commerce_line_item" : [ "commerce-line-item" ],
          "tax_type_name" : "vat"
        }
      }
    ]
  }
}

Calcualtion product page, im using RPP price
Pris 14 625,00 kr. (Price)
Tilbudspris 9 506,25 kr. (Discounted Price)

Calculation on the cart

Price Quantity Remove Total
Daikin FTXS20K standart
Price: 9 506,25 kr.
9 506,25 kr.

9 506,25 kr.
Subtotal 6 581,25 kr.
Discount -5 118,75 kr.
25% VAT 2 925,00 kr.
Order total 9 506,25 kr.

If I change VAT weight greater than Custom Discount pricing rules
On product page
Pris 13 601,25 kr. (Price)
Tilbudspris 9 506,25 kr. (Discounted Price)

On shopping cart
Price Quantity Remove Total
Daikin FTXS20K standart
Price: 9 506,25 kr.
9 506,25 kr.

9 506,25 kr.
Subtotal 7 605,00 kr.
Discount -4 095,00 kr.
25% VAT 1 901,25 kr.
Order total 9 506,25 kr.

The product base price 11700 kr

How should the correct calculation ?
Could anyone help fix this?

Thanks

majusz’s picture

I also tried the promising patch in #11 to solve the problem, but there's the same issue for me as for #13 - the new actions show up in the Rules UI, but if I select it, the data selector for the next step is missing.

This is a really serious issue for our shop, and it's the same problem for both discounts and coupons - the VAT shown in the cart overview and later in the invoice is simply wrong because it's calculated without subtracting the amount of the coupon or discount.

It's probably related to the following issue, but unfortunately I lack deeper understanding of the commerce tax system to see a way of fixing it: https://drupal.org/node/1612662

Does anybody know of any plans to get patch #11 working and into the module?

steveoriol’s picture

For me the patch #11 is working well.

I use it with the great "commerce_discount" module to generate the discount rules.
After, I have just to replace the "Action" element of the associated rule by the new #11's action one:

"% off" => "Add a percentage discount to unit price"
and
"$ off" => "Add a fixed amount discount to unit price"

The really cool think, will be to add this 2 new actions in the "admin/commerce/store/discounts/add" page, so we will not have to overriden the associated rule.

Note: I have to include the TVA in setting of the product (that I prefert anyway) to have the right % of save with the using of the "commerce_price_savings_formatter" module.

jkuma’s picture

Hi steveoriol,

Thanks for using commerce_discount! I've posted a patch to solve this long time issue [#https://drupal.org/node/1962484]. May you have a look at it? thanks in advance, jo

steveoriol’s picture

FileSize
150.53 KB

Hello Jonathan,

Either with normal or development versions of the modules "commerce_discount" (patched) and "inline_conditions"
the VAT of each command item line is not recalculate, or at least I do not see it changed ...
I have probably forgotten to do something important to run the things, but what ?
I really need to make this module work, if I can not I will choose the solution # 11.
It is much less convenient but works (see the shot).
commerce_discount + #11

geek-merlin’s picture

geek-merlin’s picture

This might be on the wrong track. See #2276227: [META] Use order discount with VAT for a potential fix.

HenrikBak’s picture

I just implemented the patch from #11 and updated my discount rules and it solved my problem. Remember to clear the cache after applying the patch.

GoddamnNoise’s picture

Hi,

The patch from #11 seems to solve the problem with a discount, but it doesn't work when using coupons. If the discount is associated to a coupon and you change the action of the rule by the one in #11, when you try to apply the coupon, you always get an "Unable to redeem coupon" error and the coupon and the discount are not applied.

I've been digging into the coupon and discount modules code, but i couldn't find a way to make it work. Any ideas?.

caw67’s picture

patch11 poesnt work. htere is no dsicount calculated

diriy’s picture

Priority: Normal » Critical

subscribed

rszrama’s picture

Priority: Critical » Normal

Feature requests are seldom critical. Please refer to: https://www.drupal.org/node/45111

7thkey’s picture

Could be this issue also be related?
https://www.drupal.org/node/2655094
Product with dynamic prices (with included VAT) like bookings/auctions, setting the price with rules "Calculating the sell price of a product" does not calculate the VAT correctly (it looks like VAT is calculating the old value of product instead of the new value...).

I am not sure that #11 will fix the problem because this is not a discount/coupon module related.
Any ideas?