--- uc_coupon.module	24 Feb 2009 03:03:06 -0000	1.18.2.3
+++ uc_coupon.module	6 Mar 2009 01:27:27 -0000
@@ -435,6 +435,13 @@ function uc_coupon_validate($code) {
   if ($coupon_data) {
     $coupon_result->valid = FALSE;
 
+    if (module_exists('uc_taxes')) {
+      $taxes = uc_taxes_get_rates();
+    }
+    else {
+      $taxes = array();
+    }
+
     if ($coupon_data->products) {
       // Product coupons apply to the subtotal and quantity of matching products.
       $coupon_products = explode(',', $coupon_data->products);
@@ -443,6 +450,16 @@ function uc_coupon_validate($code) {
         if (in_array($item->nid, $coupon_products)) {
           $applicable_total += $item->price * $item->qty;
           $applicable_qty += $item->qty;
+
+          // Calculate per-tax applicable total of matching products.
+          if ($taxes) {
+            $node = node_load($item->nid);
+            foreach ($taxes as $tax) {
+              if (in_array($node->type, $tax->taxed_product_types)) {
+                $taxable_total[$tax->id] += $item->price * $item->qty;
+              }
+            }
+          }
         }
       }
     }
@@ -450,7 +467,18 @@ function uc_coupon_validate($code) {
       // Standard coupons apply once to the whole cart.
       foreach (uc_cart_get_contents() as $item) {
         $cart_total += $item->price * $item->qty;
+
+        // Calculate per-tax product totals.
+        if ($taxes) {
+          $node = node_load($item->nid);
+          foreach ($taxes as $tax) {
+            if (in_array($node->type, $tax->taxed_product_types)) {
+              $taxable_total[$tax->id] += $item->price * $item->qty;
+            }
+          }
+        }
       }
+
       $applicable_total = $cart_total;
       $applicable_qty = 1;
     }
@@ -513,6 +541,18 @@ function uc_coupon_validate($code) {
     else if ($coupon_data->type == 'price') {
       $coupon_result->amount = min($applicable_total, $applicable_qty * $coupon_data->value);
     }
+
+    // Calculate taxable coupon subtotals proportional to the full applicable total of the coupon.
+    foreach ($taxes as $tax) {
+      $tax_subtotal = $coupon_result->amount * ($taxable_total[$tax->id] / $applicable_total);
+      if ($tax_subtotal > 0) {
+        $coupon_result->taxable[] = array(
+          'id' => 'coupon_tax_'. $tax->id,
+          'title' => t('Coupon subtotal with @tax', array('@tax' => $tax->name)),
+          'amount' => $tax_subtotal,
+        );
+      }
+    }
   }
   else {
     // The coupon was not found, inactive, or is expired in the list of coupons
@@ -592,6 +632,18 @@ function uc_checkout_pane_coupon($op, &$
           db_query("INSERT INTO {uc_coupons_orders} (cid, oid, code, value) VALUES (%d, %d, '%s', %f)", $coupon->cid, $arg1->order_id, $coupon->code, $coupon->amount);
           uc_order_line_item_add($arg1->order_id, 'coupon', $coupon->title, -$coupon->amount);
         }
+
+        if (is_array($coupon->taxable)) {
+          foreach ($coupon->taxable as $tax_item) {
+            $lid = db_result(db_query("SELECT line_item_id FROM {uc_order_line_items} WHERE order_id = %d AND type = '%s'", $arg1->order_id, $tax_item['id']));
+            if ($lid) {
+              uc_order_update_line_item($lid, $tax_item['title'], -$tax_item['amount']);
+            }
+            else {
+              uc_order_line_item_add($arg1->order_id, $tax_item['id'], $tax_item['title'], -$tax_item['amount']);
+            }
+          }
+        }
       }
       return TRUE;
 
@@ -635,6 +687,21 @@ function uc_coupon_line_item() {
     'add_list' => TRUE,
     'calculated' => TRUE,
   );
+
+  if (module_exists('uc_taxes')) {
+    foreach (uc_taxes_get_rates() as $tax) {
+      $items[] = array(
+        'id' => 'coupon_tax_'. $tax->id,
+        'title' => t('Coupon subtotal with @tax', array('@tax' => $tax->name)),
+        'weight' => 8,
+        'default' => FALSE,
+        'stored' => TRUE,
+        'add_list' => FALSE,
+        'calculated' => FALSE,
+      );
+    }
+  }
+
   return $items;
 }
 
