From f3b46d9e70ae7b4ad81883f2a2b0ef183728b1b2 Mon Sep 17 00:00:00 2001
From: jucallme <jucallme@gmail.com>
Date: Tue, 3 Apr 2012 00:21:18 -0300
Subject: [PATCH] working implementation of ajax

---
 commerce_coupon.rules.inc                  |  130 ++++++++++++++++++++++++++++
 commerce_coupon.rules_defaults.inc         |   64 ++++++++++++++
 includes/commerce_coupon.checkout_pane.inc |   72 +++++++++++++++
 3 files changed, 266 insertions(+), 0 deletions(-)

diff --git a/commerce_coupon.rules.inc b/commerce_coupon.rules.inc
index d825df5..479d301 100644
--- a/commerce_coupon.rules.inc
+++ b/commerce_coupon.rules.inc
@@ -103,6 +103,33 @@ function commerce_coupon_rules_action_info() {
     ),
   );
 
+  $actions['commerce_coupon_action_set_granted_percent_amount'] = array(
+    'label' => t('Set granted coupon amount'),
+    'parameter' => array(
+      'commerce_coupon_log' => array(
+        'type' => 'commerce_coupon_log',
+        'label' => t('Commerce Coupon Log'),
+      ),
+      'percent' => array(
+        'type' => 'decimal',
+        'label' => t('Percent Amount'),
+      ),
+      'amount' => array(
+        'type' => 'decimal',
+        'label' => t('Balance Amount'),
+      ),
+      'currency_code' => array(
+        'type' => 'text',
+        'label' => t('Currency Code'),
+      ),
+    ),
+    'group' => t('Commerce Coupon'),
+    'base' => 'commerce_coupon_action_is_invalid_coupon',
+    'callbacks' => array(
+      'execute' => 'commerce_coupon_action_set_granted_percent_amount',
+    ),
+  );
+
   $actions['commerce_coupon_action_get_coupons_for_order'] = array(
     'label' => t('Get coupons for order'),
     'parameter' => array(
@@ -172,6 +199,42 @@ function commerce_coupon_rules_action_info() {
     ),
       );
 
+  $actions['commerce_coupon_action_create_coupon_percent_line_item'] = array(
+    'label' => t('Create coupon line item'),
+    'parameter' => array(
+      'commerce_coupon' => array(
+        'type' => 'commerce_coupon',
+        'label' => t('Commerce Coupon'),
+      ),
+      'commerce_order' => array(
+        'type' => 'commerce_order',
+        'label' => t('commerce order'),
+      ),
+      'percent' => array(
+        'type' => 'decimal',
+        'label' => t('percent amount'),
+      ),
+      'amount' => array(
+        'type' => 'decimal',
+        'label' => t('coupon amount'),
+      ),
+      'currency_code' => array(
+        'type' => 'text',
+        'label' => t('coupon amount currency code'),
+      ),
+    ),
+    'provides' => array(
+      'commerce_coupon_line_item' => array(
+        'type' => 'commerce_line_item',
+        'label' => t('commerce coupon line item'),
+      ),
+    ),
+    'group' => t('Commerce Coupon'),
+    'base' => 'commerce_coupon_action_create_coupon_percent_line_item',
+    'callbacks' => array(
+      'execute' => 'commerce_coupon_action_create_coupon_percent_line_item',
+    ),
+  );
 
   $actions['commerce_coupon_action_get_coupon_uses'] = array(
     'label' => t('Get the redemption number of a coupon'),
@@ -245,6 +308,37 @@ function commerce_coupon_action_set_granted_amount($commerce_coupon_log, $amount
 
 }
 
+function commerce_coupon_action_set_granted_percent_amount($commerce_coupon_log, $percent, $amount, $currency_code) {
+  if (!($commerce_coupon_log instanceof EntityMetadataWrapper)) {
+    $commerce_coupon_log = entity_metadata_wrapper('commerce_coupon_log', $commerce_coupon_log);
+  }
+
+  $coupon = $commerce_coupon_log->coupon;
+
+  // Get the price component to use in this price.
+  $price_component_name = 'commerce_coupon_' . $coupon->type;
+  drupal_alter('commerce_coupon_price_component_name', $price_component_name, $coupon);
+
+  // Set the unit price on the line item object.
+  $commerce_coupon_log->commerce_granted_amount->amount = ($amount * $percent / 100);
+  $commerce_coupon_log->commerce_granted_amount->currency_code = $currency_code;
+
+
+  // Add the base price to the components array.
+  if (!commerce_price_component_load(55, $price_component_name)) {
+    $commerce_coupon_log->commerce_granted_amount->data = commerce_price_component_add(
+      $commerce_coupon_log->commerce_granted_amount->value(),
+      $price_component_name,
+      $commerce_coupon_log->commerce_granted_amount->value(),
+      TRUE,
+      FALSE
+    );
+  }
+
+  commerce_coupon_log_save($commerce_coupon_log->value());
+}
+
+
 function commerce_coupon_action_get_coupons_for_order($commerce_coupon) {
   if (!$commerce_coupon) {
     return array();
@@ -252,6 +346,42 @@ function commerce_coupon_action_get_coupons_for_order($commerce_coupon) {
   return array('order_coupons' => commerce_coupon_get_coupons_by_order($commerce_coupon->order_number));
 }
 
+function commerce_coupon_action_create_coupon_percent_line_item($commerce_coupon, $commerce_order, $percent, $amount, $currency_code) {
+  if (!($commerce_order instanceof EntityMetadataWrapper)) {
+    $commerce_order = entity_metadata_wrapper('commerce_order', $commerce_order);
+  }
+
+  // Get the price component to use in this price.
+  $price_component_name = 'commerce_coupon_' . $commerce_coupon->type;
+  drupal_alter('commerce_coupon_price_component_name', $price_component_name, $commerce_coupon);
+
+  $line_item = commerce_coupon_line_item_new($commerce_coupon, $commerce_order->order_id->value());
+  $line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
+
+  // Set the unit price on the line item object.
+  $line_item_wrapper->commerce_unit_price->amount = ($amount * $percent / 100) * -1;
+  $line_item_wrapper->commerce_unit_price->currency_code = $currency_code;
+
+
+  // Add the base price to the components array.
+  if (!commerce_price_component_load($line_item_wrapper->commerce_unit_price->value(), $price_component_name)) {
+    $line_item_wrapper->commerce_unit_price->data = commerce_price_component_add(
+      $line_item_wrapper->commerce_unit_price->value(),
+      $price_component_name,
+      $line_item_wrapper->commerce_unit_price->value(),
+      TRUE,
+      FALSE
+    );
+  }
+
+  commerce_line_item_save($line_item);
+
+  $commerce_order->commerce_line_items[] = $line_item;
+  $commerce_order->save();
+
+  return array('commerce_coupon_line_item' => $line_item);
+}
+
 function commerce_coupon_action_create_coupon_line_item($commerce_coupon, $commerce_order, $amount, $currency_code) {
   if (!($commerce_order instanceof EntityMetadataWrapper)) {
     $commerce_order = entity_metadata_wrapper('commerce_order', $commerce_order);
diff --git a/commerce_coupon.rules_defaults.inc b/commerce_coupon.rules_defaults.inc
index a4b8e64..e3efb21 100644
--- a/commerce_coupon.rules_defaults.inc
+++ b/commerce_coupon.rules_defaults.inc
@@ -49,5 +49,69 @@ function commerce_coupon_default_rules_configuration() {
   ));
   $rules['commerce_coupon_basic_validate_uses_of_coupon'] = $rule;
 
+
+  // Create fixed amount rule
+  $rule = rules_reaction_rule(array(), array(
+    'commerce_coupon_line_item' => array(
+      'type' => 'commerce_coupon_line_item',
+      'label' => 'commerce coupon line item')
+    )
+  );
+
+  $rule->label = t('Calculate coupon with fixed amount');
+  $rule->active = TRUE;
+
+  $rule
+  ->event('commerce_coupon_redeem')
+  ->condition('entity_has_field', array('entity:select' => 'coupon', 'field' => 'commerce_coupon_fixed_amount'))
+  ->condition(rules_and()->condition('data_is_empty', array('data:select' => 'coupon:commerce-coupon-fixed-amount'))->negate() )
+  ->condition('data_is', array('data:select' => 'coupon:commerce-coupon-fixed-amount:amount', 'op' => '>', 'value' => 0))
+  ->action('commerce_coupon_action_create_coupon_line_item', array(
+    'commerce_coupon:select' => 'coupon',
+    'commerce_order:select' => 'commerce-order',
+    'amount:select' => 'coupon:commerce-coupon-fixed-amount:amount',
+    'currency_code:select' => 'coupon:commerce-coupon-fixed-amount:currency-code'
+  ))
+  ->action('commerce_coupon_action_set_granted_amount', array(
+    'commerce_coupon_log:select' => 'coupon-log',
+    'amount:select' => 'coupon:commerce-coupon-fixed-amount:amount',
+    'currency_code:select' => 'coupon:commerce-coupon-fixed-amount:currency-code'
+  ));
+
+  $rules['commerce_coupon_basic_fixed_amount'] = $rule;
+
+
+  // Create percent amount rule
+  $rule = rules_reaction_rule(array(), array(
+    'commerce_coupon_line_item' => array(
+      'type' => 'commerce_coupon_line_item',
+      'label' => 'commerce coupon line item')
+    )
+  );
+
+  $rule->label = t('Calculate coupon with percent amount');
+  $rule->active = TRUE;
+
+  $rule
+  ->event('commerce_coupon_redeem')
+  ->condition('entity_has_field', array('entity:select' => 'coupon', 'field' => 'commerce_coupon_percent_amount'))
+  ->condition(rules_and()->condition('data_is_empty', array('data:select' => 'coupon:commerce-coupon-percent-amount'))->negate() )
+  ->condition('data_is', array('data:select' => 'coupon:commerce-coupon-percent-amount', 'op' => '>', 'value' => 0))
+  ->action('commerce_coupon_action_create_coupon_percent_line_item', array(
+    'commerce_coupon:select' => 'coupon',
+    'commerce_order:select' => 'commerce-order',
+    'percent:select' => 'coupon:commerce-coupon-percent-amount',
+    'amount:select' => 'commerce-order:commerce-order-total:amount',
+    'currency_code:select' => 'commerce-order:commerce-order-total:currency-code'
+  ))
+  ->action('commerce_coupon_action_set_granted_percent_amount', array(
+    'commerce_coupon_log:select' => 'coupon-log',
+    'percent:select' => 'coupon:commerce-coupon-percent-amount',
+    'amount:select' => 'commerce-order:commerce-order-total:amount',
+    'currency_code:select' => 'commerce-order:commerce-order-total:currency-code'
+  ));
+
+  $rules['commerce_coupon_basic_percent_amount'] = $rule;
+
   return $rules;
 }
diff --git a/includes/commerce_coupon.checkout_pane.inc b/includes/commerce_coupon.checkout_pane.inc
index 9fe3096..8550e6f 100644
--- a/includes/commerce_coupon.checkout_pane.inc
+++ b/includes/commerce_coupon.checkout_pane.inc
@@ -11,7 +11,14 @@
  * Payment pane: form callback.
  */
 function commerce_coupon_pane_checkout_form($form, &$form_state, $checkout_pane, $order) {
+  // wrap the hole form in a div that we can replace it, from our ajax callback.
+  // this is so the sub total value and imbeded view will get updated with new
+  // coupons that are added from the ajax call back.
+
+
   $pane_form = array();
+  $pane_form['#prefix'] = '<div id="coupon-call-back">';
+  $pane_form['#suffix'] = '</div>';
 
   // Store the payment methods in the form for validation purposes.
   $pane_form['coupon_code'] = array(
@@ -20,6 +27,21 @@ function commerce_coupon_pane_checkout_form($form, &$form_state, $checkout_pane,
     '#description' => t('Enter here your coupon code.'),
   );
 
+  $pane_form['coupon_add'] = array(
+    '#type' => 'button',
+    '#value' => t('Add coupon'),
+    '#ajax' => array(
+      'callback' => 'commerce_coupon_add_coupon_callback',
+      'wrapper' => 'coupon-call-back',
+    ),
+    "#limit_validation_errors" => array(),
+  );
+
+  $pane_form['order'] = array(
+    '#type' => 'value',
+    '#value' => $order
+  );
+
   // Extract the View and display keys from the cart contents pane setting.
   list($view_id, $display_id) = explode('|', variable_get('commerce_coupon_review_pane_view', 'commerce_coupon_review_pane|default'));
   if (!empty($view_id) && !empty($display_id)) {
@@ -67,7 +89,57 @@ function commerce_coupon_pane_checkout_form_submit($form, &$form_state, $checkou
   }
 }
 
+/**
+ * Callback for the ajax button coupon_add.
+ */
+function commerce_coupon_add_coupon_callback($form, &$form_state) {
+  list($view_id, $display_id) = explode('|', variable_get('commerce_coupon_review_pane_view', 'commerce_coupon_review_pane|default'));
+  if (!empty($view_id) && !empty($display_id)) {
+    //dsm($form_state['values']['commerce_coupon']);
+    $order = $form_state['values']['commerce_coupon']['order'];
+    $code =  $form_state['values']['commerce_coupon']['coupon_code'];
+    if (!empty($code) && commerce_coupon_code_is_valid($code, $order)) {
+      $coupon = commerce_coupon_load_by_code($code);
+      commerce_coupon_redeem_coupon($coupon, $order);
+      // clear the value, as we dont want errors when the user hits submit on fnal check out, as we would try add the value in the field again.
+      $form['commerce_coupon']['coupon_code']['#value'] = '';
+
+      if (isset($order->order_id) && is_numeric($order->order_id)) {
+        // this is to get the summary of the form rerendered.
+        $alter_coupon_commands = &drupal_static('alter_coupon_commands');
+        $coupon_current_order = &drupal_static('coupon_current_order');
+        $alter_coupon_commands = TRUE;
+        $coupon_current_order = $order->order_id;
+      }
+    }
+    else {
+      drupal_set_message(t('Your coupon code is not valid.'), 'error');
+    }
+    $form['commerce_coupon']['redeemed_coupons']['#markup'] = '<div id="coupon-call-back">' . commerce_embed_view($view_id, $display_id, array($order->order_id)) . '</div>';
+  }
+
+  return $form['commerce_coupon'];
+}
+
+/**
+ * Implements hook_ajax_render_alter().
+ *
+ * This is to get the summary of the cart to rerender on the add coupon button.
+ */
+function commerce_coupon_ajax_render_alter(&$commands) {
+  $alter_coupon_commands = &drupal_static('alter_coupon_commands');
+  $current_order = &drupal_static('coupon_current_order');
+
+  if ($alter_coupon_commands) {
+    $contents = array();
+    $contents['cart_contents_view'] = array(
+      '#markup' => commerce_embed_view('commerce_cart_summary', 'default', array($current_order)),
+    );
+    $contents = drupal_render($contents);
 
+    $commands[] = ajax_command_replace('.view-commerce-cart-summary', $contents);
+  }
+}
 
 /**
  * Implements the callback for the checkout pane review form
-- 
1.7.5.4

