You are here

function commerce_vat_rate_apply in Commerce VAT 7

Applies a vat rate to the unit price of a line item.

Parameters

$vat_rate: The vat rate to apply to the line item.

$line_item: The line item whose unit price will be modified to include the vat.

int|null $amount: Only for proportional VAT calculation: The unit price amount to calculate the vat for. Defaults to unit price amount of line item.

Return value

A price array representing the vat applied to the line item or FALSE if none was applied.

1 call to commerce_vat_rate_apply()
commerce_vat_rate_rules_apply in ./commerce_vat.rules.inc
Rules action: loads and applies a vat rate to the given line item.
1 string reference to 'commerce_vat_rate_apply'
commerce_vat_default_rules_configuration in ./commerce_vat.rules_defaults.inc
Implements hook_default_rules_configuration().

File

./commerce_vat.module, line 301
Defines VAT rates and Rules integration for configuring vat rules for applicability and display.

Code

function commerce_vat_rate_apply($vat_rate, $line_item, $amount = NULL) {
  $wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
  if ($wrapper->order->created
    ->value()) {
    $order_date = $wrapper->order->created
      ->value();
  }
  else {
    $order_date = time();
  }
  foreach ($vat_rate['rates'] as $rate) {
    if (strtotime($rate['start']) < $order_date) {
      $rate_info = $rate;
      break;
    }
  }

  // If a valid rate is specified...
  if (isset($rate_info['rate']) && is_numeric($rate_info['rate'])) {

    // Don't apply vat if the unit price has a NULL amount.
    if (is_null($wrapper->commerce_unit_price
      ->value())) {
      return;
    }

    // Invoke the vat rate's calculation callback and apply the returned vat
    // price to the line item.
    if ($vat_price = $vat_rate['calculation_callback']($vat_rate, $rate_info, $wrapper, $amount)) {

      // Add the vat to the unit price's data array along with a display inclusive
      // property used to track whether or not the vat is included in the price.
      $included = FALSE;
      $direction = variable_get('commerce_vat_direction', 'forward');
      if ($direction == 'reverse') {
        $data = $wrapper->commerce_unit_price->data
          ->value();
        $amount = $wrapper->commerce_unit_price->amount
          ->value();

        // For 0 amount line items the VAT is also 0.
        if ($amount == 0) {
          return;
        }

        // Reduce components proportionally.
        $amount_to_reduce_total = $vat_price['amount'];
        $amount_to_reduce_left = $vat_price['amount'];
        $nonzero_components = array();
        foreach ($data['components'] as &$component) {

          // Do not apply vat on vat components.
          if (strpos($component['name'], 'vat') === 0) {
            continue;
          }
          if ($component['price']['amount']) {
            $nonzero_components[] =& $component;
          }
          $amount_to_reduce_current = commerce_vat_rate_round_amount($component['price']['amount'] / $amount * $amount_to_reduce_total, $vat_price['currency_code']);
          $component['price']['amount'] -= $amount_to_reduce_current;
          $amount_to_reduce_left -= $amount_to_reduce_current;
        }

        // Change components only if there was a nonzero-one.
        if (!empty($nonzero_components)) {

          // Remaining rounding difference deliberately reduces first nonzero component.
          $nonzero_components[0]['price']['amount'] -= $amount_to_reduce_left;
          $wrapper->commerce_unit_price->data = $data;
          $included = TRUE;
        }
      }
      else {

        // Include the vat amount in the displayed unit price.
        $wrapper->commerce_unit_price->amount = $wrapper->commerce_unit_price->amount
          ->value() + $vat_price['amount'];
        $included = TRUE;
      }

      // Update the data array with the vat component.
      $wrapper->commerce_unit_price->data = commerce_price_component_add($wrapper->commerce_unit_price
        ->value(), $vat_rate['price_component'] . '|' . $rate_info['name'], $vat_price, $included);
      return $vat_price;
    }
  }
  return FALSE;
}