I hope this isn't a repeat, I've searched but it hasn't been answered.

If building a pizza, a person would want to add multiple toppings. Is there a way to do this check-boxes? And then associate an image with those check boxes?

If this is possible, then is there a way to make the toppings selected call a sku which would generate a price? For example:
1-meat topping= 11.99
1-veg topping=10.99,
3-veg topping=12.99,
2-veg and 1-meat = 13.99, and so on and so forth.

The problem with the pricing is that it isn't a consistent add-on price. Thus, it is necessary to have a unique product-sku for each product selection.

Thanks for the help,
tim

Comments

rszrama’s picture

Version: 7.x-1.0-rc3 » 7.x-1.x-dev
Status: Active » Fixed

You wouldn't necessarily have to make these unique SKUs. In Drupal Commerce, you can add fields to line items that are exposed to the Add to Cart form, such as a Toppings checkboxes field. You can then use product pricing rules to adjust the price of the pizza in the cart based on toppings selected. This means you're going to have a more Rules intensive pricing system, which will be more complicated than just putting a price in a textfield somewhere, but it also means you won't have to have a unique SKU for every combination of toppings available... which would honestly probably be impossible to manage. Instead you could have unique SKUs for different sizes and / or varieties of pizza (12" New York style, 18" Chicago style, etc.).

If you want to limit the number of toppings selected in any given checkboxes list, you're going to have to get into the code and write a custom Add to Cart form validate handler. No way around that. Also, make sure you're using the latest release of Commerce.

Randy Fay just posted a couple of tutorials and screencasts showing how to add fields to line item types and use them on the Add to Cart form. Check them out here:

http://www.commerceguys.com/resources/articles/238
http://www.commerceguys.com/resources/articles/240

timodwhit’s picture

Status: Fixed » Needs work

Thanks for the Help!

I managed to solve the problem, slightly.

I ditched taxonomy terms for toppings and created line item type that would have multiple toppings, or single toppings.

With a personal pizza which only has a single topping, the pricing rule is simple and can be compared to the rfay's screencast on selection. The problem arises when the list has multiple toppings as check boxes.

I have tried to create simple rules similar to those found on the screencast, but the compare data becomes more complicated because you are given choices: commerce-line-item:fieild-toppings:toppings:1, toppings:2, toppings:3, toppings:4.

The pricing rule is going to be naturally more complex, and thats fine. But I can't even get a simple rule to work if the buttons are check boxes instead of radio buttons.

Let me know if you have any suggestions: I'll post my pricing rule later tonight.

timodwhit’s picture

Thanks for the Help!

I managed to solve the problem, slightly.

I ditched taxonomy terms for toppings and created line item type that would have multiple toppings, or single toppings.

With a personal pizza which only has a single topping, the pricing rule is simple and can be compared to the rfay's screencast on selection. The problem arises when the list has multiple toppings as check boxes.

I have tried to create simple rules similar to those found on the screencast, but the compare data becomes more complicated because you are given choices: commerce-line-item:fieild-toppings:toppings:1, toppings:2, toppings:3, toppings:4.

The pricing rule is going to be naturally more complex, and thats fine. But I can't even get a simple rule to work if the buttons are check boxes instead of radio buttons.

Let me know if you have any suggestions: I'll post my pricing rule later tonight.

rszrama’s picture

Status: Needs work » Fixed

Ultimately you may need to develop (or pay someone to develop) a custom action then that evaluates the toppings selected and affects the price accordingly. Rules is great, but it can be quicker to work in PHP at times.

timodwhit’s picture

Figured Out how to use rules to achieve this:

The rules are pretty nasty, but let me clarify the case under which I was working: I need to fill the med and large popcorn tins with three different flavors, then dependent on the type of flavor filled with the prices would change. There are only 4 prices, thus I only needed to create 4 rules. I'm sure this can be made in a prettier rule and/or php code, but for what I need it works.

I ended up using taxonomy terms and just defining my rules differently than rfay on post in ryan's prior post.

2 taxonomy vocabularies: size and flavor.

Let me know if you spot any errors or see any big flaws. The biggest part of the problem is making sure that the setup is proper prior to applying the rules.

For medium tins here is the first rule I used:

