=== modified file 'docs/hooks.php'
--- docs/hooks.php	2009-09-21 14:13:04 +0000
+++ docs/hooks.php	2009-09-22 14:42:10 +0000
@@ -1518,6 +1518,25 @@
   return $models;
 }
 
+/**
+ * Allow modules to take action when a stock level is changed.
+ *
+ * @param $sku
+ *   The SKU whose stock level is being changed.
+ * @param $stock
+ *   The stock level before the adjustment.
+ * @param $qty
+ *   The amount by which the stock level was changed.
+ */
+function hook_uc_stock_adjusted($sku, $stock, $qty) {
+  $params = array(
+    'sku' => $sku,
+    'stock' => $stock,
+    'qty' => $qty,
+  );
+
+  drupal_mail('uc_stock_notify', 'stock-adjusted', uc_store_email_from(), language_default(), $params);
+}
 
 /**
  * Allows modules to alter items before they're added to the UC Google Analytics

=== modified file 'uc_order/uc_order.admin.inc'
--- uc_order/uc_order.admin.inc	2009-09-21 14:13:04 +0000
+++ uc_order/uc_order.admin.inc	2009-09-22 15:15:46 +0000
@@ -1236,12 +1236,23 @@
     }
   }
 
+  if (module_exists('uc_stock')) {
+    $qtys = array();
+    foreach ($order->products as $product) {
+      $qtys[$product->order_product_id] = $product->qty;
+    }
+  }
+
   unset($order->products);
   if (is_array($_POST['products'])) {
     foreach ($_POST['products'] as $product) {
       if (!isset($product['remove']) && intval($product['qty']) > 0) {
         $product['data'] = unserialize($product['data']);
         $order->products[] = (object) $product;
+
+        if (module_exists('uc_stock')) {
+          uc_stock_adjust($product['model'], $qtys[$product['order_product_id']] - $product['qty']);
+        }
       }
       else {
         $log['remove_'. $product['nid']] = $product['title'] .' removed from order.';
@@ -1321,9 +1332,20 @@
       if (variable_get('uc_order_logging', TRUE)) {
         uc_order_log_changes($order->order_id, array('add' => 'Added ('. $product->qty .') '. $product->title .' to order.'));
       }
+
+      // Decrement stock?
+      if (module_exists('uc_stock')) {
+        uc_stock_decrement_product_stock($product);
+      }
       break;
     case 'remove':
-      db_query("DELETE FROM {uc_order_products} WHERE order_product_id = %d", intval($_POST['opid']));
+      $order_product_id = intval($_POST['opid']);
+      // Put back the stock?
+      if (module_exists('uc_stock')) {
+        $product = db_fetch_object(db_query("SELECT model, qty FROM {uc_order_products} WHERE order_product_id = %d", $order_product_id));
+        uc_stock_adjust($product->model, $product->qty);
+      }
+      db_query("DELETE FROM {uc_order_products} WHERE order_product_id = %d", $order_product_id);
       break;
   }
 

=== modified file 'uc_order/uc_order.module'
--- uc_order/uc_order.module	2009-09-21 14:13:04 +0000
+++ uc_order/uc_order.module	2009-09-22 14:24:14 +0000
@@ -1059,8 +1059,6 @@
            ((is_null($order->billing_country) || $order->billing_country == 0) ? variable_get('uc_store_country', 840) : $order->billing_country),
            $order->payment_method, serialize($order->data), ip_address(), time(), $order->order_id);
 
-  // Review this query for removal in the future. -RS
-  db_query("DELETE FROM {uc_order_products} WHERE order_id = %d", $order->order_id);
   if (is_array($order->products)) {
     foreach ($order->products as $product) {
       drupal_alter('order_product', $product, $order);

=== modified file 'uc_stock/uc_stock.ca.inc'
--- uc_stock/uc_stock.ca.inc	2009-07-21 14:53:39 +0000
+++ uc_stock/uc_stock.ca.inc	2009-09-22 14:42:10 +0000
@@ -59,22 +59,6 @@
  */
 function uc_stock_action_decrement_stock($order, $settings) {
   if (is_array($order->products)) {
-    $stock_warnings = array();
-    foreach ($order->products as $product) {
-      if (($stock = uc_stock_level($product->model)) !== FALSE) {
-        $stock_level = db_fetch_object(db_query("SELECT * FROM {uc_product_stock} WHERE sku = '%s'", $product->model));
-        if ((($stock - $product->qty) <= $stock_level->threshold) && !in_array($product->model, array_keys($stock_warnings))) {
-          $stock_level->stock -= $product->qty;
-          $stock_warnings[$product->model] = $stock_level;
-        }
-        uc_stock_adjust($product->model, -$product->qty);
-        uc_order_comment_save($order->order_id, 0, t('The stock level for %model_name has been decreased to !qty.', array('%model_name' => $product->model, '!qty' => ($stock - $product->qty))));
-      }
-    }
-    if (!empty($stock_warnings) && variable_get('uc_stock_threshold_notification', FALSE)) {
-      foreach ($stock_warnings as $model => $stock_level) {
-        _uc_stock_send_mail($order, $stock_level);
-      }
-    }
+    array_walk($order->products, 'uc_stock_decrement_product_stock');
   }
 }

