You are here

function commerce_discount_calculate_order_total in Commerce Discount 7

Dumb copy of commerce_order_calculate_total() which accepts a wrapped order. This is necessary when called from within a function that already has a wrapped order entity to make sure the static cache of the commerce_order_total field is correctly updated.

5 calls to commerce_discount_calculate_order_total()
commerce_discount_commerce_cart_order_refresh in ./commerce_discount.module
Implements hook_commerce_cart_order_refresh().
commerce_discount_fixed_amount in ./commerce_discount.rules.inc
Rules action: Apply fixed amount discount.
commerce_discount_free_products in ./commerce_discount.rules.inc
Rules action: Apply free bonus products discount.
commerce_discount_percentage in ./commerce_discount.rules.inc
Rules action: Apply percentage discount.
_commerce_discount_add_shipping_discount_price_component in ./commerce_discount.rules.inc
Helper function for the shipping discount rules action.

File

./commerce_discount.module, line 1455
Defines the discount and discount offer entities, bundles and functionality.

Code

function commerce_discount_calculate_order_total($order_wrapper) {

  // First determine the currency to use for the order total.
  $default_currency_code = $currency_code = commerce_default_currency();
  $currencies = array();

  // Populate an array of how many line items on the order use each currency.
  foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {

    // If the current line item actually no longer exists...
    if (!$line_item_wrapper
      ->value()) {

      // Remove the reference from the order and continue to the next value.
      $order_wrapper->commerce_line_items
        ->offsetUnset($delta);
      continue;
    }
    $line_item_currency_code = $line_item_wrapper->commerce_total->currency_code
      ->value();
    if (!isset($currencies[$line_item_currency_code])) {
      $currencies[$line_item_currency_code] = 1;
    }
    else {
      $currencies[$line_item_currency_code]++;
    }
  }
  reset($currencies);

  // If only one currency is present on the order, use that to calculate the
  // order total.
  if (count($currencies) == 1) {
    $currency_code = key($currencies);
  }
  elseif (isset($currencies[$default_currency_code])) {

    // Otherwise use the site default currency if it's in the order.
    $currency_code = $default_currency_code;
  }
  elseif (count($currencies) > 1) {

    // Otherwise use the first currency on the order. We do this instead of
    // trying to determine the most dominant currency for now because using the
    // first currency leaves the option open for a UI based module to let
    // customers reorder the items in the cart by currency to get the order
    // total in a different currency. The currencies array still contains useful
    // data, though, should we decide to expand on the count by currency approach.
    $currency_code = key($currencies);
  }

  // Initialize the order total with the selected currency.
  $order_wrapper->commerce_order_total->amount = 0;
  $order_wrapper->commerce_order_total->currency_code = $currency_code;

  // Reset the data array of the order total field to only include a
  // base price component, set the currency code from any line item.
  $base_price = array(
    'amount' => 0,
    'currency_code' => $currency_code,
    'data' => array(),
  );
  $order_wrapper->commerce_order_total->data = commerce_price_component_add($base_price, 'base_price', $base_price, TRUE);
  $order_total = $order_wrapper->commerce_order_total
    ->value();

  // Then loop over each line item and add its total to the order total.
  $amount = 0;
  foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {

    // Convert the line item's total to the order's currency for totalling.
    $line_item_total = $line_item_wrapper->commerce_total
      ->value();
    $component_total = commerce_price_component_total($line_item_total);

    // Add the totals.
    $amount += commerce_currency_convert($component_total['amount'], $component_total['currency_code'], $currency_code);

    // Combine the line item total's component prices into the order total.
    $order_total['data'] = commerce_price_components_combine($order_total, $line_item_total);
  }

  // Update the order total price field with the final total amount and data.
  $order_wrapper->commerce_order_total->amount = round($amount);
  $order_wrapper->commerce_order_total->data = $order_total['data'];
}