Incompatibility between disable-stock-reservation and 2.4.0 In store pickup during Ampersand\DisableStockReservation\Plugin\SourceDeductionProcessor->afterPlace
mrobichaud-absolunet opened this issue · 4 comments
An exception occurs if you are connected and there are orders not completed on other customer.
At some point in the stack when this function is called a list of all pending pickup orders are loaded and magento send an exception if you try to load an order that isn't associated to the connected customer. When this happen, since it's in the afterPlace, the order is created but the checkout process never complete and the customer is presented with a "No such entity found for entity_id = ###"
The specific line where it all start (95)
$sourceSelectionResult = $this->getSourceSelectionResultFromOrder->execute($order);
Here's a stack trace of the exception
#0 /srv/www/vendor/magento/module-sales/Model/ResourceModel/Order/Plugin/Authorization.php(45): Magento\Framework\Exception\NoSuchEntityException::singleField('orderId', '35')
#1 /srv/www/vendor/magento/framework/Interception/Interceptor.php(146): Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization->afterLoad(Object(Magento\Sales\Model\ResourceModel\Order\Interceptor), Object(Magento\Sales\Model\ResourceModel\Order\Interceptor), Object(Magento\Sales\Model\Order\Interceptor), '35', NULL)
#2 /srv/www/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Sales\Model\ResourceModel\Order\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Sales\Model\Order\Interceptor), '35', NULL)
#3 /srv/www/generated/code/Magento/Sales/Model/ResourceModel/Order/Interceptor.php(117): Magento\Sales\Model\ResourceModel\Order\Interceptor->___callPlugins('load', Array, Array)
#4 /srv/www/vendor/magento/framework/Model/AbstractModel.php(540): Magento\Sales\Model\ResourceModel\Order\Interceptor->load(Object(Magento\Sales\Model\Order\Interceptor), '35', NULL)
#5 /srv/www/generated/code/Magento/Sales/Model/Order/Interceptor.php(4964): Magento\Framework\Model\AbstractModel->load('35', NULL)
#6 /srv/www/vendor/magento/module-sales/Model/Order/ShippingAssignmentBuilder.php(79): Magento\Sales\Model\Order\Interceptor->load('35')
#7 /srv/www/vendor/magento/module-sales/Model/OrderRepository.php(294): Magento\Sales\Model\Order\ShippingAssignmentBuilder->create()
#8 /srv/www/vendor/magento/module-sales/Model/OrderRepository.php(216): Magento\Sales\Model\OrderRepository->setShippingAssignments(Object(Magento\Sales\Model\Order\Interceptor))
#9 /srv/www/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Sales\Model\OrderRepository->getList(Object(Magento\Framework\Api\SearchCriteria))
#10 /srv/www/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Sales\Model\OrderRepository\Interceptor->___callParent('getList', Array)
#11 /srv/www/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Sales\Model\OrderRepository\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\Api\SearchCriteria))
#12 /srv/www/generated/code/Magento/Sales/Model/OrderRepository/Interceptor.php(39): Magento\Sales\Model\OrderRepository\Interceptor->___callPlugins('getList', Array, Array)
#13 /srv/www/vendor/magento/module-inventory-in-store-pickup-sales/Model/SourceSelection/GetActiveStorePickupOrdersBySource.php(65): Magento\Sales\Model\OrderRepository\Interceptor->getList(Object(Magento\Framework\Api\SearchCriteria))
#14 /srv/www/vendor/magento/module-inventory-in-store-pickup-sales/Model/SourceSelection/GetSourceItemQtyAvailableService.php(105): Magento\InventoryInStorePickupSales\Model\SourceSelection\GetActiveStorePickupOrdersBySource->execute('4101')
#15 /srv/www/vendor/magento/module-inventory-in-store-pickup-sales/Model/SourceSelection/GetSourceItemQtyAvailableService.php(76): Magento\InventoryInStorePickupSales\Model\SourceSelection\GetSourceItemQtyAvailableService->getStorePickupOrdersBySourceItem(Object(Magento\Inventory\Model\SourceItem))
#16 /srv/www/vendor/magento/module-inventory-in-store-pickup-sales/Model/SourceSelection/GetSourceItemQtyAvailableService.php(64): Magento\InventoryInStorePickupSales\Model\SourceSelection\GetSourceItemQtyAvailableService->getStorePickupReservedQty(Object(Magento\Inventory\Model\SourceItem))
#17 /srv/www/vendor/magento/module-inventory-source-selection-api/Model/Algorithms/Result/GetDefaultSortedSourcesResult.php(115): Magento\InventoryInStorePickupSales\Model\SourceSelection\GetSourceItemQtyAvailableService->execute(Object(Magento\Inventory\Model\SourceItem))
#18 /srv/www/vendor/magento/module-inventory-source-selection/Model/Algorithms/PriorityBasedAlgorithm.php(73): Magento\InventorySourceSelectionApi\Model\Algorithms\Result\GetDefaultSortedSourcesResult->execute(Object(Magento\InventorySourceSelection\Model\Request\InventoryRequest), Array)
#19 /srv/www/vendor/magento/module-inventory-source-selection-api/Model/SourceSelectionService.php(61): Magento\InventorySourceSelection\Model\Algorithms\PriorityBasedAlgorithm->execute(Object(Magento\InventorySourceSelection\Model\Request\InventoryRequest))
**#20 /srv/www/vendor/ampersand/magento2-disable-stock-reservation/src/Model/GetSourceSelectionResultFromOrder.php(79): Magento\InventorySourceSelectionApi\Model\SourceSelectionService->execute(Object(Magento\InventorySourceSelection\Model\Request\InventoryRequest), 'priority')
#21 /srv/www/vendor/ampersand/magento2-disable-stock-reservation/src/Plugin/SourceDeductionProcessor.php(95): Ampersand\DisableStockReservation\Model\GetSourceSelectionResultFromOrder->execute(Object(Magento\Sales\Model\Order\Interceptor))
#22 /srv/www/vendor/magento/framework/Interception/Interceptor.php(146): Ampersand\DisableStockReservation\Plugin\SourceDeductionProcessor->afterPlace(Object(Magento\Sales\Model\Service\OrderService\Interceptor), Object(Magento\Sales\Model\Order\Interceptor), Object(Magento\Sales\Model\Order\Interceptor))**
#23 /srv/www/vendor/magento/module-inventory-sales/Plugin/Sales/OrderManagement/AppendReservationsAfterOrderPlacementPlugin.php(195): Magento\Sales\Model\Service\OrderService\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Sales\Model\Order\Interceptor))
#24 /srv/www/vendor/magento/framework/Interception/Interceptor.php(135): Magento\InventorySales\Plugin\Sales\OrderManagement\AppendReservationsAfterOrderPlacementPlugin->aroundPlace(Object(Magento\Sales\Model\Service\OrderService\Interceptor), Object(Closure), Object(Magento\Sales\Model\Order\Interceptor))
#25 /srv/www/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Sales\Model\Service\OrderService\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Sales\Model\Order\Interceptor))
#26 /srv/www/generated/code/Magento/Sales/Model/Service/OrderService/Interceptor.php(117): Magento\Sales\Model\Service\OrderService\Interceptor->___callPlugins('place', Array, Array)
#27 /srv/www/vendor/magento/module-quote/Model/QuoteManagement.php(563): Magento\Sales\Model\Service\OrderService\Interceptor->place(Object(Magento\Sales\Model\Order\Interceptor))
#28 /srv/www/vendor/magento/module-quote/Model/QuoteManagement.php(453): Magento\Quote\Model\QuoteManagement->submitQuote(Object(Magento\Quote\Model\Quote\Interceptor), Array)
#29 /srv/www/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Quote\Model\QuoteManagement->submit(Object(Magento\Quote\Model\Quote\Interceptor), Array)
#30 /srv/www/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Quote\Model\QuoteManagement\Interceptor->___callParent('submit', Array)
#31 /srv/www/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Quote\Model\QuoteManagement\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Quote\Model\Quote\Interceptor))
#32 /srv/www/generated/code/Magento/Quote/Model/QuoteManagement/Interceptor.php(91): Magento\Quote\Model\QuoteManagement\Interceptor->___callPlugins('submit', Array, Array)
#33 /srv/www/vendor/magento/module-quote/Model/QuoteManagement.php(411): Magento\Quote\Model\QuoteManagement\Interceptor->submit(Object(Magento\Quote\Model\Quote\Interceptor))
#34 /srv/www/generated/code/Magento/Quote/Model/QuoteManagement/Interceptor.php(63): Magento\Quote\Model\QuoteManagement->placeOrder(94, NULL)
#35 /srv/www/vendor/magento/module-checkout/Model/PaymentInformationManagement.php(86): Magento\Quote\Model\QuoteManagement\Interceptor->placeOrder(94)
#36 /srv/www/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Checkout\Model\PaymentInformationManagement->savePaymentInformationAndPlaceOrder(94, Object(Magento\Quote\Model\Quote\Payment), Object(Magento\Quote\Model\Quote\Address\Interceptor))
#37 /srv/www/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Checkout\Model\PaymentInformationManagement\Interceptor->___callParent('savePaymentInfo...', Array)
#38 /srv/www/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Checkout\Model\PaymentInformationManagement\Interceptor->Magento\Framework\Interception\{closure}(94, Object(Magento\Quote\Model\Quote\Payment), Object(Magento\Quote\Model\Quote\Address\Interceptor))
#39 /srv/www/generated/code/Magento/Checkout/Model/PaymentInformationManagement/Interceptor.php(26): Magento\Checkout\Model\PaymentInformationManagement\Interceptor->___callPlugins('savePaymentInfo...', Array, Array)
#40 [internal function]: Magento\Checkout\Model\PaymentInformationManagement\Interceptor->savePaymentInformationAndPlaceOrder(94, Object(Magento\Quote\Model\Quote\Payment), Object(Magento\Quote\Model\Quote\Address\Interceptor))
#41 /srv/www/vendor/magento/module-webapi/Controller/Rest/SynchronousRequestProcessor.php(95): call_user_func_array(Array, Array)
#42 /srv/www/vendor/magento/module-webapi/Controller/Rest.php(188): Magento\Webapi\Controller\Rest\SynchronousRequestProcessor->process(Object(Magento\Framework\Webapi\Rest\Request\Proxy))
#43 /srv/www/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Webapi\Controller\Rest->dispatch(Object(Magento\Framework\App\Request\Http))
#44 /srv/www/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Webapi\Controller\Rest\Interceptor->___callParent('dispatch', Array)
#45 /srv/www/vendor/fastly/magento2/Model/FrontControllerPlugin.php(131): Magento\Webapi\Controller\Rest\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#46 /srv/www/vendor/magento/framework/Interception/Interceptor.php(135): Fastly\Cdn\Model\FrontControllerPlugin->aroundDispatch(Object(Magento\Webapi\Controller\Rest\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#47 /srv/www/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Webapi\Controller\Rest\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#48 /srv/www/generated/code/Magento/Webapi/Controller/Rest/Interceptor.php(26): Magento\Webapi\Controller\Rest\Interceptor->___callPlugins('dispatch', Array, Array)
#49 /srv/www/vendor/magento/framework/App/Http.php(116): Magento\Webapi\Controller\Rest\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#50 /srv/www/generated/code/Magento/Framework/App/Http/Interceptor.php(24): Magento\Framework\App\Http->launch()
#51 /srv/www/vendor/magento/framework/App/Bootstrap.php(263): Magento\Framework\App\Http\Interceptor->launch()
#52 /srv/www/pub/index.php(40): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http\Interceptor))
#53 {main}
After some investigation, the problem comes mainly from this interface that changes with in store pickup.
Magento\InventorySourceSelectionApi\Model\GetSourceItemQtyAvailableInterface
Normally if points to this code
Magento\InventorySourceSelectionApi\Model\GetSourceItemQtyAvailableService
public function execute(SourceItemInterface $sourceItem): float { return $sourceItem->getQuantity(); }
But with the in store pickup module a new class is created and the code is as follow
Magento\InventoryInStorePickupSales\Model\SourceSelection\GetSourceItemQtyAvailableService
public function execute(SourceItemInterface $sourceItem): float
{
/* TODO: create config and check if store pickup is enabled? */
return $sourceItem->getQuantity() - $this->getStorePickupReservedQty($sourceItem);
}
Since this extension disable reservation $this->getStorePickupReservedQty($sourceItem);
isn't really necessary. Our solution was to revert back the preference in a di.xml
<preference for="Magento\InventorySourceSelectionApi\Model\GetSourceItemQtyAvailableInterface" type="Magento\InventorySourceSelectionApi\Model\GetSourceItemQtyAvailableService" />
hi @mrobichaudb, could you provide a few more steps on how to replicate this error? I presume it's only when there are store pick up orders associated with the source item? We are currently trying to ensure this module is viable for Magento 2.4 and are keen to implement a fix for this (potentially the aforementioned di.xml fix) but do not want to lose any non-MSI functionality on the new in-store pickup feature.
- You need order that has the Pickup in store as delivery option and is not completed. (I think it need to be a connected user but I'm not sure)
- You need to do a second order with a different connected user (this time it needs to be a user for sure). You should have an error when you try placing the order
- What I don't know is if the two orders needs to be the same product or the same pickup location to throw the error.
@mrobichaud-absolunet we believe this issue is resolved as of #43
Can you please review and let me know if you have any further issues.
Thanks