1

Related to this question: How to mark product if it has already been purchased by current user?

I have a Drupal Commerce shop, where I'm trying to use the Flag module to mark products to inform users if they have already purchased that particular product.

Now I'm trying to create a rule (using Rules) triggered on "Completing the checkout process" to flag all products that were purchased. Problem is I can't gain access to the commerce_product field (product reference field) of the line item, no matter what I do, and because of that I can't find the info I need to flag the products.

Could someone show how to do this in detail, preferably with example(s)?

2

Below is a possible approach you can use to solve your question. It provides the details about how I was able to have a set of Drupal messages being shown at checkout time, which look similar to this testcase I used (for a cart with 3 line items):

Current line item has label 'USB-BLU-08' and id '17'
Some details about this product: Product ID = 28, Product SKU = USB-BLU-08, Product Title = Storage 1, Product Creator = Hillary.Trump

Current line item has label 'TSH4-BLK-MD' and id '18'
Some details about this product: Product ID = 53, Product SKU = TSH4-BLK-MD, Product Title = Tshirt 4, Product Creator = Donald.Clinton

Current line item has label 'MES1-BLU-OS' and id '19'
Some details about this product: Product ID = 2, Product SKU = MES1-BLU-OS, Product Title = Messenger Bag 1, Product Creator = Pierre.Vriens

To get this to work, I created a custom rule, which also performs a custom Rules Component. Read on for details about them ...

Step 1: Create a Rules Component

Create a Rules Component which looks like so (use the Rules UI to import it in your own site):

{ "rules_perform_an_action_on_a_selected_line_item" : {
    "LABEL" : "Perform an action on a selected line item",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "selected_line_item" : { "label" : "Selected Line Item", "type" : "commerce_line_item" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "selected-line-item" ], "field" : "commerce_product" } }
    ],
    "DO" : [
      { "entity_fetch" : {
          "USING" : {
            "type" : "commerce_product",
            "id" : [ "selected-line-item:commerce-product:product-id" ]
          },
          "PROVIDE" : { "entity_fetched" : { "product_fetched" : "Fetched Product" } }
        }
      },
      { "drupal_message" : { "message" : "Some details about this product: Product ID = [product-fetched:product-id], Product SKU = [product-fetched:sku], Product Title = [product-fetched:title], Product Creator = [product-fetched:creator]" } }
    ]
  }
}

Some details about it:

  • Parameters: selected_line_item ( = the line item being processed).
  • Rules Condition: entity (= selected-line-item) has field (= commerce_product).
  • Rules Actions:
    • Fetch entity (= commerce_product) by ID (= selected-line-item:commerce-product:product-id).
    • Show a Drupal message, starting with "Some details about this product ..." (feel free to remove this Rules Action after you finish QA-testing).

Step 2: Create a rule that invokes the Rules Component from Step 1

Create a rule which looks like so (use the Rules UI to import it in your own site):

{ "rules_access_product_fields_at_checkout" : {
    "LABEL" : "Access product fields at checkout",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "commerce_checkout" ],
    "ON" : { "commerce_checkout_complete" : [] },
    "DO" : [
      { "LOOP" : {
          "USING" : { "list" : [ "commerce-order:commerce-line-items" ] },
          "ITEM" : { "line_item" : "Current line item" },
          "DO" : [
            { "drupal_message" : { "message" : "Current line item has label \u0027[line-item:line-item-label]\u0027 and id \u0027[line-item:line-item-id]\u0027" } },
            { "component_rules_perform_an_action_on_a_selected_line_item" : { "selected_line_item" : [ "line-item" ] } }
          ]
        }
      }
    ]
  }
}

Some details about it:

  • Rules Event: After completing the checkout process.
  • Rules Condition: none.
  • Rules Action: Create a loop, to iterate over each line item. And for each line item, perform these Rules Actions:
    • Show a Drupal message, starting with "Current line item has ..." (feel free to remove this Rules Action after you finish QA-testing).
    • Perform the Rules Component from Step 1 for the current line item being processed.

Step 3: Homework (= your turn)

To actually answer your question, i.e. to flag the product of each line item, you should only adapt the Rules Action in the Rules Component from Step 1. Since you have all data from each line item available at that point, it should be straight forward to tune the Rules Component to fit your needs (i.e flag the product by the current user).

  • @Nenotek merci for the confirmation (+accept/vote)! Next (rules) question? – Pierre.Vriens Jul 20 '17 at 8:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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