Index: uc_followup.module
===================================================================
--- uc_followup.module	(revision 507)
+++ uc_followup.module	(working copy)
@@ -84,6 +84,13 @@
     'page arguments' => array('uc_followup_skip_confirm', 3, 6),
     'access arguments' => array('administer order workflow'),
     'file' => 'uc_followup.admin.inc',
+  );  
+  $items['autocomplete/uc_followup_node_title_autocomplete'] = array(
+    'title' => t('Node title autocomplete'),
+    'page callback' => 'uc_followup_node_title_autocomplete',
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_followup.admin.inc',
   );
   return $items;
 }
@@ -264,6 +271,9 @@
         )
       )
     )',
+    
+    // Only get products which are listed in the "uses products" field
+    "(p.nid in (f.product_ids) OR f.product_ids = '' OR f.product_ids IS NULL)",
   );
   $where = array_merge($where, $where_defaults);
 
@@ -272,6 +282,7 @@
   $query[] = implode(', ', $select);
   $query[] = 'FROM {uc_followup} f';
   $query[] = 'LEFT JOIN {uc_orders} o ON o.order_status = f.order_status';  // Join all orders, for which there is a folowup rule (this will multiply the number of rows returned).
+  $query[] = 'LEFT JOIN  uc_order_products p on o.order_id = p.order_id';
   $query[] = 'LEFT JOIN (
     SELECT followup_id, order_id, COUNT(order_id) as sent_count, MAX(date) as last_sent
       FROM {uc_followup_sent}
Index: uc_followup.install
===================================================================
--- uc_followup.install	(revision 507)
+++ uc_followup.install	(working copy)
@@ -69,6 +69,10 @@
         'type' => 'text',
         'not null' => FALSE
       ),
+      'product_ids' => array(
+      'type' => 'text',
+      'not null' => FALSE,
+      ),
     ),
     'primary key' => array('followup_id'),
   );
@@ -181,4 +185,16 @@
   db_add_field($ret, 'uc_followup', 'effective_date', $field);
 
   return $ret;
+}
+function uc_followup_update_6002() {
+  $ret = array();
+
+  // Add a 'product_ids' column to the uc_followup, and set it to the current timestamp on all records.
+  $field = array(
+    'type' => 'text',
+    'not null' => FALSE,
+  );
+  db_add_field($ret, 'uc_followup', 'product_ids', $field);
+
+  return $ret;
 }
\ No newline at end of file
Index: uc_followup.admin.inc
===================================================================
--- uc_followup.admin.inc	(revision 507)
+++ uc_followup.admin.inc	(working copy)
@@ -9,17 +9,27 @@
  * List all follow-ups.
  */
 function uc_followup_list() {
-  $result = db_query('SELECT followup_id, order_status, effective_date, hours_past, name, status, repeat_after, repeat_max FROM {uc_followup} ORDER BY status DESC');
+  $result = db_query('SELECT followup_id, order_status, effective_date, hours_past, name, status, repeat_after, repeat_max, product_ids FROM {uc_followup} ORDER BY status DESC');
 
-  $header = array(t('Name'), t('Triggers on'), t('Effective date'), t('Status'), '');
+  $header = array(t('Name'), t('Triggers on'), t('Effective date'), t('Status'), t('Products'), '');
   $rows = array();
   while ($followup = db_fetch_array($result)) {
     $row = array();
+    // if there are products tied to this, get their names
+    if($followup['product_ids']) :
+      $product_ids = explode(',', $followup['product_ids']);
+      $products_array = _uc_followup_get_product_names($product_ids);
+      $products = implode(', ', $products_array);
+    else :
+      $products = t('All products');    
+    endif;
+    
     $row['name'] = check_plain($followup['name']);
     $row['triggers'] = t('%hours after order became %status', array('%hours' => format_plural($followup['hours_past'], '1 hour', '@count hours'), '%status' => uc_order_status_data($followup['order_status'], 'title')));
     $row['triggers'] .= $followup['repeat_after'] ? ' ('. t('repeat every %hours %times', array('%hours' => format_plural($followup['repeat_after'], '1 hour', '@count hours'), '%times' => $followup['repeat_max'] ? format_plural($followup['repeat_max'], '1 time', '@count times') : '')) .')' : '';
     $row['effective'] .= $followup['effective_date'] ? date('m/d/Y', $followup['effective_date']) : '';
     $row['status'] = variable_get('uc_followup_auto_send', TRUE) ? $followup['status'] ? t('Auto') : t('Manual') : t('Manual (global)');
+    $row['products'] = $products;
     $row['operations'] = l(t('Edit'), 'admin/store/follow-up/edit/'. $followup['followup_id']) .' &nbsp; &nbsp; &nbsp '. l(t('Delete'), 'admin/store/follow-up/delete/'. $followup['followup_id']);
     $rows[] = $row;
   }
@@ -75,6 +85,27 @@
     '#default_value' => $edit['order_status'],
     '#required' => TRUE,
   );
