Problem/Motivation

With Commerce 2.x Condition groups apply AND/OR functionality to your entire list of conditions. This is helpful, but quite limited. If you want one condition to be mandatory, and one of two other conditions, it can't be accomplished through the UI.

Proposed resolution

Since we now have a drag and drop table, we should allow nesting conditions under AND and OR logic, similar to the Rules interface.

User interface changes

Rules UI AND/OR nesting can certainly be confusing to new-comers, but has proven to me at least to be very dependable once it's learned. We could make it a little more user friendly, and provide a brief video on how to properly nest conditions.

API changes

For this to work correctly, we will at least need to provide the option to disable the ConditionGroups options when the module is installed:

  • All conditions must pass
  • Only one condition must pass

^^ These of course would create conflicting logic with a nested approach.

Remaining Tasks

Do it.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

tonytheferg created an issue. See original summary.

mglaman made their first commit to this issue’s fork.

mglaman’s picture

Status: Active » Needs review
mglaman’s picture

StatusFileSize
new54.79 KB

This works allowing an OR

tonytheferg’s picture

StatusFileSize
new12.83 KB

Here's a patch of the MR.

tonytheferg’s picture

StatusFileSize
new8.44 KB

Looks like the class got removed in the merge request.

diff --git a/commerce_conditions_plus.services.yml b/commerce_conditions_plus.services.yml
index 199337b..f0a4a91 100644
--- a/commerce_conditions_plus.services.yml
+++ b/commerce_conditions_plus.services.yml
@@ -1,4 +1,3 @@
 services:
   commerce_conditions_plus.conditions_evaluator:
-    class: \Drupal\commerce_conditions_plus\ConditionsEvaluator
     arguments: ['@plugin.manager.commerce_condition']
diff --git a/src/ConditionsEvaluator.php b/src/ConditionsEvaluator.php
index 04b4e13..14f6a48 100644
--- a/src/ConditionsEvaluator.php
+++ b/src/ConditionsEvaluator.php
@@ -2,19 +2,12 @@

Here is a patch with the class.

tonytheferg’s picture

StatusFileSize
new29.87 KB

2 conditions under an OR statement seem to work, but I am noticing this when I have one condition, then and OR, and 2 conditions under the OR.


TypeError: Argument 2 passed to Drupal\commerce_conditions_plus\ConditionsEvaluator::evaluateConditionGroup() must be of the type string, null given, called in /var/www/html/web/modules/contrib/commerce_conditions_plus/src/ConditionsEvaluator.php on line 51 in Drupal\commerce_conditions_plus\ConditionsEvaluator->evaluateConditionGroup() (line 66 of /var/www/html/web/modules/contrib/commerce_conditions_plus/src/ConditionsEvaluator.php)

This condition should validate if the shipment weight is under 1 lb, and EITHER the category exists OR the total is over $75

tonytheferg’s picture

Here is an example of a free first class shipping method to show how the nested conditions should work.

Because we are currently using AND as the default operator, if the table does not begin with an OR operator, then the nest begins with AND logic.

Important: When nesting conditions, the nested operator inherits it's parent operator logic.

(I will follow up with a condition set that starts with OR and nests an AND in the near future.)

Here is what the table will look like:

Only local images are allowed.

  1. The Shipment weight must be under 1 lb AND EITHER
    1. Order product categories contains the free first class shipping category OR
    2. Current order total is greater than $74.99

So the first condition must pass, AND one of the two OR conditions must also pass.

  • The Shipment weight must be under 1 lb, AND the Order product categories contains the free first class shipping category
  • The Shipment weight must is under 1 lb, AND the Current order total is greater than $74.99

A side note on the default operator logic

When considering how to make this cooperate with the existing conditions group logic, I think instead of setting the base logic to a default AND, we could potentially just pass the ConditionGroups options as default value.

  • All conditions must pass
  • Only one condition must pass

Either way the added operators will govern their nested conditions, so the default value only governs where the conditions aren't nested.

tonytheferg’s picture

StatusFileSize
new54.88 KB

Ok, I actually have this working, starting with an AND condition.
table

  1. The Shipment Address must be under United States, AND
  2. The Shipment weight must be under 1 lb AND
    1. EITHER Order product categories contains the free first class shipping category
    2. ORCurrent order total is greater than $74.99

Our OR operator is indeed receiving the parent AND operator in the array, so I think we are moving in the right direction.

Array
(
    [parent] => commerce_conditions_plus_and_operator
    [depth] => 1
    [sort_weight] => -4
    [negate] => 0
)
tonytheferg’s picture

Noticing this in the logs upon saving the form:
Notice: Undefined index: configuration in Drupal\commerce\Plugin\Field\FieldWidget\ConditionsWidget->massageFormValues() (line 181 of /var/www/html/web/modules/contrib/commerce/src/Plugin/Field/FieldWidget/ConditionsWidget.php)

tonytheferg’s picture

StatusFileSize
new41.69 KB

More findings confirming #10 with nesting. The first operator needs a [parent] operator set. The picture below works, but it required an initial AND operator to provide a [parent] for the OR.
It would not work without it.

This validates correctly if:

  • EITHER The Shpping addres is US, OR
  • BOTH the Current order total is less than $200 AND the product category does not exist in the order.

nesting

Seeing that [parent] is empty on the first operator introduced to the table, we should do one of the following:

  1. Hardcode the first operator to have the [parent] set to commerce_conditions_plus_and_operator,
  2. Use the condition groups setting that commerce ships with to set it to commerce_conditions_plus_and_operator or commerce_conditions_plus_or_operator. We could then hook into the description to clarify its purpose when using it with conditions plus.
tonytheferg’s picture

Actually #12 is not working, I don't think. It seems you can nest an OR under an AND, but you can't nest an AND under an OR.

Even when removing the 1st AND in the picture above, when you introduce a nested AND, it seems to set the logic for the whole tree as AND.

  • mglaman committed 4b92ef9 on 1.0.x
    Issue #3221291 by mglaman, tonytheferg: Expand the conditions table to...
mglaman’s picture

Status: Needs review » Fixed
tonytheferg’s picture

Status: Fixed » Closed (fixed)