diff --git a/uc_vat/uc_vat.module b/uc_vat/uc_vat.module index 0259e46..7112cb9 100644 --- a/uc_vat/uc_vat.module +++ b/uc_vat/uc_vat.module @@ -1,5 +1,4 @@ data['taxes'])) { // Use stored tax rates from an existing order if available. $tax_rates = $context['subject']['order']->data['taxes']; @@ -632,7 +634,7 @@ function uc_vat_line_item_price_alter(&$price, &$context, &$options, $tax_rates) foreach ($tax_rates as $tax_rate) { // Special handling for modules that provide their own tax adjustments. $callback = _line_item_data($line_item['type'], 'tax_adjustment'); - if (variable_get('uc_vat_line_item_adjustment', FALSE) && $callback && function_exists($callback)) { + if ($callback && function_exists($callback)) { $price['price'] += $callback($line_item['amount'], $order, $tax_rate); } else { @@ -678,9 +680,7 @@ function uc_vat_line_item_data_alter(&$items) { case 'tax': // Allow per-line item tax adjustments. - if (variable_get('uc_vat_line_item_adjustment', FALSE)) { - $item['callback'] = 'uc_vat_line_item_tax'; - } + $item['callback'] = 'uc_vat_line_item_tax'; // Tax amounts are added in to other line items, so the actual tax line // items should not be added to the order total - unless VAT is excluded @@ -786,6 +786,18 @@ function uc_vat_line_item_tax($op, $order) { } /** +* Implements hook_calculate_tax() +*/ +function uc_vat_calculate_tax($order) { + $taxes = uc_taxes_calculate_tax(drupal_clone($order)); + $vats = uc_vat_calculate_vat($order); + foreach (array_keys($vats) as $id) { + $vats[$id]->amount -= $taxes[$id]->amount; + } + return $vats; +} + +/** * Calculate all taxes on an order using VAT rules. * * @see uc_taxes_calculate_tax() @@ -875,7 +887,10 @@ function uc_vat_apply_tax($order, $tax) { $taxable_amount = 0; if (is_array($order->products)) { foreach ($order->products as $item) { - $taxable_amount += uc_taxes_apply_item_tax($item, $tax); + // We call our own function for applying taxes here, because we don't want to calculate a tax + // based on a price altered by this module. If we don't do this, the calculated tax will be + // based on a price inclusive tax. + $taxable_amount += uc_vat_uc_taxes_apply_item_tax($item, $tax); } } $taxed_line_items = $tax->taxed_line_items; @@ -923,6 +938,51 @@ function uc_vat_apply_tax($order, $tax) { } /** + * Calculates tax for a single product. + * + * This function is similar to uc_taxes_apply_item_tax(), but with one difference: + * It set's an option called uc_vat to FALSE which means to this module that any + * price altering by this module should be canceled. + * If this module *does* do a price alter when applying taxes, then the tax amount + * will be based on the tax inclusive price. And taxes should be based on the tax + * *exclusive* price of course! + * + * @param object $item + * @param object $tax + * @return float + */ +function uc_vat_uc_taxes_apply_item_tax($item, $tax) { + $node = node_load($item->nid); + + // Special handling for manually added "Blank line" products. + if (!$node) { + $node = new stdClass(); + $node->type = 'blank-line'; + $node->shippable = $item->weight > 0; + } + + // Tax products if they are of a taxed type and if it is shippable if + // the tax only applies to shippable products. + if (in_array($node->type, $tax->taxed_product_types) && ($tax->shippable == 0 || $node->shippable == 1)) { + $context = array( + 'revision' => 'altered', + 'type' => 'cart_item', + 'subject' => array( + 'cart_item' => $item, + 'node' => $item->nid ? $node : FALSE, + ), + ); + $price_info = array( + 'price' => $item->price, + 'qty' => $item->qty, + ); + + // Calculate price, but bypass any alterations normally done in uc_vat. + return uc_price($price_info, $context, $options = array('uc_vat' => FALSE)); + } +} + +/** * Callback for "subtotal excluding VAT" line item. */ function uc_vat_line_item_tax_subtotal($op, $order) { @@ -1229,7 +1289,7 @@ function uc_vat_uc_payment_get_totals() { uc_payment_get_totals(); exit; } - + $order = unserialize($_POST['order']); if (!$order) { return '';