--- uc_vat.module	2010-10-04 20:40:18.628056800 +0200
+++ uc_vat.moduleN	2010-10-04 20:37:44.613417500 +0200
@@ -443,6 +443,47 @@ function uc_vat_order($op, $arg1, $arg2)
         $data['taxes'] = uc_vat_load_taxes($arg1, user_load($arg1->uid));
         db_query("UPDATE {uc_orders} SET data = '%s' WHERE order_id = %d", serialize($data), $arg1->order_id);
       }
+      if (variable_get('uc_vat_calculate_shipping_taxes', FALSE)) {
+        // save recalculated taxes with shipping
+        $shipping        = FALSE;
+        $shipping_costs  = 0;
+        $order_subtotal  = 0;
+        $shipping_wo_tax = FALSE;
+        $shipping_tax    = 0;
+
+        foreach ($arg1->line_items as $ind => $item) {
+          if ($item['type'] == 'shipping') {
+            $shipping = TRUE;
+            $shipping_costs = $item['amount'];
+            $shipping_lineitem = $item['line_item_id'];
+          }
+          $order_subtotal = $arg1->order_total;
+          if ($item['type'] == 'tax' && $shipping == TRUE) {
+            $tmp_amount = $shipping_costs * (($item['data']['taxable_amount'] + $item['amount']) / $order_subtotal);
+            $tax_amount = $tmp_amount * ($item['data']['tax_rate'] / (1 + $item['data']['tax_rate']));
+            $amount     = $arg1->line_items[$ind]['amount'] + $tax_amount;
+            $shipping_tax += $tax_amount;
+            uc_order_update_line_item($item['line_item_id'], $item['title'], $amount, $data = NULL);
+          }
+          if ($item['type'] == 'shipping_wo_vat') {
+            $shipping_wo_tax = TRUE;
+          }
+
+        }
+        
+        if ($shipping_wo_tax == TRUE) {
+            //uc_order_update_line_item($shipping_lineitem, t("Shipping inclusive of VAT"), $amount, $data = NULL);
+            db_query("UPDATE {uc_order_line_items} SET weight = 2 WHERE line_item_id = %d", $shipping_lineitem);
+            // see uc_order.line_item.inc
+          }
+        // add additional line item shipping w/o tax
+        if (variable_get('uc_vat_show_shipping_wo_tax', FALSE) && $shipping_wo_tax == FALSE) {
+          uc_order_line_item_add($arg1->order_id, 'shipping_wo_vat', t('Shipping cost excluding VAT'), $shipping_costs - $shipping_tax, $weight=1, $data = NULL);
+          //weight does not work in function,  so
+          $vat_line_id= db_fetch_object(db_query("SELECT MAX(line_item_id) from uc_order_line_items WHERE type='shipping_wo_vat'"));
+          db_query("UPDATE {uc_order_line_items} SET weight = 1 WHERE line_item_id = %d", $vat_line_id);
+        }
+      }
   }
 }
 
@@ -680,12 +721,41 @@ function uc_vat_line_item_tax_subtotal($
     }
   }
   if (is_array($order->line_items)) {
+    // get shipping costs
+    foreach ($order->line_items as $key => $line_item) {
+      if ($line_item['type'] == 'shipping') {
+        $shipping = TRUE;
+        $shipping_costs = $line_item['amount'];
+      }
+    }
+    //get taxes
+    $taxes_order    = uc_taxes_calculate($order);
+    $order_subtotal = 0;
+    $shipping_tax   = 0;
+    //get subtotal w/o taxes
+    foreach ($taxes_order as $id => $tax) {
+      $order_subtotal += $tax->data['taxable_amount'] + $tax->amount;
+    }
+    //get shipping taxes
+    foreach ($taxes_order as $id => $tax) {
+      // calculate shipping tax proportionally
+      $tmp_amount = $shipping_costs * (($tax->data['taxable_amount'] + $tax->amount) / $order_subtotal);
+      $shipping_tax += $tmp_amount * ($tax->data['tax_rate'] / (1 + $tax->data['tax_rate']));
+    }
     foreach ($order->line_items as $key => $line_item) {
       if ($line_item['type'] == 'tax') {
         $has_taxes = TRUE;
       }
-      if (_line_item_data($line_item['type'], 'calculated') == TRUE) {
-        $amount += $line_item['amount'];
+      if (variable_get('uc_vat_calculate_shipping_taxes', FALSE) ) {
+        // calculate subtotal w/o shipping tax
+        if (_line_item_data($line_item['type'], 'calculated') == TRUE && $shipping_tax > 0) {
+          $amount += ($shipping_costs - $shipping_tax);
+        }
+      }
+      else {
+        if (_line_item_data($line_item['type'], 'calculated') == TRUE) {
+          $amount += $line_item['amount'];
+        }
       }
     }
   }
@@ -739,6 +809,42 @@ function uc_vat_uc_taxes_javascript() {
         $taxes[$id]->name = t('incl. !tax', array('!tax' => $tax->name));
       }
     }
