You are here

function commerce_discount_percentage in Commerce Discount 7

Rules action: Apply percentage discount.

1 string reference to 'commerce_discount_percentage'
commerce_discount_commerce_discount_offer_type_info in ./commerce_discount.module
Implements hook_commerce_discount_offer_type_info().

File

./commerce_discount.rules.inc, line 945
Rules integration for the Commerce Discount module.

Code

function commerce_discount_percentage(EntityDrupalWrapper $wrapper, $discount_name) {
  $discount_wrapper = entity_metadata_wrapper('commerce_discount', $discount_name);
  $rate = $discount_wrapper->commerce_discount_offer->commerce_percentage
    ->value() / 100;

  // Get the line item types to apply the discount to.
  $line_item_types = variable_get('commerce_discount_line_item_types', array_diff(commerce_product_line_item_types(), array(
    'product_discount',
  )));

  // Filter out 0 values in the variable.
  $line_item_types = array_filter($line_item_types);
  switch ($wrapper
    ->type()) {
    case 'commerce_order':

      // Exit if there are no line items or the wrapper doesn't contain
      // the commerce_discounts property.
      if (!isset($wrapper->commerce_discounts) || !$wrapper->commerce_line_items
        ->value()) {
        return;
      }

      // Set reference to the discount.
      // @todo: It doesn't work with the wrapper.
      $order = $wrapper
        ->value();
      $order->commerce_discounts[LANGUAGE_NONE][]['target_id'] = $discount_wrapper->discount_id
        ->value();
      $calculated_discount = 0;

      // Loop the line items of the order and calculate the total discount.
      foreach ($wrapper->commerce_line_items as $line_item_wrapper) {

        // Check if the line item is configured in the discount settings to
        // apply the discount.
        $line_item_type = $line_item_wrapper
          ->getBundle();
        if (in_array($line_item_type, $line_item_types, TRUE)) {
          $line_item_total = commerce_price_wrapper_value($line_item_wrapper, 'commerce_total', TRUE);
          $calculated_discount += $line_item_total['amount'] * $rate;
        }
      }
      if ($calculated_discount) {
        $discount_amount = array(
          'amount' => $calculated_discount * -1,
          'currency_code' => $wrapper->commerce_order_total->currency_code
            ->value(),
        );

        // Modify the existing discount line item or add a new line item
        // if that fails.
        if (!commerce_discount_set_existing_line_item_price($wrapper, $discount_name, $discount_amount)) {
          commerce_discount_add_line_item($wrapper, $discount_name, $discount_amount);
        }

        // Update the total order price, for the next rules condition (if any).
        commerce_discount_calculate_order_total($wrapper);
      }
      break;
    case 'commerce_line_item':

      // Check if the line item is configured in the discount settings to apply
      // the discount.
      $line_item_type = $wrapper
        ->getBundle();
      if (!in_array($line_item_type, $line_item_types, TRUE)) {
        return;
      }

      // Check whether this discount was already added as a price component.
      $unit_price = commerce_price_wrapper_value($wrapper, 'commerce_unit_price', TRUE);
      foreach ($unit_price['data']['components'] as $component) {
        if (!empty($component['price']['data']['discount_name']) && $component['price']['data']['discount_name'] == $discount_name) {
          return;
        }
      }
      $discount_amount = array(
        'amount' => $unit_price['amount'] * $rate * -1,
        'currency_code' => $unit_price['currency_code'],
      );
      commerce_discount_add_price_component($wrapper, $discount_name, $discount_amount);
      break;
  }
}