You are here

protected function EuropeanUnionVat::resolveZones in Commerce Core 8.2

Resolves the tax zones for the given order item and customer profile.

Parameters

\Drupal\commerce_order\Entity\OrderItemInterface $order_item: The order item.

\Drupal\profile\Entity\ProfileInterface $customer_profile: The customer profile. Contains the address and tax number.

Return value

\Drupal\commerce_tax\TaxZone[] The tax zones.

Overrides LocalTaxTypeBase::resolveZones

File

modules/tax/src/Plugin/Commerce/TaxType/EuropeanUnionVat.php, line 39

Class

EuropeanUnionVat
Provides the European Union VAT tax type.

Namespace

Drupal\commerce_tax\Plugin\Commerce\TaxType

Code

protected function resolveZones(OrderItemInterface $order_item, ProfileInterface $customer_profile) {
  $zones = $this
    ->getZones();

  /** @var \Drupal\address\AddressInterface $customer_address */
  $customer_address = $customer_profile
    ->get('address')
    ->first();
  $customer_country = $customer_address
    ->getCountryCode();
  $customer_zones = $this
    ->getMatchingZones($customer_address);
  if (empty($customer_zones)) {

    // The customer is not in the EU.
    return [];
  }
  $order = $order_item
    ->getOrder();
  $store = $order
    ->getStore();
  $store_address = $store
    ->getAddress();
  $store_country = $store_address
    ->getCountryCode();
  $store_zones = $this
    ->getMatchingZones($store_address);
  $store_registration_zones = array_filter($zones, function ($zone) use ($store) {

    /** @var \Drupal\commerce_tax\TaxZone $zone */
    return $this
      ->checkRegistrations($store, $zone);
  });
  $customer_tax_number = '';
  if (!$customer_profile
    ->get('tax_number')
    ->isEmpty()) {

    /** @var \Drupal\commerce_tax\Plugin\Field\FieldType\TaxNumberItemInterface $tax_number_item */
    $tax_number_item = $customer_profile
      ->get('tax_number')
      ->first();
    if ($tax_number_item
      ->checkValue('european_union_vat')) {
      $customer_tax_number = $tax_number_item->value;
    }
  }

  // Since january 1st 2015 all digital goods sold to EU customers
  // must use the customer zone. For example, an ebook sold
  // to Germany needs to have German VAT applied.
  $taxable_type = $this
    ->getTaxableType($order_item);
  $year = $order
    ->getCalculationDate()
    ->format('Y');
  $is_digital = $taxable_type == TaxableType::DIGITAL_GOODS && $year >= 2015;
  if (empty($store_zones) && !empty($store_registration_zones)) {

    // The store is not in the EU but is registered to collect VAT for
    // digital goods.
    $resolved_zones = [];
    if ($is_digital) {
      $resolved_zones = $customer_tax_number ? [
        $zones['ic'],
      ] : $customer_zones;
    }
  }
  elseif ($customer_tax_number && $customer_country != $store_country) {

    // Intra-community supply (B2B).
    $resolved_zones = [
      $zones['ic'],
    ];
  }
  elseif ($is_digital) {
    $resolved_zones = $customer_zones;
  }
  else {

    // Physical products use the origin zone, unless the store is
    // registered to pay taxes in the destination zone. This is required
    // when the total yearly transactions breach the defined threshold.
    // See http://www.vatlive.com/eu-vat-rules/vat-registration-threshold/
    $resolved_zones = $store_zones;
    $customer_zone = reset($customer_zones);
    if ($this
      ->checkRegistrations($store, $customer_zone)) {
      $resolved_zones = $customer_zones;
    }
  }
  return $resolved_zones;
}