diff -urpb /home/michael/uc_coupon/uc_coupon.install ./uc_coupon.install
--- /home/michael/uc_coupon/uc_coupon.install	2008-06-05 14:52:30.000000000 +0930
+++ ./uc_coupon.install	2008-06-05 12:58:09.000000000 +0930
@@ -17,6 +17,7 @@ function uc_coupon_install() {
         status int(1) NOT NULL default '1',
         valid_until int(11) default NULL,
         max_uses int(4) NOT NULL,
+        max_uses_per_user int(4) NOT NULL,
         users text,
         roles int(1) NOT NULL,
         minimum_order decimal(6,2) NOT NULL default 0.00,
@@ -42,3 +43,14 @@ function uc_coupon_uninstall() {
   db_query("DROP TABLE {uc_coupons_orders}");
   drupal_set_message("UC Coupon Successfully Uninstalled.");
 }
\ No newline at end of file
+
+function uc_coupon_update_1() {
+  $ret = array();
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      $ret[] = update_sql("ALTER TABLE {uc_coupons} ADD max_uses_per_user int(4) NOT NULL AFTER max_uses");
+      break;
+  }
+  return $ret;
+}
diff -urpb /home/michael/uc_coupon/uc_coupon.module ./uc_coupon.module
--- /home/michael/uc_coupon/uc_coupon.module	2008-06-05 14:52:30.000000000 +0930
+++ ./uc_coupon.module	2008-06-05 14:26:25.000000000 +0930
@@ -236,6 +236,15 @@ function uc_coupon_add_form($action, $ci
     '#size' => 25,
     '#weight' => 11,
   );
