Implementing Option-only Pricing in Drupal Commerce (D7)
Drupal Commerce can be confusing to get one's arms around, even if (or especially if) coming from using Ubercart or some other relatively point-and-click cart. I recently had the need to do something I considered a simple requirement, and having retail experience, something intrinsic to most catalogs: products with option-only pricing.
What is option-only pricing? I'll first give an example of the alternative, a bakery. They sell birthday cakes. A 12-inch cake with no-frills icing is $15. There are then a number of options available, such as butter-cream icing, decorations, etc. So, in adding this product to a catalog, you can show the base product at $15, and then the list of options and the price for each.
With option-only pricing, there is no base price. It is required that an option be selected. Yes, it would seem, then, that the term 'option' is misused, but one does have an option of which to select, even if a selection is required. An example of this is the one I will use in this tutorial: container quantity. This is not the quantity put into the shopping cart, which is unit quantity, but the number of items the product contains.
For our purposes, the store is ABC Pharmacy, and the product is Vitamin C. The buyer can choose to put any number of bottles in their cart, the unit quantity, but they must select whether they want a bottle of 50, 100 or 200 tablets, the container quantity. There is no price for Vitamin C without a quantity... no 'per-tablet' price. Each container quantity has its own price.
There is more than one way to achieve this. Keep in mind that while Commerce is very abstract, and as such makes availabe many potential approaches, not all are equivalent. For example, it is important to ensure that the method doesn't exist outside Commerce's pricing logic ... selecting the option should show the user what the price is, and that price should transfer with the product to the shopping cart and order. So, adding a field to the product to provide a container quantity option won't result in the price reflecting the selection without more effort.
We're going to accomplish the requirement by having each option be an individual product, and no, that doesn't mean that each is going to appear on a separate page, though it esaily could if that were also a requirement. One thing about Commerce that often leaves a newbie scratching his head is that there are Store products and Display products. Why? Well, one reason is so that there can be more than one presentation for a product...you can define more than one display per store product. Another reason is that in decoupling the presentation, it is possible to NOT have a display for certain products. In that way, several products can share one presentation, such as items in a gift basket that are not purchasable individually, or, as in our example, items that will be presented together on one product page as options. Let's get started.
1. On the modules page (admin/modules), ensure that the Product Reference module in the Commerce section is enabled
2. Add a product to the store (admin/commerce/products/add/product). Make sure that the product name contains the option information.You may also want it to contain the price, as below. The price will show when the buyer selects the option, but if you want the user to know what the price is without having to first select the item, make the price part of the title. This improves the user experience, though it is extra effort to change the price. You could also write some theming code to make the price part of the displayed title.
3. Repeat step 2 for the remaining options. The following screen capture shows the list of added products. I've circled the option information.
4. Next, we need to create a new content type (if you don't already have one for this purpose) to be the product display (admin/structure/types/add). We'll name the content type Product options, enter a brief description, and change the title field label from Title to Product name as shown below, then click Save and add fields.
Initially, the content type will contain the Title field (now Product name) and Body. The Body field is used for the product description. It is not option-specific, in that it doesn't change when an option is selected. If the product description needs to contain option information, have it contain the information for all options. We do not need to repeat any of the fields from the Store product, such as Sku or Price, because the Store product fields will be used in addition to the Display product fields. The field we do need to add is the magic that links this content to the store product(s), and that is a Product reference field.
5. We'll name the new field Select size, so that the label provides the instruction to the buyer. The field type is Product reference, and we will want the users to select from a group of radio buttons.
6. The next screen simply tells you that there are no field settings needed. Just click the button to save the settings you didn't set ;-)
7. On the next page, check the box for Required field. The next check box, already checked, tells Drupal to use the Store product fields as part of the product display.
8. Check the box that defines which product type can be used. In my case, there is only one choice, Products, but you may have others if you defined them. Set the number of items to Unlimited. This refers to the number of Store products that can refer to a Display product...not the number of items a buyer can select. Save the field.
9. Click the tab for managing the field display (admin/structure/types/manage/product-display/display). For the format of the Select size field, choose Add to Cart form. To the right of that, as shown highlighted, below, click the settings icon.
10. Check the box to display a quantity field, and click the Update button.
9. Add Product display content (node/add/product-display). We'll call the Display product Vitamin C. The important part of the content form is the Select size field as shown below. It is here that you select the products that will be shown as options when this product is displayed. Since we've only created options for one product, Vitamin C, we will select them all and save the content.
10. View the product (node/#). Naturally it will need styling, but you get the idea! Select a different option from the select box, and the price changes.