Index: userpoints.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/userpoints/userpoints.install,v
retrieving revision 1.15.2.2
diff -u -r1.15.2.2 userpoints.install
--- userpoints.install	9 Jan 2009 08:41:49 -0000	1.15.2.2
+++ userpoints.install	16 Mar 2009 23:18:43 -0000
@@ -84,6 +84,12 @@
         'not null' => TRUE,
         'default' => 0,
       ),
+      'changed' => array(
+        'description' => t('Efective timestamp of last action on this transaction, for tracking purposes.'),
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
       'status' => array(
         'description' => t('Status'),
         'type' => 'int',
@@ -148,6 +154,8 @@
       'operation' => array('operation'),
       'reference' => array('reference'),
       'status' => array('status'),
+      //Optional as in update_6011
+      'changed' => array('changed'),
     )
   );
   return $schema;
@@ -243,3 +251,23 @@
   $ret[] = update_sql("UPDATE {permission} SET perm = REPLACE(perm, 'admin userpoints', 'administer userpoints') WHERE perm LIKE '%admin userpoints%'");
   return $ret;
 }
+
+/*
+ * From: http://drupal.org/node/395500
+ * "time_stamp parameter is not considered in userpoints api"
+ */
+function userpoints_update_6011() {
+  $ret = array();
+  db_add_field($ret, 'userpoints_txn', 'changed', array(
+    'type' => 'int',
+    'not null' => TRUE,
+    'default' => 0,
+    'description' => t("Efective timestamp of last action on this transaction, for tracking purposes."),
+    )
+  );
+//Optional: An index could help about tracking operations so it would be better to define here..
+  db_add_index($ret, 'userpoints_txn', 'changed', array('changed'));
+//Optional: update table information to mark each transaction as changed on creation only..
+  $ret[] = update_sql("UPDATE {userpoints_txn} SET changed = time_stamp");
+  return $ret;
+}
Index: userpoints.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/userpoints/userpoints.module,v
retrieving revision 1.67.2.39
diff -u -r1.67.2.39 userpoints.module
--- userpoints.module	17 Feb 2009 15:21:23 -0000	1.67.2.39
+++ userpoints.module	16 Mar 2009 23:24:15 -0000
@@ -470,7 +470,8 @@
  *    Accepts an array of keyed variables and parameters  
  *    'points' => # of points (int) (required)
  *    'moderate' => TRUE/FALSE 
- *    'uid' => $user->uid 
+ *    'uid' => $user->uid
+ *    'time_stamp' => unix time of the points assignement date
  *    'operation' => 'published' 'moderated' etc.
  *    'tid' => 'category ID' 
  *    'expirydate' => timestamp or 0, 0 = non-expiring; NULL = site default
@@ -486,7 +487,6 @@
  *     'reason' => (string) error message to indicate reason for failure
  */
 function userpoints_userpointsapi($params) {
-
   //Test for the existence of parameters and set defaults if necessary
   if (!isset($params['txn_id'])) {
     //If a txn_id is passed in we'll do an UPDATE thus the std checks don't apply
@@ -681,6 +681,17 @@
       $params['expirydate'] = userpoints_get_default_expiry_date();
     }
   } // if txn_id
+
+  //control times_tamp functionality
+  $time = time();
+  //Don't let trash go to database
+  //Don't let future timestamps
+  if (!isset($params['time_stamp']) || !is_numeric($params['time_stamp']) || $params['time_stamp'] > $time || $params['time_stamp'] < 0) {
+      $params['time_stamp'] = $time;
+  }
+  //Always force changed timestamp to current time() for transaction tracking
+  $params['changed'] = $time;
+
   if (is_numeric($params['txn_id'])) {
     //A transaction ID was passed in so we'll update the transaction
     $result = db_query("SELECT txn_id, uid, approver_uid, points, 
@@ -690,41 +701,21 @@
       WHERE txn_id = %d",
       $params['txn_id']);
     $txn = db_fetch_array($result);
-    foreach ($txn as $key => $value) {
-      if (isset($params[$key])) {
-        $arr[] = $key .' = \''. $params[$key] .'\'';
-      } 
-      else {
-        $params[$key] = $value;
-      }
-    }
 
-    db_query('UPDATE {userpoints_txn} SET '. implode(', ', $arr) .' 
-              WHERE txn_id = %d',
-              $params['txn_id']
-            );
-    _userpoints_update_cache($params);
+    //don't superseed existing keys, just complete missing keys
+    $params += $txn;
+    //Update existing transaction record for key txn_id
+    $ret = drupal_write_record('userpoints_txn', $params, array('txn_id'));
+    //Only update if the record has been successfully updated
+    if ($ret != FALSE) {
+      _userpoints_update_cache($params);
+    }
   }
   else {
-    $ret = db_query("INSERT INTO {userpoints_txn}
-      (uid, points, time_stamp, status, operation, description, 
-      reference, expirydate, expired, parent_txn_id, tid, entity_id, entity_type)
-      VALUES (%d, %d, %d, %d, '%s', '%s', '%s', %d, %d, %d, %d, %d, '%s')",
-      $params['uid'],
-      $params['points'],
-      time(),
-      $params['status'],
-      $params['operation'],
-      $params['description'],
-      $params['reference'],
-      $params['expirydate'],
-      $params['expired'], 
-      $params['parent_txn_id'],
-      $params['tid'],
-      $params['entity_id'],
-      $params['entity_type']
-    );
-    if ($params['status'] != true && $ret != false) {
+    //Create new transaction record
+    $ret = drupal_write_record('userpoints_txn', $params);
+    //don't cache entry if it's pending
+    if ($params['status'] != TRUE && $ret != FALSE) {
       _userpoints_update_cache($params);
     }
   }
@@ -1212,6 +1203,7 @@
                   'description' => $form_state['values']['description'],
                   'reference' => $form_state['values']['reference'],
                   'tid' => $form_state['values']['tid'],
+                  'time_stamp' => strtotime($form_state['values']['time_stamp']),
                 );
       if ($form_state['values']['expirydate']) {
         //Check for the existence of an expirydate 

