Drupal Commerce has the best implementation for handling virtual products sales as if in a real life store, in my opinion. Each product has a product display (or container) which houses each individual product, a variation per se, ( ex: shirt Z size small, shirt Z size medium) which provides better stock management and a streamlined business process if you do have a physical store and virtual store.
There's just one major caveat: each product variation has to your product data attached, not the product display. So a t-shirt with 6 sizes is actually 6 products. That means entering a sale price 6 times, updating shipping information 6 times. I've been working on a client project that has over 1,200 products. There was no way in hell I was going to tell them, "Yeah, after your migrate your products over, you're going to have to edit each variation with that shipping information."
I created a basic bulk product update rule that will take matching fields found on the product display and the product variation to update the product variation's information.
I'm assuming you've decided what fields you want to update, in my case it was shipping information. You cannot calculate shipping through USPS, UPS, or FedEx unless those fields are attached to the product variation. Edit your variation type and product display fields. Add the fields you'd like to have updated.
This variation type has field_weight and field_dimensions, which are also fields within the product display.
Now it is time to create a new rule. Head over to admin/config/workflow/rules and create a new rule for the event "Node: After saving new content." Once that action has processed and you're at the form to edit your rule, we want to add a new event for when the product display is updated. Click on "Add Event" and select "Node: After updating existing content"
So now our rule knows when to fire. First we need to define a few conditions that,
Check the content type and only execute if proper product display
Checks the fields we want bulk updated, brings them into play
Checks that the product reference field is not empty.
Add a new condition of Node: Content is of type and select the content type that is the product display you would like to use. Then, for each field you'd like to have updated, add a new condition for Entity: Entity has field select the field you wish to have its content carried over into the product variations. Finally, do a Data: Data value is empty to check your product reference field. If you're using default fields, it should be node:field-product. You'll need to check "Negate" to make the condition "Not Empty".
Last but not least we have to run through our actions. First create a loop based on your product reference field, use the default variable information if you'd like - comes out to Current product (commerce_product) or something of that sort. Rules will remember the variable on actions nested within the loop.
Now that the loop is created, we need to have our rule grab the product variation's entity ID. Add an action to Fetch entity by ID. The entity type will be "Commerce Product" and the token will be the variable defined at the loop and field of product-id - example above commerce-product:product-id
Next we need to use some PHP code - you have to have the PHP Filter module enabled! Add an action for PHP: Execute custom PHP Code. The code simply takes the data from the node field and replaces the product entity's data with it. For example, using my variables and field_weight, I have the following code
That's it! Save this action and we're almost set. Add one more action to save the entity (Entity: Save entity). Give it a whirl, and rejoice. I'm hoping to have this up as a video tutorial soon. Please comment with questions or issues!
Note: One thing I do is create a child theme for my administration theme. That way I can use CSS to hide these fields attached to product variation types. Makes life a little less confusing for the client, and a clean interface is always a happy interface.