--- ../uc_eway.original/uc_eway.recurring.inc	2009-10-20 20:31:00.000000000 -0700
+++ uc_eway.recurring.inc	2009-10-29 16:21:39.000000000 -0700
@@ -8,6 +8,77 @@
  */
 
 /*******************************************************************************
+ * Hooks for Drupal
+ ******************************************************************************/
+
+/**
+ * Implementtion of hook_cron().
+ */
+function uc_eway_cron() {
+  $fail = $success = $pending = 0;
+
+  $fees = uc_eway_recurring_get_fees_for_renew();
+
+  watchdog('uc_eway', 'cron called. got ' . count($fees) . ' fees');
+  if (!empty($fees)) {
+    watchdog('uc_eway', 'got orders with fees');
+    foreach($fees as $fee) {
+      watchdog('uc_eway', 'about to test fee ' . var_export($fee, TRUE));
+      if (!uc_eway_recurring_renew_pending($fee)) {
+        if ($order_id = uc_recurring_renew($fee)) {
+          watchdog('uc_eway', 'fee captured with order id ' . $order_id);
+          $success++;
+        }
+        else {
+          // payment attempted but failed
+          watchdog('uc_eway', 'fee capture failed for fee: ' . var_export($fee, TRUE));
+          $fail++;
+        }
+      }
+      else {
+        watchdog('uc_eway', 'fee is pending: ' . var_export($fee, TRUE));
+        $pending++;
+      }
+    }
+    watchdog('uc_eway', '@success recurring fees processed successfully; @fail failed; @pending pending', array('@success' => $success, '@fail' => $fail, '@pending' => $pending));
+  }
+
+  watchdog('uc_eway', 'cron exiting uc_eway_cron()');
+}
+
+/*******************************************************************************
+ * Hooks for ubercart
+ ******************************************************************************/
+
+/**
+ * Implementation of hook_uc_checkout_complete().
+ */
+function uc_eway_uc_checkout_complete($order, $account) {
+  $fees = uc_recurring_get_fees($order, TRUE);
+
+  //watchdog('uc_eway', 'order: ' . var_export($order, TRUE) . ', fee: ' . var_export($fees, TRUE));
+  foreach ($fees as $fee) {
+    if ($fee->uid == 0) { // check for anonymous uid
+      $fee->uid = $order->uid;
+      uc_recurring_fee_user_save($fee);
+    }
+    if ($fee->data['eway_rebill_customer_id']) {
+      $customer_id = $fee->data['eway_rebill_customer_id'];
+    }
+  }
+
+  // if the user is newly created we get the eway rebill customer id from
+  // the fee object and save it in the account
+  if (!$account->eway_rebill_customer_id) {
+    //watchdog('uc_eway', 'settings eway_rebill_customer_id for user ' . $account->uid . ' to ' . $customer_id);
+    user_save($account, array(
+      'eway_rebill_customer_id' => $customer_id,
+    ));
+  }
+}
+
+
+/*******************************************************************************
  * Hooks for uc_recurring
  ******************************************************************************/
 
