=== modified file 'uc_product_kit/uc_product_kit.install'
--- uc_product_kit/uc_product_kit.install	2009-01-19 19:41:59 +0000
+++ uc_product_kit/uc_product_kit.install	2009-02-20 20:42:44 +0000
@@ -173,3 +173,12 @@
 
   return $ret;
 }
+
+function uc_product_kit_update_6002() {
+  $ret = array();
+
+  $ret[] = update_sql("UPDATE {uc_product_kits} AS pk JOIN {uc_products} AS p ON pk.product_id = p.nid SET pk.discount = pk.discount - p.sell_price WHERE pk.discount >= 0");
+
+  return $ret;
+}
+

=== modified file 'uc_product_kit/uc_product_kit.module'
--- uc_product_kit/uc_product_kit.module	2009-02-18 13:51:39 +0000
+++ uc_product_kit/uc_product_kit.module	2009-02-23 15:12:26 +0000
@@ -183,6 +183,23 @@
   $obj->ordering = $node->ordering;
   $obj->shippable = FALSE;
 
+  $override_discounts = isset($node->kit_total) && is_numeric($node->kit_total);
+  $product_count = count($node->products);
+
+  // Get the price of all the products without any discounts. This number is
+  // used if a total kit price was specified to calculate the individual
+  // product discounts.
+  if ($override_discounts) {
+    $base_price = 0;
+    foreach ($node->products as $nid) {
+      $product = node_load($nid, NULL, TRUE);
+      if (is_null($node->items[$nid]['qty']) || $node->items[$nid]['qty'] === '') {
+        $node->items[$nid]['qty'] = 1;
+      }
+      $base_price += $product->sell_price * $node->items[$nid]['qty'];
+    }
+  }
+
   $values = array();
   $placeholders = array();
   foreach ($node->products as $nid) {
@@ -190,26 +207,34 @@
     $values[] = $node->nid;
     $values[] = $nid;
     $values[] = $node->mutable;
-    $product = node_load($nid, NULL, TRUE);
+    $product = node_load($nid);
+
+    // When a total kit price is specified, calculate the individual product
+    // discounts needed to reach it, taking into account the product quantities
+    // and their relative prices. More expensive products should be given a
+    // proportionally higher discount.
+    if ($override_discounts) {
+      $price = $product->sell_price;
+      // After all the algebra that went into finding this formula, it's
+      // surprising how simple it is.
+      $discount = ($node->kit_total - $base_price) * $price / $base_price;
+    }
+    else {
+      $discount = $node->items[$nid]['discount'];
+    }
 
     if (is_null($node->items[$nid]['qty']) || $node->items[$nid]['qty'] === '') {
       $node->items[$nid]['qty'] = 1;
     }
-    $values[] = $node->items[$nid]['qty'];
-    $values[] = $node->items[$nid]['discount'];
+
+    $product->qty = $node->items[$nid]['qty'];
+    $product->sell_price += $discount;
+
+    $values[] = $product->qty;
+    $values[] = $discount;
     $values[] = $node->items[$nid]['ordering'];
     $placeholders[] = '(%d, %d, %d, %d, %d, %f, %d)';
 
-    $product->qty = $node->items[$nid]['qty'];
-    if (is_numeric($node->items[$nid]['discount'])) {
-      if ($node->items[$nid]['discount'] < 0) {
-        $product->sell_price += $node->items[$nid]['discount'];
-      }
-      else {
-        $product->sell_price = $node->items[$nid]['discount'];
-      }
-    }
-    $obj->model .= $product->model .' / ';
     $obj->list_price += $product->list_price * $product->qty;
     $obj->cost += $product->cost * $product->qty;
     $obj->sell_price += $product->sell_price * $product->qty;
@@ -332,6 +357,9 @@
 function uc_product_kit_form(&$node) {
   $form = array();
 
+  $sign_flag = variable_get('uc_sign_after_amount', FALSE);
+  $currency_sign = variable_get('uc_currency_sign', '$');
+
   $form['title'] = array('#type' => 'textfield',
     '#title' => t('Name'),
     '#required' => TRUE,
@@ -386,7 +414,8 @@
     '#options' => $products,
     '#default_value' => isset($node->products) ? array_keys($node->products) : array(),
   );
-  $form['base']['items'] = array('#tree' => TRUE);
+  $total = 0;
+  $form['base']['items'] = array('#tree' => TRUE, '#weight' => 1);
   if (isset($node->products)) {
     foreach ($node->products as $i => $product) {
       $form['base']['items'][$i] = array('#type' => 'fieldset',
@@ -407,11 +436,27 @@
       $item = node_load($i);
       $form['base']['items'][$i]['discount'] = array('#type' => 'textfield',
         '#title' => t('Discount'),
-        '#description' => t('Enter a negative value to lower the item price by that amount. Enter a postive value to set the item price to that amount. This discount is applied to each %product in the kit.', array('%product' => $product->title)),
-        '#default_value' => (is_null($product->discount) || $product->discount === '' ? $item->sell_price : $product->discount),
+        '#description' => t('Enter a positive or negative value to raise or lower the item price by that amount. This change is applied to each %product in the kit.', array('%product' => $product->title)),
+        '#field_prefix' => t('@price + ', array('@price' => uc_currency_format($product->sell_price))),
+        '#default_value' => isset($product->discount) ? $product->discount : 0,
         '#size' => 5,
       );
+      $total += $product->sell_price * $product->qty;
+      if (isset($product->discount)) {
+        $total += $product->discount * $product->qty;
+      }
     }
+    $form['base']['kit_total'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Total price'),
+      '#default_value' => '',
+      '#description' => t('If this field is set, the discounts of the individual products will be recalculated to equal this value. Currently, the total sell price is %price.', array('%price' => uc_currency_format($total))),
+      '#weight' => 0,
+      '#size' => 20,
+      '#maxlength' => 35,
+      '#field_prefix' => $sign_flag ? '' : $currency_sign,
+      '#field_suffix' => $sign_flag ? $currency_sign : '',
+    );
   }
   $form['base']['default_qty'] = array('#type' => 'textfield',
     '#title' => t('Default quantity to add to cart'),

