2

I am using Drupal commerce and I try to make a rule to remove two specific line items from the cart. However, the most I can achieve is to empty the whole cart.

Can this be done with rules?

closed as too broad by kiamlaluno Oct 27 '18 at 20:38

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • Which specific line items do you wnat to remove? and if possible why? – harshal Nov 2 '13 at 4:10
  • The SKU's for the two line items I want to remove are "item1" and "item2"when a user adds a certain line_item to the cart I want to just loop through all items in the cart and remove the two with matching SKUs. "item1" and "item2" are separate products but if a user adds the "doublepack" product which is a bundle of them both, then I want to remove any of the two previous products that might have been added separately to the cart. – Andrew Nov 2 '13 at 10:56
3
  • You remove a product from the cart by deleting the line-item entity for that product.
  • But first you must expose the line-item data to your Rule so you can check whether it should be deleted. Line-item data including sku is not available to Rules Actions unless you do this.
  • Note that you can access some properties about the line-item, such as commerce-line-item:type, in your Rule Condition, but this is for the line-item referenced in the event, not for the other line-items in the cart. You cannot access other line-items' data, such as sku, in your Rule Action.
  • You force the other line items' sku and other data to become available to your Rule Actions by checking a property of each line item in the Action, even if you don't otherwise need to do the check. In this example I check the type of each line-item to be evaluated for deletion.
  • Much of the documentation available as of today is a couple of years old and calls for use of Rules components ... nowadays Rules Conditional is the way to go as it allows you to bring conditional logic right into your Action (so you can choose which line items to delete, for example). You may choose to put this Rule in a component if you have many varied situations in which you want to call it. If you only have one or two situations, using conditional logic within the Rule Action, via Rules Conditional, is much simpler.

In the example below, the Rule is evaluated on the event "After removing a product from the cart" because I have an add-on product that should be removed after the "mother" product is removed by the customer. But you can use any Commerce event.

The Condition here is to check whether the product removed from the cart by the customer was a "mother" product ... you may not need any conditions for your Rule.

The Action first does the aforementioned check of the line-item type to bring the line-item properties into scope for the Action data selector, then loops through the list of line-items, and tests each one for the skus you want to delete. Then deletes the line-item if there is a match. You could of course delete based on price, quantity, or anything else in the line-item data.

Note that once you start to loop through a list, the data you are after will be accessed through the variable list-item: which represents whatever you are looping through; in this case, the line-items. Note that list-item and line-item are syntactically very close, watch for typos!

{ "rules_delete_products_from_cart_by_sku" : {
    "LABEL" : "Delete Products from Cart by SKU",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "TAGS" : [ "Commerce Cart" ],
    "REQUIRES" : [ "rules", "rules_conditional", "commerce_cart" ],
    "ON" : { "commerce_cart_product_remove" : [] },
    "IF" : [
      { "data_is" : {
          "data" : [ "commerce-line-item:type" ],
          "value" : "my_product_type"
          }
       }
     ],
    "DO" : [
      { "LOOP" : {
          "USING" : { "list" : [ "commerce-order:commerce-line-items" ] },
          "ITEM" : { "list_item" : "Current list item" },
          "DO" : [
            { "CONDITIONAL" : [
                {
                  "IF" : { "data_is" : { "data" : [ "list-item:type" ], "value" : "product" } },
                  "DO" : [
                    { "CONDITIONAL" : [
                        {
                          "IF" : { "data_is" : {
                              "data" : [ "list-item:commerce-product:sku" ],
                              "op" : "IN",
                              "value" : { "value" : [ "SKU-01", "SKU-03" ] }
                            }
                          },
                          "DO" : [ { "entity_delete" : { "data" : [ "list-item" ] } } ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

Hope this helps someone on the same journey I am!

  • Hi and welcome to Drupal Answers. Thorough answer! – Wtower Jan 23 '15 at 13:00
  • It works perfect! – ropic Sep 4 '15 at 0:35
  • Interesting answer. Though instead of using "Conditional Rules" (which still does not have an oficial D7 relese, and some bugs), I prefer using Rules Components, stil. For more details, refer to this question. – Pierre.Vriens Oct 28 '18 at 8:59

Not the answer you're looking for? Browse other questions tagged or ask your own question.