6

I need help on this code which is invoked on calculate sell price rules event on cart view. Line items and order are properly modified. But nothing is displayed, old unit price amount and old total amount are displayed. Even after cart refresh. Any idea ?

                                                                      
/**                                                                             
* Calculates the price when line item are dispalyed 
* or created.                  
*/               

function mymodule_calculate_product_price_cart($order) {                
    $order_wrapper = entity_metadata_wrapper('commerce_order', $order);           
    // Iterates on line items and alter the price.                                
    $commerce_line_items = array();                                               
    foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
      $line_item = $line_item_wrapper->value();                                   
      $type = $line_item_wrapper->commerce_product->value()->type;                
      if ($type === 'insurance') {                                                
        $package_price   = $line_item_wrapper->commerce_product->field_package_ref->commerce_price->amount->value();
        $warranty_price  = $line_item_wrapper->commerce_product->commerce_price->amount->value();
        $amount = _mymodule_calculate_policy_price($warranty_price, $package_price);
      }                                                                           
      elseif ($type === 'little_product') {                                       
        $amount = $line_item_wrapper->commerce_product->commerce_price->amount->value();
      }                                                                           
      else {                                                                      
        $commerce_line_items[$delta] = $line_item;                                
        continue;                                                                 
      }                                                                           
      $qty = $line_item->quantity;                                                
      // This sets the unit price by adding a component price 'base_price'        
      mymodule_line_item_price_amount($line_item, $amount, 'commerce_unit_price');
      mymodule_line_item_price_amount($line_item, $qty * $amount, 'commerce_total');
      commerce_line_item_save($line_item);                                        
      entity_get_controller('commerce_line_item')->resetCache(array($line_item->line_item_id));
      $commerce_line_items[$delta] = $line_item;                                  
    }                                                                             
    $order_wrapper->commerce_line_items = $commerce_line_items;                   
    module_invoke_all('commerce_cart_order_refresh', $order_wrapper);             
    commerce_order_save($order_wrapper->value());                                 
  }  

6 Answers 6

6

I finally made it work.

function mymodule_commerce_commerce_cart_order_refresh($order_wrapper) {         
  foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
    $line_item = $line_item_wrapper->value();                                   
    $type = $line_item_wrapper->commerce_product->value()->type;                
    if ($type === 'insurance') {                                                
      $package_price   = $line_item_wrapper->commerce_product->field_package_ref->commerce_price->amount->value();
      $warranty_price  = $line_item_wrapper->commerce_product->commerce_price->amount->value();
      $amount = _mymodule_commerce_calculate_policy_price($warranty_price, $package_price);
    }                                                                           
    elseif ($type === 'little_product') {                                       
      $amount = $line_item_wrapper->commerce_product->commerce_price->amount->value();
    }                                                                           
    else {                                                                      
      return TRUE;                                                              
    }                                                                           
    $qty = $line_item->quantity;                                                
    // This sets the unit price by adding a component price 'base_price'.        
    mymodule_commerce_line_item_price_amount($line_item, $amount, 'commerce_unit_price');
    mymodule_commerce_line_item_price_amount($line_item, $qty * $amount, 'commerce_total');
    commerce_line_item_save($line_item);                                        
    entity_get_controller('commerce_line_item')->resetCache(array($line_item->line_item_id));
  }                                                                             
}            
2
  • commerce_cart_ordrer_refresh is better since it is called from within hook_commerce_product_cart_add Commented Oct 12, 2012 at 15:16
  • thank you so much for sharing your solution! I have been pulling my hair out trying to get this work with hook_commerce_cart_product_add Commented Apr 8, 2013 at 15:39
3

I tested the above answer, it useful but not changed the Order Total Amount.
After do some research and I finally get all done.
For those people who don't want to use rules and hope to alter the price directly. Here is my solution:

// Alter the price in list and single product page
function my_module_commerce_product_calculate_sell_price_line_item_alter($line_item){

    $price = 100; // 1 dollar
    $line_item->commerce_unit_price[LANGUAGE_NONE]['0']['amount']=$price;

}

// Alter the price in cart & order
function my_module_commerce_cart_line_item_refresh($line_item, $order_wrapper){

    $price = 100; //1 dollar
    $line_item->commerce_unit_price[LANGUAGE_NONE]['0']['amount']=$price;
    $line_item->commerce_unit_price[LANGUAGE_NONE]['0']['data']['components']['0']['price']['amount']=$price; // alter the base_price component

}
1
  • One step closer to solution :) But bow I'm missing tax (VAT) value on order since they show up as 0,00 and what I've been looking into Tax module seems another week or two to resolve. Just can't understand that how the documentation/API descriptions can be so poor. Documentation driven development would help in this matter... Commented Jul 24, 2017 at 19:56
2

I made own solution to alter price, in this example it just double price (for which is Rules solution better) but I need robust solution for my ecommerce site with custom products.

/**
 * Implements hook_commerce_cart_line_item_refresh().
 */
function HOOK_commerce_cart_line_item_refresh($line_item, $order_wrapper) {
  $qty = $line_item->quantity;
  $price = $line_item->commerce_unit_price[LANGUAGE_NONE][0]['amount']*2;

  $line_item->commerce_unit_price[LANGUAGE_NONE][0]['data']['components'][0]['price']['amount'] = $price;
  $line_item->commerce_unit_price[LANGUAGE_NONE][0]['amount'] = $price;
  $line_item->commerce_total[LANGUAGE_NONE][0]['data']['components'][0]['price']['amount'] = $qty*$price;
  $line_item->commerce_total[LANGUAGE_NONE][0]['amount'] = $qty*$price;
  commerce_line_item_save($line_item);
  entity_get_controller('commerce_line_item')->resetCache(array($line_item->line_item_id));
}
1

If I am not mistaken this can be entirely done with Rules, as I just discovered.

  1. In the admin menu, go to Store » Settings » Product pricing rules.
  2. Add a new pricing rule.
  3. Leave the Calculating the sell price of a product trigger.
  4. Add the condition Order is a cart.
  5. Add any other conditions you might need such as product types. (You might need to add the Entity had field condition to check if the commerce-line-item has a commerce-product field in order for product properties to be exposed).
  6. Add one of the actions in the Commerce-line-item group. They offer to set specific amounts, or perform calculations.

More information about pricing rules

0

Try to implement hook_commerce_cart_product_add in your module.

1
  • I have tried it, but drupal commerce does not care about my line item which is saved, and reloaded ... old prices are dispalyed in the cart dispite a commerce_unit_price, and a commerce_total properly set. Commented Oct 12, 2012 at 9:34
-1

This part :

line_item->commerce_unit_price[LANGUAGE_NONE]['0']['data']['components']['0']['price']['amount']=$price; // Alter the base_price component

... made my day (Commerce 7.x-1.10).

It correctly sets the order total amount on top of the line item amount.

If you don't do this, your order total will be out of sync.

2
  • How is it different answer from answer by Pari or answer by Tim Yao?
    – Mołot
    Commented Nov 4, 2014 at 8:16
  • Sorry, I intend to post a comment to Tim Yao answer, not an new answer, just to emphasis its relevancy.
    – Countzero
    Commented Nov 4, 2014 at 8:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.