How to implement a Rules Action to loop through quantity of a products bought? With the Drupal Commerce module, I created a new product type I use for selling points to my customers. The product has a custom field named “points” (field type integer) where I specify the amount of point to sell.

On checkout I grant the points to the user with this rule, using the Rules module (thanks to Vic, see "How do I sell points using a new product type?):


  
  Rule Event: on payment completed Action: loop through the order
  line-items. Each line-item has an action to call the next component
  with parameters of order and the line-item.
  Component Parameters:
  order, line-item Condition: data comparison line-item:type is Product
  (to expose line-item:commerce-product) Action: call next component
  with parameters of order and line-item:commerce-product
  Component
  Parameters: order, product Condition: data comparison product:type is
  Product (to expose the product:field-points-to-add) • Action: add
  userpoints, number to add being product:field-points-to-add
  


The problem comes when the quantity of the products sold is more than 1 because the action loops only through line-item and not through line-item:quantity.

Any suggestion for looping through line-item:quantity?
Consider this Rules Component (in Rules export format, use the Rules UI to import it in your own site):

{ "rules_grant_user_points_multiple_times" : {
    "LABEL" : "Grant user points multiple times",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "userpoints_rules" ],
    "USES VARIABLES" : {
      "points_to_grant" : { "label" : "Points to grant", "type" : "integer" },
      "quantity" : { "label" : "Quantity", "type" : "integer" }
    },
    "DO" : [
      { "data_calc" : {
          "USING" : {
            "input_1" : [ "points-to-grant" ],
            "op" : "*",
            "input_2" : [ "quantity" ]
          },
          "PROVIDE" : { "result" : { "calculated_points" : "Calculated points" } }
        }
      },
      { "userpoints_action_grant_points" : {
          "user" : [ "site:current-user" ],
          "points" : [ "calculated-points" ],
          "tid" : "0",
          "entity" : [ "site:current-user" ],
          "operation" : "Insert",
          "display" : "1",
          "moderate" : "default"
        }
      }
    ]
  }
}


Some more details about this Rules Component:


It uses 2 parameters (both "integer"), i.e.:


Points to grant, which is like your custom field named “points”.
Quantity, which is like your quantity of the products sold.

Rules Actions:


Calculate a new variable (= calculated_points), which is simply a multiplication of the above 2 parameters.
Grant user points for an amount equal to ... euh ... indeed: calculated_points (adapt the details of the actual transaction to fit your needs).



These User Points will be granted to the "current user". Optionally you could just make that yet another parameter for the Rules Component also. I.e. if "current user" is not the customer who bought the quantity of products (which would allow one customer to buy such points for another user should you want to allow that, similar to a gift-card).

With that, all that's left is to finds the right spot in your existing Rules logic (related to checkout), to use the above Rules Component.

Easy, no?