You are here

public function LocalTaxTypeBase::apply in Commerce Core 8.2

Applies the tax type to the given order.

Taxes should be added on the order item level, to make returns and refunds easier. This is true even for taxes that are only shown at the order level, such as sales taxes.

Parameters

\Drupal\commerce_order\Entity\OrderInterface $order: The order.

Overrides TaxTypeInterface::apply

File

modules/tax/src/Plugin/Commerce/TaxType/LocalTaxTypeBase.php, line 112

Class

LocalTaxTypeBase
Provides the base class for local tax types.

Namespace

Drupal\commerce_tax\Plugin\Commerce\TaxType

Code

public function apply(OrderInterface $order) {
  $calculation_date = $order
    ->getCalculationDate();
  $store = $order
    ->getStore();
  $prices_include_tax = $store
    ->get('prices_include_tax')->value;
  $zones = $this
    ->getZones();
  foreach ($order
    ->getItems() as $order_item) {
    $customer_profile = $this
      ->resolveCustomerProfile($order_item);
    if (!$customer_profile) {
      continue;
    }
    $rates = $this
      ->resolveRates($order_item, $customer_profile);
    foreach ($rates as $zone_id => $rate) {
      $zone = $zones[$zone_id];
      $percentage = $rate
        ->getPercentage($calculation_date);

      // Stores are allowed to enter prices without tax even if they're
      // going to be displayed with tax, and vice-versa.
      // Now that the rates are known, use them to determine the final
      // unit price (which will in turn finalize the order item total).
      if ($prices_include_tax != $this
        ->isDisplayInclusive()) {
        $unit_price = $order_item
          ->getUnitPrice();
        $tax_amount = $percentage
          ->calculateTaxAmount($unit_price, $prices_include_tax);
        $tax_amount = $this->rounder
          ->round($tax_amount);
        if ($prices_include_tax && !$this
          ->isDisplayInclusive()) {
          $unit_price = $unit_price
            ->subtract($tax_amount);
        }
        elseif (!$prices_include_tax && $this
          ->isDisplayInclusive()) {
          $unit_price = $unit_price
            ->add($tax_amount);
        }
        $order_item
          ->setUnitPrice($unit_price);
      }

      // Now determine the tax amount, taking into account other adjustments.
      $adjusted_total_price = $order_item
        ->getAdjustedTotalPrice([
        'promotion',
        'fee',
      ]);
      $tax_amount = $percentage
        ->calculateTaxAmount($adjusted_total_price, $this
        ->isDisplayInclusive());
      if ($this
        ->shouldRound()) {
        $tax_amount = $this->rounder
          ->round($tax_amount);
      }
      $order_item
        ->addAdjustment(new Adjustment([
        'type' => 'tax',
        'label' => $zone
          ->getDisplayLabel(),
        'amount' => $tax_amount,
        'percentage' => $percentage
          ->getNumber(),
        'source_id' => $this->parentEntity
          ->id() . '|' . $zone
          ->getId() . '|' . $rate
          ->getId(),
        'included' => $this
          ->isDisplayInclusive(),
      ]));
    }
  }
}