Separate line items when line item details are different As an ability the user might choose gift wrapping option for some of his/her products on add to cart form , what I did is creating a new product type called gift wrapping item, so site operators can add different kinds of wrapping options with different prices. I also altered the add to cart form so a new form item is added which gives the costumer the ability to choose a wrapping type, so far so good, user choice then is saved as a line item property (product ID of wrapping option is save in 'field_wrapping_option' which is added to product line item), and wrapping price is added to line item base price.

The problem is raised when user want to add 2 item from same product but he/she wants wrapping only for one of the two. In this case both products are stored in same line item and wrapping price also is added for them both.

I used hook_commerce_cart_product_comparison_properties_alter to force drupal create different line item when 'field_wrapping_option' are different on line items, but it didn't make things better, now every add to cart operation lead to new line item even when same wrapping option has chosen by user, and even worse situation happens when user first add a product without gift wrapping first and then adds a product with wrapping option which cause the first line item change into a product with gift wrapping.

Now the question is : How to Separate line items when line item details are different?
You could first have a look at Commerce Product Add-on module. That solution would split them per product type e.g. if you add one product with gift wrapping and one without you will have one line item for the product with quantity 2 and one for the gift wrapping with quantity 1. This gives the customer visibility of the exact pricing.

If however you still want to do it the way you described, the hook you mentioned should work.

function MY_MOULE_commerce_cart_product_comparison_properties_alter(
  &amp;$comparison_properties,
  $line_item
) {                                                                                                                                                                                                                
  $comparison_properties[] = 'field_wrapping_option';
}


Possible cause of trouble would be if the 'field_wrapping_option' of the line item being added is not set at all. The existing line item would always have the field set, even with an empty value, while you will have to set it for the incoming line item. It is possible that you set the field value only when gift wrapping is selected, try setting the field value to NULL if no gift wrapping is selected.

$line_item_wrapper-&gt;field_wrapping_option-&gt;set(NULL);


To further debug why line items are not properly combined, look at the 'commerce_cart_product_add' function at the commerce_cart.module file. The following code is the most relevant.

// Loop over each line item on the order.                                                                                                                                                                                                
foreach ($order_wrapper-&gt;commerce_line_items as $delta =&gt; $matching_line_item_wrapper) {
  // Examine each of the comparison properties on the line item.                                                                                                                                                                         
  foreach ($comparison_properties as $property) {
    // If the property is not present on either line item, bypass it.                                                                                                                                                                    
    if (!isset($matching_line_item_wrapper-&gt;value()-&gt;{$property}) &amp;&amp; !isset($line_item_wrapper-&gt;value()-&gt;{$property})) {
      continue;
    }

    // If any property does not match the same property on the incoming line                                                                                                                                                             
    // item or exists on one line item but not the other...                                                                                                                                                                              
    if ((!isset($matching_line_item_wrapper-&gt;value()-&gt;{$property}) &amp;&amp; isset($line_item_wrapper-&gt;value()-&gt;{$property})) ||
      (isset($matching_line_item_wrapper-&gt;value()-&gt;{$property}) &amp;&amp; !isset($line_item_wrapper-&gt;value()-&gt;{$property})) ||
      $matching_line_item_wrapper-&gt;{$property}-&gt;raw() != $line_item_wrapper-&gt;{$property}-&gt;raw()) {
      // Continue the loop with the next line item.                                                                                                                                                                                      
      continue 2;
    }
  }

  // If every comparison line item matched, combine into this line item.                                                                                                                                                                 
  $matching_line_item = $matching_line_item_wrapper-&gt;value();
  break;
}