Drupal Commerce: Apply taxes after discount

Drupal Commerce is an open source eCommerce framework. This tutorial fixes the VAT + Sale Prices problem for Checkout and Commerce Email.

Drupal Commerce is an open source eCommerce framework. We have used it for many web stores, but never tried to use it with Commerce Sale Price. Drupal Commerce is not able to calculate the taxes correctly if there are discounts available. It calculates the taxes of the original total, but taxes should apply to SUBTOTAL minus DISCOUNT.

Drupal Views allowed to only modify the line item section and not the summary below it. There were many threads in Internet, but we did not find any working patch for this problem, so we had to develop own solution to the problem. All products have VAT +24% included.

Create Global: PHP to Commerce Cart Summary's footer (/admin/structure/views/view/commerce_cart_summary/edit/default). Only thing what we need to know is Commerce Order ID, and that can be taken from URL with $_GET. Put the code below to PHP area and save the View.

<?php
// @author: Timo Anttila (info@tuspe.com)
$q = explode('/', $_GET['q']);
$order = commerce_order_load($q[1]);
$subtotal = $order->commerce_order_total['und'][0]['data']['components'][0]['price']['amount'];
$subtotal = ($subtotal / 100) * 1.24;
$discount = $order->commerce_order_total['und'][0]['data']['components'][1]['price']['amount'];

if ($discount > 0) { $shipping = $shipping; $discount = 0; }
else {
$discount = ($discount / 100) * -1;
$shipping = $order->commerce_order_total['und'][0]['data']['components'][2]['price']['amount'];
}

$total = $subtotal - $discount;
$without_vat = $total / 1.24;
$vat = $total - $without_vat;
?>

With print_r($order) you can find all the variables available.

First, get the Order ID from URL and use it to find a right order from commerce_order_load. Use right prices and calculate right subtotal. $subtotal is subtotal without VAT and decimals, so first we must divide that by 100. Then 1.24 times subtotal is the right total sum to work with.

If you want to use shipping price with discounts and VAT, then you must check if the product have a discount or not. Drupal uses $order->commerce_order_total ['und'][0]['data']['components'][1]['price']['amount'] for both discount and shipping price depending on the situation. The code above checks if the price is negative or not. The discount price is always negative, so that's the easiest way to make sure if that is discounted amount or not.

The discount must be positive number after check so: ($discount / 100) * -1.

The order total is subtotal minus discount, VAT is subtotal minus $without_vat.

Subtotal <?php echo $subtotal; ?> €.
Discount <?php echo $discount; ?> €.
VAT 24% <?php echo $vat; ?> €
Shipping <?php echo $shipping; ?> €
Order total <?php echo $total;?> €

The code above prints all the necessary information to screen. You can customize it as you like. Disable Drupal Commerce's Order Total from Checkout Views footer.

You can use the same code for Commerce Email (commerce_email).

This is not working with Coupons, and if client using reports from Paytrail or Checkout, there will be wrong numbers still. This only makes buying customer see the numbers right.

Tested on Drupal 7 and Drupal Commerce 7.x-1.13.
Big thanks for Joonas from Comspot for helping me out.