You are here

class TaxOrderProcessor in Commerce Core 8.2

Applies taxes to orders during the order refresh process.

Hierarchy

Expanded class hierarchy of TaxOrderProcessor

1 string reference to 'TaxOrderProcessor'
commerce_tax.services.yml in modules/tax/commerce_tax.services.yml
modules/tax/commerce_tax.services.yml
1 service uses TaxOrderProcessor
commerce_tax.tax_order_processor in modules/tax/commerce_tax.services.yml
Drupal\commerce_tax\TaxOrderProcessor

File

modules/tax/src/TaxOrderProcessor.php, line 14

Namespace

Drupal\commerce_tax
View source
class TaxOrderProcessor implements OrderProcessorInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The rounder.
   *
   * @var \Drupal\commerce_price\RounderInterface
   */
  protected $rounder;

  /**
   * The store tax.
   *
   * @var \Drupal\commerce_tax\StoreTaxInterface
   */
  protected $storeTax;

  /**
   * Constructs a new TaxOrderProcessor object.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\commerce_price\RounderInterface $rounder
   *   The rounder.
   * @param \Drupal\commerce_tax\StoreTaxInterface $store_tax
   *   The store tax.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, RounderInterface $rounder, StoreTaxInterface $store_tax) {
    $this->entityTypeManager = $entity_type_manager;
    $this->rounder = $rounder;
    $this->storeTax = $store_tax;
  }

  /**
   * {@inheritdoc}
   */
  public function process(OrderInterface $order) {
    $tax_types = $this
      ->getTaxTypes();
    foreach ($tax_types as $tax_type) {
      if ($tax_type
        ->getPlugin()
        ->applies($order)) {
        $tax_type
          ->getPlugin()
          ->apply($order);
      }
    }

    // Don't overcharge a tax-exempt customer if the price is tax-inclusive.
    // For example, a 12 EUR price with 20% EU VAT gets reduced to 10 EUR
    // when selling to customers outside the EU, but only if no other tax
    // was applied (e.g. a Japanese customer paying Japanese tax due to the
    // store being registered to collect tax there).
    $calculation_date = $order
      ->getCalculationDate();
    $store = $order
      ->getStore();
    if ($store
      ->get('prices_include_tax')->value) {
      foreach ($order
        ->getItems() as $order_item) {
        $tax_adjustments = array_filter($order_item
          ->getAdjustments(), function ($adjustment) {

          /** @var \Drupal\commerce_order\Adjustment $adjustment */
          return $adjustment
            ->getType() == 'tax';
        });
        if (empty($tax_adjustments)) {
          $unit_price = $order_item
            ->getUnitPrice();
          $rates = $this->storeTax
            ->getDefaultRates($store, $order_item);
          foreach ($rates as $rate) {
            $percentage = $rate
              ->getPercentage($calculation_date);
            $tax_amount = $percentage
              ->calculateTaxAmount($order_item
              ->getUnitPrice(), TRUE);
            $tax_amount = $this->rounder
              ->round($tax_amount);
            $unit_price = $unit_price
              ->subtract($tax_amount);
          }
          $order_item
            ->setUnitPrice($unit_price, $order_item
            ->isUnitPriceOverridden());
        }
      }
    }
  }

  /**
   * Gets the available tax types.
   *
   * @return \Drupal\commerce_tax\Entity\TaxTypeInterface[]
   *   The tax types.
   */
  protected function getTaxTypes() {
    $tax_type_storage = $this->entityTypeManager
      ->getStorage('commerce_tax_type');

    /** @var \Drupal\commerce_tax\Entity\TaxTypeInterface[] $tax_types */
    $tax_types = $tax_type_storage
      ->loadByProperties([
      'status' => TRUE,
    ]);
    uasort($tax_types, [
      TaxType::class,
      'sort',
    ]);
    return $tax_types;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
TaxOrderProcessor::$entityTypeManager protected property The entity type manager.
TaxOrderProcessor::$rounder protected property The rounder.
TaxOrderProcessor::$storeTax protected property The store tax.
TaxOrderProcessor::getTaxTypes protected function Gets the available tax types.
TaxOrderProcessor::process public function Processes an order. Overrides OrderProcessorInterface::process
TaxOrderProcessor::__construct public function Constructs a new TaxOrderProcessor object.