+  
+  $product_ids = explode(',', $edit['product_ids']);
+  if($product_ids) :
+    $products_array = _uc_followup_get_product_names($product_ids);
+    $products = array();
+    
+    foreach($products_array as $nid => $product) :
+      $products[] = $product . ' [pid: ' . $nid . ']';
+    endforeach;
+    $products = implode(', ', $products);  
+  else :
+    $products = '';
+  endif;  
+  
+  $form['product_ids'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Products'),
+    '#description' => t('Select products this followup should apply to. If no products are selected, this followup will apply to all products'),
+    '#autocomplete_path' => 'autocomplete/uc_followup_node_title_autocomplete',
+    '#default_value' => $products,
+  );
 
   // Effective date
   $effective_date = $edit['effective_date'] ? $edit['effective_date'] : time();
@@ -196,6 +227,25 @@
  * Save a follow-up to database.
  */
 function uc_followup_form_submit($form, &$form_state) {
+  if($form_state['values']['product_ids']) :
+    $product_names = explode(', ', $form_state['values']['product_ids']);
+    $product_ids = array();
+    foreach($product_names as $product) :
+      if($product) :
+        $pattern = '/(.*)\s\[pid: (\d+)\]/i';
+/*         $name = preg_replace($pattern, '${1}', $product); */
+        $pid = preg_replace($pattern, '${2}', $product);
+        if($pid == '[pid: ]')
+          $pid = NULL;
+        $product_ids[] = $pid;
+      endif;
+    endforeach;
+    if(!empty($product_ids)) :
+      $product_ids = array_unique($product_ids);
+      $form_state['values']['product_ids'] = implode(',', $product_ids);
+    endif;
+  endif;  
+  
   if ($form_state['values']['followup_id']) {
     drupal_write_record('uc_followup', $form_state['values'], 'followup_id');
     drupal_set_message(t('Follow-up updated.'));
@@ -528,4 +578,36 @@
   drupal_set_message(t('Follow-up skipped.'));
 
   $form_state['redirect'] = 'admin/store/orders/'. $order->order_id .'/follow-up';
+}
+
+/**
+ * Autocomplete node titles 
+ *
+ */
+ 
+function uc_followup_node_title_autocomplete($string) {
+  $strings = drupal_explode_tags($string);
+  $last_string = trim(array_pop($strings));
+  $matches = array();
+  
+  if($last_string != '') :
+    $result = db_query_range("SELECT n.nid as nid, n.title as title, p.model as model" . " FROM {uc_products} p INNER JOIN {node} n ON p.nid=n.nid WHERE n.title LIKE LOWER('%%%s%%')", $last_string, 0, 10);
+    $prefix = count($strings) ? implode(', ', $strings) .', ' : '';
+    while ($row = db_fetch_object($result)) :
+      $matches[$prefix . $row->title . ' [pid: ' . $row->nid .']'] = check_plain($row->title ." (". $row->model .")");
+    endwhile;
+  endif;
+  print drupal_to_js($matches);
+  exit();
+}
+
+function _uc_followup_get_product_names($pids = array()) {
+  $products = array();
+  foreach($pids as $pid) :
+/*     drupal_set_message($pid); */
+    $name = db_result(db_query('SELECT title FROM {node} WHERE nid = %d ', $pid));
+/*     drupal_set_message($name); */
+    $products[$pid] = $name;
+  endforeach;
+  return $products;
 }
\ No newline at end of file