@@ -28,7 +99,7 @@ function uc_eway_recurring_info() {
     'fee handler' => 'eway',
     'payment method' => 'credit',
     'process callback' => 'uc_eway_recurring_process',
-    'renew callback' => 'uc_recurring_eway_renew',
+    'renew callback' => 'uc_eway_recurring_renew',
     'cancel callback' => '_uc_eway_recurring_delete_rebill_event',
     'menu' => array(
       'cancel' => UC_RECURRING_MENU_DEFAULT,
@@ -38,56 +109,72 @@ function uc_eway_recurring_info() {
 }
 
 /**
- * Implements callback uc_recurring_[payment_method]_fee()
+ * Implements callback for process
  */
 function uc_eway_recurring_process($order, &$fee) {
-  $account = user_load(array('uid' => $order->uid));
+  // get or create the eway rebill customer id
+  if ($order->uid) {
+    $account = user_load(array('uid' => $order->uid));
+    watchdog('uc_eway', 'Order has user: ' . var_export($account, TRUE));
+
+    // is this user already a rebill customer?
+    if (!$account->eway_rebill_customer_id) {
+      $customer_id = _uc_eway_recurring_create_rebill_customer($order);
+    }
 
-  // is this user already a rebill customer?
-  if (!$account->eway_rebill_customer_id) {
-    watchdog('uc_eway_recurring', 'Creating new Rebill CustomerID for user %uid.', array('%uid' => $account->uid));
-    $account = _uc_eway_recurring_create_rebill_customer($order);
+    user_save($account, array(
+      'eway_rebill_customer_id' => $customer_id,
+    ));
   }
   else {
-    watchdog('uc_eway_recurring', 'Using existing Rebill CustomerID (%customer_id) for user %uid.', array('%customer_id', $account->eway_rebill_customer_id, '%uid' => $user->uid));
+    // anonymous user in checkout and user hasn't been created yet.
+    // store the rebill customer id in the fee for now, we'll add it
+    // to the user object in hook_uc_checkout_complete()
+    $customer_id = _uc_eway_recurring_create_rebill_customer($order);
+
+    watchdog('uc_eway', 'Order has no user yet.');
   }
 
-  // how about now?
-  if (!$account->eway_rebill_customer_id) {
-    watchdog('uc_eway', 'Failed to create Rebill Customer');
+  if (!$customer_id) {
     return FALSE;
   }
 
+  // set the customer id in the fee object to be saved in checkout_complete()
+  $fee->data['eway_rebill_customer_id'] = $customer_id;
+
   // create a rebill event
-  $result = _uc_eway_recurring_create_rebill_event($order, $fee, $account);
+  $result = _uc_eway_recurring_create_rebill_event($order, $fee);
 
   if ($result['error']) {
-    watchdog('uc_eway_recurring', 'Failed to create Rebill Event: %error', array('%error' => $result['ErrorDetails']));
+    watchdog('uc_eway', t('Failed to create Rebill Event: ' . var_export($result, TRUE)));
     return FALSE;
   }
   else {
-    watchdog('uc_eway_recurring', 'Created Rebill Event: %rid', array('%rid', $result['RebillID']));
+    //watchdog('uc_eway_recurring', t('Created Rebill Event: ' . $result['RebillID']));
+    //$fee->fee_handler = 'eway';
+    $fee->own_handler = TRUE;
     $fee->data['rebill_id'] = $result['RebillID'];
+
     return TRUE;
   }
 }
 
 /**
- * Implements callback uc_recurring_[fee_handler]_renew()
+ * Renew callback.
  */
-function uc_recurring_eway_renew($order, $fee) {
+function uc_eway_recurring_renew($order, $fee) {
   $account = user_load(array('uid' => $order->uid));
 
   $result = _uc_eway_recurring_query_rebill_transactions($fee, $account);
-  watchdog('uc_eway_recurring', 'QueryTransactionResponse: %response', array('%response' => var_export($result, TRUE)));
+  watchdog('uc_eway', 'QueryTransactionResponse: %response', array('%response' => var_export($result, TRUE)));
 
   // get all transactions, test if this fee went through
   if (count($result['Successful']['QueryTransactionsResult'])) {
-    watchdog('uc_eway_recurring', 'Renew charged for fee: %fee, Transaction status is SUCCESSFUL: %result', array('%fee' => var_export($fee, TRUE), '%result' => var_export($result['Successful'], TRUE)));
+    watchdog('uc_eway', 'Renew charged for fee: %fee, Transaction status is SUCCESSFUL: %result', array('%fee' => var_export($fee, TRUE), '%result' => var_export($result['Successful'], TRUE)));
     return TRUE;
   }
   else if (count($result['Failed']['QueryTransactionsResult'])) {
-    watchdog('uc_eway_recurring', 'Renew failed for fee: %fee, Transaction status is FAILED: %result', array('%fee' => var_export($fee, TRUE), '%result' => var_export($result['Failed'], TRUE)));
+    watchdog('uc_eway', 'Renew failed for fee: %fee, Transaction status is FAILED: %result', array('%fee' => var_export($fee, TRUE), '%result' => var_export($result['Failed'], TRUE)));
     return FALSE;
   }
   else {
@@ -97,40 +184,77 @@ function uc_recurring_eway_renew($order,
 }
 
 /**
- * Implements *optional* callback uc_recurring_[fee_handler]_renew_pending()
+ * Implementation of hook_recurring_user_delete().
+ */
+function uc_eway_recurring_user_delete($rfid) {
+  $fee = uc_recurring_fee_user_load($rfid);
+  _uc_eway_recurring_delete_rebill_event($fee);
+}
+
+/*******************************************************************************
+ * Module functions
+ ******************************************************************************/
+
+/**
+ * Check rebill event status
  */
-function uc_recurring_eway_renew_pending($fee) {
+function uc_eway_recurring_renew_query($fee) {
   $account = user_load(array('uid' => $fee->uid));
   $result = _uc_eway_recurring_query_rebill_transactions($fee, $account);
 
-  watchdog('uc_eway_recurring', 'uc_recurring_eway_renew_fee(): %result', array('%result' => var_export($result, TRUE)));
+  // get all transactions, test if this fee went through
+  if (isset($result['Successful']['QueryTransactionsResult']['rebillTransaction'])) {
+    watchdog('uc_eway', t('Renew charged for fee: ' . var_export($fee, TRUE) . ', Transaction status is SUCCESSFUL: ' . var_export($result['Successful'], TRUE)));
+    return TRUE;
+  }
+  elseif (isset($result['Failed']['QueryTransactionsResult']['rebillTransaction'])) {
+    watchdog('uc_eway', t('Renew failed for fee: ' . var_export($fee, TRUE) . ', Transaction status is FAILED: ' . var_export($result['Failed'], TRUE)));
+    return FALSE;
+  }
+  else {
+    // something went very wrong
+    watchdog('uc_eway', t('eWAY returned nonsense for fee: ' . var_export($fee, TRUE) . ', SOAP response: ' . var_export($result, TRUE)));
+    return FALSE;
+  }
+}
+
+/**
+ * Check if a rebill event has been processed by eWay
+ */
+function uc_eway_recurring_renew_pending($fee) {
+  $account = user_load(array('uid' => $fee->uid));
+  
+  $result = _uc_eway_recurring_query_rebill_transactions($fee, $account);
 
+  //watchdog('uc_eway_recurring', 'uc_recurring_eway_renew_fee(): ' . var_export($result, TRUE));
+  
   if (isset($result['Future']['QueryTransactionsResult']['rebillTransaction'])) {
-    watchdog('uc_eway_recurring', 'FUTURE!');
+    //watchdog('uc_eway_recurring', 'FUTURE!');
     return TRUE;
   }
-  else if (isset($result['Pending']['QueryTransactionsResult']['rebillTransaction'])) {
-    watchdog('uc_eway_recurring', 'PENDING!');
+  elseif (isset($result['Pending']['QueryTransactionsResult']['rebillTransaction'])) {
+    //watchdog('uc_eway_recurring', 'PENDING!');
     return TRUE;
   }
   else {
-    watchdog('uc_eway_recurring', 'returning FALSE!');
+    //watchdog('uc_eway_recurring', 'returning FALSE!');
     return FALSE;
   }
 }
 
 /**
- * Implementation of hook_recurring_user_delete().
+ * Get all pending fees that should be renewed.
  */
-function uc_eway_recurring_user_delete($rfid) {
-  $fee = uc_recurring_fee_user_load($rfid);
-  _uc_eway_recurring_delete_rebill_event($fee);
+function uc_eway_recurring_get_fees_for_renew() {
+  $fees= array();
+  $result = db_query("SELECT * FROM {uc_recurring_users} WHERE remaining_intervals <> 0 AND next_charge <= %d AND fee_handler = 'eway' ORDER BY order_id DESC", time());
+  while ($fee = db_fetch_object($result)) {
+    $fee->data = unserialize($fee->data);
+    $fees[$fee->rfid] = $fee;
+  }
+  return $fees;
 }
 
-/*******************************************************************************
- * Module functions
- ******************************************************************************/
-
 /**
  * Returns the path of the NuSOAP library
  */
@@ -160,46 +284,18 @@ function _uc_eway_recurring_soap_call($o
   }
 
   //if (variable_get('uc_eway_test_mode', UC_EWAY_TEST_MODE_DEFAULT)) {
-    watchdog('uc_eway_recurring', 'SOAP Call (%operation) request: %request, response: %response', array('%operation' => $operation, '%request' => var_export($params, TRUE), '%response' => var_export($result, TRUE)));
+    watchdog('uc_eway', 'SOAP Call (%operation) request: %request, response: %response', array('%operation' => $operation, '%request' => var_export($params, TRUE), '%response' => var_export($result, TRUE)));
   //  watchdog('uc_eway_recurring', 'NuSOAP client: %client', array('%client' => var_export($client, TRUE)));
   //}
 
   return $result;
 }
 
-// DEBUG TIME FUNCTION
-function _time($type = 'none') {
-  return time();
-  switch($type) {
-    case 'uc_recurring_fee':
-      $hour = 7;
-      $minute = 0;
-      $second = 0;
-      $month = 6;
-      $day = 27;
-      $year = 2009;
-      break;
-    case 'uc_recurring_renew':
-      $hour = 7;
-      $minute = 1;
-      $second = 0;
-      $month = 6;
-      $day = 27;
-      $year = 2009;
-      break;
-    default:
-      return time();
-  }
-
-  $time = mktime($hour, $minute, $second, $month, $day, $year);
-  return $time;
-}
-
 /**
  * Create Rebill Customer
  */
 function _uc_eway_recurring_create_rebill_customer($order) {
-  $account = user_load(array('uid' => $order->uid));
+  //$account = user_load(array('uid' => $order->uid));
 
   $country = uc_get_country_data(array('country_id' => $order->billing_country));
 
@@ -226,12 +322,19 @@ function _uc_eway_recurring_create_rebil
 
   $response = _uc_eway_recurring_soap_call('CreateRebillCustomer', $data);
   if ($response['CreateRebillCustomerResult']['Result'] == 'Success') {
+    return $response['CreateRebillCustomerResult']['RebillCustomerID'];
+    /*
     $account = user_save($account, array(
       'eway_rebill_customer_id' => $response['CreateRebillCustomerResult']['RebillCustomerID'],
     ));
+    */
+  }
+  else
+  {
+  	return FALSE;
   }
 
-  return $account;
+  //return $account;
 }
 
 /**
@@ -255,7 +358,7 @@ function _uc_eway_recurring_delete_rebil
 /**
  * Create Rebill Event
  */
-function _uc_eway_recurring_create_rebill_event($order, $fee, $account) {
+function _uc_eway_recurring_create_rebill_event($order, $fee) {
   // create invoice description
   $description = '';
   if (is_array($order->products)) {
@@ -275,34 +378,43 @@ function _uc_eway_recurring_create_rebil
   $cc_name = strlen($order->payment_details['cc_name']) ? $order->payment_details['cc_name'] : $order->billing_first_name . ' ' . $order->billing_last_name;
 
   // get data from uc_recurring -> eway rebill format
+  $initial_charge = split(' ', $fee->initial_charge);
+  if ((int)$initial_charge[0] === 0) {
+    $init_fee = (int)$fee->fee_amount * 100;
+  }
+  else {
+    $init_fee = 0;
+  }
+
+  // pretend now is GMT + 12 as eway will complain if we're behind AEST
+  $now = gmdate('U', time() + 3600 * 12);
+
   $regular_interval = split(' ', $fee->regular_interval);
-  $start_timestamp = strtotime('+' . $fee->regular_interval);
+  $start_timestamp = strtotime('+' . $fee->regular_interval, $now);
   switch($regular_interval[1]) {
     case 'days': $interval_type = 1; break;
     case 'weeks': $interval_type = 2; break;
     case 'months': $interval_type = 3; break;
     case 'years': $interval_type = 4; break;
   }
-  if ($fee->remaining_intervals) {
-    // End date has to be calculated from the start date, not the date of purchase, so:
-    // +1 regular interval to get to the start date then + (regular interval * remaining intervals to get the number rebills)
-    $end_date = date('d/m/Y', strtotime('+' . ($regular_interval[0] + ($regular_interval[0] * $fee->remaining_intervals)) . ' ' . $regular_interval[1]));
+  if ($fee->number_intervals) {
+    $end_date = date('d/m/Y', strtotime('+' . $regular_interval[0] * $fee->number_intervals . ' ' . $regular_interval[1], $now));
   }
   else {
     $end_date = UC_EWAY_RECURRING_VAST_END_DATE;
   }
 
   $data = array(
-    'RebillCustomerID' => $account->eway_rebill_customer_id,
+    'RebillCustomerID' => $fee->data['eway_rebill_customer_id'],
     'RebillInvRef' => $order->order_id,
     'RebillInvDes' => substr($description, 0, 10000),
     'RebillCCName' => $cc_name,
     'RebillCCNumber' => $order->payment_details['cc_number'],
     'RebillCCExpMonth' => $order->payment_details['cc_exp_month'],
     'RebillCCExpYear' => $order->payment_details['cc_exp_year'],
-    'RebillInitAmt' => 0,
-    'RebillInitDate' => date('d/m/Y'),
-    'RebillRecurAmt' => (int) $fee->fee_amount * 100,
+    'RebillInitAmt' => $init_fee,
+    'RebillInitDate' => date('d/m/Y', $now),
+    'RebillRecurAmt' => (int)$fee->fee_amount * 100,
     'RebillStartDate' => date('d/m/Y', $start_timestamp),
     'RebillInterval' => $regular_interval[0],
     'RebillIntervalType' => $interval_type,
