From b4d3fbd6a78c3ddf90dba4348b4a7dbaa8932a17 Mon Sep 17 00:00:00 2001 From: Johannes Feustel Date: Thu, 4 Jul 2024 17:45:32 +0200 Subject: [PATCH] [FEATURE] Make Shipping methods be available based on cart conditions (#545) Implemented the ability to configure conditions in typoscript setup to switch shipping methods based on products in the cart. This allows e.g. for dynamic application of shipping methods, ensuring that shipping method A (free) is used by default, and shipping method B (with actual costs) is applied when physical products are detected in the cart. Fixes: #545 --- Classes/Domain/Model/Cart/Service.php | 25 ++++- .../FlexibleAvailabilityForShipping/Index.rst | 104 ++++++++++++++++++ .../Configuration/ShippingMethods/Index.rst | 1 + 3 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 Documentation/Administrator/Configuration/ShippingMethods/FlexibleAvailabilityForShipping/Index.rst diff --git a/Classes/Domain/Model/Cart/Service.php b/Classes/Domain/Model/Cart/Service.php index 538bd7b9..b3bc9648 100644 --- a/Classes/Domain/Model/Cart/Service.php +++ b/Classes/Domain/Model/Cart/Service.php @@ -203,18 +203,33 @@ public function getFallBackId(): ?int public function isAvailable(): bool { + $return = true; + // keep available.from and available.until even though this is redundant to ... if (isset($this->config['available'])) { - $availableFrom = $this->config['available']['from']; - if (isset($availableFrom) && $this->cart->getGross() < (float)$availableFrom) { + $availableFrom = $this->config['available']['from'] ?? false; + if ($availableFrom && $this->cart->getGross() < (float)$availableFrom) { return false; } - $availableUntil = $this->config['available']['until']; - if (isset($availableUntil) && $this->cart->getGross() > (float)$availableUntil) { + $availableUntil = $this->config['available']['until'] ?? false; + if ($availableUntil && $this->cart->getGross() > (float)$availableUntil) { return false; } } - return true; + if (isset($this->config['available']) && is_array($this->config['available']) && isset($this->config['available']['_typoScriptNodeValue'])) { + $availableType = $this->config['available']['_typoScriptNodeValue']; + + $conditionValue = $this->getConditionValueFromCart($availableType); + + $return = false; + foreach ($this->config['available'] as $availableKey => $availableValue) { + if (is_array($availableValue) && ((float)$availableValue['value'] <= (float)$conditionValue)) { + $return = (bool) ($availableValue['available'] ?? false); + } + } + } + + return $return; } public function isFree(): bool diff --git a/Documentation/Administrator/Configuration/ShippingMethods/FlexibleAvailabilityForShipping/Index.rst b/Documentation/Administrator/Configuration/ShippingMethods/FlexibleAvailabilityForShipping/Index.rst new file mode 100644 index 00000000..9ab36fd3 --- /dev/null +++ b/Documentation/Administrator/Configuration/ShippingMethods/FlexibleAvailabilityForShipping/Index.rst @@ -0,0 +1,104 @@ +.. include:: ../../../../Includes.txt + +.. _shipping_method_flex_availablility: + +============================ +Flexible availability for shipping +============================ + +It can be a requirement that the shipping method availability should depend on +the products in the shopping cart. For these cases the extension provides a default +implementation (see `cart/Classes/Domain/Model/Cart/Service.php`) with +configuration options very similar to + :ref:`Flexible prices for shipping `. +The implementation can be adapted to own needs by using the `ServiceInterface` +also described in :ref:`Flexible prices for shipping `. + +.. code-block:: typoscript + :caption: Can be set in e.g. EXT:sitepackage/Configuration/TypoScript/setup.typoscript + + plugin.tx_cart { + shippings { + countries { + de { + preset = 1 + options { + 1 { + title = PDF/Email + taxClassId = 1 + fallBackId = 2 + status = open + free { + from = 0 + } + available = by_number_of_physical_products + available { + 0 { + value = 0 + available = 1 + } + 2 { + value = 1 + available = 0 + } + } + } + + 2 { + title = Standard Delivery + taxClassId = 1 + fallBackId = 1 + status = open + extra = 99.00 + available = by_number_of_physical_products + available { + 0 { + value = 0 + available = 0 + } + 2 { + value = 1 + available = 1 + } + } + } + } + } + } + } + +plugin.tx_cart.shipping.countries.de +==================================== +.. confval:: options..available + + :Type: string + + ============================== =========================================== + Setting Explanation what is used for the comparison + ============================== =========================================== + by_price The total price of the shopping cart. + by_price_of_physical_products The total price of physical products in the shopping cart (EXT:cart_products allows to define products as "virtual producs"). + by_quantity The amount of physical(!) products. (This is a synonym for `by_number_of_physical_products`) + by_number_of_physical_products The amount of physical products + by_number_of_virtual_products The amount of virtual products + by_number_of_all_products The amount of all products + by_service_attribute_1_sum The sum of the values of `Service Attribute 1` of all products in the cart. + by_service_attribute_1_max The highest value of `Service Attribute 1` of all product in the cart. + by_service_attribute_2_sum The sum of the values of `Service Attribute 2` of all products in the cart. + by_service_attribute_2_max The highest value of `Service Attribute 2` of all product in the cart. + by_service_attribute_3_sum The sum of the values of `Service Attribute 3` of all products in the cart. + by_service_attribute_3_max The highest value of `Service Attribute 3` of all product in the cart. + ============================== =========================================== + + +.. confval:: options..available..value + + :Type: int + + Defines the matching condition. + +.. confval:: options..available..available + + :Type: float + + Boolean value to define whether the shipping method is available. diff --git a/Documentation/Administrator/Configuration/ShippingMethods/Index.rst b/Documentation/Administrator/Configuration/ShippingMethods/Index.rst index 69d06ae4..f42b9494 100644 --- a/Documentation/Administrator/Configuration/ShippingMethods/Index.rst +++ b/Documentation/Administrator/Configuration/ShippingMethods/Index.rst @@ -289,3 +289,4 @@ See :ref:`plugin.tx_cart.settings.showCartAction.showPartials.shippingMethodForm :titlesonly: FlexiblePricesForShipping/Index + FlexibleAvailabilityForShipping/Index