From 8a7f971110ee970386b7218e64a0d6e71905b0c3 Mon Sep 17 00:00:00 2001 From: mandan2 Date: Mon, 18 Sep 2023 17:42:16 +0300 Subject: [PATCH 1/5] PIPRES-338: Mixed cart subscription listing improvements --- controllers/front/recurringOrderDetail.php | 2 +- controllers/front/subscriptions.php | 2 +- src/Service/MailService.php | 3 +- subscription/Entity/MolRecurringOrder.php | 4 + .../Factory/CreateSubscriptionDataFactory.php | 6 +- .../SubscriptionGridDefinitionFactory.php | 12 +-- .../Grid/SubscriptionGridQueryBuilder.php | 4 +- .../Handler/SubscriptionCreationHandler.php | 1 + .../Install/DatabaseTableInstaller.php | 55 +++++++++++++- subscription/Presenter/OrderPresenter.php | 35 +++++++++ .../Presenter/RecurringOrderLazyArray.php | 40 ++++++++++ .../Presenter/RecurringOrderPresenter.php | 15 +++- .../Presenter/RecurringOrdersPresenter.php | 15 +--- .../Presenter/OrderPresenterTest.php | 74 +++++++++++++++++++ tests/bootstrap.php | 20 ++++- upgrade/Upgrade-6.0.4.php | 47 ++++++++++++ 16 files changed, 300 insertions(+), 35 deletions(-) create mode 100644 subscription/Presenter/OrderPresenter.php create mode 100644 subscription/Presenter/RecurringOrderLazyArray.php create mode 100644 tests/Integration/Subscription/Presenter/OrderPresenterTest.php diff --git a/controllers/front/recurringOrderDetail.php b/controllers/front/recurringOrderDetail.php index b0b5d0b48..6fe4b7b86 100644 --- a/controllers/front/recurringOrderDetail.php +++ b/controllers/front/recurringOrderDetail.php @@ -27,7 +27,7 @@ use Mollie\Controller\AbstractMollieController; use Mollie\Subscription\Handler\FreeOrderCreationHandler; use Mollie\Subscription\Handler\SubscriptionCancellationHandler; -use Mollie\Subscription\Logger\RecurringOrderPresenter; +use Mollie\Subscription\Presenter\RecurringOrderPresenter; use Mollie\Subscription\Repository\RecurringOrderRepositoryInterface; class MollieRecurringOrderDetailModuleFrontController extends AbstractMollieController diff --git a/controllers/front/subscriptions.php b/controllers/front/subscriptions.php index 5bc2db973..b0a9d81b2 100644 --- a/controllers/front/subscriptions.php +++ b/controllers/front/subscriptions.php @@ -1,7 +1,7 @@ id_product, false, $customer->id_lang); - $totalPrice = NumberUtility::times((float) $recurringOrderProduct->unit_price, (float) $recurringOrderProduct->quantity); + $totalPrice = $recurringOrder->total_tax_incl; $unitPrice = new Number((string) $recurringOrderProduct->unit_price); return [ diff --git a/subscription/Entity/MolRecurringOrder.php b/subscription/Entity/MolRecurringOrder.php index 691339212..07adcee47 100644 --- a/subscription/Entity/MolRecurringOrder.php +++ b/subscription/Entity/MolRecurringOrder.php @@ -29,6 +29,9 @@ class MolRecurringOrder extends ObjectModel /** @var string */ public $status; + /** @var float */ + public $total_tax_incl; + /** @var string */ public $payment_method; @@ -71,6 +74,7 @@ class MolRecurringOrder extends ObjectModel 'mollie_customer_id' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], 'description' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], 'status' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], + 'total_tax_incl' => ['type' => self::TYPE_FLOAT, 'validate' => 'isFloat'], 'payment_method' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], 'next_payment' => ['type' => self::TYPE_DATE], 'reminder_at' => ['type' => self::TYPE_DATE], diff --git a/subscription/Factory/CreateSubscriptionDataFactory.php b/subscription/Factory/CreateSubscriptionDataFactory.php index 109774f7b..6563b892c 100644 --- a/subscription/Factory/CreateSubscriptionDataFactory.php +++ b/subscription/Factory/CreateSubscriptionDataFactory.php @@ -74,10 +74,14 @@ public function build(Order $order, array $subscriptionProduct): SubscriptionDat $currency = $this->currencyAdapter->getById((int) $order->id_currency); $description = $this->subscriptionDescription->getSubscriptionDescription($order); + $orderTotal = (float) $subscriptionProduct['total_price_tax_incl'] + + (float) $order->total_wrapping_tax_incl + + (float) $order->total_shipping_tax_incl; + /** * NOTE: we will only send product price as total for subscriptions */ - $orderAmount = new Amount((float) $subscriptionProduct['total_price_tax_incl'], $currency->iso_code); + $orderAmount = new Amount($orderTotal, $currency->iso_code); $subscriptionData = new SubscriptionDataDTO( $molCustomer->customer_id, $orderAmount, diff --git a/subscription/Grid/SubscriptionGridDefinitionFactory.php b/subscription/Grid/SubscriptionGridDefinitionFactory.php index ea1f1b8dd..876d18058 100644 --- a/subscription/Grid/SubscriptionGridDefinitionFactory.php +++ b/subscription/Grid/SubscriptionGridDefinitionFactory.php @@ -104,10 +104,10 @@ protected function getColumns() 'sortable' => true, ]) ) - ->add((new DataColumn('unit_price')) - ->setName($this->module->l('Unit price', self::FILE_NAME)) + ->add((new DataColumn('total_price')) + ->setName($this->module->l('Total price', self::FILE_NAME)) ->setOptions([ - 'field' => 'unit_price', + 'field' => 'total_price', 'sortable' => true, ]) ) @@ -220,14 +220,14 @@ protected function getFilters() ]) ->setAssociatedColumn('status') ) - ->add((new Filter('unit_price', MoneyType::class)) + ->add((new Filter('total_price', MoneyType::class)) ->setTypeOptions([ 'required' => false, 'attr' => [ - 'placeholder' => $this->module->l('Unit price', self::FILE_NAME), + 'placeholder' => $this->module->l('Total price', self::FILE_NAME), ], ]) - ->setAssociatedColumn('unit_price') + ->setAssociatedColumn('total_price') ) ->add((new Filter('iso_code', TextType::class)) ->setTypeOptions([ diff --git a/subscription/Grid/SubscriptionGridQueryBuilder.php b/subscription/Grid/SubscriptionGridQueryBuilder.php index 61a4db912..7abda1f96 100644 --- a/subscription/Grid/SubscriptionGridQueryBuilder.php +++ b/subscription/Grid/SubscriptionGridQueryBuilder.php @@ -47,7 +47,7 @@ public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria): $qb = $this->getQueryBuilder($searchCriteria->getFilters()) ->select('recurring_order.*') ->addSelect($this->getNameField() . ' as fullname') - ->addSelect('ROUND(orders.total_paid, 2) as unit_price') + ->addSelect('recurring_order.total_tax_incl as total_price') ->addSelect('currency.iso_code') ; @@ -106,7 +106,7 @@ private function applyFilters(array $filters, QueryBuilder $qb): void 'fullname' => $this->getNameField(), 'description' => 'recurring_order.description', 'status' => 'recurring_order.status', - 'unit_price' => 'orders.total_paid', + 'total_price' => 'recurring_order.total_tax_incl', 'iso_code' => 'currency.iso_code', ]; diff --git a/subscription/Handler/SubscriptionCreationHandler.php b/subscription/Handler/SubscriptionCreationHandler.php index 864c0479d..89c5c220a 100644 --- a/subscription/Handler/SubscriptionCreationHandler.php +++ b/subscription/Handler/SubscriptionCreationHandler.php @@ -85,6 +85,7 @@ private function createRecurringOrder(MolRecurringOrdersProduct $recurringOrders $recurringOrder->id_address_invoice = $order->id_address_invoice; $recurringOrder->description = $subscription->description; $recurringOrder->status = $subscription->status; + $recurringOrder->total_tax_incl = (float) $subscription->amount->value; $recurringOrder->payment_method = $method; $recurringOrder->next_payment = $subscription->nextPaymentDate; $recurringOrder->reminder_at = $subscription->nextPaymentDate; //todo: add logic to get reminder date when reminder is done diff --git a/subscription/Install/DatabaseTableInstaller.php b/subscription/Install/DatabaseTableInstaller.php index d8ea0783b..c51066c94 100644 --- a/subscription/Install/DatabaseTableInstaller.php +++ b/subscription/Install/DatabaseTableInstaller.php @@ -18,7 +18,7 @@ public function install(): bool } } - return true; + return $this->alterTableCommands(); } /** @@ -45,6 +45,7 @@ private function getCommands(): array `mollie_customer_id` VARCHAR(64) NOT NULL, `payment_method` VARCHAR(64) NOT NULL, `id_mol_recurring_orders_product` INT(64) NOT NULL, + `total_tax_incl` decimal(20, 6) NOT NULL, `date_add` datetime NOT NULL, `date_update` datetime NOT NULL ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;'; @@ -61,4 +62,56 @@ private function getCommands(): array return $sql; } + + private function alterTableCommands(): bool + { + $queries = [ + [ + 'verification' => ' + SELECT COUNT(*) > 0 AS count + FROM information_schema.columns + WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mollie_payments" AND column_name = "mandate_id"; + ', + 'alter' => [ + ' + ALTER TABLE ' . _DB_PREFIX_ . 'mollie_payments + ADD COLUMN mandate_id VARCHAR(64); + ', + ], + ], + [ + 'verification' => ' + SELECT COUNT(*) > 0 AS count + FROM information_schema.columns + WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mol_recurring_order" AND column_name = "total_tax_incl"; + ', + 'alter' => [ + ' + ALTER TABLE ' . _DB_PREFIX_ . 'mol_recurring_order + ADD COLUMN total_tax_incl decimal(20, 6) NOT NULL; + ', + ' + UPDATE ' . _DB_PREFIX_ . 'mol_recurring_order ro + JOIN ' . _DB_PREFIX_ . 'orders o ON ro.id_order = o.id_order + SET ro.total_tax_incl = o.total_paid_tax_incl; + ', + ], + ], + ]; + + foreach ($queries as $query) { + /* only run if it doesn't exist */ + if (Db::getInstance()->getValue($query['verification'])) { + continue; + } + + foreach ($query['alter'] as $alterQuery) { + if (!Db::getInstance()->execute($alterQuery)) { + return false; + } + } + } + + return true; + } } diff --git a/subscription/Presenter/OrderPresenter.php b/subscription/Presenter/OrderPresenter.php new file mode 100644 index 000000000..c907b7e7c --- /dev/null +++ b/subscription/Presenter/OrderPresenter.php @@ -0,0 +1,35 @@ +getCartProducts(); + + foreach ($orderProducts as $orderProduct) { + if ((int) $orderProduct['id_product_attribute'] !== $recurringOrderProductAttributeId) { + $order->total_paid_tax_excl -= (float) $orderProduct['total_price_tax_excl']; + + continue; + } + + $order->total_products = (float) $orderProduct['total_price_tax_excl']; + $order->total_products_wt = (float) $orderProduct['total_price_tax_incl']; + $order->total_paid_tax_incl = $recurringOrderTotalTaxIncl; + $order->total_paid = $recurringOrderTotalTaxIncl; + + break; + } + + $orderLazyArray = new RecurringOrderLazyArray($order); + + $orderLazyArray->setRecurringOrderProductAttributeId($recurringOrderProductAttributeId); + + return $orderLazyArray; + } +} diff --git a/subscription/Presenter/RecurringOrderLazyArray.php b/subscription/Presenter/RecurringOrderLazyArray.php new file mode 100644 index 000000000..7d91bf59f --- /dev/null +++ b/subscription/Presenter/RecurringOrderLazyArray.php @@ -0,0 +1,40 @@ +recurringOrderProductAttributeId = $recurringOrderProductAttributeId; + } + + /** + * @arrayAccess + * + * @return array + */ + public function getProducts(): array + { + $subscriptionProduct = []; + + $orderProducts = parent::getProducts(); + + foreach ($orderProducts as $orderProduct) { + if ((int) $orderProduct['id_product_attribute'] !== $this->recurringOrderProductAttributeId) { + continue; + } + + $subscriptionProduct[] = $orderProduct; + + break; + } + + return $subscriptionProduct; + } +} diff --git a/subscription/Presenter/RecurringOrderPresenter.php b/subscription/Presenter/RecurringOrderPresenter.php index abb4c60b8..c70178452 100644 --- a/subscription/Presenter/RecurringOrderPresenter.php +++ b/subscription/Presenter/RecurringOrderPresenter.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Mollie\Subscription\Logger; +namespace Mollie\Subscription\Presenter; use Currency; use Mollie\Adapter\Language; @@ -10,7 +10,6 @@ use Mollie\Subscription\Repository\RecurringOrderRepositoryInterface; use Mollie\Subscription\Repository\RecurringOrdersProductRepositoryInterface; use Order; -use PrestaShop\PrestaShop\Adapter\Presenter\Order\OrderPresenter; use Product; class RecurringOrderPresenter @@ -23,17 +22,21 @@ class RecurringOrderPresenter private $language; /** @var MethodApi */ private $methodApi; + /** @var OrderPresenter */ + private $orderPresenter; public function __construct( RecurringOrderRepositoryInterface $recurringOrderRepository, RecurringOrdersProductRepositoryInterface $recurringOrdersProductRepository, Language $language, - MethodApi $methodApi + MethodApi $methodApi, + OrderPresenter $orderPresenter ) { $this->recurringOrderRepository = $recurringOrderRepository; $this->recurringOrdersProductRepository = $recurringOrdersProductRepository; $this->language = $language; $this->methodApi = $methodApi; + $this->orderPresenter = $orderPresenter; } public function present(int $recurringOrderId): array @@ -56,7 +59,11 @@ public function present(int $recurringOrderId): array $recurringOrderData['recurring_order'] = $recurringOrder; $recurringOrderData['recurring_product'] = $recurringProduct; $recurringOrderData['product'] = $product; - $recurringOrderData['order'] = (new OrderPresenter())->present($order); + $recurringOrderData['order'] = $this->orderPresenter->present( + $order, + (int) $recurringProduct->id_product_attribute, + (float) $recurringOrder->total_tax_incl + ); $recurringOrderData['payment_methods'] = $this->methodApi->getMethodsForFirstPayment($this->language->getContextLanguage()->locale, $currency->iso_code); return $recurringOrderData; diff --git a/subscription/Presenter/RecurringOrdersPresenter.php b/subscription/Presenter/RecurringOrdersPresenter.php index 3557f0f36..42bc1f93b 100644 --- a/subscription/Presenter/RecurringOrdersPresenter.php +++ b/subscription/Presenter/RecurringOrdersPresenter.php @@ -2,19 +2,17 @@ declare(strict_types=1); -namespace Mollie\Subscription\Logger; +namespace Mollie\Subscription\Presenter; use Currency; use Mollie\Adapter\Context; use Mollie\Adapter\Language; use Mollie\Adapter\Link; use Mollie\Adapter\ToolsAdapter; -use Mollie\Repository\OrderRepositoryInterface; use Mollie\Subscription\Repository\RecurringOrderRepositoryInterface; use Mollie\Subscription\Repository\RecurringOrdersProductRepositoryInterface; use Mollie\Utility\NumberUtility; use MolRecurringOrder; -use Order; use Product; class RecurringOrdersPresenter @@ -29,8 +27,6 @@ class RecurringOrdersPresenter private $language; /** @var ToolsAdapter */ private $tools; - /** @var OrderRepositoryInterface */ - private $orderRepository; /** @var Context */ private $context; @@ -40,7 +36,6 @@ public function __construct( Link $link, Language $language, ToolsAdapter $tools, - OrderRepositoryInterface $orderRepository, Context $context ) { $this->recurringOrderRepository = $recurringOrderRepository; @@ -48,7 +43,6 @@ public function __construct( $this->recurringOrdersProductRepository = $recurringOrdersProductRepository; $this->language = $language; $this->tools = $tools; - $this->orderRepository = $orderRepository; $this->context = $context; } @@ -64,11 +58,6 @@ public function present(string $molCustomerId): array $recurringOrdersPresentData = []; /** @var MolRecurringOrder $recurringOrder */ foreach ($recurringOrders as $recurringOrder) { - /** @var Order $order */ - $order = $this->orderRepository->findOneBy([ - 'id_order' => $recurringOrder->id_order, - ]); - $recurringProduct = $this->recurringOrdersProductRepository->findOneBy([ 'id_mol_recurring_orders_product' => $recurringOrder->id, ]); @@ -79,7 +68,7 @@ public function present(string $molCustomerId): array $recurringOrderData['recurring_order'] = $recurringOrder; $recurringOrderData['details_url'] = $this->link->getModuleLink('mollie', 'recurringOrderDetail', ['id_mol_recurring_order' => $recurringOrder->id]); $recurringOrderData['product_name'] = is_array($product->name) ? $product->name[$this->context->getLanguageId()] : $product->name; - $recurringOrderData['total_price'] = $this->tools->displayPrice(NumberUtility::toPrecision((float) $order->total_paid, 2), new Currency($recurringOrder->id_currency)); + $recurringOrderData['total_price'] = $this->tools->displayPrice(NumberUtility::toPrecision((float) $recurringOrder->total_tax_incl, 2), new Currency($recurringOrder->id_currency)); $recurringOrderData['currency'] = new \Currency($recurringOrder->id_currency); $recurringOrdersPresentData[] = $recurringOrderData; } diff --git a/tests/Integration/Subscription/Presenter/OrderPresenterTest.php b/tests/Integration/Subscription/Presenter/OrderPresenterTest.php new file mode 100644 index 000000000..a7601cd92 --- /dev/null +++ b/tests/Integration/Subscription/Presenter/OrderPresenterTest.php @@ -0,0 +1,74 @@ + 1, + 'id_product_attribute' => 1, + 'total_price_tax_excl' => 10.00, + 'product_price' => 10.00, + 'total_price' => 10.00, + 'total_price_tax_incl' => 12.10, + 'product_price_wt' => 12.10, + 'total_wt' => 12.10, + 'product_name' => 'test-product-1', + 'product_quantity' => 1, + 'product_id' => 1, + 'id_customization' => 1, + ], + [ + 'product_attribute_id' => 2, + 'id_product_attribute' => 2, + 'total_price_tax_excl' => 100.00, + 'product_price' => 100.00, + 'total_price' => 100.00, + 'total_price_tax_incl' => 121.00, + 'product_price_wt' => 121.00, + 'total_wt' => 121.00, + 'product_name' => 'test-product-2', + 'product_quantity' => 2, + 'product_id' => 2, + 'id_customization' => 1, + ], + [ + 'product_attribute_id' => 3, + 'id_product_attribute' => 3, + 'total_price_tax_excl' => 1000.00, + 'product_price' => 1000.00, + 'total_price' => 1000.00, + 'total_price_tax_incl' => 1210.00, + 'product_price_wt' => 1210.00, + 'total_wt' => 1210.00, + 'product_name' => 'test-product-3', + 'product_quantity' => 3, + 'product_id' => 3, + 'id_customization' => 1, + ], + ]; + + $order = $this->createMock(\Order::class); + $order->total_paid_tax_excl = 1500; + $order->id_currency = 1; + $order->method('getCartProducts')->willReturn($products); + $order->method('getProducts')->willReturn($products); + + $orderPresenter = new OrderPresenter(); + + $result = $orderPresenter->present( + $order, + 3, + 1300 + ); + + $this->assertCount(1, $result->getProducts()); + $this->assertEquals(3, $result->getProducts()[0]['id_product_attribute']); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index f29c2f9d7..6db43cd14 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,9 +1,21 @@ boot(); +} +// any actions to apply before any given tests can be done here diff --git a/upgrade/Upgrade-6.0.4.php b/upgrade/Upgrade-6.0.4.php index 497c98904..3b8831c31 100644 --- a/upgrade/Upgrade-6.0.4.php +++ b/upgrade/Upgrade-6.0.4.php @@ -28,6 +28,10 @@ function upgrade_module_6_0_4(Mollie $module): bool updateConfigurationValues604($module); updateOrderStatusNames604($module); + if (!modifyExistingTables604()) { + return false; + } + return true; } @@ -105,3 +109,46 @@ function updateOrderStatusNames604(Mollie $module) $authorizablePaymentStatusAuthorized->save(); } +function modifyExistingTables604(): bool +{ + $sql = ' + SELECT COUNT(*) > 0 AS count + FROM information_schema.columns + WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mol_recurring_order" AND column_name = "total_tax_incl"; + '; + + /** only add it if it doesn't exist */ + if (!(int) Db::getInstance()->getValue($sql)) { + $sql = ' + ALTER TABLE ' . _DB_PREFIX_ . 'mol_recurring_order + ADD COLUMN total_tax_incl decimal(20, 6) NOT NULL; + '; + + try { + if (!Db::getInstance()->execute($sql)) { + return false; + } + } catch (Exception $e) { + PrestaShopLogger::addLog("Mollie upgrade error: {$e->getMessage()}"); + + return false; + } + } + + $sql = ' + UPDATE ' . _DB_PREFIX_ . 'mol_recurring_order ro + JOIN ' . _DB_PREFIX_ . 'orders o ON ro.id_order = o.id_order + SET ro.total_tax_incl = o.total_paid_tax_incl; + '; + + try { + Db::getInstance()->execute($sql); + } catch (Exception $e) { + PrestaShopLogger::addLog("Mollie upgrade error: {$e->getMessage()}"); + + return false; + } + + return true; +} + From 47a046240c06fd19382f031f7adf91f214964771 Mon Sep 17 00:00:00 2001 From: mandan2 Date: Tue, 19 Sep 2023 09:35:59 +0300 Subject: [PATCH 2/5] added rounding for total price and moved part of install improvements to main install file --- src/Install/DatabaseTableInstaller.php | 38 ++++++++++++++++++- src/Install/DatabaseTableUninstaller.php | 1 - src/Service/MailService.php | 8 ++-- .../Grid/SubscriptionGridQueryBuilder.php | 2 +- .../Install/DatabaseTableInstaller.php | 15 +------- .../Presenter/RecurringOrderPresenter.php | 3 +- 6 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/Install/DatabaseTableInstaller.php b/src/Install/DatabaseTableInstaller.php index 48ee1371b..ddd16f01b 100644 --- a/src/Install/DatabaseTableInstaller.php +++ b/src/Install/DatabaseTableInstaller.php @@ -21,12 +21,12 @@ public function install() $commands = $this->getCommands(); foreach ($commands as $query) { - if (false == Db::getInstance()->execute($query)) { + if (!Db::getInstance()->execute($query)) { return false; } } - return true; + return $this->alterTableCommands(); } /** @@ -142,4 +142,38 @@ private function getCommands() return $sql; } + + private function alterTableCommands(): bool + { + $queries = [ + [ + 'verification' => ' + SELECT COUNT(*) > 0 AS count + FROM information_schema.columns + WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mollie_payments" AND column_name = "mandate_id"; + ', + 'alter' => [ + ' + ALTER TABLE ' . _DB_PREFIX_ . 'mollie_payments + ADD COLUMN mandate_id VARCHAR(64); + ', + ], + ], + ]; + + foreach ($queries as $query) { + /* only run if it doesn't exist */ + if (Db::getInstance()->getValue($query['verification'])) { + continue; + } + + foreach ($query['alter'] as $alterQuery) { + if (!Db::getInstance()->execute($alterQuery)) { + return false; + } + } + } + + return true; + } } diff --git a/src/Install/DatabaseTableUninstaller.php b/src/Install/DatabaseTableUninstaller.php index 7f6d24ed5..2dde9bee9 100644 --- a/src/Install/DatabaseTableUninstaller.php +++ b/src/Install/DatabaseTableUninstaller.php @@ -34,7 +34,6 @@ private function getCommands(): array $sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'mol_country`;'; $sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'mol_payment_method`;'; $sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'mol_payment_method_issuer`;'; - $sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'mol_order_payment_fee`;'; $sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'mol_carrier_information`;'; $sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'mol_pending_order_cart`;'; $sql[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'mol_excluded_country`;'; diff --git a/src/Service/MailService.php b/src/Service/MailService.php index 153d5cc0e..0b772ae6b 100644 --- a/src/Service/MailService.php +++ b/src/Service/MailService.php @@ -28,12 +28,12 @@ use Mollie\Adapter\ToolsAdapter; use Mollie\Subscription\Repository\RecurringOrderRepositoryInterface; use Mollie\Subscription\Repository\RecurringOrdersProductRepositoryInterface; +use Mollie\Utility\NumberUtility; use MolRecurringOrder; use MolRecurringOrdersProduct; use Order; use OrderState; use PDF; -use PrestaShop\Decimal\Number; use Product; use State; use Tools; @@ -185,13 +185,13 @@ private function getSubscriptionCancellationWarningMailData( Customer $customer ): array { $product = new Product($recurringOrderProduct->id_product, false, $customer->id_lang); - $totalPrice = $recurringOrder->total_tax_incl; - $unitPrice = new Number((string) $recurringOrderProduct->unit_price); + $totalPrice = NumberUtility::toPrecision((float) $recurringOrder->total_tax_incl, 2); + $unitPrice = NumberUtility::toPrecision((float) $recurringOrderProduct->unit_price, 2); return [ 'subscription_reference' => $recurringOrder->mollie_subscription_id, 'product_name' => $product->name, - 'unit_price' => $this->toolsAdapter->displayPrice($unitPrice->toPrecision(2), new Currency($recurringOrder->id_currency)), + 'unit_price' => $this->toolsAdapter->displayPrice($unitPrice, new Currency($recurringOrder->id_currency)), 'quantity' => $recurringOrderProduct->quantity, 'total_price' => $this->toolsAdapter->displayPrice($totalPrice, new Currency($recurringOrder->id_currency)), 'firstName' => $customer->firstname, diff --git a/subscription/Grid/SubscriptionGridQueryBuilder.php b/subscription/Grid/SubscriptionGridQueryBuilder.php index 7abda1f96..307d27150 100644 --- a/subscription/Grid/SubscriptionGridQueryBuilder.php +++ b/subscription/Grid/SubscriptionGridQueryBuilder.php @@ -47,7 +47,7 @@ public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria): $qb = $this->getQueryBuilder($searchCriteria->getFilters()) ->select('recurring_order.*') ->addSelect($this->getNameField() . ' as fullname') - ->addSelect('recurring_order.total_tax_incl as total_price') + ->addSelect('ROUND(recurring_order.total_tax_incl, 2) as total_price') ->addSelect('currency.iso_code') ; diff --git a/subscription/Install/DatabaseTableInstaller.php b/subscription/Install/DatabaseTableInstaller.php index c51066c94..f146e7377 100644 --- a/subscription/Install/DatabaseTableInstaller.php +++ b/subscription/Install/DatabaseTableInstaller.php @@ -13,7 +13,7 @@ public function install(): bool $commands = $this->getCommands(); foreach ($commands as $query) { - if (false == Db::getInstance()->execute($query)) { + if (!Db::getInstance()->execute($query)) { return false; } } @@ -66,19 +66,6 @@ private function getCommands(): array private function alterTableCommands(): bool { $queries = [ - [ - 'verification' => ' - SELECT COUNT(*) > 0 AS count - FROM information_schema.columns - WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mollie_payments" AND column_name = "mandate_id"; - ', - 'alter' => [ - ' - ALTER TABLE ' . _DB_PREFIX_ . 'mollie_payments - ADD COLUMN mandate_id VARCHAR(64); - ', - ], - ], [ 'verification' => ' SELECT COUNT(*) > 0 AS count diff --git a/subscription/Presenter/RecurringOrderPresenter.php b/subscription/Presenter/RecurringOrderPresenter.php index c70178452..6d2a6c5cd 100644 --- a/subscription/Presenter/RecurringOrderPresenter.php +++ b/subscription/Presenter/RecurringOrderPresenter.php @@ -9,6 +9,7 @@ use Mollie\Subscription\Api\MethodApi; use Mollie\Subscription\Repository\RecurringOrderRepositoryInterface; use Mollie\Subscription\Repository\RecurringOrdersProductRepositoryInterface; +use Mollie\Utility\NumberUtility; use Order; use Product; @@ -62,7 +63,7 @@ public function present(int $recurringOrderId): array $recurringOrderData['order'] = $this->orderPresenter->present( $order, (int) $recurringProduct->id_product_attribute, - (float) $recurringOrder->total_tax_incl + NumberUtility::toPrecision((float) $recurringOrder->total_tax_incl, 2) ); $recurringOrderData['payment_methods'] = $this->methodApi->getMethodsForFirstPayment($this->language->getContextLanguage()->locale, $currency->iso_code); From 176c63cd670ed732b25816429ee1bafef9cccd62 Mon Sep 17 00:00:00 2001 From: mandan2 Date: Tue, 19 Sep 2023 09:57:36 +0300 Subject: [PATCH 3/5] fix --- src/Install/DatabaseTableInstaller.php | 43 ++++++-------- src/Service/MailService.php | 12 +++- .../Install/DatabaseTableInstaller.php | 58 +++++++++---------- .../Presenter/RecurringOrderPresenter.php | 5 +- 4 files changed, 58 insertions(+), 60 deletions(-) diff --git a/src/Install/DatabaseTableInstaller.php b/src/Install/DatabaseTableInstaller.php index ddd16f01b..7815d683d 100644 --- a/src/Install/DatabaseTableInstaller.php +++ b/src/Install/DatabaseTableInstaller.php @@ -145,33 +145,24 @@ private function getCommands() private function alterTableCommands(): bool { - $queries = [ - [ - 'verification' => ' - SELECT COUNT(*) > 0 AS count - FROM information_schema.columns - WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mollie_payments" AND column_name = "mandate_id"; - ', - 'alter' => [ - ' - ALTER TABLE ' . _DB_PREFIX_ . 'mollie_payments - ADD COLUMN mandate_id VARCHAR(64); - ', - ], - ], - ]; - - foreach ($queries as $query) { - /* only run if it doesn't exist */ - if (Db::getInstance()->getValue($query['verification'])) { - continue; - } + $query = ' + SELECT COUNT(*) > 0 AS count + FROM information_schema.columns + WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mollie_payments" AND column_name = "mandate_id"; + '; - foreach ($query['alter'] as $alterQuery) { - if (!Db::getInstance()->execute($alterQuery)) { - return false; - } - } + /* only run if it doesn't exist */ + if (Db::getInstance()->getValue($query)) { + return true; + } + + $query = ' + ALTER TABLE ' . _DB_PREFIX_ . 'mollie_payments + ADD COLUMN mandate_id VARCHAR(64); + '; + + if (!Db::getInstance()->execute($query)) { + return false; } return true; diff --git a/src/Service/MailService.php b/src/Service/MailService.php index 0b772ae6b..3b0d812d7 100644 --- a/src/Service/MailService.php +++ b/src/Service/MailService.php @@ -185,8 +185,16 @@ private function getSubscriptionCancellationWarningMailData( Customer $customer ): array { $product = new Product($recurringOrderProduct->id_product, false, $customer->id_lang); - $totalPrice = NumberUtility::toPrecision((float) $recurringOrder->total_tax_incl, 2); - $unitPrice = NumberUtility::toPrecision((float) $recurringOrderProduct->unit_price, 2); + + $totalPrice = NumberUtility::toPrecision( + (float) $recurringOrder->total_tax_incl, + NumberUtility::DECIMAL_PRECISION + ); + + $unitPrice = NumberUtility::toPrecision( + (float) $recurringOrderProduct->unit_price, + NumberUtility::DECIMAL_PRECISION + ); return [ 'subscription_reference' => $recurringOrder->mollie_subscription_id, diff --git a/subscription/Install/DatabaseTableInstaller.php b/subscription/Install/DatabaseTableInstaller.php index f146e7377..497e6718c 100644 --- a/subscription/Install/DatabaseTableInstaller.php +++ b/subscription/Install/DatabaseTableInstaller.php @@ -65,38 +65,34 @@ private function getCommands(): array private function alterTableCommands(): bool { - $queries = [ - [ - 'verification' => ' - SELECT COUNT(*) > 0 AS count - FROM information_schema.columns - WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mol_recurring_order" AND column_name = "total_tax_incl"; - ', - 'alter' => [ - ' - ALTER TABLE ' . _DB_PREFIX_ . 'mol_recurring_order - ADD COLUMN total_tax_incl decimal(20, 6) NOT NULL; - ', - ' - UPDATE ' . _DB_PREFIX_ . 'mol_recurring_order ro - JOIN ' . _DB_PREFIX_ . 'orders o ON ro.id_order = o.id_order - SET ro.total_tax_incl = o.total_paid_tax_incl; - ', - ], - ], - ]; - - foreach ($queries as $query) { - /* only run if it doesn't exist */ - if (Db::getInstance()->getValue($query['verification'])) { - continue; - } + $query = ' + SELECT COUNT(*) > 0 AS count + FROM information_schema.columns + WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mol_recurring_order" AND column_name = "total_tax_incl"; + '; - foreach ($query['alter'] as $alterQuery) { - if (!Db::getInstance()->execute($alterQuery)) { - return false; - } - } + /* only run if it doesn't exist */ + if (Db::getInstance()->getValue($query)) { + return true; + } + + $query = ' + ALTER TABLE ' . _DB_PREFIX_ . 'mol_recurring_order + ADD COLUMN total_tax_incl decimal(20, 6) NOT NULL; + '; + + if (!Db::getInstance()->execute($query)) { + return false; + } + + $query = ' + UPDATE ' . _DB_PREFIX_ . 'mol_recurring_order ro + JOIN ' . _DB_PREFIX_ . 'orders o ON ro.id_order = o.id_order + SET ro.total_tax_incl = o.total_paid_tax_incl; + '; + + if (!Db::getInstance()->execute($query)) { + return false; } return true; diff --git a/subscription/Presenter/RecurringOrderPresenter.php b/subscription/Presenter/RecurringOrderPresenter.php index 6d2a6c5cd..3601cec40 100644 --- a/subscription/Presenter/RecurringOrderPresenter.php +++ b/subscription/Presenter/RecurringOrderPresenter.php @@ -63,7 +63,10 @@ public function present(int $recurringOrderId): array $recurringOrderData['order'] = $this->orderPresenter->present( $order, (int) $recurringProduct->id_product_attribute, - NumberUtility::toPrecision((float) $recurringOrder->total_tax_incl, 2) + NumberUtility::toPrecision( + (float) $recurringOrder->total_tax_incl, + NumberUtility::DECIMAL_PRECISION + ) ); $recurringOrderData['payment_methods'] = $this->methodApi->getMethodsForFirstPayment($this->language->getContextLanguage()->locale, $currency->iso_code); From 1a4feb0d262f84316b51ff3a5b64579ea0df95f4 Mon Sep 17 00:00:00 2001 From: mandan2 Date: Tue, 19 Sep 2023 10:00:46 +0300 Subject: [PATCH 4/5] added mandate_id append to upgrade file too --- upgrade/Upgrade-6.0.4.php | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/upgrade/Upgrade-6.0.4.php b/upgrade/Upgrade-6.0.4.php index 3b8831c31..57205a314 100644 --- a/upgrade/Upgrade-6.0.4.php +++ b/upgrade/Upgrade-6.0.4.php @@ -112,16 +112,16 @@ function updateOrderStatusNames604(Mollie $module) function modifyExistingTables604(): bool { $sql = ' - SELECT COUNT(*) > 0 AS count - FROM information_schema.columns - WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mol_recurring_order" AND column_name = "total_tax_incl"; + SELECT COUNT(*) > 0 AS count + FROM information_schema.columns + WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND table_name = "' . _DB_PREFIX_ . 'mol_recurring_order" AND column_name = "total_tax_incl"; '; /** only add it if it doesn't exist */ if (!(int) Db::getInstance()->getValue($sql)) { $sql = ' - ALTER TABLE ' . _DB_PREFIX_ . 'mol_recurring_order - ADD COLUMN total_tax_incl decimal(20, 6) NOT NULL; + ALTER TABLE ' . _DB_PREFIX_ . 'mol_recurring_order + ADD COLUMN total_tax_incl decimal(20, 6) NOT NULL; '; try { @@ -149,6 +149,30 @@ function modifyExistingTables604(): bool return false; } + $sql = ' + SELECT COUNT(*) > 0 AS count + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = "' . _DB_NAME_ . '" AND TABLE_NAME = "' . _DB_PREFIX_ . 'mollie_payments" AND COLUMN_NAME = "mandate_id" + '; + + /** only add it if it doesn't exist */ + if (!Db::getInstance()->getValue($sql)) { + $sql = ' + ALTER TABLE ' . _DB_PREFIX_ . 'mollie_payments + ADD `mandate_id` VARCHAR(64); + '; + + try { + if (!Db::getInstance()->execute($sql)) { + return false; + } + } catch (Exception $e) { + PrestaShopLogger::addLog("Mollie upgrade error: {$e->getMessage()}"); + + return false; + } + } + return true; } From 44f1eeaabd0d66ef41c273989361d4f028f5fe6b Mon Sep 17 00:00:00 2001 From: mandan2 Date: Tue, 19 Sep 2023 10:13:56 +0300 Subject: [PATCH 5/5] fix --- .../Integration/Subscription/Presenter/OrderPresenterTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Integration/Subscription/Presenter/OrderPresenterTest.php b/tests/Integration/Subscription/Presenter/OrderPresenterTest.php index a7601cd92..1b3ad9a7a 100644 --- a/tests/Integration/Subscription/Presenter/OrderPresenterTest.php +++ b/tests/Integration/Subscription/Presenter/OrderPresenterTest.php @@ -60,7 +60,8 @@ public function testItSuccessfullyPresentsOrder(): void $order->method('getCartProducts')->willReturn($products); $order->method('getProducts')->willReturn($products); - $orderPresenter = new OrderPresenter(); + /** @var OrderPresenter $orderPresenter */ + $orderPresenter = $this->getService(OrderPresenter::class); $result = $orderPresenter->present( $order,