Googletorp's suggestion seemed like it won't give me quite the result I needed so I tried to do the whole thing with my own add-to-cart form, line item/order creation and so on, but ended up with a lot of issues and work that made me go back and try the suggested approach. Got exactly what I needed much easier in the end. Posting the entire solution here to save possible trouble for others.
First I added a format field (that referenced the same taxonomy terms as the one attached to the product) for the used line item. Set it up so it would be included in the Add to Cart forms. After that I added the pricing rule via the GUI:
- Events - Calculating the sell price of a product.
- Conditions - Entity has field (line item format field).
- Actions - Multiply the unit price by some amount (amount specified in the terms coefficient field).
To modify line item titles to show the selected format I found help here: http://digibits.org/blog/drupal-commerce-dynamic-line-item-titles. The code:
function mymodule_commerce_line_item_type_info_alter(&$line_items) {
$line_items['product']['callbacks']['title'] = 'mymodule_line_item_title';
}
function mymodule_line_item_title($line_item) {
$term = taxonomy_term_load($line_item->field_line_item_format[LANGUAGE_NONE][0]['tid']);
return t('!product (!title)', array(
'!product' => commerce_product_line_item_title($line_item),
'!title' => $term->name,
));
}
Now I needed to restrict the format selection for customers depending of what the administrator has chosen for the product and display them all as add-to-cart buttons not a select list. This was doable via hook_form_alter():
function mymodule_form_alter(&$form, &$form_state, $form_id) {
// Alter add to cart forms.
if (strpos($form_id, 'commerce_cart_add_to_cart_form_') === 0) {
// If the product is available for sale.
if ($form['submit']['#value'] == t('Add to cart')) {
// The form should only be for a single product so we can get the id from the product_id field.
$product_id = $form['product_id']['#value'];
$product = commerce_product_load($product_id);
// The original submit button isn't needed.
unset($form['submit']);
$i = 1;
// Create a submit button and additional markup for every given format.
foreach ($product->field_format_types[LANGUAGE_NONE] as $format) {
// #name will be used to determine the selected product format instead of the select list value.
$form['submit_'.$i] = array(
'#type' => 'submit',
'#value' => t('Add to cart'),
'#name' => $format['tid'],
);
$i++;
}
// This form submit handler needs to be called before any others.
array_unshift($form['#submit'], 'mymodule_add_to_cart_form_submit');
}
}
}
function mymodule_add_to_cart_form_submit($form, &$form_state) {
//drupal_set_message('<pre>'.var_export($form_state['triggering_element'], TRUE).'</pre>');
// Get the clicked submit button name.
$name = $form_state['triggering_element']['#name'];
// Use the clicked submit button name to set the correct product format.
$form_state['values']['line_item_fields']['field_line_item_format'][LANGUAGE_NONE][0]['tid'] = $name;
}
In the end I hid the select list via css and that was it.