1

Im looking for a way to create a rule in drupal commerce that updates a user profile after checkout based on a line item purchased.

Example. User purchases bulk training hours as a product. The product has a field called hours which we set to a static number. Assume 10.

When the product is purchased, the hours should be added to the user profile which has a field called training hours. Whatever the current number of hours in the profile is should be added. Ie user has 5 hours remaining, pays for 10 more and now shows 15.

I cant figure out a good way to create this rule.

EDIT 2: So from reading some other posts I see tried to create a component that can be accessed during the loop. For testing purposes I have changed the rule to start when checkout is complete.

It picks up the products and it then loops through the line items but in the loop I still cannot figure out how to access the field called field_coaching_hours that is part of the product. For not during the loop it emails me each time it finds a line item so I can tell that its working.

I suspect that I need to add up all the field_coaching_hours using a variable and then somehow call a separate rule to add it to the user profile.

Main Rule:

{ "rules_update_coaching_hours" : {
"LABEL" : "Update Coaching Hours",
"PLUGIN" : "reaction rule",
"OWNER" : "rules",
"REQUIRES" : [ "commerce_order", "rules", "commerce_checkout" ],
"ON" : { "commerce_checkout_complete" : [] },
"IF" : [
  { "commerce_order_contains_product_type" : {
      "commerce_order" : [ "commerce_order" ],
      "product_type" : { "value" : {
          "coaching" : "coaching",
          "consulting" : "consulting",
          "product" : "product"
        }
      },
      "operator" : "\u003E=",
      "value" : "1"
    }
  }
],
"DO" : [
  { "LOOP" : {
      "USING" : { "list" : [ "commerce-order:commerce-line-items" ] },
      "ITEM" : { "current_line_item" : "Current line item" },
      "DO" : [
        { "component_rules_get_coaching_hours" : { "current_line_item" : [ "current_line_item" ] } }
      ]
    }
  }
]
}
}

component:

{ "rules_get_coaching_hours" : {
"LABEL" : "Get Coaching Hours",
"PLUGIN" : "rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules", "mimemail" ],
"USES VARIABLES" : { "current_line_item" : { "label" : "Commerce Line Item", "type" : "commerce_line_item" } },
"IF" : [
  { "entity_has_field" : { "entity" : [ "current-line-item" ], "field" : "field_coaching_hours" } }
],
"DO" : [
  { "mimemail" : {
      "USING" : {
        "key" : "SENT",
        "to" : "myemail@email.com",
        "subject" : "Component Rule Run",
        "body" : "[current-line-item:commerce-product]",
        "plaintext" : "[current-line-item:commerce-product]"
      },
      "PROVIDE" : { "send_status" : { "send_status" : "Send status" } }
    }
  }
]
}
}
  • i havent really tried anything yet as i am not sure of the approach to take, obviously i know the rule has to happen after checkout but I dont know how to have it read the line items to see if any of the purchased products included training hours. – dajuice Jul 12 '17 at 14:46
  • What I started doing what having the rule activate when payment in full is received. And then make the condition to be a specific sku since the training hours are related to certain sku's. The action I think should be to loop through the line items to see if any line includes training hours. However i cannot seem to get the right data selectors to show me the coaching hours in the product variation. I posted a possible rule export above – dajuice Jul 12 '17 at 15:03
  • Aha, looks like you're making progress (at least to narrow down your question). Here is a possible hint: make sure to add a "Entity has field" Rules Condition (for those coaching hours). If you can still not get it to work, please further edit your question and include an export of the further refined rule you have so far (and notify me via an extra comment). – Pierre.Vriens Jul 12 '17 at 15:08
  • Oops, in your updated question I now see your exported rule. So you're now at the point where you want to use a rules condition inside a rules action (within the loop), right ? Am I close? – Pierre.Vriens Jul 12 '17 at 15:11
  • I've updated the export with the current rule and loop – dajuice Jul 12 '17 at 21:49
0