+    // proportional shipping tax calculation
+    if (variable_get('uc_vat_calculate_shipping_taxes', FALSE)) {
+      // you cannot loop through taxes > causes recursion
+      $taxes_n        = $taxes;
+      $shipping_tax   = 0;
+      $order_subtotal = 0;
+      $shipping       = FALSE;
+      $shipping_costs = 0;
+      $shipping_taxes = array();
+      // get shipping costs
+      foreach ($order->line_items as $item) {
+        if ($item['type'] == 'shipping') {
+          $shipping       = TRUE;
+          $shipping_costs = $item['amount'];
+          $shipping_title = $item['title'];
+        }
+        if ($item['type'] == 'subtotal') {
+          $order_subtotal = $item['amount'];
+        }
+      }
+      // tax recalculate - with shipping
+      if ($shipping == TRUE) {
+        foreach ($order->taxes as $id => $tax) {
+          // calculate shipping tax proportionally
+          $tmp_amount = $shipping_costs * (($tax->data['taxable_amount'] + $tax->amount) / $order_subtotal);
+          $shipping_taxes[$id] = $tmp_amount * ($tax->data['tax_rate'] / (1 + $tax->data['tax_rate']));
+          $shipping_tax += $shipping_taxes[$id];
+          foreach ($taxes_n as $ind => $tax1) {
+            if ($tax1->id == $id) {
+              $taxes[$ind]->amount += $shipping_taxes[$id];
+            }
+          }
+        }
+      }
+    }
+    // end of shippig tax calc
 
     $callback = _line_item_data('tax_subtotal', 'callback');
     if (function_exists($callback)) {
@@ -754,6 +860,18 @@ function uc_vat_uc_taxes_javascript() {
       }
     }
   }
+  // show shipping costs w/o taxes on payment form (pane)
+  if (variable_get('uc_vat_show_shipping_wo_tax', FALSE)) {
+    if ($shipping_costs > 0) {
+      $taxes['shipping'] = (object)array(
+        'id' => 'test',
+        'name' => t('Shipping cost without VAT'),
+        'amount' => $shipping_costs - $shipping_tax,
+        'weight' => -130,
+        'summed' => 0,
+      );
+    }
+  }
   drupal_json((array) $taxes);
 }
 
@@ -764,7 +882,7 @@ function uc_vat_cart_pane_alter(&$panes)
   if (uc_cart_is_shippable() && variable_get('uc_vat_suffix_shipping', FALSE)) {
     foreach ($panes as &$pane) {
       if ($pane['id'] == 'cart_form') {
-        $pane['body'] = str_replace('<div id="cart-form-buttons">', theme('uc_vat_excluding_shipping_costs', 'div') . '<div id="cart-form-buttons">', $pane['body']);
+        $pane['body'] = str_replace('<div id="cart-form-buttons">', theme('uc_vat_excluding_shipping_costs', 'div') .'<div id="cart-form-buttons">', $pane['body']);
       }
     }
   }
@@ -881,6 +999,20 @@ function uc_checkout_pane_cart_vat($op,
       return array('contents' => $contents, 'next-button' => FALSE);
 
     case 'review':
+      if (variable_get('uc_vat_calculate_shipping_taxes', FALSE)) {
+        $tax_amount = 0;
+        foreach ($arg1->line_items as $ind => $item) {
+          if ($item['type'] == 'tax') {
+            $tax_amount += $item['amount'];
+          }
+        }
+        // calculate subtotal
+        foreach ($arg1->line_items as $ind => $item) {
+          if ($item['type'] == 'tax_subtotal') {
+            $arg1->line_items[$ind]['amount'] = $arg1->order_total - $tax_amount;
+          }
+        }
+      }
       $output = '<table>';
       $context = array(
         'revision' => 'themed',
@@ -899,8 +1031,7 @@ function uc_checkout_pane_cart_vat($op,
           'product' => $item,
           'node' => node_load($item->nid),
         );
-        $output .= '<tr valign="top"><td>'. $item->qty .'&times;</td><td width="100%">'. $desc
-                  .'</td><td nowrap="nowrap">'. uc_price($price_info, $context) .'</td></tr>';
+        $output .= '<tr valign="top"><td>'. $item->qty .'&times;</td><td width="100%">'. $desc .'</td><td nowrap="nowrap">'. uc_price($price_info, $context) .'</td></tr>';
       }
       $output .= '</table>';
       $review[] = $output;
@@ -980,3 +1111,4 @@ function uc_vat_views_handlers() {
     ),
   );
 }
+
