1

I'm making a commerce site with Drupal 8 and Drupal commerce and I have a not so common request. Some of the products should be available to buy only in groups (bundles) with some other products. E.g. if you want to buy product A in quantity 100 you must also buy product B, product C and/or product D and sum of them (B+C+D) must also be 100. Other way it shouldn't be possible to buy any of them separately.

I saw that there are some Bundle modules (not even sure if they could fulfill this request), but they exist only for Drupal 7.

So is there some module for D8 which will allow grouping products like this. If not what would be the best way to achieve this feature?

1
+50

As far as I know, there are no supported modules to acheive what you want.

So if you want a sustainable and future proof solution, you should probably code it yourself.

I would go for solution, where I create a custom entity type, Product Validation.

Here are some fields, that I think it should contain:

  1. Product ID (The product it's active on).
  2. Applies above (quantity) (A minimum quantity that must be purchased, before the validation is applyed).
  3. Depending products (Products that be must purchased too).
  4. Min SUM (The minimum sum of all the depending products).

Those are just fields that should probably be there, you can always add more fields like, if only one of depending products must be purchased, or all of them, maybe also support for multiple product ID's to avoid creating duplicates, etc.

Then add a custom validate handler, when the user clicks the place order button on the cart page.

EDIT: To alter the cart form you could use hook_form_alter, and check if (strpos($form_id, 'views_form_commerce_cart_form_default') === 0. The cart form has a unique ID per order so that's why you want to do like that. Then you can add $form['#validate'][] = 'MY_MODULE_product_validation', where the logic will then be.

Your logic will look similar to this:

$product_validation = $entityTypeManager->getStorage('product_validation')->loadByProperties([
  'product_id' => $product->id(),
]);

if (isset($product_validation)) {
  if ($product_validation->getAppliesAbove() > $product->quantity) {
    $total_quantity = 0;
    foreach ($product_validation->getDependingProducts() as $dep_product) {
      // Check if $dep_product has been added to cart.
      // If yes $total_quantity += $cart->getItem('something')->quantity.
    }
    if ($product_validation->getMinSum() >= $total_quantity) {
      return TRUE;
    }
    return $form_state->setError($form, 'something');
  }
}

OBS: This code is using dummy variables and is intended to help you understand the logic, not as a "ready to implement" solution.

I hope it all makes sense.

  • I was thinking of some similar solution (if there really is no bundle module) I just didn't know where exactly to hook. Is there appropriate hook where I can add my validation code or maybe some event to listen to? Do you maybe know that? – MilanG Jul 15 '19 at 8:25
  • 1
    As @TonyTheFerg mentions, there are the commerce_product_bundle module which is only released in a dev version, but using that module you would probably have to contribute to it, since it would only provide you with a starting point and not the complete solution. To alter the cart form you could use hook_form_alter, and check if (strpos($form_id, 'views_form_commerce_cart_form_default') === 0. The cart form has a unique ID per order so that's why you want to do like that. Then you can add $form['#validate'][] = 'MY_MODULE_product_validation', where the logic will then be. – user72672 Jul 15 '19 at 8:35
0

Drupal Commerce doesn't currently have a STABLE bundle module ported to 8, but if you like living on the edge, commerce_product_bundles which is under development MIGHT be able to get the job done. You can assign multiple bundle items (a product wrapped in a bundle item) to a bundle group (a group of bundle items sold together), and can specify the minimum and maximum quantities for each of those bundle items, as well as a new selling price if you like.

You might be limited setting the minimum and maximum quantities of Products B, C, D to reach 100 the way you mentioned, in that you would need to give a fixed quantity range to B,C and D. (like 34, 33, 33 etc) But you certainly can require/allow the 100 of A, and predetermine a satisfactory combo of B,C,D equaling 100. You can also require products B,C,D, and not require A... etc. You'd have to test it with your use case to see if it's sufficient.

The docs don't explain the full function of the D8 development version, but you can read their brainstorming session here: https://www.drupal.org/project/commerce_product_bundle/issues/2799643

Just beware, when I tested the module personally, it broke my cart path when I tried uninstalling it, so test it locally first. You might be able to sponsor some tweaks and a stable release on it, or this may give you some ideas as to how to accomplish it yourself with your own custom code.

Here are some photos of the UI to help you wrap your mind around the function: Hope this helps!

enter image description here enter image description here

  • From the docs, This module extends Drupal Commerce by allowing the site admin to collect a number of existing products together in a bundle, and offer them at a new bundle price, with a new bundle SKU. Which means that it's possible to group multiple products into one single one with a new price. First of all that's not what OP is asking for, 2nd that module, as you slightly mention, doesn't even have a release for D8 yet, only a dev release. – user72672 Jul 14 '19 at 9:28
  • Edited. I disagree with your first of all, and I clarified your second of all. The docs don't give any detail on the minimum and maximum quantities aspect that the D8 dev version allow. I HAVE used the module... The dev version certainly allows you to set minimum quantities to multiple individual products and present them as a bundle for the end user. – TonyTheFerg Jul 14 '19 at 11:00
  • Ok, don't know if I made it clear enough. Commerce product bundles, takes e.g. 3 different products and sell them for a fixed price. What OP wants is to make sure that the user buys the other products too if too few products of a specefic type has been brought and not all of them together with a fixed quantity and price. If OP was to use that module he would either need to hack it or contribute to it, which makes it easier to code it. Hope you understand my point. – user72672 Jul 14 '19 at 11:25
  • CPB will give you a min/max RANGE, allowing the customer to manipulate that range on multiple products within the bundle. Price is mostly irrelevant as the question made no mention of discount, just bundling via minimum quantity requirements. From what I understand anyway. Not sure my answer deserved a down vote. – TonyTheFerg Jul 14 '19 at 11:31
  • Removed the downvote, since you made your answer more clear. Still don't think that the module is applicable here, since it requires the bundle to have a total price, which should be calculated based on quantity and not by a fixed value. – user72672 Jul 14 '19 at 11:44

Not the answer you're looking for? Browse other questions tagged or ask your own question.