diff --git a/src/ServiceProvider/BaseServiceProvider.php b/src/ServiceProvider/BaseServiceProvider.php index 2e033af63..44f50e108 100644 --- a/src/ServiceProvider/BaseServiceProvider.php +++ b/src/ServiceProvider/BaseServiceProvider.php @@ -106,6 +106,8 @@ use Mollie\Subscription\Repository\RecurringOrderRepositoryInterface; use Mollie\Subscription\Repository\RecurringOrdersProductRepository; use Mollie\Subscription\Repository\RecurringOrdersProductRepositoryInterface; +use Mollie\Subscription\Repository\SpecificPriceRepository; +use Mollie\Subscription\Repository\SpecificPriceRepositoryInterface; use Mollie\Subscription\Utility\Clock; use Mollie\Subscription\Utility\ClockInterface; use Mollie\Utility\Decoder\DecoderInterface; @@ -139,6 +141,7 @@ public function register(Container $container) $this->addService($container, RetryHandlerInterface::class, $container->get(RetryHandler::class)); + $this->addService($container, SpecificPriceRepositoryInterface::class, $container->get(SpecificPriceRepository::class)); $this->addService($container, ProductRepositoryInterface::class, $container->get(ProductRepository::class)); $this->addService($container, OrderDetailRepositoryInterface::class, $container->get(OrderDetailRepository::class)); $this->addService($container, CountryRepositoryInterface::class, $container->get(CountryRepository::class)); diff --git a/subscription/Action/CreateSpecificPriceAction.php b/subscription/Action/CreateSpecificPriceAction.php new file mode 100644 index 000000000..fde4e0a9a --- /dev/null +++ b/subscription/Action/CreateSpecificPriceAction.php @@ -0,0 +1,67 @@ +specificPriceRepository = $specificPriceRepository; + } + + /** + * @throws \Throwable + */ + public function run(CreateSpecificPriceData $data): \SpecificPrice + { + /** @var \SpecificPrice[] $specificPrices */ + $specificPrices = $this->specificPriceRepository->findAllBy([ + 'id_product' => $data->getProductId(), + 'id_product_attribute' => $data->getProductAttributeId(), + 'price' => $data->getPrice(), + 'id_customer' => $data->getCustomerId(), + 'id_shop' => $data->getShopId(), + 'id_currency' => $data->getCurrencyId(), + 'id_shop_group' => $data->getShopGroupId(), + 'id_country' => 0, + 'id_group' => 0, + 'from_quantity' => 0, + 'reduction' => 0, + 'reduction_type' => 'amount', + 'from' => '0000-00-00 00:00:00', + 'to' => '0000-00-00 00:00:00', + ]); + + foreach ($specificPrices as $specificPrice) { + $specificPrice->delete(); + } + + $specificPrice = new \SpecificPrice(); + + $specificPrice->id_product = $data->getProductId(); + $specificPrice->id_product_attribute = $data->getProductAttributeId(); + $specificPrice->price = $data->getPrice(); + $specificPrice->id_customer = $data->getCustomerId(); + $specificPrice->id_shop = $data->getShopId(); + $specificPrice->id_currency = $data->getCurrencyId(); + $specificPrice->id_shop_group = $data->getShopGroupId(); + $specificPrice->id_country = 0; + $specificPrice->id_group = 0; + $specificPrice->from_quantity = 0; + $specificPrice->reduction = 0; + $specificPrice->reduction_type = 'amount'; + $specificPrice->from = '0000-00-00 00:00:00'; + $specificPrice->to = '0000-00-00 00:00:00'; + + $specificPrice->add(); + + return $specificPrice; + } +} diff --git a/subscription/Controller/Symfony/SubscriptionFAQController.php b/subscription/Controller/Symfony/SubscriptionFAQController.php index efbfee5de..44654a77e 100644 --- a/subscription/Controller/Symfony/SubscriptionFAQController.php +++ b/subscription/Controller/Symfony/SubscriptionFAQController.php @@ -29,8 +29,7 @@ public function indexAction() 'carrierInformation3' => $this->module->l('Carrier cannot be changed after first subscription order is placed.', self::FILE_NAME), 'carrierInformation4' => $this->module->l('Selected carrier pricing/weight settings or carrier selection in Mollie should not change. If they do, subscription orders must be cancelled and carrier re-selected in module settings.', self::FILE_NAME), 'cartRuleTitle' => $this->module->l('Cart rules', self::FILE_NAME), - 'cartRule' => $this->module->l('A customer can\'t add subscription items with different recurring periods to the same shopping cart.', self::FILE_NAME), - 'cartRule2' => $this->module->l('Do not use cart rules with subscription products as this will cause errors due to incorrect pricing.', self::FILE_NAME), + 'cartRule1' => $this->module->l('Do not use cart rules with subscription products as this will cause errors due to incorrect pricing.', self::FILE_NAME), 'giftWrappingTitle' => $this->module->l('Gift wrapping', self::FILE_NAME), 'giftWrapping1' => $this->module->l('Gift wrapping feature is not supported for subscription orders.', self::FILE_NAME), 'subscriptionOrderLogicTitle' => $this->module->l('Recurring order creation', self::FILE_NAME), diff --git a/subscription/DTO/CreateSpecificPriceData.php b/subscription/DTO/CreateSpecificPriceData.php new file mode 100644 index 000000000..03574251f --- /dev/null +++ b/subscription/DTO/CreateSpecificPriceData.php @@ -0,0 +1,115 @@ +productId = $productId; + $this->productAttributeId = $productAttributeId; + $this->price = $price; + $this->customerId = $customerId; + $this->shopId = $shopId; + $this->shopGroupId = $shopGroupId; + $this->currencyId = $currencyId; + } + + /** + * @return int + */ + public function getProductId(): int + { + return $this->productId; + } + + /** + * @return int + */ + public function getProductAttributeId(): int + { + return $this->productAttributeId; + } + + /** + * @return float + */ + public function getPrice(): float + { + return $this->price; + } + + /** + * @return int + */ + public function getCustomerId(): int + { + return $this->customerId; + } + + /** + * @return int + */ + public function getShopId(): int + { + return $this->shopId; + } + + /** + * @return int + */ + public function getShopGroupId(): int + { + return $this->shopGroupId; + } + + /** + * @return int + */ + public function getCurrencyId(): int + { + return $this->currencyId; + } + + public static function create( + int $productId, + int $productAttributeId, + float $price, + int $customerId, + int $shopId, + int $shopGroupId, + int $currencyId + ): self { + return new self( + $productId, + $productAttributeId, + $price, + $customerId, + $shopId, + $shopGroupId, + $currencyId + ); + } +} diff --git a/subscription/Handler/RecurringOrderHandler.php b/subscription/Handler/RecurringOrderHandler.php index c7cfb4b0e..56833468a 100644 --- a/subscription/Handler/RecurringOrderHandler.php +++ b/subscription/Handler/RecurringOrderHandler.php @@ -7,7 +7,6 @@ use Cart; use Mollie; use Mollie\Adapter\ConfigurationAdapter; -use Mollie\Adapter\Shop; use Mollie\Api\Resources\Payment; use Mollie\Api\Resources\Subscription as MollieSubscription; use Mollie\Api\Types\PaymentStatus; @@ -17,12 +16,15 @@ use Mollie\Exception\TransactionException; use Mollie\Logger\PrestaLoggerInterface; use Mollie\Repository\CarrierRepositoryInterface; +use Mollie\Repository\OrderRepositoryInterface; use Mollie\Repository\PaymentMethodRepositoryInterface; use Mollie\Service\MailService; use Mollie\Service\MollieOrderCreationService; use Mollie\Service\OrderStatusService; use Mollie\Service\PaymentMethodService; +use Mollie\Subscription\Action\CreateSpecificPriceAction; use Mollie\Subscription\Api\SubscriptionApi; +use Mollie\Subscription\DTO\CreateSpecificPriceData; use Mollie\Subscription\Exception\CouldNotHandleRecurringOrder; use Mollie\Subscription\Factory\GetSubscriptionDataFactory; use Mollie\Subscription\Repository\RecurringOrderRepositoryInterface; @@ -32,7 +34,6 @@ use MolRecurringOrder; use MolRecurringOrdersProduct; use Order; -use SpecificPrice; class RecurringOrderHandler { @@ -54,8 +55,6 @@ class RecurringOrderHandler private $paymentMethodService; /** @var ClockInterface */ private $clock; - /** @var Shop */ - private $shop; /** @var MailService */ private $mailService; /** @var ConfigurationAdapter */ @@ -66,6 +65,10 @@ class RecurringOrderHandler private $carrierRepository; /** @var PrestaLoggerInterface */ private $logger; + /** @var CreateSpecificPriceAction */ + private $createSpecificPriceAction; + /** @var Mollie\Repository\OrderRepositoryInterface */ + private $orderRepository; public function __construct( SubscriptionApi $subscriptionApi, @@ -77,12 +80,13 @@ public function __construct( OrderStatusService $orderStatusService, PaymentMethodService $paymentMethodService, ClockInterface $clock, - Shop $shop, MailService $mailService, ConfigurationAdapter $configuration, RecurringOrdersProductRepositoryInterface $recurringOrdersProductRepository, CarrierRepositoryInterface $carrierRepository, - PrestaLoggerInterface $logger + PrestaLoggerInterface $logger, + CreateSpecificPriceAction $createSpecificPriceAction, + OrderRepositoryInterface $orderRepository ) { $this->subscriptionApi = $subscriptionApi; $this->subscriptionDataFactory = $subscriptionDataFactory; @@ -93,12 +97,13 @@ public function __construct( $this->orderStatusService = $orderStatusService; $this->paymentMethodService = $paymentMethodService; $this->clock = $clock; - $this->shop = $shop; $this->mailService = $mailService; $this->configuration = $configuration; $this->recurringOrdersProductRepository = $recurringOrdersProductRepository; $this->carrierRepository = $carrierRepository; $this->logger = $logger; + $this->createSpecificPriceAction = $createSpecificPriceAction; + $this->orderRepository = $orderRepository; } public function handle(string $transactionId): string @@ -152,9 +157,23 @@ private function createSubscription(Payment $transaction, MolRecurringOrder $rec return; } + /** @var \Order|null $originalOrder */ + $originalOrder = $this->orderRepository->findOneBy([ + 'id_order' => $recurringOrder->id_order, + ]); + + if (!$originalOrder) { + return; + } + /** @var Cart $newCart */ $newCart = $newCart['cart']; + $newCart->id_shop = $originalOrder->id_shop; + $newCart->id_shop_group = $originalOrder->id_shop_group; + + $newCart->update(); + /** @var MolRecurringOrdersProduct $subscriptionProduct */ $subscriptionProduct = $this->recurringOrdersProductRepository->findOneBy([ 'id_mol_recurring_orders_product' => $recurringOrder->id_mol_recurring_orders_product, @@ -209,7 +228,18 @@ private function createSubscription(Payment $transaction, MolRecurringOrder $rec throw CouldNotHandleRecurringOrder::failedToApplySelectedCarrier(); } - $specificPrice = $this->createSpecificPrice($recurringOrderProduct, $recurringOrder); + /** + * Creating temporary specific price for recurring order that will be deleted after order is created + */ + $specificPrice = $this->createSpecificPriceAction->run(CreateSpecificPriceData::create( + (int) $recurringOrderProduct->id_product, + (int) $recurringOrderProduct->id_product_attribute, + (float) $recurringOrderProduct->unit_price, + (int) $recurringOrder->id_customer, + (int) $newCart->id_shop, + (int) $newCart->id_shop_group, + (int) $recurringOrder->id_currency + )); $paymentMethod = $this->paymentMethodService->getPaymentMethod($transaction); @@ -284,32 +314,6 @@ private function cancelSubscription(int $recurringOrderId): void $this->mailService->sendSubscriptionCancelWarningEmail($recurringOrderId); } - /** - * creating temporary specific price for recurring order that will be deleted after order is created - */ - private function createSpecificPrice(MolRecurringOrdersProduct $molRecurringOrdersProduct, MolRecurringOrder $recurringOrder): SpecificPrice - { - $specificPrice = new SpecificPrice(); - $specificPrice->id_product = $molRecurringOrdersProduct->id_product; - $specificPrice->id_product_attribute = $molRecurringOrdersProduct->id_product_attribute; - $specificPrice->price = $molRecurringOrdersProduct->unit_price; - $specificPrice->id_customer = $recurringOrder->id_customer; - $specificPrice->id_shop = $this->shop->getShop()->id; - $specificPrice->id_currency = $recurringOrder->id_currency; - $specificPrice->id_country = 0; - $specificPrice->id_shop_group = 0; - $specificPrice->id_group = 0; - $specificPrice->from_quantity = 0; - $specificPrice->reduction = 0; - $specificPrice->reduction_type = 'amount'; - $specificPrice->from = '0000-00-00 00:00:00'; - $specificPrice->to = '0000-00-00 00:00:00'; - - $specificPrice->add(); - - return $specificPrice; - } - private function updateSubscriptionOrderAddress(Cart $cart, int $addressInvoiceId, int $addressDeliveryId): Cart { $cart->id_address_invoice = $addressInvoiceId; diff --git a/subscription/Repository/SpecificPriceRepository.php b/subscription/Repository/SpecificPriceRepository.php new file mode 100644 index 000000000..3702afea1 --- /dev/null +++ b/subscription/Repository/SpecificPriceRepository.php @@ -0,0 +1,11 @@ +assertDatabaseHasNot(\SpecificPrice::class, [ + 'id_product' => (int) $product->id, + 'id_product_attribute' => (int) \Product::getDefaultAttribute($product->id), + 'price' => 10.00, + 'id_customer' => 1, + 'id_shop' => 1, + 'id_currency' => 1, + 'id_shop_group' => 1, + 'id_country' => 0, + 'id_group' => 0, + 'from_quantity' => 0, + 'reduction' => 0, + 'reduction_type' => 'amount', + 'from' => '0000-00-00 00:00:00', + 'to' => '0000-00-00 00:00:00', + ]); + + /** @var CreateSpecificPriceAction $createSpecificPrice */ + $createSpecificPrice = $this->getService(CreateSpecificPriceAction::class); + + $result = $createSpecificPrice->run(CreateSpecificPriceData::create( + (int) $product->id, + (int) \Product::getDefaultAttribute($product->id), + 10.00, + 1, + 1, + 1, + 1 + )); + + $this->assertDatabaseHas(\SpecificPrice::class, [ + 'id_product' => (int) $product->id, + 'id_product_attribute' => (int) \Product::getDefaultAttribute($product->id), + 'price' => 10.00, + 'id_customer' => 1, + 'id_shop' => 1, + 'id_currency' => 1, + 'id_shop_group' => 1, + 'id_country' => 0, + 'id_group' => 0, + 'from_quantity' => 0, + 'reduction' => 0, + 'reduction_type' => 'amount', + 'from' => '0000-00-00 00:00:00', + 'to' => '0000-00-00 00:00:00', + ]); + + $product->delete(); + $result->delete(); + } +} diff --git a/views/templates/admin/Subscription/subscriptions-faq.html.twig b/views/templates/admin/Subscription/subscriptions-faq.html.twig index 45db6380e..58d78f091 100644 --- a/views/templates/admin/Subscription/subscriptions-faq.html.twig +++ b/views/templates/admin/Subscription/subscriptions-faq.html.twig @@ -84,8 +84,7 @@
{{ cartRule|escape }}
-{{ cartRule2|escape }}
+{{ cartRule1|escape }}