You are here

function commerce_line_item_rebase_unit_price in Commerce Core 7

Recalculates the price components of the given line item's unit price based on its current amount and currency code.

When a line item's unit price is adjusted via the line item manager widget, its components need to be recalculated using the given price as the new base price. Otherwise old component data will be used when calculating the total of the order, causing it not to match with the actual line item total.

This function recalculates components by using the new unit price amount as the base price and allowing other modules to add additional components to the new components array as required based on the prior components.

Parameters

$line_item: The line item object whose unit price components should be recalculated. The unit price amount and currency code should already be set to their new value.

See also

hook_commerce_line_item_rebase_unit_price()

1 call to commerce_line_item_rebase_unit_price()
commerce_line_item_manager_validate in modules/line_item/commerce_line_item.module
Validation callback for a commerce_line_item_manager element.

File

modules/line_item/commerce_line_item.module, line 1367
Defines the core Commerce line item entity and API functions interact with line items on orders.

Code

function commerce_line_item_rebase_unit_price($line_item) {

  // Prepare a line item wrapper.
  $wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
  $price = $wrapper->commerce_unit_price
    ->value();

  // Extract the old components array and reset the current one.
  $old_components = array();
  $component_type = 'base_price';
  if (!empty($price['data']['components'])) {
    $old_components = $price['data']['components'];

    // Find the base price component type used so line items that don't use the
    // base_price component can preserve their own initial component type.
    $base_component = reset($old_components);
    $component_type = $base_component['name'];
    if (!commerce_price_component_type_load($component_type)) {
      $component_type = 'base_price';
    }
  }

  // Set the current price as the new base price.
  $price['data']['components'] = array();
  $price['data'] = commerce_price_component_add($price, $component_type, $price, TRUE, FALSE);

  // Set the unit price to the current price array.
  $wrapper->commerce_unit_price = $price;

  // Give other modules a chance to add components to the array.
  foreach (module_implements('commerce_line_item_rebase_unit_price') as $module) {
    $function = $module . '_commerce_line_item_rebase_unit_price';
    $function($price, $old_components, $line_item);
  }

  // Set the unit price once again to the price with any additional components.
  $wrapper->commerce_unit_price = $price;
}