=== modified file 'uc_stock/uc_stock.module'
--- uc_stock/uc_stock.module	2009-09-15 15:00:54 +0000
+++ uc_stock/uc_stock.module	2009-09-22 16:00:39 +0000
@@ -173,8 +173,18 @@
  * @param $qty
  *   The amount to add to or subtract from the stock level.
  */
-function uc_stock_adjust($sku, $qty) {
+function uc_stock_adjust($sku, $qty, $check_active = TRUE) {
+  $stock = db_fetch_object(db_query("SELECT active, stock FROM {uc_product_stock} WHERE sku = '%s'", $sku));
+
+  if ($check_active) {
+    if (!$stock->active) {
+      return;
+    }
+  }
+
   db_query("UPDATE {uc_product_stock} SET stock = stock + %d WHERE sku = '%s'", $qty, $sku);
+
+  module_invoke_all('uc_stock_adjusted', $sku, $stock->stock, $qty);
 }
 
 /**
@@ -195,10 +205,28 @@
  * @param $sku
  *   The Ubercart product SKU of the stock level to return.
  * @return:
- *   The associated stock level with the particular SKU or FALSE if not active.
+ *   The SKU's stock level, or FALSE if not active.
  */
 function uc_stock_level($sku) {
-  return db_result(db_query("SELECT stock FROM {uc_product_stock} WHERE sku = '%s' AND active = 1", $sku));
+  $stock = db_fetch_object(db_query("SELECT active, stock FROM {uc_product_stock} WHERE sku = '%s'", $sku));
+
+  if ($stock && $stock->active) {
+    return $stock->stock;
+  }
+
+  return FALSE;
+}
+
+/**
+ * Check if a sku has an active stock record.
+ *
+ * @param $sku
+ *   The Ubercart product SKU to check
+ * @return (bool)
+ *   Whether or not the sku has an active stock record.
+ */
+function uc_stock_is_active($sku) {
+  return (bool) db_result(db_query("SELECT active FROM {uc_product_stock} WHERE sku = '%s'", $sku));
 }
 
 /**
@@ -248,3 +276,30 @@
   );
 }
 
+/**
+ * Decrement a product's stock.
+ *
+ * @param $product
+ *   The product whose stock is decrementing.
+ */
+function uc_stock_decrement_product_stock($product) {
+  // Product has an active stock?
+  if (!uc_stock_is_active($product->model)) {
+    return;
+  }
+
+  // Decrement the product's stock.
+  uc_stock_adjust($product->model, -$product->qty);
+
+  // Load the new stock record
+  $stock = db_fetch_object(db_query("SELECT * FROM {uc_product_stock} WHERE sku = '%s'", $product->model));
+
+  // Should we notify?
+  if (variable_get('uc_stock_threshold_notification', FALSE) && $stock->stock <= $stock->threshold) {
+    _uc_stock_send_mail($order, $stock);
+  }
+
+  // Save a comment about the stock level.
+  uc_order_comment_save($order->order_id, 0, t('The stock level for %model_name has been decreased to !qty.', array('%model_name' => $product->model, '!qty' => $stock->stock)));
+}
+

