You are here

function commerce_gc_commerce_cart_order_refresh in Commerce GC 7

File

./commerce_gc.module, line 153
Provides Giftcard coupon bundle, Giftcard Transaction entity and basic user interface elements.

Code

function commerce_gc_commerce_cart_order_refresh($order_wrapper) {
  $order = $order_wrapper
    ->value();
  $line_item_data = array();
  $delete_line_item_ids = array();
  $remove_coupon_ids = array();

  // Create a list of line items in the order keyed by coupon id so that if
  // necessary we can reference/delete them later if they no longer are valid.
  foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
    if ($line_item_wrapper->type
      ->value() == 'giftcard_use') {
      $coupon_id = $line_item_wrapper->commerce_giftcard->coupon_id
        ->value();
      $line_item_data[$coupon_id] = array(
        'line_item' => clone $line_item_wrapper,
        'delta' => $delta,
      );

      // Set giftcard line item prices to zero. We always have to recalculate the price, similar to how commerce
      // discount works.
      commerce_gc_remove_giftcard_components($line_item_wrapper->commerce_unit_price);
      commerce_gc_remove_giftcard_components($line_item_wrapper->commerce_total);
    }
  }

  // Strip out giftcard components from order total.
  commerce_gc_remove_giftcard_components($order_wrapper->commerce_order_total);

  // Add giftcard use line items if necessary.
  foreach ($order_wrapper->commerce_coupons as $delta => $coupon_wrapper) {
    if ($coupon_wrapper
      ->value() && $coupon_wrapper->type
      ->value() == 'giftcard_coupon') {
      $coupon = $coupon_wrapper
        ->value();
      $coupon_id = $coupon->coupon_id;
      commerce_order_calculate_total($order);

      // Evaluate conditions.
      if (commerce_coupon_evaluate_conditions($coupon_wrapper, $order_wrapper)) {

        // We know the balance is positive, but we need to know exactly how much
        // of the giftcard can be applied based on the order total minus the
        // amount of any line item tied to the use of this particular giftcard.
        $amount = commerce_gc_order_giftcard_amount($order_wrapper, $coupon_wrapper);
        $price = array(
          'amount' => -$amount,
          'currency_code' => commerce_default_currency(),
        );

        // Add a new line item if one does not already exist.
        if (!isset($line_item_data[$coupon_wrapper->coupon_id
          ->value()])) {
          $new_line_item = commerce_gc_add_line_item($order_wrapper, $coupon_wrapper, $price);
          $new_line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $new_line_item);
          $new_delta = $order_wrapper->commerce_line_items
            ->count();

          // Track this line item because we might have to delete it later.
          $line_item_data[$coupon_wrapper->coupon_id
            ->value()] = array(
            'line_item' => $new_line_item_wrapper,
            'delta' => $new_delta,
          );
        }
        else {
          $line_item_wrapper = $line_item_data[$coupon_id]['line_item'];
          commerce_gc_line_item_set_price($price, $line_item_wrapper, $coupon_wrapper);
          $line_item_wrapper
            ->save();
        }

        // Make sure this line item doesn't get deleted later, as long as its amount is not zero.
        if ($price['amount'] < 0) {
          unset($line_item_data[$coupon_id]);
        }
        else {
          $remove_coupon_ids[] = $coupon_id;
        }
      }
      else {
        $remove_coupon_ids[] = $coupon_id;
      }
    }
  }

  // Remove coupons and line items that no longer apply.
  foreach ($line_item_data as $coupon_id => $data) {

    // It is not safe to use the offsetUnset pattern because this is not
    // compatible with other modules that have already made changes to the
    // line item list in this fashion - namely Commerce Discount.
    $lang = field_language('commerce_order', $order, 'commerce_line_items');
    $delta = $line_item_data[$coupon_id]['delta'];
    unset($order->commerce_line_items[$lang][$delta]);
    if ($line_item_data[$coupon_id]['line_item']
      ->value()) {
      $delete_line_item_ids[] = $line_item_data[$coupon_id]['line_item']->line_item_id
        ->value();
    }
  }

  // Finally get rid of all line items that need to be removed.
  commerce_line_item_delete_multiple(array_values($delete_line_item_ids));

  // Get rid of orphaned coupon references.
  foreach ($remove_coupon_ids as $coupon_id) {
    $coupon = commerce_coupon_load($coupon_id);

    // Remove coupons from the order.
    commerce_coupon_remove_coupon_from_order($order, $coupon, FALSE);
  }
}