magento-2-smtp
magento-2-smtp copied to clipboard
Issue with \Mageplaza\Smtp\Plugin\AccountManagement::afterIsEmailAvailable when there is no active quote
Preconditions (*)
- Magento 2.4.2
- onestepcheckout/iosc 1.2.049
- mageplaza/magento-2-smtp >=4.4.0
Steps to reproduce (*)
Install and configure the two modules.
Expected result (*)
Checkout process succeeds
Actual result (*)
Complete checkout process on onestepcheckout fails.
The reason for the failure is that onestepcheckout calls \Magento\Customer\Api\AccountManagementInterface::isEmailAvailable after the checkout submission. Because this is after the checkout, then that means the quote doesn't exist any longer (it's been converted to an order). \Mageplaza\Smtp\Plugin\AccountManagement::afterIsEmailAvailable assumes that the quote is active though:
$quote = $this->cartRepository->getActive($cartId);
Because that cartId won't exist, then it causes the error. It would be better to do some additional checking to make sure the loaded cart ID exists.
Hi,
I checked and found that in \Mageplaza\Smtp\Plugin\AccountManagement::afterIsEmailAvailable there was code that checked the existence of $cartId || https://prnt.sc/17z3se5 Please check again for me.
Thank you!
Hi @HuyPhuc98
The problem isn't that there isn't a $cartId, the problem is that there is no quote for that ID. As I mention above, the reason there is no quote in the case I've seen because it's converted into an order.
You should do some error handling in this case, instead of just assuming the quote exists.
Can you tell me the steps to reproduce this problem? Thank you!
If you have this setup, you will see it on a order completion via onestepcheckout:
Magento 2.4.2
onestepcheckout/iosc 1.2.049
mageplaza/magento-2-smtp >=4.4.0
If you want to simulate it though, then you need to create an event listener on:
<event name="checkout_submit_all_after">
Which calls
\Magento\Customer\Api\AccountManagementInterface::isEmailAvailable
We had the same issue. It gives a No such entity with cartid = ### upon placing the order, because the quote is no longer active. But only in combination with onestepcheckout/iosc, because they have a CheckoutSubmitAfter observer that does some registration checks using isEmailAvailable after checkout submit.
We wrote a custom plugin to replace ->getActive with ->get and some extra checks/error handling in case it doesn't exist.
Hi,
Since the problem is only with onestepcheckout/iosc and I can't buy that module at the moment, I can't reproduce and test this issue. Thank you for notifying the problem with the SMTP module. I will check the issue in the future if possible.
Thank you!
This issue crashed the whole account-creation-while-completing-order process at our store. It took several days to find out that the vendor/mageplaza/module-smtp/Plugin/AccountManagement.php file is causing this. This should definately not happen as there are so many shops using OSCs. We dont't even use the onestepcheckout/iosc descirbed by JSeverein but a different OSC. Plus I found this, this should show you how far this issue reaches: https://help-m2.onestepcheckout.com/help/placing-an-order-with-quote_id-xxxx-is-failed
https://github.com/mageplaza/magento-2-smtp/pull/329/ enjoy
#329 enjoy
kind of workaround but it isn't a fix. Does it send an email for account registration after an order with your workaround ?
#324 this is a better solution
works fine to me, and literally saves my life after like a week of digging in that non-debuggable and non-testable problem of mine.
@LusienGG Sure I just needed to get away from errors it creates not sure what it even does or why this extension exists and is useful for.
It might work for you but doing it like this and on high load occasions you are prob ending with deadlocks and extra load on checkout process . It loads what is already available (if it used event instead of plugin) and causes a extra save on non related item that could easily be solved with cron without impacting checkout performance or could be saved on order placement time (if it used a event for that instead of plugin) without extra save process
We had the same error with OSC and with auto registration enabled. We finally fixed by overriding the smtp plugin as follows:
public function afterIsEmailAvailable(CustomerAccountManagement $subject, $result, $customerEmail)
{
$cartId = $this->checkoutSession->getQuote()->getId();
if (!$cartId) {
return $result;
}
//$quote = null;
/**
* return $result if no quote is found!
* fix for if no active quote is found error is thrown when auto registration is used with OSC
*/
try {
/** @var Quote $quote */
$quote = $this->cartRepository->getActive($cartId);
$quote->setCustomerEmail($customerEmail);
} catch (Exception $e) {
return $result;
}
try {
$this->cartRepository->save($quote);
return $result;
} catch (Exception $e) {
return false;
}
}
So, instead of blinding adding try catch and return false, the quote is first checked and if quote is not found, original $result is returned.
instead of
$quote = $this->cartRepository->getActive($cartId);
You can always use a method that retrieves a quote without checking if it is active or not . It is not related to OneStepCheckout type of extensions but rather on what step the payment method decides to deactivate quote and on what other occasions your plugin is evoked . Event observer is evoked on event you need, plugin in all cases where the plugged method is executed and that might not be on your suitable event time or context.
When we encountered this issue, we chose to apply #329 to fix it. This worked for logged-in customers, but for orders placed as guest+signup the problem persisted. We have now applied #324 (instead of #329) and the website is behaving as expected.
I've also opened #361 to fix a related issue where the plugin erroneously changes the return value from isEmailAvailable(). (This makes #329 work again.)
I think a combination of #324 (just get the quote, ignore its "active" status) and #329 (catch all the errors) and #361 (preserve return value) is the best way forward to fixing this problem.