Commit dcc08bbc authored by Roman Khimin's avatar Roman Khimin Committed by Ryan Szrama
Browse files

Issue #3203747 by dwkitchen, tbenice, khiminrm, rszrama: Update...

Issue #3203747 by dwkitchen, tbenice, khiminrm, rszrama: Update resolveCustomerProfile() to reflect changes in TaxTypeBase, ensuring the shipping address takes priority for tax calculation purposes.
parent d3b3b5ab
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ services:

  commerce_avatax.avatax_lib:
    class: Drupal\commerce_avatax\AvataxLib
    arguments: ['@plugin.manager.commerce_adjustment_type', '@commerce_avatax.chain_tax_code_resolver', '@commerce_avatax.client_factory', '@config.factory', '@event_dispatcher', '@logger.channel.commerce_avatax', '@module_handler', '@cache.commerce_avatax']
    arguments: ['@plugin.manager.commerce_adjustment_type', '@entity_type.manager', '@commerce_avatax.chain_tax_code_resolver', '@commerce_avatax.client_factory', '@config.factory', '@event_dispatcher', '@logger.channel.commerce_avatax', '@module_handler', '@cache.commerce_avatax']

  commerce_avatax.client_factory:
    class: Drupal\commerce_avatax\ClientFactory
+75 −5
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ use Drupal\Component\Utility\Variable;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
@@ -33,6 +34,14 @@ class AvataxLib implements AvataxLibInterface {
   */
  protected $adjustmentTypeManager;

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


  /**
   * The chain tax code resolver.
   *
@@ -87,6 +96,8 @@ class AvataxLib implements AvataxLibInterface {
   *
   * @param \Drupal\commerce_order\AdjustmentTypeManager $adjustment_type_manager
   *   The adjustment type manager.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\commerce_avatax\Resolver\ChainTaxCodeResolverInterface $chain_tax_code_resolver
   *   The chain tax code resolver.
   * @param \Drupal\commerce_avatax\ClientFactory $client_factory
@@ -102,8 +113,9 @@ class AvataxLib implements AvataxLibInterface {
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
   *   The cache backend.
   */
  public function __construct(AdjustmentTypeManager $adjustment_type_manager, ChainTaxCodeResolverInterface $chain_tax_code_resolver, ClientFactory $client_factory, ConfigFactoryInterface $config_factory, EventDispatcherInterface $event_dispatcher, LoggerInterface $logger, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend) {
  public function __construct(AdjustmentTypeManager $adjustment_type_manager, EntityTypeManagerInterface $entity_type_manager, ChainTaxCodeResolverInterface $chain_tax_code_resolver, ClientFactory $client_factory, ConfigFactoryInterface $config_factory, EventDispatcherInterface $event_dispatcher, LoggerInterface $logger, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend) {
    $this->adjustmentTypeManager = $adjustment_type_manager;
    $this->entityTypeManager = $entity_type_manager;
    $this->chainTaxCodeResolver = $chain_tax_code_resolver;
    $this->config = $config_factory->get('commerce_avatax.settings');
    $this->client = $client_factory->createInstance($this->config->get());
@@ -462,6 +474,7 @@ class AvataxLib implements AvataxLibInterface {

  /**
   * Resolves the customer profile for the given order item.
   *
   * Stolen from TaxTypeBase::resolveCustomerProfile().
   *
   * @param \Drupal\commerce_order\Entity\OrderItemInterface $order_item
@@ -472,15 +485,72 @@ class AvataxLib implements AvataxLibInterface {
   */
  protected function resolveCustomerProfile(OrderItemInterface $order_item) {
    $order = $order_item->getOrder();
    $customer_profile = $order->getBillingProfile();
    // A shipping profile is preferred, when available.
    $customer_profile = $this->buildCustomerProfile($order);
    // Allow the customer profile to be altered, per order item.
    $event = new CustomerProfileEvent($customer_profile, $order_item);
    $this->eventDispatcher->dispatch(TaxEvents::CUSTOMER_PROFILE, $event);
    $this->eventDispatcher->dispatch($event, TaxEvents::CUSTOMER_PROFILE);
    $customer_profile = $event->getCustomerProfile();

    return $customer_profile;
  }

  /**
   * Builds a customer profile for the given order.
   *
   * Constructed only for the purposes of tax calculation, never saved.
   * The address comes one of the saved profiles, with the following priority:
   * - Shipping profile
   * - Billing profile
   * - Store profile (if the tax type is display inclusive)
   * The tax number comes from the billing profile, if present.
   *
   * @param \Drupal\commerce_order\Entity\OrderInterface $order
   *   The order.
   *
   * @return \Drupal\profile\Entity\ProfileInterface|null
   *   The customer profile, or NULL if not available yet.
   */
  protected function buildCustomerProfile(OrderInterface $order) {
    $order_uuid = $order->uuid();
    if (!isset($this->profiles[$order_uuid])) {
      $order_profiles = $order->collectProfiles();
      $address = NULL;
      foreach (['shipping', 'billing'] as $scope) {
        if (isset($order_profiles[$scope])) {
          $address_field = $order_profiles[$scope]->get('address');
          if (!$address_field->isEmpty()) {
            $address = $address_field->getValue();
            break;
          }
        }
      }
      // @todo What to do if AvaTax is configured to display inclusive
      //if (!$address && $this->isDisplayInclusive()) {
        // Customer is still unknown, but prices are displayed tax-inclusive
        // (VAT scenario), better to show the store's default tax than nothing.
      //  $address = $order->getStore()->getAddress();
      //}
      if (!$address) {
        // A customer profile isn't usable without an address. Stop here.
        return NULL;
      }

      $tax_number = NULL;
      if (isset($order_profiles['billing']) && $order_profiles['billing']->hasField('tax_number')) {
        $tax_number = $order_profiles['billing']->get('tax_number')->getValue();
      }
      $profile_storage = $this->entityTypeManager->getStorage('profile');
      $this->profiles[$order_uuid] = $profile_storage->create([
        'type' => 'customer',
        'uid' => 0,
        'address' => $address,
        'tax_number' => $tax_number,
      ]);
    }

    return $this->profiles[$order_uuid];
  }

  /**
   * Performs an HTTP request to AvaTax.
   *
+1 −0
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ class AddressValidationTest extends KernelTestBase {

    return new AvataxLib(
      $this->container->get('plugin.manager.commerce_adjustment_type'),
      $this->container->get('entity_type.manager'),
      $this->container->get('commerce_avatax.chain_tax_code_resolver'),
      $client_factory->reveal(),
      $this->container->get('config.factory'),