diff -Nuar a/vendor/magento/module-checkout/Model/GuestPaymentInformationManagement.php b/vendor/magento/module-checkout/Model/GuestPaymentInformationManagement.php index 592e87b5c4c..72536b3b47b 100644 --- a/vendor/magento/module-checkout/Model/GuestPaymentInformationManagement.php +++ b/vendor/magento/module-checkout/Model/GuestPaymentInformationManagement.php @@ -57,18 +57,12 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa private $logger; /** - * @var ResourceConnection - */ - private $connectionPool; - - /** * @param \Magento\Quote\Api\GuestBillingAddressManagementInterface $billingAddressManagement * @param \Magento\Quote\Api\GuestPaymentMethodManagementInterface $paymentMethodManagement * @param \Magento\Quote\Api\GuestCartManagementInterface $cartManagement * @param \Magento\Checkout\Api\PaymentInformationManagementInterface $paymentInformationManagement * @param \Magento\Quote\Model\QuoteIdMaskFactory $quoteIdMaskFactory * @param CartRepositoryInterface $cartRepository - * @param ResourceConnection $connectionPool * @codeCoverageIgnore */ public function __construct( @@ -77,8 +71,7 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa \Magento\Quote\Api\GuestCartManagementInterface $cartManagement, \Magento\Checkout\Api\PaymentInformationManagementInterface $paymentInformationManagement, \Magento\Quote\Model\QuoteIdMaskFactory $quoteIdMaskFactory, - CartRepositoryInterface $cartRepository, - ResourceConnection $connectionPool = null + CartRepositoryInterface $cartRepository ) { $this->billingAddressManagement = $billingAddressManagement; $this->paymentMethodManagement = $paymentMethodManagement; @@ -86,7 +79,6 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa $this->paymentInformationManagement = $paymentInformationManagement; $this->quoteIdMaskFactory = $quoteIdMaskFactory; $this->cartRepository = $cartRepository; - $this->connectionPool = $connectionPool ?: ObjectManager::getInstance()->get(ResourceConnection::class); } /** @@ -98,33 +90,23 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa \Magento\Quote\Api\Data\PaymentInterface $paymentMethod, \Magento\Quote\Api\Data\AddressInterface $billingAddress = null ) { - $salesConnection = $this->connectionPool->getConnection('sales'); - $checkoutConnection = $this->connectionPool->getConnection('checkout'); - $salesConnection->beginTransaction(); - $checkoutConnection->beginTransaction(); - + $this->savePaymentInformation($cartId, $email, $paymentMethod, $billingAddress); try { - $this->savePaymentInformation($cartId, $email, $paymentMethod, $billingAddress); - try { - $orderId = $this->cartManagement->placeOrder($cartId); - } catch (\Magento\Framework\Exception\LocalizedException $e) { - throw new CouldNotSaveException( - __($e->getMessage()), - $e - ); - } catch (\Exception $e) { - $this->getLogger()->critical($e); - throw new CouldNotSaveException( - __('An error occurred on the server. Please try to place the order again.'), - $e - ); - } - $salesConnection->commit(); - $checkoutConnection->commit(); + $orderId = $this->cartManagement->placeOrder($cartId); + } catch (\Magento\Framework\Exception\LocalizedException $e) { + $this->getLogger()->critical( + 'Placing an order with quote_id ' . $cartId . ' is failed: ' . $e->getMessage() + ); + throw new CouldNotSaveException( + __($e->getMessage()), + $e + ); } catch (\Exception $e) { - $salesConnection->rollBack(); - $checkoutConnection->rollBack(); - throw $e; + $this->getLogger()->critical($e); + throw new CouldNotSaveException( + __('An error occurred on the server. Please try to place the order again.'), + $e + ); } return $orderId; diff -Nuar a/vendor/magento/module-checkout/Model/PaymentInformationManagement.php b/vendor/magento/module-checkout/Model/PaymentInformationManagement.php index e8ab07db184..cf29da7a13c 100644 --- a/vendor/magento/module-checkout/Model/PaymentInformationManagement.php +++ b/vendor/magento/module-checkout/Model/PaymentInformationManagement.php @@ -85,6 +85,9 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor try { $orderId = $this->cartManagement->placeOrder($cartId); } catch (\Magento\Framework\Exception\LocalizedException $e) { + $this->getLogger()->critical( + 'Placing an order with quote_id ' . $cartId . ' is failed: ' . $e->getMessage() + ); throw new CouldNotSaveException( __($e->getMessage()), $e diff -Nuar a/vendor/magento/module-sales-rule/Model/Coupon/UpdateCouponUsages.php b/vendor/magento/module-sales-rule/Model/Coupon/UpdateCouponUsages.php new file mode 100644 index 00000000000..3236c80e1b7 --- /dev/null +++ b/vendor/magento/module-sales-rule/Model/Coupon/UpdateCouponUsages.php @@ -0,0 +1,153 @@ +ruleFactory = $ruleFactory; + $this->ruleCustomerFactory = $ruleCustomerFactory; + $this->coupon = $coupon; + $this->couponUsage = $couponUsage; + } + + /** + * Executes the current command. + * + * @param OrderInterface $subject + * @param bool $increment + * @return OrderInterface + */ + public function execute(OrderInterface $subject, bool $increment): OrderInterface + { + if (!$subject || !$subject->getAppliedRuleIds()) { + return $subject; + } + // lookup rule ids + $ruleIds = explode(',', $subject->getAppliedRuleIds()); + $ruleIds = array_unique($ruleIds); + $customerId = (int)$subject->getCustomerId(); + // use each rule (and apply to customer, if applicable) + foreach ($ruleIds as $ruleId) { + if (!$ruleId) { + continue; + } + $this->updateRuleUsages($increment, (int)$ruleId, $customerId); + } + $this->updateCouponUsages($subject, $increment, $customerId); + + return $subject; + } + + /** + * Update the number of rule usages. + * + * @param bool $increment + * @param int $ruleId + * @param int $customerId + */ + private function updateRuleUsages(bool $increment, int $ruleId, int $customerId) + { + /** @var \Magento\SalesRule\Model\Rule $rule */ + $rule = $this->ruleFactory->create(); + $rule->load($ruleId); + if ($rule->getId()) { + $rule->loadCouponCode(); + if ($increment || $rule->getTimesUsed() > 0) { + $rule->setTimesUsed($rule->getTimesUsed() + ($increment ? 1 : -1)); + $rule->save(); + } + if ($customerId) { + $this->updateCustomerRuleUsages($increment, $ruleId, $customerId); + } + } + } + + /** + * Update the number of rule usages per customer. + * + * @param bool $increment + * @param int $ruleId + * @param int $customerId + */ + private function updateCustomerRuleUsages(bool $increment, int $ruleId, int $customerId): void + { + /** @var \Magento\SalesRule\Model\Rule\Customer $ruleCustomer */ + $ruleCustomer = $this->ruleCustomerFactory->create(); + $ruleCustomer->loadByCustomerRule($customerId, $ruleId); + if ($ruleCustomer->getId()) { + if ($increment || $ruleCustomer->getTimesUsed() > 0) { + $ruleCustomer->setTimesUsed($ruleCustomer->getTimesUsed() + ($increment ? 1 : -1)); + } + } elseif ($increment) { + $ruleCustomer->setCustomerId($customerId)->setRuleId($ruleId)->setTimesUsed(1); + } + $ruleCustomer->save(); + } + + /** + * Update the number of coupon usages. + * + * @param OrderInterface $subject + * @param bool $increment + * @param int $customerId + */ + private function updateCouponUsages(OrderInterface $subject, bool $increment, int $customerId): void + { + $this->coupon->load($subject->getCouponCode(), 'code'); + if ($this->coupon->getId()) { + if ($increment || $this->coupon->getTimesUsed() > 0) { + $this->coupon->setTimesUsed($this->coupon->getTimesUsed() + ($increment ? 1 : -1)); + $this->coupon->save(); + } + if ($customerId) { + $this->couponUsage->updateCustomerCouponTimesUsed($customerId, $this->coupon->getId(), $increment); + } + } + } +} diff -Nuar a/vendor/magento/module-sales-rule/Model/ResourceModel/Coupon/Usage.php b/vendor/magento/module-sales-rule/Model/ResourceModel/Coupon/Usage.php index db32bdbe1e9..39a2f8855e2 100644 --- a/vendor/magento/module-sales-rule/Model/ResourceModel/Coupon/Usage.php +++ b/vendor/magento/module-sales-rule/Model/ResourceModel/Coupon/Usage.php @@ -27,9 +27,10 @@ class Usage extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb * * @param int $customerId * @param mixed $couponId + * @param bool $increment * @return void */ - public function updateCustomerCouponTimesUsed($customerId, $couponId) + public function updateCustomerCouponTimesUsed($customerId, $couponId, $increment = true): void { $connection = $this->getConnection(); $select = $connection->select(); @@ -44,13 +45,13 @@ class Usage extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb $timesUsed = $connection->fetchOne($select, [':coupon_id' => $couponId, ':customer_id' => $customerId]); - if ($timesUsed > 0) { + if ($timesUsed !== false) { $this->getConnection()->update( $this->getMainTable(), - ['times_used' => $timesUsed + 1], + ['times_used' => $timesUsed + ($increment ? 1 : -1)], ['coupon_id = ?' => $couponId, 'customer_id = ?' => $customerId] ); - } else { + } elseif ($increment) { $this->getConnection()->insert( $this->getMainTable(), ['coupon_id' => $couponId, 'customer_id' => $customerId, 'times_used' => 1] diff -Nuar a/vendor/magento/module-sales-rule/Plugin/CouponUsagesDecrement.php b/vendor/magento/module-sales-rule/Plugin/CouponUsagesDecrement.php new file mode 100644 index 00000000000..87a7c2ed1bd --- /dev/null +++ b/vendor/magento/module-sales-rule/Plugin/CouponUsagesDecrement.php @@ -0,0 +1,59 @@ +updateCouponUsages = $updateCouponUsages; + $this->orderRepository = $orderRepository; + } + + /** + * Decrements number of coupon usages after cancelling order. + * + * @param OrderService $subject + * @param bool $result + * @param int $orderId + * @return bool + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterCancel(OrderService $subject, bool $result, $orderId): bool + { + $order = $this->orderRepository->get($orderId); + if ($result) { + $this->updateCouponUsages->execute($order, false); + } + + return $result; + } +} diff -Nuar a/vendor/magento/module-sales-rule/Plugin/CouponUsagesIncrement.php b/vendor/magento/module-sales-rule/Plugin/CouponUsagesIncrement.php new file mode 100644 index 00000000000..14bbb5fce02 --- /dev/null +++ b/vendor/magento/module-sales-rule/Plugin/CouponUsagesIncrement.php @@ -0,0 +1,47 @@ +updateCouponUsages = $updateCouponUsages; + } + + /** + * Increments number of coupon usages after placing order. + * + * @param OrderService $subject + * @param OrderInterface $result + * @return OrderInterface + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterPlace(OrderService $subject, OrderInterface $result): OrderInterface + { + $this->updateCouponUsages->execute($result, true); + + return $result; + } +} diff -Nuar a/vendor/magento/module-sales-rule/etc/di.xml b/vendor/magento/module-sales-rule/etc/di.xml index 475d5472abc..9326fc93a82 100644 --- a/vendor/magento/module-sales-rule/etc/di.xml +++ b/vendor/magento/module-sales-rule/etc/di.xml @@ -182,7 +182,10 @@ - + + + + diff -Nuar a/vendor/magento/module-sales-rule/etc/events.xml b/vendor/magento/module-sales-rule/etc/events.xml index e6b84502552..fb0f711144e 100644 --- a/vendor/magento/module-sales-rule/etc/events.xml +++ b/vendor/magento/module-sales-rule/etc/events.xml @@ -6,9 +6,6 @@ */ --> - - -