diff --git a/config/common.yml b/config/common.yml index 088128b69..0e63db593 100644 --- a/config/common.yml +++ b/config/common.yml @@ -462,6 +462,7 @@ services: PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentPendingQuery: "ps_checkout.query.handler.order.get_order_for_payment_pending" PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentRefundedQuery: "ps_checkout.query.handler.order.get_order_for_payment_refunded" PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentReversedQuery: "ps_checkout.query.handler.order.get_order_for_payment_reversed" + PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForApprovalReversedQuery: "ps_checkout.query.handler.order.get_order_for_approval_reversed" PrestaShop\Module\PrestashopCheckout\PayPal\Identity\Query\GetClientTokenPayPalQuery: "ps_checkout.query.handler.paypal.identity.get_client_token" PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetCurrentPayPalOrderStatusQuery: "ps_checkout.query.handler.paypal.order.get_current_paypal_order_status" PrestaShop\Module\PrestashopCheckout\PayPal\Order\Query\GetPayPalOrderForCheckoutCompletedQuery: "ps_checkout.query.handler.paypal.order.get_paypal_order_for_checkout_completed" @@ -497,6 +498,7 @@ services: - "@ps_checkout.cache.paypal.order" - "@ps_checkout.checkout.checker" - "@ps_checkout.paypal.order.service.check_transition_paypal_order_status" + - "@ps_checkout.order.state.service.order_state_mapper" ps_checkout.event.subscriber.paypal.capture: class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Capture\EventSubscriber\PayPalCaptureEventSubscriber' @@ -604,6 +606,12 @@ services: arguments: - "@ps_checkout.repository.pscheckoutcart" + ps_checkout.query.handler.order.get_order_for_approval_reversed: + class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForApprovalReversedQueryHandler' + public: true + arguments: + - "@ps_checkout.repository.pscheckoutcart" + ps_checkout.query.handler.paypal.identity.get_client_token: class: 'PrestaShop\Module\PrestashopCheckout\PayPal\Identity\QueryHandler\GetClientTokenPayPalQueryHandler' public: true diff --git a/src/Order/Query/GetOrderForApprovalReversedQuery.php b/src/Order/Query/GetOrderForApprovalReversedQuery.php new file mode 100644 index 000000000..f9c4ec4ea --- /dev/null +++ b/src/Order/Query/GetOrderForApprovalReversedQuery.php @@ -0,0 +1,50 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Order\Query; + +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Exception\PayPalOrderException; +use PrestaShop\Module\PrestashopCheckout\PayPal\Order\ValueObject\PayPalOrderId; + +class GetOrderForApprovalReversedQuery +{ + /** + * @var PayPalOrderId + */ + private $orderPayPalId; + + /** + * @param string $orderPayPalId + * + * @throws PayPalOrderException + */ + public function __construct($orderPayPalId) + { + $this->orderPayPalId = new PayPalOrderId($orderPayPalId); + } + + /** + * @return PayPalOrderId + */ + public function getOrderPayPalId() + { + return $this->orderPayPalId; + } +} diff --git a/src/Order/Query/GetOrderForApprovalReversedQueryResult.php b/src/Order/Query/GetOrderForApprovalReversedQueryResult.php new file mode 100644 index 000000000..96cc0b578 --- /dev/null +++ b/src/Order/Query/GetOrderForApprovalReversedQueryResult.php @@ -0,0 +1,102 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Order\Query; + +use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderException; +use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException; +use PrestaShop\Module\PrestashopCheckout\Order\State\ValueObject\OrderStateId; +use PrestaShop\Module\PrestashopCheckout\Order\ValueObject\OrderId; + +class GetOrderForApprovalReversedQueryResult +{ + /** + * @var OrderId + */ + private $orderId; + + /** + * @var OrderStateId + */ + private $currentStateId; + + /** + * @var bool + */ + private $hasBeenPaid; + + /** + * @var bool + */ + private $hasBeenCanceled; + + /** + * @param int $orderId + * @param int $currentStateId + * @param bool $hasBeenPaid + * @param bool $hasBeenCanceled + * + * @throws OrderException + * @throws OrderStateException + */ + public function __construct( + $orderId, + $currentStateId, + $hasBeenPaid, + $hasBeenCanceled + ) { + $this->orderId = new OrderId($orderId); + $this->currentStateId = new OrderStateId($currentStateId); + $this->hasBeenPaid = $hasBeenPaid; + $this->hasBeenCanceled = $hasBeenCanceled; + } + + /** + * @return OrderId + */ + public function getOrderId() + { + return $this->orderId; + } + + /** + * @return OrderStateId + */ + public function getCurrentStateId() + { + return $this->currentStateId; + } + + /** + * @return bool + */ + public function hasBeenPaid() + { + return $this->hasBeenPaid; + } + + /** + * @return bool + */ + public function hasBeenCanceled() + { + return $this->hasBeenCanceled; + } +} diff --git a/src/Order/QueryHandler/GetOrderForApprovalReversedQueryHandler.php b/src/Order/QueryHandler/GetOrderForApprovalReversedQueryHandler.php new file mode 100644 index 000000000..4c394c044 --- /dev/null +++ b/src/Order/QueryHandler/GetOrderForApprovalReversedQueryHandler.php @@ -0,0 +1,92 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\Order\QueryHandler; + +use Configuration; +use Order; +use PrestaShop\Module\PrestashopCheckout\Cart\Exception\CartNotFoundException; +use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; +use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderNotFoundException; +use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForApprovalReversedQuery; +use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForApprovalReversedQueryResult; +use PrestaShop\Module\PrestashopCheckout\Order\State\OrderStateConfigurationKeys; +use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository; +use PrestaShopCollection; +use PrestaShopDatabaseException; +use PrestaShopException; +use PsCheckoutCart; +use Validate; + +class GetOrderForApprovalReversedQueryHandler +{ + /** + * @var PsCheckoutCartRepository + */ + private $psCheckoutCartRepository; + + public function __construct(PsCheckoutCartRepository $psCheckoutCartRepository) + { + $this->psCheckoutCartRepository = $psCheckoutCartRepository; + } + + /** + * @param GetOrderForApprovalReversedQuery $query + * + * @return GetOrderForApprovalReversedQueryResult + * + * @throws PsCheckoutException + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ + public function handle(GetOrderForApprovalReversedQuery $query) + { + /** @var PsCheckoutCart|false $psCheckoutCart */ + $psCheckoutCart = $this->psCheckoutCartRepository->findOneByPayPalOrderId($query->getOrderPayPalId()->getValue()); + + if (!$psCheckoutCart) { + throw new CartNotFoundException('No PrestaShop Cart associated to this PayPal Order at this time.'); + } + + $orders = new PrestaShopCollection(Order::class); + $orders->where('id_cart', '=', $psCheckoutCart->getIdCart()); + + if (!$orders->count()) { + throw new OrderNotFoundException('No PrestaShop Order associated to this PayPal Order at this time.'); + } + + /** @var Order $order */ + $order = $orders->getFirst(); + + if (!Validate::isLoadedObject($order)) { + throw new OrderNotFoundException('No PrestaShop Order associated to this PayPal Order at this time.'); + } + + $hasBeenCanceled = count($order->getHistory($order->id_lang, (int) Configuration::getGlobalValue(OrderStateConfigurationKeys::CANCELED))); + + return new GetOrderForApprovalReversedQueryResult( + (int) $order->id, + (int) $order->getCurrentState(), + (bool) $order->hasBeenPaid(), + (bool) $hasBeenCanceled + ); + } +} diff --git a/src/PayPal/Order/EventSubscriber/PayPalOrderEventSubscriber.php b/src/PayPal/Order/EventSubscriber/PayPalOrderEventSubscriber.php index b1ed55843..9d74b1b9c 100644 --- a/src/PayPal/Order/EventSubscriber/PayPalOrderEventSubscriber.php +++ b/src/PayPal/Order/EventSubscriber/PayPalOrderEventSubscriber.php @@ -22,7 +22,14 @@ namespace PrestaShop\Module\PrestashopCheckout\PayPal\Order\EventSubscriber; use PrestaShop\Module\PrestashopCheckout\Checkout\CheckoutChecker; +use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; +use PrestaShop\Module\PrestashopCheckout\Order\Command\UpdateOrderStatusCommand; +use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderNotFoundException; +use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForApprovalReversedQuery; +use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForApprovalReversedQueryResult; +use PrestaShop\Module\PrestashopCheckout\Order\State\OrderStateConfigurationKeys; +use PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\CheckTransitionPayPalOrderStatusService; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\CapturePayPalOrderCommand; use PrestaShop\Module\PrestashopCheckout\PayPal\Order\Command\SavePayPalOrderCommand; @@ -64,18 +71,31 @@ class PayPalOrderEventSubscriber implements EventSubscriberInterface */ private $checkTransitionPayPalOrderStatusService; + /** + * @var OrderStateMapper + */ + private $orderStateMapper; + + /** + * @var CommandBusInterface + */ + private $commandBus; + public function __construct( Ps_checkout $module, PsCheckoutCartRepository $psCheckoutCartRepository, CacheInterface $orderPayPalCache, CheckoutChecker $checkoutChecker, - CheckTransitionPayPalOrderStatusService $checkTransitionPayPalOrderStatusService + CheckTransitionPayPalOrderStatusService $checkTransitionPayPalOrderStatusService, + OrderStateMapper $orderStateMapper ) { $this->module = $module; $this->psCheckoutCartRepository = $psCheckoutCartRepository; $this->orderPayPalCache = $orderPayPalCache; $this->checkoutChecker = $checkoutChecker; $this->checkTransitionPayPalOrderStatusService = $checkTransitionPayPalOrderStatusService; + $this->orderStateMapper = $orderStateMapper; + $this->commandBus = $this->module->getService('ps_checkout.bus.command'); } /** @@ -99,6 +119,7 @@ public static function getSubscribedEvents() ], PayPalOrderApprovalReversedEvent::class => [ ['saveApprovalReversedPayPalOrder'], + ['setApprovalReversedOrderStatus'], ['clearCache'], ], ]; @@ -116,7 +137,7 @@ public function saveCreatedPayPalOrder(PayPalOrderCreatedEvent $event) return; } - $this->module->getService('ps_checkout.bus.command')->handle(new SavePayPalOrderCommand( + $this->commandBus->handle(new SavePayPalOrderCommand( $event->getOrderPayPalId()->getValue(), PayPalOrderStatus::CREATED, $event->getOrderPayPal() @@ -135,7 +156,7 @@ public function saveApprovedPayPalOrder(PayPalOrderApprovedEvent $event) return; } - $this->module->getService('ps_checkout.bus.command')->handle(new SavePayPalOrderCommand( + $this->commandBus->handle(new SavePayPalOrderCommand( $event->getOrderPayPalId()->getValue(), PayPalOrderStatus::APPROVED, $event->getOrderPayPal() @@ -154,7 +175,7 @@ public function saveCompletedPayPalOrder(PayPalOrderCompletedEvent $event) return; } - $this->module->getService('ps_checkout.bus.command')->handle(new SavePayPalOrderCommand( + $this->commandBus->handle(new SavePayPalOrderCommand( $event->getOrderPayPalId()->getValue(), PayPalOrderStatus::COMPLETED, $event->getOrderPayPal() @@ -173,7 +194,7 @@ public function saveApprovalReversedPayPalOrder(PayPalOrderApprovalReversedEvent return; } - $this->module->getService('ps_checkout.bus.command')->handle(new SavePayPalOrderCommand( + $this->commandBus->handle(new SavePayPalOrderCommand( $event->getOrderPayPalId()->getValue(), PayPalOrderStatus::REVERSED, $event->getOrderPayPal() @@ -199,7 +220,7 @@ public function capturePayPalOrder(PayPalOrderApprovedEvent $event) $this->checkoutChecker->continueWithAuthorization($psCheckoutCart->getIdCart(), $event->getOrderPayPal()); - $this->module->getService('ps_checkout.bus.command')->handle( + $this->commandBus->handle( new CapturePayPalOrderCommand( $event->getOrderPayPalId()->getValue(), $psCheckoutCart->getPaypalFundingSource() @@ -207,6 +228,31 @@ public function capturePayPalOrder(PayPalOrderApprovedEvent $event) ); } + public function setApprovalReversedOrderStatus(PayPalOrderApprovalReversedEvent $event) + { + try { + /** @var GetOrderForApprovalReversedQueryResult $order */ + $order = $this->commandBus->handle( + new GetOrderForApprovalReversedQuery( + $event->getOrderPayPalId()->getValue() + ) + ); + } catch (OrderNotFoundException $exception) { + return; + } + + if ($order->hasBeenCanceled() || $order->hasBeenPaid()) { + return; + } + + $this->commandBus->handle( + new UpdateOrderStatusCommand( + $order->getOrderId()->getValue(), + $this->orderStateMapper->getIdByKey(OrderStateConfigurationKeys::CANCELED) + ) + ); + } + public function updateCache(PayPalOrderEvent $event) { $currentOrderPayPal = $this->orderPayPalCache->get($event->getOrderPayPalId()->getValue());