Discussions

Same product with different formats that determine price and get added to line item titles

I have a taxonomy term select list where the administrator can add one or more formats to a product entity. The term itself has a price coefficient field that should be used to determine the price of the product in that format. On the product display page there should be a 'add to cart' button for every format of that product. The title of the product in the cart/order views should display the format and the price should be according to what was calculated using the product base price and the format coefficient.

It could be assumed that every product display has only one product entity associated with it if this makes things easier.

I could probably work out the details myself, but having trouble finding ways to implement the necessary functionality as I have very little experience with the module (and views, rules modules). Maybe there's good hooks or things I could do via the admin interface already? Some pointers, ideas or even good alternatives that get the same result overall would be much appreciated.

Posted: Dec 16, 2011

Comments

Dooshta on December 20, 2011

Solved it. Here's the summary in case anyone else needs to do something similar:

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:

<?php
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():

<?php
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.