{ "rules_2_gallon_tin__2_gourmet_1_classic" : {
    "LABEL" : "2 Gallon Tin  2 Gourmet 1 Classic",
    "PLUGIN" : "reaction rule",
    "WEIGHT" : "-2",
    "REQUIRES" : [ "rules", "commerce_line_item", "commerce_product_reference" ],
    "ON" : [ "commerce_product_calculate_sell_price" ],
    "IF" : [
      { "entity_has_field" : { "entity" : [ "commerce-line-item" ], "field" : "commerce_product" } },
      { "entity_has_field" : {
          "entity" : [ "commerce-line-item" ],
          "field" : "field_multiple_flavors_taxo"
        }
      },
      { "OR" : [
          { "AND" : [
              { "OR" : [
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "7"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "9"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "4"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "8"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "6"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "10"
                    }
                  }
                ]
              },
              { "OR" : [
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "16"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "15"
                    }
                  }
                ]
              }
            ]
          },
          { "AND" : [
              { "OR" : [
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "7"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "9"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "4"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "8"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "6"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "10"
                    }
                  }
                ]
              },
              { "OR" : [
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "7"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "9"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "4"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "8"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "6"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "10"
                    }
                  }
                ]
              },
              { "OR" : [
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "16"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "15"
                    }
                  }
                ]
              }
            ]
          }
        ]
      },
      { "component_rules_2_gal_tin" : { "product" : [ "commerce-line-item:commerce-product" ] } }
    ],
    "DO" : [
      { "commerce_line_item_unit_price_amount" : {
          "commerce_line_item" : [ "commerce_line_item" ],
          "amount" : "4000",
          "component_name" : "base_price"
        }
      }
    ]
  }
}

Here is the second rule:

{ "rules_2_gallon_tin_2_gourmet_1_classic" : {
    "LABEL" : "2 Gallon Tin 1 Gourmet 2 Classic",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules", "commerce_line_item", "commerce_product_reference" ],
    "ON" : [ "commerce_product_calculate_sell_price" ],
    "IF" : [
      { "entity_has_field" : { "entity" : [ "commerce-line-item" ], "field" : "commerce_product" } },
      { "entity_has_field" : {
          "entity" : [ "commerce-line-item" ],
          "field" : "field_multiple_flavors_taxo"
        }
      },
      { "AND" : [
          { "list_contains" : {
              "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
              "item" : "15"
            }
          },
          { "list_contains" : {
              "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
              "item" : "16"
            }
          },
          { "OR" : [
              { "list_contains" : {
                  "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                  "item" : "7"
                }
              },
              { "list_contains" : {
                  "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                  "item" : "9"
                }
              },
              { "list_contains" : {
                  "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                  "item" : "4"
                }
              },
              { "list_contains" : {
                  "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                  "item" : "8"
                }
              },
              { "list_contains" : {
                  "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                  "item" : "6"
                }
              },
              { "list_contains" : {
                  "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                  "item" : "10"
                }
              }
            ]
          }
        ]
      },
      { "component_rules_2_gal_tin" : { "product" : [ "commerce-line-item:commerce-product" ] } }
    ],
    "DO" : [
      { "commerce_line_item_unit_price_amount" : {
          "commerce_line_item" : [ "commerce_line_item" ],
          "amount" : "3500",
          "component_name" : "base_price"
        }
      }
    ]
  }
}

Here is the third rule:

{ "rules_2_gallon_tin_classic" : {
    "LABEL" : "2 Gallon Tin Classic",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules", "commerce_line_item", "commerce_product_reference" ],
    "ON" : [ "commerce_product_calculate_sell_price" ],
    "IF" : [
      { "entity_has_field" : { "entity" : [ "commerce-line-item" ], "field" : "commerce_product" } },
      { "entity_has_field" : {
          "entity" : [ "commerce-line-item" ],
          "field" : "field_multiple_flavors_taxo"
        }
      },
      { "OR" : [
          { "AND" : [
              { "OR" : [
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "15"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "16"
                    }
                  }
                ]
              },
              { "NOT OR" : [
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "7"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "9"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "4"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "8"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "6"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "10"
                    }
                  }
                ]
              }
            ]
          },
          { "AND" : [
              { "list_contains" : {
                  "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                  "item" : "15"
                }
              },
              { "list_contains" : {
                  "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                  "item" : "16"
                }
              },
              { "NOT OR" : [
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "7"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "9"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "4"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "8"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "6"
                    }
                  },
                  { "list_contains" : {
                      "list" : [ "commerce-line-item:field-multiple-flavors-taxo" ],
                      "item" : "10"
                    }
                  }
                ]
              }
            ]
          }
        ]
      },
      { "component_rules_2_gal_tin" : { "product" : [ "commerce-line-item:commerce-product" ] } }
    ],
    "DO" : [
      { "commerce_line_item_unit_price_amount" : {
          "commerce_line_item" : [ "commerce_line_item" ],
          "amount" : "3000",
          "component_name" : "base_price"
        }
      }
    ]
  }
}

Overall: The rules look worse than they really are. There does seem to be some redundancy present in the rules, but if you set the price to the most used, this should cut down the actual work. The other thing that was tricky was if you use "list contains item" then make sure that you specify that the list DOES NOT include other items.

Thanks for the help and feed back!

rszrama’s picture

