|
| 1 | +<?php |
| 2 | +/** |
| 3 | + * PostFinance Checkout Magento 2 |
| 4 | + * |
| 5 | + * This Magento 2 extension enables to process payments with PostFinance Checkout (https://postfinance.ch/en/business/products/e-commerce/postfinance-checkout-all-in-one.html/). |
| 6 | + * |
| 7 | + * @package PostFinanceCheckout_Payment |
| 8 | + * @author wallee AG (http://www.wallee.com/) |
| 9 | + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache Software License (ASL 2.0) |
| 10 | + */ |
| 11 | +namespace PostFinanceCheckout\Payment\Model\Resolver; |
| 12 | + |
| 13 | +use Magento\Checkout\Model\Session as CheckoutSession; |
| 14 | +use Magento\CustomerGraphQl\Model\Customer\GetCustomer; |
| 15 | +use Magento\Framework\Event\ManagerInterface; |
| 16 | +use Magento\Framework\Exception\LocalizedException; |
| 17 | +use Magento\Framework\Exception\NoSuchEntityException; |
| 18 | +use Magento\Framework\GraphQl\Config\Element\Field; |
| 19 | +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; |
| 20 | +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; |
| 21 | +use Magento\Framework\GraphQl\Query\ResolverInterface; |
| 22 | +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; |
| 23 | +use Magento\Customer\Model\Session; |
| 24 | +use Magento\GraphQl\Model\Query\ContextInterface; |
| 25 | +use Magento\Quote\Model\Quote; |
| 26 | +use Magento\Quote\Api\CartRepositoryInterface; |
| 27 | +use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; |
| 28 | +use Magento\Sales\Api\Data\OrderInterface; |
| 29 | +use Psr\Log\LoggerInterface; |
| 30 | +use PostFinanceCheckout\Payment\Api\OrderRepositoryInterface; |
| 31 | + |
| 32 | +class RestoreQuote implements ResolverInterface |
| 33 | +{ |
| 34 | + /** |
| 35 | + * |
| 36 | + * @var Session |
| 37 | + */ |
| 38 | + private $customerSession; |
| 39 | + |
| 40 | + /** |
| 41 | + * |
| 42 | + * @var CheckoutSession |
| 43 | + */ |
| 44 | + private $checkoutSession; |
| 45 | + |
| 46 | + /** |
| 47 | + * |
| 48 | + * @var GetCustomer |
| 49 | + */ |
| 50 | + private $getCustomer; |
| 51 | + |
| 52 | + /** |
| 53 | + * |
| 54 | + * @var CartRepositoryInterface |
| 55 | + */ |
| 56 | + private $cartRepository; |
| 57 | + |
| 58 | + /** |
| 59 | + * |
| 60 | + * @var OrderRepositoryInterface |
| 61 | + */ |
| 62 | + private $orderRepository; |
| 63 | + |
| 64 | + /** |
| 65 | + * |
| 66 | + * @var MaskedQuoteIdToQuoteIdInterface |
| 67 | + */ |
| 68 | + private $maskedQuoteIdToQuoteIdService; |
| 69 | + |
| 70 | + /** |
| 71 | + * |
| 72 | + * @var ManagerInterface |
| 73 | + */ |
| 74 | + private $eventManager; |
| 75 | + |
| 76 | + /** |
| 77 | + * |
| 78 | + * @var LoggerInterface |
| 79 | + */ |
| 80 | + private $logger; |
| 81 | + |
| 82 | + |
| 83 | + public function __construct( |
| 84 | + Session $customerSession, |
| 85 | + CheckoutSession $checkoutSession, |
| 86 | + GetCustomer $getCustomer, |
| 87 | + CartRepositoryInterface $cartRepository, |
| 88 | + \Wallee\Payment\Api\OrderRepositoryInterface $orderRepository, |
| 89 | + MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteIdService, |
| 90 | + ManagerInterface $eventManager, |
| 91 | + LoggerInterface $logger |
| 92 | + ) { |
| 93 | + $this->checkoutSession = $checkoutSession; |
| 94 | + $this->customerSession = $customerSession; |
| 95 | + $this->getCustomer = $getCustomer; |
| 96 | + $this->cartRepository = $cartRepository; |
| 97 | + $this->orderRepository = $orderRepository; |
| 98 | + $this->maskedQuoteIdToQuoteIdService = $maskedQuoteIdToQuoteIdService; |
| 99 | + $this->eventManager = $eventManager; |
| 100 | + $this->logger = $logger; |
| 101 | + } |
| 102 | + |
| 103 | + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) |
| 104 | + { |
| 105 | + $customerId = null; |
| 106 | + |
| 107 | + //only perform validations if the user is anonymous. |
| 108 | + if ($this->checkoutSession->getQuote()->getCustomerId() || !$this->customerSession->getCustomer()->getId()) { |
| 109 | + /** @var ContextInterface $context */ |
| 110 | + if (false === $context->getExtensionAttributes()->getIsCustomer()) { |
| 111 | + throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); |
| 112 | + } |
| 113 | + |
| 114 | + $customer = $this->getCustomer->execute($context); |
| 115 | + $customerId = $customer->getId(); |
| 116 | + |
| 117 | + if (!empty($this->customerSession) && $customerId !== $this->customerSession->getCustomer()->getId()) { |
| 118 | + throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); |
| 119 | + } |
| 120 | + } |
| 121 | + |
| 122 | + try { |
| 123 | + $cartIdMasked = $args['input']['cart_id']; |
| 124 | + return $this->restoreQuote($cartIdMasked, $customerId); |
| 125 | + } catch (NoSuchEntityException|\Exception $e) { |
| 126 | + $this->logger->critical($e); |
| 127 | + throw new GraphQlNoSuchEntityException(__($e->getMessage())); |
| 128 | + } |
| 129 | + } |
| 130 | + |
| 131 | + /** |
| 132 | + * Restores a client's quote from a cart id |
| 133 | + * |
| 134 | + * @param string $cartIdMasked |
| 135 | + * @param string $customerId |
| 136 | + * @return array |
| 137 | + * @throws LocalizedException |
| 138 | + */ |
| 139 | + private function restoreQuote(string $cartIdMasked, string $customerId) |
| 140 | + { |
| 141 | + try { |
| 142 | + // Convert the masked ID to the real quote ID |
| 143 | + $quoteId = $this->maskedQuoteIdToQuoteIdService->execute($cartIdMasked); |
| 144 | + |
| 145 | + // Get the quote using the actual ID |
| 146 | + /** @var Quote $quote */ |
| 147 | + $quote = $this->cartRepository->get($quoteId); |
| 148 | + $order = $this->getOrderByQuote($quote); |
| 149 | + |
| 150 | + //some validations |
| 151 | + $this->guardQuoteBelongsToCurrentCustomer($order, $customerId); |
| 152 | + $this->guardQuoteIsStillActive($quote); |
| 153 | + |
| 154 | + //restore a customer's quote |
| 155 | + $quote |
| 156 | + ->setIsActive(1) |
| 157 | + ->setReservedOrderId(null); |
| 158 | + |
| 159 | + $this->cartRepository->save($quote); |
| 160 | + |
| 161 | + $this->checkoutSession |
| 162 | + ->replaceQuote($quote) |
| 163 | + ->unsLastRealOrderId(); |
| 164 | + |
| 165 | + $this->eventManager->dispatch('restore_quote', ['order' => $order, 'quote' => $quote]); |
| 166 | + $this->logger->debug("RESTORE-QUOTE-MUTATION::restoreQuote - Quote with id $cartIdMasked was restored"); |
| 167 | + |
| 168 | + return ['result' => 'OK']; |
| 169 | + } catch (NoSuchEntityException|\Exception $e) { |
| 170 | + return ['result' => 'KO. ' . $e->getMessage()]; |
| 171 | + } |
| 172 | + } |
| 173 | + |
| 174 | + /** |
| 175 | + * Get an order by quote |
| 176 | + * |
| 177 | + * @param Quote $quote |
| 178 | + * @return OrderInterface|null |
| 179 | + * @throws \Exception |
| 180 | + */ |
| 181 | + public function getOrderByQuote(Quote $quote) |
| 182 | + { |
| 183 | + $orderId = $quote->getReservedOrderId(); |
| 184 | + |
| 185 | + if (empty($orderId)) { |
| 186 | + throw new \Exception(__('The quote does not have an associated order')); |
| 187 | + } |
| 188 | + |
| 189 | + return $this->orderRepository->getOrderById($orderId); |
| 190 | + } |
| 191 | + |
| 192 | + /** |
| 193 | + * Check if quote belongs to the current customer |
| 194 | + * |
| 195 | + * @param OrderInterface $order |
| 196 | + * @param int $customerId |
| 197 | + * @return void |
| 198 | + * @throws \Exception |
| 199 | + */ |
| 200 | + private function guardQuoteBelongsToCurrentCustomer(OrderInterface $order, int $customerId) |
| 201 | + { |
| 202 | + $orderCustomerId = $order->getCustomerId(); |
| 203 | + if ((int)$orderCustomerId !== $customerId) { |
| 204 | + $this->logger->debug("RESTORE-QUOTE-MUTATION::guardQuoteBelongsToCurrentCustomer - customer id '$customerId' doesn't match with order customer id '$orderCustomerId'"); |
| 205 | + throw new \Exception(__('The current customer isn\'t authorized.')); |
| 206 | + } |
| 207 | + } |
| 208 | + |
| 209 | + /** |
| 210 | + * Check if the quote is still active, only quotes that are not active will be activated |
| 211 | + * |
| 212 | + * @param Quote $quote |
| 213 | + * @return void |
| 214 | + * @throws \Exception |
| 215 | + */ |
| 216 | + private function guardQuoteIsStillActive(Quote $quote) |
| 217 | + { |
| 218 | + if ($quote->getIsActive()) { |
| 219 | + $this->logger->debug("RESTORE-QUOTE-MUTATION::guardQuoteIsStillActive - quote is still activated"); |
| 220 | + |
| 221 | + throw new \Exception(__('The quote is still active.')); |
| 222 | + } |
| 223 | + } |
| 224 | +} |
0 commit comments