I did figure this out and its working. I had to use some extra code to expose the custom field but it does work.

The component is as follows, this extracts the coaching hours and sends it out to the main loop via a provider variable:

{ "rules_get_coaching_hours" : {
"LABEL" : "Get Coaching Hours",
"PLUGIN" : "rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules" ],
"USES VARIABLES" : {
  "current_line_item" : { "label" : "Commerce Line Item", "type" : "commerce_line_item" },
  "included_coaching_hours" : {
    "label" : "Item Coaching Hours Included",
    "type" : "decimal",
    "parameter" : false
  }
},
"IF" : [
  { "data_is" : { "data" : [ "current-line-item:type" ], "value" : "product" } },
  { "data_is" : {
      "data" : [ "current-line-item:commerce-product:type" ],
      "op" : "IN",
      "value" : { "value" : {
          "coaching" : "coaching",
          "consulting" : "consulting",
          "product" : "product"
        }
      }
    }
  },
  { "entity_has_field" : {
      "entity" : [ "current-line-item:commerce-product" ],
      "field" : "field_coaching_hours"
    }
  },
  { "data_is" : {
      "data" : [ "current-line-item:commerce-product:field-coaching-hours" ],
      "op" : "\u003E",
      "value" : "0"
    }
  }
],
"DO" : [
  { "data_set" : {
      "data" : [ "included-coaching-hours" ],
      "value" : [ "current-line-item:commerce-product:field-coaching-hours" ]
    }
  }
],
"PROVIDES VARIABLES" : [ "included_coaching_hours" ]
}
}

The the main rule is as follows. It loops through the line items and sums up total number of hours. The last line then updates the custom field in the user record.

{ "rules_update_coaching_hours" : {
"LABEL" : "Update Coaching Hours",
"PLUGIN" : "reaction rule",
"OWNER" : "rules",
"REQUIRES" : [ "commerce_order", "rules", "commerce_payment" ],
"ON" : { "commerce_payment_order_paid_in_full" : [] },
"IF" : [
  { "commerce_order_contains_product_type" : {
      "commerce_order" : [ "commerce_order" ],
      "product_type" : { "value" : {
          "coaching" : "coaching",
          "consulting" : "consulting",
          "product" : "product"
        }
      },
      "operator" : "\u003E=",
      "value" : "1"
    }
  }
],
"DO" : [
  { "variable_add" : {
      "USING" : { "type" : "decimal", "value" : "0" },
      "PROVIDE" : { "variable_added" : { "total_coaching_hours" : "Total Coaching Hours" } }
    }
  },
  { "LOOP" : {
      "USING" : { "list" : [ "commerce-order:commerce-line-items" ] },
      "ITEM" : { "current_line_item" : "Current line item" },
      "DO" : [
        { "component_rules_get_coaching_hours" : {
            "USING" : { "current_line_item" : [ "current_line_item" ] },
            "PROVIDE" : { "included_coaching_hours" : { "included_coaching_hours" : "Item Coaching Hours Included" } }
          }
        },
        { "data_calc" : {
            "USING" : {
              "input_1" : [ "total-coaching-hours" ],
              "op" : "+",
              "input_2" : [ "included-coaching-hours" ]
            },
            "PROVIDE" : { "result" : { "coaching_result" : "Coaching Summation result" } }
          }
        },
        { "data_set" : { "data" : [ "total-coaching-hours" ], "value" : [ "coaching-result" ] } }
      ]
    }
  },
  { "data_calc" : {
      "USING" : {
        "input_1" : [ "commerce-order:owner:field-coaching-hours" ],
        "op" : "+",
        "input_2" : [ "total-coaching-hours" ]
      },
      "PROVIDE" : { "result" : { "updated_hours" : "updated coaching hours" } }
    }
  },
  { "data_set" : {
      "data" : [ "commerce-order:owner:field-coaching-hours" ],
      "value" : [ "updated-hours" ]
    }
  }
]
}
}

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.