How to create a rule that loops the line items of a completed order and do a data comparison on a custom field that's on a product? I'm trying to create a rule that triggers on the event 'Completing the checkout process' that will then loop through the line items of the order. For each line item I'd like to do a Data comparison on a custom field that's on a commerce product.

This is the rule I created:



"LABEL" : "User needs approval for anything over 500",
"PLUGIN" : "reaction rule",
"ACTIVE" : false,
"OWNER" : "rules",
"REQUIRES" : [ "rules", "commerce_checkout" ],
"ON" : { "commerce_checkout_complete" : [] },
"IF" : [
  { "entity_has_field" : {
      "entity" : [ "site:current-user:profile-educator" ],
      "field" : "field_borrow_level"
    }
  },
  { "AND" : [
      { "data_is" : {
          "data" : [ "site:current-user:profile-educator:field-borrow-level" ],
          "value" : "need_approval_greater_than_amount"
        }
      }
    ]
  }
],
"DO" : [
  { "LOOP" : {
      "USING" : { "list" : [ "commerce-order:commerce-line-items" ] },
      "ITEM" : { "list_item" : "Current list item" },
      "DO" : []
    }
  }
]


And this is the component that I was trying to run through the loop:



"LABEL" : "Check price of each line item",
"PLUGIN" : "rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules", "commerce_price" ],
"USES VARIABLES" : {
  "current_line_item" : { "label" : "Current Line Item", "type" : "commerce_line_item" },
  "current_product" : { "label" : "Current Product", "type" : "commerce_product" }
},
"IF" : [
  { "entity_has_field" : { "entity" : [ "current-product" ], "field" : "field_purchase_cost" } },
  { "AND" : [
      { "commerce_price_compare_price" : {
          "first_price" : [ "current-product:field-purchase-cost" ],
          "operator" : "\u003E=",
          "second_price" : { "value" : { "amount" : 50000, "currency_code" : "USD" } }
        }
      }
    ]
  }
],
"DO" : [
  { "drupal_message" : { "message" : "You need School Administrator approval to check out any item valued over $500." } }
]


For some more context: This site is a library for special education teachers to be able to check out software and hardware for their use in the classroom. Which means that the price for each item is zero since the site is loaning out items at no cost to the teachers. The hang up in this case is that there are three different ‘borrow levels’ for a teacher. The ‘borrow levels’ are: 1. You can check out any item. 2. You can check out any item up to a $500 value. If an item is above $500 you need approval from your school administrator before the order is approved. 3. You need approval from your school administrator to check out anything.

My question here pertains to users with a ‘borrow level’ of 2. Since the products all have a price of zero we added a custom field to the commerce product that has the replacement cost of an item. So, when an order is placed and the user is borrow level 2 I need to look at each item in that order and determine if the replacement cost is over $500. If nothing is over $500, then the order can be flagged as approved. If there’s one or more items that have a replacement cost of $500 or more we need to send an email to that teacher’s school administrator telling them they need to log in and approve or deny the request the teacher has made.
First things first ...:


Your "AND" (in your rule, and in your component) appear to be redundant. If you doubt/wonder about that, have a look at my answer to the question "Which is the difference of combining rules with AND or just leave them follow one each other?".
So I'll ignore those already.
The list_item in your Rule (within the loop) is a variable name you get out-of-the-Rules-box. But to improve readability of your Rule, I suggest to rename that to something like current_line_item (and description like "Current line item").
While building (developing) your Rule (and component), I find it a handy facility to start with a rules action like "Display a Message" (which you can find within the "System" group). And for the actual message to be shown, already include tokens that may be interesting to know more about. Typically some "id" and some "description".
With the above Rule refinements, do some first unit testing, so that at least you get 1 Drupal message for each line item (produced via that Rules Action in your loop).


Remaining refinement(s):


Do some research/experiments to see how, starting from your current_line_item (my suggested new name for list_item!!!) you can find your way to the product the line item is related to.
You should be especially interested in something that smells, sounds and looks like the "ID" of the product the line item is about. If you think you found it, add that token to your message being displayed (to be sure you have what we should be interested in).
Assuming you found the product ID somehow, ADD a subsequent Rules action to perform a "fetch entity by ID", to actually fetch the product, with ID ... you guessed it ... the token you found in the previous step.
From then on, you have everything you need (I think) to add an extra Rules Action to simply perform your Rules Component, passing it the corresponding parameters.
In the end, when everything works as you want, you may want to remove or refine that "Show a message" Rules Action from before.


PS 1: The above is based on the assumption that I don't know "Drupal Commerce" at all ... hm, hm.

PS 2: I'm assuming this is about D7, though it will probably also work in a similar way if some day the question is about D8.