Shipping and product line item types in Drupal Commerce

In Drupal Commerce, a line item is any item added to an order that affects the order total. They represent products, shipping rates, certain types of discounts, and more. During sell price calculation for products and rate calculation for shipping, you actually apply discounts, fees, and tax rates as manipulations to the unit price of line items.

I've been dealing a lot with line items during a personal shipping sprint I've been on the last week and a half to help launch a client site. That work has involved a complete rewrite of Commerce Shipping in the 2.x branch to support carrier calculated rates (such as those returned by ConnectShip, UPS, FedEx, etc.). That work in turn has resulted in the release of a Physical Fields module that defines weight and dimensions fields and a Commerce Physical Product module that provides API support for determining when orders contain shippable products, the total weight of the order, and other useful things.

Once this site launches, I'll give more attention to the upgrade path for folks using Shipping 1.x to move up to Shipping 2.x. (I'll also need to rewrite the flat rate shipping method to go along with it.) To push forward integration with different carriers, we'll be holding a Shipping Sprint at DrupalCamp Atlanta, fittingly the corporate home of UPS.

During the course of my work on Commerce Physical Product, I was reminded that determining whether or not a line item represents a product isn't as straightforward as you would first think. It's nothing terribly tricky, but you can't just perform a simple check on the product type to reliably determine if a line item represents a product.

This is insufficient:

<?php
if ($line_item->type == 'product') {
 
// ...
}
?>

The reason is Drupal Commerce allows you to have multiple product line item types, each with their own unique fields that may be exposed through the Add to Cart form. This feature lets you sell customizable products where the various customizations are stored with the product reference in the line item.

A simple use case is adding a custom price field to a donation product line item type allowing customers to tell you how much they want to donate to a specific campaign. This can all be configured through the Field UI and Rules, mitigating the need for modules like UC Variable Price. Trés cool.

Since you can have multiple product line item types, we provide a helper function that returns an array of the names of every product line item type defined on the site. Instead of the code above, you can perform an in_array() check on the type of a line item to see if it is of any of the valid product line item types:

<?php
if (in_array($line_item->type, commerce_product_line_item_types())) {
 
// ...
}
?>

Any time you're writing code that should apply to a product line item, be sure to use this method instead of the first. Hope that helps you as you work on your Drupal Commerce contribs and custom modules. I almost forgot about this when writing Commerce Physical Product. Granted, I haven't been sleeping much recently, but if it's that easy for me to forget, I bet it's a bit unknown to the general public.

Comments

Ryan
Glad to read you are looking again at the shipping module
Please also look at the error in Vat when using shipping, as it stands Commerce can not be used for retail use in the UK where the item price inculdes vat

http://www.drupalcommerce.org/node/792
3rd post down page

I've fixed those and related issues in the 2.x branch of Shipping.

So if I am setting up shipping on a new Drupal Commerce site (and assuming I am selling products), I should download:

  • Commerce Shipping, 2.x
  • Physical Fields
  • Commerce Physical Fields

Anything else? Also, if I wanted to use FedEx, UPS, USPS, and the like for shipping, that's currently ongoing, including a code sprint at Drupalcamp Atlanta, right?

Just trying to figure out what I need, and what's available. Thanks for the good work.