Problem/Motivation
I am getting an error on the order screen when trying to sort orders. I have a bunch of orders that were migrated from a different platform and not all of the orders in draft have addresses.
TypeError: Argument 1 passed to Drupal\commerce_tax\TaxZone::match() must implement interface CommerceGuys\Addressing\AddressInterface, null given, called in /var/www/html/drupal/web/modules/contrib/commerce/modules/tax/src/Plugin/Commerce/TaxType/LocalTaxTypeBase.php on line 254 in Drupal\commerce_tax\TaxZone->match() (line 138 of /var/www/html/drupal/web/modules/contrib/commerce/modules/tax/src/TaxZone.php) #0 /var/www/html/drupal/web/modules/contrib/commerce/modules/tax/src/Plugin/Commerce/TaxType/LocalTaxTypeBase.php(254): Drupal\commerce_tax\TaxZone->match(NULL) #1 /var/www/html/drupal/web/modules/contrib/commerce/modules/tax/src/Plugin/Commerce/TaxType/LocalTaxTypeBase.php(229): Drupal\commerce_tax\Plugin\Commerce\TaxType\LocalTaxTypeBase->resolveZones(Object(Drupal\commerce_order\Entity\OrderItem), Object(Drupal\profile\Entity\Profile)) #2 /var/www/html/drupal/web/modules/contrib/commerce/modules/tax/src/Plugin/Commerce/TaxType/LocalTaxTypeBase.php(112): Drupal\commerce_tax\Plugin\Commerce\TaxType\LocalTaxTypeBase->resolveRates(Object(Drupal\commerce_order\Entity\OrderItem), Object(Drupal\profile\Entity\Profile)) #3 /var/www/html/drupal/web/modules/contrib/commerce/modules/tax/src/TaxOrderProcessor.php(85): Drupal\commerce_tax\Plugin\Commerce\TaxType\LocalTaxTypeBase->apply(Object(Drupal\commerce_order\Entity\Order)) #4 /var/www/html/drupal/web/modules/contrib/commerce/modules/order/src/OrderRefresh.php(155): Drupal\commerce_tax\TaxOrderProcessor->process(Object(Drupal\commerce_order\Entity\Order)) #5 /var/www/html/drupal/web/modules/contrib/commerce/modules/order/src/OrderStorage.php(99): Drupal\commerce_order\OrderRefresh->refresh(Object(Drupal\commerce_order\Entity\Order)) #6 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(426): Drupal\commerce_order\OrderStorage->doPreSave(Object(Drupal\commerce_order\Entity\Order)) #7 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(774): Drupal\Core\Entity\EntityStorageBase->save(Object(Drupal\commerce_order\Entity\Order)) #8 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/Entity.php(390): Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object(Drupal\commerce_order\Entity\Order)) #9 /var/www/html/drupal/web/modules/contrib/commerce/modules/order/src/OrderStorage.php(133): Drupal\Core\Entity\Entity->save() #10 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(286): Drupal\commerce_order\OrderStorage->postLoad(Array) #11 /var/www/html/drupal/web/core/modules/views/src/Plugin/views/query/Sql.php(1610): Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) #12 /var/www/html/drupal/web/core/modules/views/src/Plugin/views/query/Sql.php(1535): Drupal\views\Plugin\views\query\Sql->loadEntities(Array) #13 /var/www/html/drupal/web/core/modules/views/src/ViewExecutable.php(1426): Drupal\views\Plugin\views\query\Sql->execute(Object(Drupal\views\ViewExecutable)) #14 /var/www/html/drupal/web/core/modules/views/src/ViewExecutable.php(1454): Drupal\views\ViewExecutable->execute(NULL) #15 /var/www/html/drupal/web/core/modules/views/src/Plugin/views/display/Page.php(183): Drupal\views\ViewExecutable->render() #16 /var/www/html/drupal/web/core/modules/views/src/ViewExecutable.php(1630): Drupal\views\Plugin\views\display\Page->execute() #17 /var/www/html/drupal/web/core/modules/views/src/Element/View.php(77): Drupal\views\ViewExecutable->executeDisplay('page_1', Array) #18 [internal function]: Drupal\views\Element\View::preRenderViewElement(Array) #19 /var/www/html/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(378): call_user_func(Array, Array) #20 /var/www/html/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #21 /var/www/html/drupal/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(226): Drupal\Core\Render\Renderer->render(Array, false) #22 /var/www/html/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(582): Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() #23 /var/www/html/drupal/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(227): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #24 /var/www/html/drupal/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(117): Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch)) #25 /var/www/html/drupal/web/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch)) #26 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #27 /var/www/html/drupal/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #28 /var/www/html/drupal/vendor/symfony/http-kernel/HttpKernel.php(156): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent)) #29 /var/www/html/drupal/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #30 /var/www/html/drupal/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #31 /var/www/html/drupal/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #32 /var/www/html/drupal/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #33 /var/www/html/drupal/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #34 /var/www/html/drupal/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #35 /var/www/html/drupal/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #36 /var/www/html/drupal/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #37 /var/www/html/drupal/web/core/lib/Drupal/Core/DrupalKernel.php(665): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #38 /var/www/html/drupal/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #39 {main}.
Proposed resolution
Just check if there is a customer address before trying to resolve zones to them.
Attaching patch for the work.
Thanks
Comments
Comment #2
dobe commentedComment #3
dobe commentedAddress variable should be optional in TaxZone::match() (2925470) Is a better solution.
Comment #4
mglamanLet's work on this here instead of the other issue. We need to see why orders without addresses are being passed.
Comment #5
mglamanSee: https://github.com/drupalcommerce/commerce/blob/8.x-2.x/modules/tax/src/...
So you have a billing profile with an empty address. Tax assumes that if a profile exists it will have an address.
Comment #6
mglamanresolveCustomerProfile needs to verify the address is not empty.
Comment #7
dobe commentedBased on conversation with @mglaman. Here is a patch.
Comment #8
mglaman+1 thank you! We have missing test coverage here that we should add.
Comment #9
dobe commentedWas running into same issue with other patch. Even though there was a store and the store has an address.
Comment #10
dobe commentedThis one is better. Had some syntax from other patch.
Comment #14
mglamanUnrelated test fails
Comment #16
dobe commentedFixing if $customer_profile is already null.
Comment #18
facine commented#16 works fine!
Comment #19
mglamanQueued some tests to see what's up, looks like a random failure.
Comment #20
bojanz commentedA bug fix can't be RTBC if it has no test.
Wouldn't it make more sense to perform the check before the store profile defaulting, so that if the current profile has no address, we calculate tax with the store address?
"If the customer profile has no address, calculate tax with the store address" sounds like a better rule than "If the customer profile has no address, calculate no tax'.
Comment #21
bojanz commentedHow about this?
Comment #23
bojanz commentedCommitted #21. Thanks, everyone!