? storm_735694.patch
Index: stormattribute/stormattribute.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/storm/stormattribute/stormattribute.install,v
retrieving revision 1.2.4.15
diff -u -p -r1.2.4.15 stormattribute.install
--- stormattribute/stormattribute.install	5 Jan 2010 16:04:53 -0000	1.2.4.15
+++ stormattribute/stormattribute.install	30 Mar 2010 20:09:13 -0000
@@ -15,6 +15,7 @@ function stormattribute_install() {
     'fixed' => 'Fixed',
     'hourly' => 'Hourly',
     'daily' => 'Daily',
+    'fixed_timetracking' => 'Fixed Timetracking',
   );
 
   $attributes['Project status'] = array(
@@ -948,3 +949,11 @@ function stormattribute_update_6110() {
 
   return $ret;  
 }
+
+function stormattribute_update_6111() {
+  $ret = array();
+
+  $ret[] = update_sql("INSERT INTO {stormattribute} (domain, akey, avalue, weight, isactive) VALUES ('Price mode', 'fixed_timetracking', 'Fixed Timetracking', 0, 1)");
+
+  return $ret;
+}
Index: stormtimetracking/stormtimetracking.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/storm/stormtimetracking/stormtimetracking.module,v
retrieving revision 1.10.4.49
diff -u -p -r1.10.4.49 stormtimetracking.module
--- stormtimetracking/stormtimetracking.module	6 Jan 2010 15:13:14 -0000	1.10.4.49
+++ stormtimetracking/stormtimetracking.module	30 Mar 2010 20:09:14 -0000
@@ -692,17 +692,30 @@ function stormtimetracking_storminvoice_
     } else {
       $new_invoice = node_load($invoice_nid);
     }
+
+    $rate_array = array('use_fixed' => FALSE, 'use_hourly' => FALSE, 'use_fixed_timetracking' => FALSE, 'rate_to_use' => 0);
     
-    $hourly_rate = stormtimetracking_timetracking_to_hourly_rate($node);
+    $rate_array = stormtimetracking_timetracking_get_rate($node);
     
     $count = count($new_invoice->items);
     
     $new_invoice->items[$count]->description  = date('d M y', $node->trackingdate) . ': ';
-    $new_invoice->items[$count]->description .= ($hourly_rate ? t('@dur hours work at @rate per hour on @desc', array('@dur' => $node->billing_duration, '@rate' => $hourly_rate, '@desc' => $node->title)) : t('@dur hours unbilled work on @desc', array('@dur' => $node->billing_duration, '@desc' => $node->title)));
+    $new_invoice->items[$count]->description .= ($rate_array['rate_to_use'] ? t('@dur hours work at @rate per hour on @desc', array('@dur' => $node->billing_duration, '@rate' => $rate_array['rate_to_use'], '@desc' => $node->title)) : t('@dur hours unbilled work on @desc', array('@dur' => $node->billing_duration, '@desc' => $node->title)));
+
+    if ($rate_array['use_hourly'] == TRUE) {
+      $new_invoice->items[$count]->amount = $node->billing_duration * $rate_array['rate_to_use'];
+      }
+
+    if ($rate_array['use_fixed'] == TRUE) {
+      $new_invoice->items[$count]->amount = $rate_array['rate_to_use'];
+      }
     
-    $new_invoice->items[$count]->amount = $node->billing_duration * $hourly_rate;
+    if ($rate_array['use_fixed_timetracking'] == TRUE) {
+      $new_invoice->items[$count]->amount = $rate_array['rate_to_use'];
+      }
+      
     // Tax percent simply uses default at the moment
-    $new_invoice->items[$count]->tax1percent = variable_get('storminvoice_tax1_percent', 20);
+    $new_invoice->items[$count]->tax1percent = variable_get('storm_tax1_percent', 20);
     //$new_invoice_item->items[$count]->tax1
     //$new_invoice_item->items[$count]->total
     
@@ -725,41 +738,62 @@ function stormtimetracking_views_api() {
 }
 
 /**
- * Try to obtain an hourly rate from a timetracking node. To do this we will 
- * use the first technique, among the following, to work:
- * 
- *  (1) try to obtain an hourly rate from a ticket
- *  (2) try to obtain an hourly rate from a task
- *  (3) try to obtain an hourly rate from a project
- *  (4) try to obtain an hourly rate from an organization
+ * Try to obtain an hourly rate or fixed price for the new invoice item for a timetracking node.
+ * To do this we will use the first technique, among the following, to work:
+  
+ *  (1) try to obtain a rate from a ticket
+ *  (2) try to obtain a rate from a task
+ *  (3) try to obtain a rate from a project
+ *  (4) try to obtain a rate from an organization
  *  (5) return an error if none of this worked.
  *
  * @return
- *   An hourly rate (can be zero).
+ *   Variables in an array.
  */
-function stormtimetracking_timetracking_to_hourly_rate($node) {
+function stormtimetracking_timetracking_get_rate($node) {
+  $rate_array = array('use_fixed' => FALSE, 'use_hourly' => FALSE, 'use_fixed_timetracking' => FALSE, 'rate_to_use' => 0);
+
   $hours_per_day = 8;
+  $found = FALSE;
   
   foreach (array('ticket' => $node->ticket_nid, 'task' => $node->task_nid, 'project' => $node->project_nid, 'organization' => $node->organization_nid) as $type => $nid) {
     if($nid) {
       $parent_item = node_load($nid);
-      switch($parent_item->pricemode) {
+      switch ($parent_item->pricemode) {
         case 'hourly':
-          $hourly_rate = $parent_item->price;
+          $rate_array['use_hourly'] = TRUE;
+          $found = TRUE;
+          $rate_array['rate_to_use'] = $parent_item->price;
           break;
+
         case 'daily':
-          $hourly_rate = $parent_item->price / $hours_per_day;
+          $rate_array['use_hourly'] = TRUE;
+          $found = TRUE;
+          $rate_array['rate_to_use'] = $parent_item->price / $hours_per_day;
           break;
+
         case 'fixed':
-          $hourly_rate = 0;
+          $rate_array['use_fixed'] = TRUE;
+          $found = TRUE;
+          $rate_array['rate_to_use'] = 0;
+          break;
+
+        case 'fixed_timetracking':
+          $rate_array['use_fixed_timetracking'] = TRUE;
+          $found = TRUE;
+          $rate_array['rate_to_use'] = $parent_item->price;
           break;
+
         default:
           continue;
       }
     }
+  if ($found == TRUE) {
+    break;
+    }
   }
-  if(!isset($hourly_rate)) {
-    drupal_set_message(t('Error whilst finding hourly rate from ticket, task, project and organization. Consider setting the pricemode and price for your client organizations to avoid this error.'), 'error');
-  } 
-  return $hourly_rate;
+  if($found == FALSE) {
+    drupal_set_message(t('Error whilst finding a rate from ticket, task, project and organization. Consider setting the pricemode and price for your client organizations to avoid this error.'), 'error');
+    }
+  return $rate_array;
 }
