0

How can I avoid grouping of the same items (products configured identically) to be grouped in the same line item with a quantity count?

I want every single item, even if an identical already exists in the cart, to be its own line item with its own ID.

I tried several rules that fire when a new product is added to cart, when a line item is updated, tried duplicating, re-adding... even tried a timestamp field which would be different for every time a user adds an item, which should result in a new line item being created - but this is just too much of a hack for me.

Is there any clean way to create a new line item for every item in the cart?

5

You can just toggle the setting on your Add to Cart form display formatter to turn off combining like items in the cart.

  • Thanks a lot! I thought there must be a setting, never would've guessed it to be there... – Victor Purolnik Dec 17 '13 at 21:11
  • I've been looking for this setting for an hour in Commerce Kickstart 2 and cannot find it. Can someone help? – Bisonbleu Sep 26 '16 at 20:30
  • This setting can be found in the Manage Display tab of a product display (i.e. the content type used to display that product). Look for the field with the Add to cart form in the Format column. – Bisonbleu Sep 26 '16 at 21:08
3

I would look into using hook_commerce_cart_product_comparison_properties_alter or any other hooks that will allow you to alter the line item before it being added to the cart such as hook_commerce_product_calculate_sell_price_line_item_alter.

Using hook_commerce_product_calculate_sell_price_line_item_alter() (or similar hooks), you can try to change the 'add_to_cart_combine' property of the line item:

/**
 * Implements hook_commerce_product_calculate_sell_price_line_item_alter().
 *
 * Alter the 'add_to_cart_combine' property to always be FALSE.
 */
function example_commerce_product_calculate_sell_price_line_item_alter($product_line_item) {
  $product_line_item->data['context']['add_to_cart_combine'] = FALSE;
}

Using hook_commerce_cart_product_comparison_properties_alter() involves more work but looks a lot less "hacky". From Commerce Cart API:

/**
 * Allows modules to add additional property names to an array of comparison
 * properties used to determine whether or not a product line item can be
 * combined into an existing line item when added to the cart.
 *
 * @param &$comparison_properties
 *   The array of property names (including field names) that map to properties
 *   on the line item wrappers being compared to check for combination.
 * @param $line_item
 *   A clone of the line item being added to the cart. Since this is a clone,
 *   changes made to it will not propagate up to the Add to Cart process.
 */
function hook_commerce_cart_product_comparison_properties_alter(&$comparison_properties) {
  // Force separate line items when the same product is added to the cart from
  // different display paths.
  $comparison_properties[] = 'commerce_display_path';
}

This means, you can add another property to the comparison properties array that will be used to determine how products can be combined to existing line items in the cart. In that case, I would add a new property that will always be different for each line item being added (e.g. a timestamp, md5 hash):

function example_commerce_cart_product_comparison_properties_alter(&$comparison_properties) {
  // Force separate line items when the same product is added to the cart at different times.
  $comparison_properties[] = 'timestamp';
}

You'll have to make sure though that you have a timestamp field in your line item (either by adding through the field manager or programmatically attaching the field).

  • Thanks for taking so much effort and helping me, this actually worked well. Still, I will use Ryan's solution for simpleness' sake. – Victor Purolnik Dec 17 '13 at 21:10
1

For anyone looking to do this (which there are a bunch of ppl..) I found a way to finally get this to work.

For starters, turn off the Combine options in your Line Item displays and Product displays.

Then install Rules Array Create module, this is key, since we need to work with a loop in Rules and the Quantity is a variable not an Array which is the only thing loops can work with.

Next, import this Rule.

{ "rules_split_quantity" : {
    "LABEL" : "Split Quantity",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_array_create", "commerce_cart" ],
    "ON" : { "commerce_cart_product_add" : [] },
    "IF" : [
      { "data_is" : { "data" : [ "quantity" ], "op" : "\u003E", "value" : "1" } }
],
"DO" : [
  { "array_create" : {
      "USING" : { "size" : [ "quantity" ] },
      "PROVIDE" : { "array_added" : { "amount_array" : "Amount Array" } }
    }
  },
  { "LOOP" : {
      "USING" : { "list" : [ "amount-array" ] },
      "ITEM" : { "list_item" : "Current list item" },
      "DO" : [
        { "commerce_cart_product_add_by_sku" : {
            "USING" : {
              "user" : [ "site:current-user" ],
              "sku" : [ "commerce-product:sku" ],
              "quantity" : "1",
              "combine" : "0"
            },
            "PROVIDE" : { "product_add_line_item" : { "product_add_line_item" : "Added product line item" } }
          }
        }
      ]
    }
  },
  { "list_remove" : {
      "list" : [ "commerce-order:commerce-line-items" ],
          "item" : [ "commerce-line-item" ]
    }
      }
    ]
  }
}

Just to add you probably noticed the "List Remove" action. This removes the original line item with it's original quantity. Without this, if you added a product with qty 5, you would end up with 6 line items. 1 with a qty of 5, and another 5 with the qty of 1.

I also changed the cart View display to only show the Quantity, and not the Quantity Text which allows people to further change their qty in the cart.

  • Could you please post your solution in answer body? – ar7max Aug 17 '15 at 19:07
  • Just to note, this works unless you use a price altering module for discounts, like Commerce Pricing Attributes. I ended up scrapping this and am working doing this in a custom module instead. See drupal.stackexchange.com/questions/182445/… – Travis Johnston Dec 1 '15 at 18:31
0

Quick and dirty option :

File : commerce_cart.module

Function : commerce_cart_product_add($uid, $line_item, $combine = TRUE)

$combine set to FALSE

Done.

Personally I'd create a custom module and use 'hook_commerce_cart_product_comparison_properties_alter'...

0

If you are adding an item to cart programmatically in Drupal 8, you can set the combine option to false.

$cart_manager = \Drupal::service('commerce_cart.cart_manager'); $cart_manager->addOrderItem($cart, $order_item, false);

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.