I'm trying to set up a Rule that will fire whenever a certain product is bought. I've been able to do this using "Order contains a particular product" which then asks for the SKU, but we'll be adding more of these products in the future (they are event registrations, by the way).

Rather than having to edit/add another rule each time a new event registration is added and adding the SKU to the condition, is it possible to have the condition reference the product type (event registration) instead of a specific SKU?

I've tried doing this by adding the condition "Entity has field" and referencing a field that is only in the event registration product type, but it doesn't seem to work. Any ideas?

Comments

rszrama’s picture

Status: Active » Closed (won't fix)

You can't do this with the basic rule, but you can either use a custom action or try your hand at a loop in your rule's actions that iterates over the commerce-order:commerce-line-items and calls a component that can perform an action based on the referenced product's type. I don't think we'll be adding any custom conditions at this point in time for this unless it becomes a more common feature request. I'll keep my eye out. If this functionality doesn't need to be configurable via the UI, there's nothing wrong with implementing hook_commerce_checkout_complete() in a custom module for the site to perform your additional business logic.

skyredwang’s picture

Category: task » feature
Status: Closed (won't fix) » Active

I also think adding a "Order contains a particular product type" rule condition is useful. I am re-opening this issue, and if I have the time, I will write a patch.

rszrama’s picture

Version: 7.x-1.0 » 7.x-1.x-dev

Sounds good. Nice to meet you in Denver!

sreynen’s picture

I think this might already be covered here:

http://drupal.org/node/1331230

I didn't end up needing this, so didn't try it, but it looks good.

rszrama’s picture

Yeah, I saw that module in a training yesterday, but I think it'd still be good to have as a core feature. I'll just remember to coordinate with them once it works in core so they can remove it from that package at the same time.

skyredwang’s picture

yeah, I also think it should go into the core instead of in a contrib

Yaazkal’s picture

Hello, reopening this issue just to give my +1 on this feature request, as in comment No. 2 it is very useful to have a "Order contains a particular product type" rule condition.

Thanks !

sonictruth’s picture

I found myself wanting this feature today so +1 for me.

derekw’s picture

I don't know how to create a patch but I think I pulled this off by copying/modifying the SKU functions. My first try so please be gentle. This seems to work for me.

At line 95 added condition commerce_order_contains_product_type


 $conditions['commerce_order_contains_product_type'] = array(
    'label' => t('Order contains a product type'),
    'parameter' => array(
      'commerce_order' => array(
        'type' => 'commerce_order',
        'label' => t('Order'),
        'description' => t('The order whose line items should be checked for the specified product type. If the specified order does not exist, the comparison will act as if it is against a quantity of 0.'),
      ),
      'product_type' => array(
        'type' => 'text',
        'label' => t('Product Type'),
	     'options list' => 'commerce_product_type_options_list',
        'restriction' => 'input',
        'description' => t('The type of the product to look for on the order.'),
      ),
      'operator' => array(
        'type' => 'text',
        'label' => t('Operator'),
        'description' => t('The operator used with the quantity value below to compare the quantity of the product type on the order.'),
        'default value' => '>=',
        'options list' => 'commerce_numeric_comparison_operator_options_list',
        'restriction' => 'input',
      ),
      'value' => array(
        'type' => 'text',
        'label' => t('Quantity'),
        'default value' => '1',
        'description' => t('The value to compare against the quantity of the specified product on the order.'),
      ),
    ),
    'group' => t('Commerce Order'),
    'callbacks' => array(
      'execute' => 'commerce_order_rules_contains_product_type',
    ),
  );

Then at line 302 Added function commerce_order_rules_contains_product_type:


/**
 * Condition callback: checks to see if a particular product type exists on an order
 * in the specified quantity.
 */
function commerce_order_rules_contains_product_type($order, $type, $operator, $value) {
  $products = array($type => 0);

  // If we actually received a valid order...
  if (!empty($order)) {
    $order_wrapper = entity_metadata_wrapper('commerce_order', $order);

    // Populate the array of the quantities of the products on the order.
    foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
      if (in_array($line_item_wrapper->type->value(), commerce_product_line_item_types())) {
        // Extract a product ID and quantity from the line item.
        $line_item_type = $line_item_wrapper->commerce_product->type->value();
        $quantity = $line_item_wrapper->quantity->value();

        // Update the product's quantity value.
        if (empty($products[$line_item_type])) {
          $products[$line_item_type] = $quantity;
        }
        else {
          $products[$line_item_type] += $quantity;
        }
      }
    }
  }

  // Make a quantity comparison based on the operator.
  switch ($operator) {
    case '<':
      return $products[$type] < $value;
    case '<=':
      return $products[$type] <= $value;
    case '=':
      return $products[$type] == $value;
    case '>=':
      return $products[$type] >= $value;
    case '>':
      return $products[$type] > $value;
  }

  return FALSE;
}
 
tuccio’s picture

farald’s picture

Here's a patch for the code in #9.

farald’s picture

Status: Active » Needs review
kenorb’s picture

chris matthews’s picture

The 6 year old patch in #11 to commerce_order.rules.inc applied cleanly to the latest commerce 7.x-1.x-dev and (if still relevant) needs to be reviewed.