From 4af448a76a10585faf247126a6f8bcfd6a328084 Mon Sep 17 00:00:00 2001 From: mandan2 Date: Tue, 26 Sep 2023 14:17:48 +0300 Subject: [PATCH] PIPRES-261: Set carrier for recurring order --- controllers/front/subscriptionWebhook.php | 9 ++ .../CouldNotHandleRecurringOrder.php | 16 ++-- subscription/Exception/ExceptionCode.php | 21 +++-- .../Handler/RecurringOrderHandler.php | 88 ++++++++++++++----- 4 files changed, 93 insertions(+), 41 deletions(-) diff --git a/controllers/front/subscriptionWebhook.php b/controllers/front/subscriptionWebhook.php index 0fe91601f..433e6b290 100644 --- a/controllers/front/subscriptionWebhook.php +++ b/controllers/front/subscriptionWebhook.php @@ -13,6 +13,7 @@ use Mollie\Controller\AbstractMollieController; use Mollie\Errors\Http\HttpStatusCode; use Mollie\Handler\ErrorHandler\ErrorHandler; +use Mollie\Logger\PrestaLoggerInterface; use Mollie\Subscription\Handler\RecurringOrderHandler; if (!defined('_PS_VERSION_')) { @@ -62,9 +63,17 @@ protected function executeWebhook() /** @var ErrorHandler $errorHandler */ $errorHandler = $this->module->getService(ErrorHandler::class); + /** @var PrestaLoggerInterface $logger */ + $logger = $this->module->getService(PrestaLoggerInterface::class); + try { $recurringOrderHandler->handle($transactionId); } catch (\Throwable $exception) { + $logger->error('Failed to handle recurring order', [ + 'Exception message' => $exception->getMessage(), + 'Exception code' => $exception->getCode(), + ]); + $errorHandler->handle($exception, null, false); $this->respond('failed', HttpStatusCode::HTTP_BAD_REQUEST); diff --git a/subscription/Exception/CouldNotHandleRecurringOrder.php b/subscription/Exception/CouldNotHandleRecurringOrder.php index 197ed5163..e1dbc95e1 100644 --- a/subscription/Exception/CouldNotHandleRecurringOrder.php +++ b/subscription/Exception/CouldNotHandleRecurringOrder.php @@ -2,25 +2,21 @@ namespace Mollie\Subscription\Exception; -use Throwable; - class CouldNotHandleRecurringOrder extends MollieSubscriptionException { - public static function failedToCreateOrderPaymentFee(Throwable $exception): CouldNotHandleRecurringOrder + public static function failedToFindSelectedCarrier(): CouldNotHandleRecurringOrder { return new self( - 'Failed to create order payment fee', - ExceptionCode::ORDER_FAILED_TO_CREATE_ORDER_PAYMENT_FEE, - $exception + 'Failed to find selected carrier', + ExceptionCode::RECURRING_ORDER_FAILED_TO_FIND_SELECTED_CARRIER ); } - public static function failedToUpdateOrderTotalWithPaymentFee(Throwable $exception): CouldNotHandleRecurringOrder + public static function failedToApplySelectedCarrier(): CouldNotHandleRecurringOrder { return new self( - 'Failed to update order total with payment fee.', - ExceptionCode::ORDER_FAILED_TO_UPDATE_ORDER_TOTAL_WITH_PAYMENT_FEE, - $exception + 'Failed to apply selected carrier', + ExceptionCode::RECURRING_ORDER_FAILED_TO_APPLY_SELECTED_CARRIER ); } } diff --git a/subscription/Exception/ExceptionCode.php b/subscription/Exception/ExceptionCode.php index 32dd51f28..b0eaec414 100644 --- a/subscription/Exception/ExceptionCode.php +++ b/subscription/Exception/ExceptionCode.php @@ -6,17 +6,20 @@ class ExceptionCode { //Order error codes starts from 1000 - public const ORDER_FAILED_TO_CREATE_ORDER_PAYMENT_FEE = 1001; - public const ORDER_FAILED_TO_UPDATE_ORDER_TOTAL_WITH_PAYMENT_FEE = 1002; - public const ORDER_FAILED_TO_FIND_SELECTED_CARRIER = 1003; - public const ORDER_FAILED_TO_FIND_ORDER_CART = 1004; - public const ORDER_FAILED_TO_FIND_ORDER_CUSTOMER = 1005; - public const ORDER_FAILED_TO_APPLY_SELECTED_CARRIER = 1006; - public const ORDER_FAILED_TO_FIND_ORDER_DELIVERY_ADDRESS = 1007; - public const ORDER_FAILED_TO_FIND_ORDER_DELIVERY_COUNTRY = 1008; - public const ORDER_FAILED_TO_GET_SELECTED_CARRIER_PRICE = 1009; + public const ORDER_FAILED_TO_FIND_SELECTED_CARRIER = 1001; + public const ORDER_FAILED_TO_FIND_ORDER_CART = 1002; + public const ORDER_FAILED_TO_FIND_ORDER_CUSTOMER = 1003; + public const ORDER_FAILED_TO_APPLY_SELECTED_CARRIER = 1004; + public const ORDER_FAILED_TO_FIND_ORDER_DELIVERY_ADDRESS = 1005; + public const ORDER_FAILED_TO_FIND_ORDER_DELIVERY_COUNTRY = 1006; + public const ORDER_FAILED_TO_GET_SELECTED_CARRIER_PRICE = 1007; //Cart error codes starts from 2000 public const CART_ALREADY_HAS_SUBSCRIPTION_PRODUCT = 2001; + + //Recurring order error codes starts from 3000 + + public const RECURRING_ORDER_FAILED_TO_FIND_SELECTED_CARRIER = 3001; + public const RECURRING_ORDER_FAILED_TO_APPLY_SELECTED_CARRIER = 3002; } diff --git a/subscription/Handler/RecurringOrderHandler.php b/subscription/Handler/RecurringOrderHandler.php index 7d4ac50da..60d919792 100644 --- a/subscription/Handler/RecurringOrderHandler.php +++ b/subscription/Handler/RecurringOrderHandler.php @@ -14,8 +14,9 @@ use Mollie\Api\Types\SubscriptionStatus; use Mollie\Config\Config; use Mollie\Errors\Http\HttpStatusCode; -use Mollie\Exception\OrderCreationException; use Mollie\Exception\TransactionException; +use Mollie\Logger\PrestaLoggerInterface; +use Mollie\Repository\CarrierRepositoryInterface; use Mollie\Repository\PaymentMethodRepositoryInterface; use Mollie\Service\MailService; use Mollie\Service\MollieOrderCreationService; @@ -61,6 +62,10 @@ class RecurringOrderHandler private $configuration; /** @var RecurringOrdersProductRepositoryInterface */ private $recurringOrdersProductRepository; + /** @var CarrierRepositoryInterface */ + private $carrierRepository; + /** @var PrestaLoggerInterface */ + private $logger; public function __construct( SubscriptionApi $subscriptionApi, @@ -75,7 +80,9 @@ public function __construct( Shop $shop, MailService $mailService, ConfigurationAdapter $configuration, - RecurringOrdersProductRepositoryInterface $recurringOrdersProductRepository + RecurringOrdersProductRepositoryInterface $recurringOrdersProductRepository, + CarrierRepositoryInterface $carrierRepository, + PrestaLoggerInterface $logger ) { $this->subscriptionApi = $subscriptionApi; $this->subscriptionDataFactory = $subscriptionDataFactory; @@ -90,6 +97,8 @@ public function __construct( $this->mailService = $mailService; $this->configuration = $configuration; $this->recurringOrdersProductRepository = $recurringOrdersProductRepository; + $this->carrierRepository = $carrierRepository; + $this->logger = $logger; } public function handle(string $transactionId): string @@ -130,10 +139,7 @@ public function handle(string $transactionId): string } /** - * @throws CouldNotHandleRecurringOrder - * @throws OrderCreationException - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException + * @throws \Throwable */ private function createSubscription(Payment $transaction, MolRecurringOrder $recurringOrder, MollieSubscription $subscription): void { @@ -146,10 +152,6 @@ private function createSubscription(Payment $transaction, MolRecurringOrder $rec return; } - $paymentMethod = $this->paymentMethodService->getPaymentMethod($transaction); - - $methodName = $paymentMethod->method_name ?: Config::$methods[$transaction->method]; - /** @var Cart $newCart */ $newCart = $newCart['cart']; @@ -182,24 +184,66 @@ private function createSubscription(Payment $transaction, MolRecurringOrder $rec $recurringOrderProduct = new MolRecurringOrdersProduct($recurringOrder->id_mol_recurring_orders_product); - $specificPrice = $this->createSpecificPrice($recurringOrderProduct, $recurringOrder); + $subscriptionCarrierId = (int) $this->configuration->get(Config::MOLLIE_SUBSCRIPTION_ORDER_CARRIER_ID); + + /** @var \Carrier|null $carrier */ + $carrier = $this->carrierRepository->findOneBy([ + 'id_carrier' => $subscriptionCarrierId, + 'active' => 1, + 'deleted' => 0, + ]); - $this->mollie->validateOrder( - (int) $newCart->id, - (int) $this->configuration->get(Config::MOLLIE_STATUS_AWAITING), - (float) $subscription->amount->value, - sprintf('subscription/%s', $methodName), - null, - ['transaction_id' => $transaction->id], - null, - false, - $newCart->secure_key + if (!$carrier) { + throw CouldNotHandleRecurringOrder::failedToFindSelectedCarrier(); + } + + $newCart->setDeliveryOption( + [(int) $newCart->id_address_delivery => sprintf('%d,', (int) $carrier->id)] ); + $newCart->update(); + + if (sprintf('%d,', (int) $carrier->id) !== + $newCart->getDeliveryOption(null, false, false)[$newCart->id_address_delivery] + ) { + throw CouldNotHandleRecurringOrder::failedToApplySelectedCarrier(); + } + + $specificPrice = $this->createSpecificPrice($recurringOrderProduct, $recurringOrder); + + $paymentMethod = $this->paymentMethodService->getPaymentMethod($transaction); + + $methodName = $paymentMethod->method_name ?: Config::$methods[$transaction->method]; + + try { + $this->mollie->validateOrder( + (int) $newCart->id, + (int) $this->configuration->get(Config::MOLLIE_STATUS_AWAITING), + (float) $subscription->amount->value, + sprintf('subscription/%s', $methodName), + null, + ['transaction_id' => $transaction->id], + null, + false, + $newCart->secure_key + ); + } catch (\Throwable $exception) { + $specificPrice->delete(); + + throw $exception; + } + + $specificPrice->delete(); + $orderId = (int) Order::getIdByCartId((int) $newCart->id); $order = new Order($orderId); - $specificPrice->delete(); + if ((float) $order->total_paid_tax_incl !== (float) $subscription->amount->value) { + $this->logger->error('Paid price is not equal to the order\'s total', [ + 'Paid price' => (float) $subscription->amount->value, + 'Order price' => (float) $order->total_paid_tax_incl, + ]); + } $this->mollieOrderCreationService->createMolliePayment($transaction, (int) $newCart->id, $order->reference, (int) $orderId, PaymentStatus::STATUS_PAID);