You are here

function commerce_price_savings_formatter_field_formatter_view in Commerce Price Savings Formatter 7

Implements hook_field_formatter_view().

File

./commerce_price_savings_formatter.module, line 154
Adds a display formatter for the price field showing the amount of savings.

Code

function commerce_price_savings_formatter_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  $settings = $display['settings'] + field_info_formatter_settings($display['type']);
  $tax_module_exists = module_exists('commerce_tax');

  // Theme the display of the price based on the display type.
  if (in_array($display['type'], array(
    'commerce_price_savings_formatter_formatter',
    'commerce_price_savings_formatter_inline',
  ))) {

    // exit if no display prices
    if (empty($settings['prices'])) {
      return $element;
    }

    // remove prices not selected
    $settings['prices'] = array_filter($settings['prices']);

    // exit if no prices selected
    if (empty($settings['prices'])) {
      return $element;
    }

    // store prices count
    $prices_count = count($settings['prices']);

    // determine if labels are shown
    $show_labels = !empty($settings['show_labels']);

    // determine theme
    $item_theme = $display['type'];

    // Loop through each price value in this field.
    foreach ($items as $delta => $item) {
      $difference = 0;
      $base_price_component = commerce_price_component_total($item, 'base_price');
      $base_currency = commerce_currency_load($base_price_component['currency_code']);
      if ($base_price_component) {

        // calculate included tax amount on base amount
        $included_tax_amount = 0;
        foreach ($item['data']['components'] as $component) {
          if (!empty($component['included']) && !empty($component['price']['data']['tax_rate'])) {
            $included_tax_amount += commerce_currency_convert($component['price']['amount'], $component['price']['currency_code'], $base_price_component['currency_code']);
          }
        }
        $base_price_component['amount'] += $included_tax_amount;

        // Calculate the difference between the base price and calculated price.
        $difference = $base_price_component['amount'] - commerce_currency_convert($item['amount'], $item['currency_code'], $base_price_component['currency_code']);

        // Get decimal value for rounding
        $difference_decimal = commerce_currency_amount_to_decimal($difference, $base_price_component['currency_code']);

        // Round per currency rounding_step
        $difference_decimal = commerce_currency_round($difference_decimal, $base_currency);

        // Update difference amount
        $difference = commerce_currency_decimal_to_amount($difference_decimal, $base_price_component['currency_code']);
      }

      // determine price direction
      $price_direction = $difference > 0 ? 'down' : ($difference < 0 ? 'up' : 'unchanged');

      // format prices
      $formatted_prices = array();
      foreach ($settings['prices'] as $price_type) {
        switch ($price_type) {
          case 'list':

            // Only show the list price if the current price is lower.
            if ($difference > 0 || $prices_count == 1) {
              $formatted_prices[$price_type] = array(
                'label' => t('List price'),
                'amount' => $base_price_component['amount'],
                'currency_code' => $base_price_component['currency_code'],
                'formatted' => commerce_currency_format($base_price_component['amount'], $base_price_component['currency_code'], $entity),
              );
            }
            break;
          case 'price':
            $formatted_prices[$price_type] = array(
              'label' => t('Price'),
              'amount' => $item['amount'],
              'currency_code' => $item['currency_code'],
              'formatted' => commerce_currency_format($item['amount'], $item['currency_code'], $entity),
            );
            break;
          case 'savings':

            // Only show the savings if the current price is lower than the list
            // price; i.e. if there actually are savings.
            if ($difference > 0) {
              $percentage = round($difference / $base_price_component['amount'] * 100) . '%';
              $formatted_prices[$price_type] = array(
                'label' => t('You save'),
                'amount' => $difference,
                'currency_code' => $item['currency_code'],
                'formatted' => commerce_currency_format($difference, $item['currency_code'], $entity),
              );
              if (!empty($base_price_component['amount'])) {
                $difference_percent = $difference / $base_price_component['amount'];
                $formatted_prices[$price_type]['percent'] = array(
                  'value' => $difference_percent,
                  'formatted' => round($difference_percent * 100) . '%',
                );
              }
            }
            break;
        }
      }

      // /settings price type loop
      // allow other to alter the formatted prices
      $context = array(
        'settings' => $settings,
        'entity_type' => $entity_type,
        'entity' => $entity,
        'field' => $field,
        'instance' => $instance,
        'langcode' => $langcode,
        'display' => $display,
      );
      drupal_alter('commerce_price_savings_formatter_prices', $formatted_prices, $context);

      // set savings
      if (!empty($formatted_prices['savings']) && !empty($settings['prices']['savings'])) {
        switch ($settings['savings']) {
          case 'percentage':
            if (!empty($formatted_prices['savings']['percent']['formatted'])) {
              $formatted_prices['savings']['formatted'] = $formatted_prices['savings']['percent']['formatted'];
            }
            else {
              $formatted_prices['savings']['formatted'] = '';
            }
            break;
          case 'both':
            if (!empty($formatted_prices['savings']['percent']['formatted'])) {
              $formatted_prices['savings']['formatted'] .= ' (' . $formatted_prices['savings']['percent']['formatted'] . ')';
            }
            break;
        }
      }

      // build price elements only formatted values
      $price_elements = array();
      foreach ($formatted_prices as $price_type => $price_data) {

        // build prices array with rendered price
        if (isset($price_data['formatted'])) {
          $price_elements[$price_type] = array(
            '#markup' => $price_data['formatted'],
          );

          // add label
          if ($show_labels) {
            $price_elements[$price_type]['#price_label'] = !empty($price_data['label']) ? $price_data['label'] : '';
          }
        }
      }
      $element[$delta] = array(
        '#theme' => $item_theme,
        '#prices' => $price_elements,
        '#price_direction' => $price_direction,
        '#attached' => array(
          'css' => array(
            drupal_get_path('module', 'commerce_price_savings_formatter') . '/theme/commerce_price_savings_formatter.css',
          ),
        ),
      );
    }

    // /item loop
  }

  // /type switch
  return $element;
}