+
+  $form['max_uses_per_user'] = array('#type' => 'textfield',
+    '#title' => t('Maximum Number of Redemptions per User'),
+    '#default_value' => $value->max_uses_per_user,
+    '#description' => 'Enter "0" for unlimited number of redemptions',
+    '#size' => 25,
+    '#weight' => 11,
+  );
+
  $form['users'] = array('#type' => 'select',
     '#multiple' => TRUE,
     '#title' => t('Allowed Users'),
@@ -244,6 +253,7 @@ function uc_coupon_add_form($action, $ci
     '#description' => 'Users who can use this coupon',
     '#weight' => 13,
   );
+
   $form['roles'] = array('#type' => 'radios',
     '#title' => 'Allowed Permissions',
     '#description' => 'Select the groups who are able to use this coupon',
@@ -294,7 +304,7 @@ function uc_coupon_add_form_submit($form
   
   // If the forms coupon id is not set then we try to insert a new coupon
   if (!isset($form['cid'])) {
-    if (db_query("INSERT INTO {uc_coupons} (name, code, value, type, status, valid_until, max_uses, users, roles, minimum_order) VALUES ('%s', '%s', '%f', '%s', '%d', '%d', '%d', '%s', '%s', %d)", $form['name'], $form['code'], $form['value'], $form['type'], $form['status'], $form['valid_until'], $form['max_uses'], $users, $form['roles'], $form['minimum_order'])) {
+    if (db_query("INSERT INTO {uc_coupons} (name, code, value, type, status, valid_until, max_uses, max_uses_per_user, users, roles, minimum_order) VALUES ('%s', '%s', '%f', '%s', '%d', '%d', '%d', '%d', '%s', '%s', %d)", $form['name'], $form['code'], $form['value'], $form['type'], $form['status'], $form['valid_until'], $form['max_uses'], $form['max_uses_per_user'], $users, $form['roles'], $form['minimum_order'])) {
       $message = "New coupon {$form['name']} added succesfully";
     }
     else {
@@ -303,7 +313,7 @@ function uc_coupon_add_form_submit($form
   }
   else {
     // Otherwise we try to update the coupon with matching coupon id
-    if (db_query("UPDATE {uc_coupons} SET name = '%s', code = '%s', value = %f, type = '%s', status = %d, valid_until = %d, max_uses = %d, users = '%s', roles = '%s', minimum_order = %d WHERE cid = %d", $form['name'], $form['code'], $form['value'], $form['type'], $form['status'], $form['valid_until'], $form['max_uses'], $users, $form['roles'], $form['minimum_order'], $form['cid'])) {
+    if (db_query("UPDATE {uc_coupons} SET name = '%s', code = '%s', value = %f, type = '%s', status = %d, valid_until = %d, max_uses = %d, max_uses_per_user = %d, users = '%s', roles = '%s', minimum_order = %d WHERE cid = %d", $form['name'], $form['code'], $form['value'], $form['type'], $form['status'], $form['valid_until'], $form['max_uses'], $form['max_uses_per_user'], $users, $form['roles'], $form['minimum_order'], $form['cid'])) {
       $message = "Coupon updated succssfully";
     }
     else {
@@ -397,19 +407,30 @@ function uc_coupon_validate($code, $orde
   $today = time();
 
   // the following query grabs a result with a matching code that has a valid date and is marked as active
-  $coupon_data = db_fetch_object(db_query("SELECT code, cid, value, type, max_uses, users, roles, minimum_order FROM {uc_coupons} WHERE code = '%s' AND status ='1' AND valid_until > %d", $code, $today));
+  $coupon_data = db_fetch_object(db_query("SELECT code, cid, value, type, max_uses, max_uses_per_user, users, roles, minimum_order FROM {uc_coupons} WHERE code = '%s' AND status ='1' AND valid_until > %d", $code, $today));
 
   if ($coupon_data) {
     $coupon_result->valid = false;
     //  CHECK MAX USES
     if ($coupon_data->max_uses > 0) {
-        $result = db_result(db_query("SELECT COUNT(*) FROM {uc_coupons_orders} AS uco LEFT JOIN {uc_orders} AS uo ON uco.oid = uo.order_id WHERE uo.order_status > 0 AND uco.cid = %d", $coupon_data->cid));
+        $result = db_result(db_query("SELECT COUNT(*) FROM {uc_coupons_orders} AS uco LEFT JOIN {uc_orders} AS uo ON uco.oid = uo.order_id WHERE (uo.order_status = 'in_checkout' OR uo.order_status = 'pending' OR uo.order_status = 'completed') AND uco.cid = %d", $coupon_data->cid));
         $coupon_used = $result;        
         // Now that we have how many times it has been used we can check against its max uses
       if ($coupon_used >= $coupon_data->max_uses) {
         return $coupon_result;
       }
     }
+    
+    //  CHECK MAX USES PER USER
+    if ($coupon_data->max_uses_per_user > 0) {
+        $result = db_result(db_query("SELECT COUNT(*) FROM {uc_coupons_orders} AS uco LEFT JOIN {uc_orders} AS uo ON uco.oid = uo.order_id WHERE (uo.order_status = 'in_checkout' OR uo.order_status = 'pending' OR uo.order_status = 'completed') AND uco.cid = %d AND uco.user = %d", $coupon_data->cid, $order->uid));
+        $coupon_used = $result;
+        // Now that we have how many times it has been used we can check against its max uses
+      if ($coupon_used >= $coupon_data->max_uses_per_user) {
+        return $coupon_result;
+      }
+    }
+
     //  CHECK MINIMUM PURCHASE VALUE
     $cart_total = uc_order_get_total($order, TRUE);  // this is also used below in the percentage discount calculation
     if ($coupon_data->minimum_order > 0 && $coupon_data->minimum_order > $cart_total) {
@@ -519,9 +540,9 @@ function uc_coupon_order($op, $arg1, $ar
         if ($coupon_result->valid) {
           // If we received a result from the database then it means there is a coupon in the table with that code
           // we then must validate the coupon with our validation function.  It will return data about the coupon to insert into the order table
-          db_query("UPDATE {uc_coupons_orders} SET cid = %d, oid = %d, code = '%s', value = %f WHERE oid = %d", $coupon_result->cid, $arg1->order_id, $coupon_result->code, $coupon_result->amount, $arg1->order_id);
+          db_query("UPDATE {uc_coupons_orders} SET cid = %d, oid = %d, code = '%s', value = %f, user = %d WHERE oid = %d", $coupon_result->cid, $arg1->order_id, $coupon_result->code, $coupon_result->amount, $arg1->uid, $arg1->order_id);
           if (db_affected_rows() == 0) {
-            db_query("INSERT INTO {uc_coupons_orders} (cid, oid, code, value) VALUES (%d, %d, '%s', %f)", $coupon_result->cid, $arg1->order_id, $coupon_result->code, $coupon_result->amount);
+            db_query("INSERT INTO {uc_coupons_orders} (cid, oid, code, value, user) VALUES (%d, %d, '%s', %f, %d)", $coupon_result->cid, $arg1->order_id, $coupon_result->code, $coupon_result->amount, $arg1->uid);
           }
           db_query("UPDATE {uc_order_line_items} SET title = 'Coupon Discount: \'%s\'', amount = -%f, weight = 0 WHERE order_id = %d AND type ='coupon'", $coupon_result->code, $coupon_result->amount, $arg1->order_id);
           if (db_affected_rows() == 0) {
Only in .: uc_coupon.patch