Epic. You win the Rules badge for the week! ; )

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

jakew’s picture

Jeez. Is there any better solution for this yet? I want my client to be able to add and manage products easily, including with multiple attributes and options, without having to create multiple product entities and then associate them individually with product reference fields in a Product node. It looks like the BPC module would get me halfway there, but wouldn't automatically add the appropriate multiple product references to the Product node and would leave behind a managerial nightmare of product attribute/option permutations. What if someone wants to add or remove an option on one of the attributes? Imagine... hunt through all the Products, find and delete the dozens of permutations for the product, use BPC again to create all the permutations, remove and re-add all the product references to the Product node... you get the picture. Not to mention that the interface for adding the product with the right combination of options the the cart would be more difficult for end users - they'd have to select the precisely right combination from a single long list instead of selecting or changing each attribute's option individually. It's a deal-breaker for Commerce for me (and I imagine for many others too); I'll probably use Ubercart instead. Please let me know if there's an easy, non-code, non-multiple-rules, non-PITA way around this!

summit’s picture

Hi,
Isn't inline entity form a solution: http://commerceguys.com/blog/commerce-module-tuesday-inline-entity-form
Greetings, Martijn

timodwhit’s picture

@jakew Actually how I answered this problem is quite different than originally posted and really quite beautiful for management but might not work for you.

What I did: I sell popcorn tins with 3 different flavor TYPES and any number of flavor OPTIONS, where each OPTION is a certain TYPE. So all my flavors options are taxonomy terms that reference my flavor TYPES. I set up a taxo reference on the commerce line item that allows the customer to pick there flavor OPTION. Based on the option it fires the rules.

From a management side: all the manager has to do to modify the form is add/remove/unplublish the flavor from term list, and that adjusts the settings across the site, I don't think it gets much easier than that.

There are multiple rules but the manager only has to insert one price and everything is adjusted from there.

xbrianx’s picture

I agree its entirely too complex to add options to products right now. Towards the end of this discussion here: http://www.drupalcommerce.org/discussions/281/understanding-product-attr...

mentions of tying attributes to actual products seems like a convenient way of doing things.

But we need to have price updates on a product page before going to the cart.

Has anyone any ideas on how to better achieve this, Especially for a regular end user to wants to create products with customized attributes/addons/rules/upgrades/etc .

joshmiller’s picture

You all might consider viewing the long'ish video here where I use the http://drupal.org/project/commerce_custom_product and taxonomy to create a customizable product. In this case, we are creating pizzas that can have various toppings that all have a price field.

http://www.youtube.com/watch?v=j9KsyvQZaAY

HFlame7’s picture

#12 was a good suggestion (thanks for the video), but I feel too many steps are involved for that method.

Although I haven't tested this module out yet, the "Commerce Pricing Attributes" seems to do what everyone on this thread wants. Unfortunately, it also relies on two other commerce contributed modules, but seems to be the best method out right now:

Module: http://drupal.org/project/commerce_pricing_attributes

Screencast: http://www.netstudio.gr/en/blog/commerce-pricing-attributes-what-it-and-...

summit’s picture

Hi,
The problem with using a solution with attributes is that if you use solution based on that you do not have SKU's / products for each of the possible options.
Greetings, Martijn

HFlame7’s picture

In response to Summit (#14), that is true but only if you actually need to have them as multiple products.

For example, if a store sold ready-made clothing (blue shirts, black shirts, red shirts, etc) then it's understandable that those would truly need to be separate products.

However, there was an example posted on another website that would highly benefit from using attributes rather than separate products:


"If we assume that the "pizza" product has 5 different types of cheese, 5 types of sausages, 5 sauces and 5 types of vegetables then we had to create 5*5*5*5 = 625 different products!"

It really just depends on the type of store you have.

mikeaja’s picture

Re #14

@Summit, absolutely, and that is exactly how attributes should be. DC discussions and documentation is using the term incorrectly, or at least unclearly.

Product variations makes sense for what DC is offering. Attributes are different, are elements of a product, not a different product.

It's driving me a little nuts that so much DC attribute talk is not about product attributes at all....... :)

rszrama’s picture

In DC we define the dichotomy like so:

  • A product attribute is something that distinguishes one of a group of products from the others in that group. In accounting systems, these distinguishing factors means the products are handled distinctly from a stock management and reporting standpoint - thus the need for a unique SKU. I don't just have a shirt in my inventory; I have a small shirt, a medium shirt, etc.
  • A product customization is something a customer defines, whether it's freeform or selected from a group of options, that enables the merchant to deliver the product according to the customer's specifications. This might be an engraving, a conference lunch selection, etc. Regardless of how many such customizations you might have, they can all be tracked against the same item in inventory, thus the ability to use a single SKU.