Tags/topics: 
1
Answers
Vote up!
0
Vote down!

Checking value of line item using Rules

My line item type has a custom field attached to it that a user selects when they add the item to their cart.

When I come to the Payment method rules, I need to check the value of this item, because I need to use either one set of payment rule configuration or another depending on the value of this field.

I don't know the best way to approach this. I'm guessing I need to use the Data Comparison condition but then how do I get my custom field to appear as a data selector?

Rules is kind of alien to me from a programming point of view and I'm not having much luck finding good documentation and tutorials on it so any help gratefully received!

Gideon Cresswell
Asked by: Gideon Cresswell
on September 29, 2014

1 Answer

Vote up!
1
Vote down!

Gideon,

Awesome name, BTW.

To get a condition to react to something from within a list, you have to create a custom rule condition. Take heart! You can copy how we do this in Drupal Commerce:

<?php
/**
 * Implements hook_rules_condition_info().
 */
function commerce_order_rules_condition_info() {
//...
$conditions['commerce_order_contains_product'] = array(
   
'label' => t('Order contains a particular product'),
   
'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. If the specified order does not exist, the comparison will act as if it is against a quantity of 0.'),
      ),
     
'product_id' => array(
       
'type' => 'text',
       
'label' => t('Product SKU'),
       
'description' => t('The SKU 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 specified product 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',
    ),
  );
}
?>

And then you create a function that goes through all the line items in an order and return a true or false...

<?php
 

/**
 * Condition callback: checks to see if a particular product exists on an order
 * in the specified quantity.
 */
function commerce_order_rules_contains_product($order, $sku, $operator, $value) {
 
$products = array($sku => 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_sku = $line_item_wrapper->commerce_product->sku->value();
       
$quantity = $line_item_wrapper->quantity->value();

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

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

  return
FALSE;
}
?>
Josh Miller
Answer by: Josh Miller
Posted: Oct 3, 2014