View Issue Details

IDProjectCategoryView StatusLast Update
0004968mantisbtbugtrackerpublic2014-11-05 01:53
Reporterralfiii Assigned Tovboctor  
PrioritynormalSeverityfeatureReproducibilityalways
Status closedResolutionwon't fix 
Product Version0.19.0 
Summary0004968: Add field for effort (costs) to fix bug
Description

I'd like to have a field "costs" with every issue, stating how much effort (e.g. in man-days) it is (estimated) to fix this issue.

This would be a great help in planning what issues need to be handled next to meet milestones.

If an issue has child issues (like 0004937) it should state:
"Not all the children of this issue are yet resolved or closed - remaining costs: xyz"

TagsNo tags attached.

Relationships

related to 0004428 closeddavidnewcomb Time Tracking 

Activities

mgerben

mgerben

2004-12-13 08:56

reporter   ~0008593

This is a beautiful feature, but do bear two things in mind:

1) You can already add custom fields to projects in Mantis. Ok, it doesn't add up all the values of the underlying bugs, but there is a way to record this data.

2) This is a bugtracker, not a planning tool.
Once you have data regarding cost and algorithms to calculate this cost, you'll want more features... and more features. Which have nothing to do with tracking bugs anymore.

ralfiii

ralfiii

2004-12-13 09:13

reporter   ~0008595

I only use Mantis as bugtracker, but even as bugtracker having a "cost" overview makes sense. e.g. you just need "Sort by costs" and this "sum of costs" to make a quick estimation of work needed for such an intermediate release.

And: would not make a bit of planning support Mantis an even better tool?

And: you are right, the demand for MORE MORE MORE could arise... :-)

stevemagruder

stevemagruder

2004-12-29 00:35

reporter   ~0008821

This kind of relates to a feature request I just made (0005055): the ability to sum a custom number/float field. Another ability that would indeed be helpful would be sorting by custom field.

onad

onad

2005-01-04 10:35

reporter   ~0008839

I think and extention to sum a custom number/float field would be handy and has a universal use.

I also agree that it would indeed be helpful for many to be able to sort by custom field.

ryandesign

ryandesign

2005-04-29 09:10

reporter   ~0009959

We have also added fields like this to our Mantis installation. Our fields are: did the customer request the change (yes/no), how many hours did it take to implement, and have we billed the customer for it (yes/no). Then we can later find all the things the customer asked us to do, that took time to do, and that we haven't billed them for yet, and bill them.

According to Joel On Software (http://www.joelonsoftware.com/articles/fog0000000245.html), tasks should be measured in hours, not days, so that's what we're doing. According to Joel we should also have a fourth field: how many hours did we anticipate it would take. This is important for the reality check later on, to see if you need to adjust your estimates for similar tasks in the future.

2005-06-06 10:04

 

SumTask.png (20,660 bytes)   
SumTask.png (20,660 bytes)   
ralfiii

ralfiii

2005-06-06 10:36

reporter   ~0010371

Oops,
I posted the screenshot here, though I wanted to post it to 0004428 - and I can't delete it anymore.
What's wrong now?!?

ralfiii

ralfiii

2005-06-14 03:55

reporter   ~0010503

Last edited: 2005-06-14 03:56

I've created a patch to 1.0.0a2 for adding

  • Original Estimation
  • Current Estimation
  • Elapsed time
    and a calculated
  • Remaining time

It also displays sums (e.g. the summed remaining time of child tasks)

I've attached the patch and 2 screenshots to issue 0004428

2005-06-14 08:59

 

RyanR

RyanR

2006-10-11 15:11

reporter   ~0013609

ralfiii, Would it be possible to repost your "costs" patch? Maybe with some tweaks for 1.1.0a? :-)

2006-10-12 06:07

 

2006-10-12 06:11

 

TimeTracking_patch_vs_105.patch (15,114 bytes)   
? bug_timetrack_view_inc.php
? config_inc.php
Index: bug_change_status_page.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/bug_change_status_page.php,v
retrieving revision 1.23
diff -u -r1.23 bug_change_status_page.php
--- bug_change_status_page.php	8 Aug 2005 22:30:58 -0000	1.23
+++ bug_change_status_page.php	6 Jul 2006 09:39:26 -0000
@@ -228,6 +228,24 @@
 <?php }
 	} ?>
 
+
+
+<?php
+#   Sx: Time tracking: Let the user specify how much time was used to resolve this issue
+if ( ( $t_resolved <= $f_new_status ) && ( CLOSED > $f_new_status ) ) { ?>
+<!-- Time estimates -->
+<tr <?php echo helper_alternate_class() ?>>
+	<td class="category">
+		<?php echo lang_get( 'elapsed' ) ?>
+	</td>
+	<td>
+		<input type="text" name="elapsed" value="<?php echo $t_bug->elapsed ?>" />
+	</td>
+</tr>
+<?php } ?>
+
+
+
 <?php
 if ( ( $f_new_status >= $t_resolved ) && ( CLOSED > $f_new_status ) ) { ?>
 <!-- Close Immediately (if enabled) -->
Index: bug_update.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/bug_update.php,v
retrieving revision 1.88.4.1
diff -u -r1.88.4.1 bug_update.php
--- bug_update.php	13 Dec 2005 00:58:52 -0000	1.88.4.1
+++ bug_update.php	11 Jul 2006 07:57:26 -0000
@@ -66,6 +66,26 @@
 	$t_bug_data->view_state			= gpc_get_int( 'view_state', $t_bug_data->view_state );
 	$t_bug_data->summary			= gpc_get_string( 'summary', $t_bug_data->summary );
 
+
+
+	# Sx: Time tracker
+	#	Store values for estimated and elapsed time
+	$t_bug_data->est_curr			= gpc_get_int( 'est_curr', $t_bug_data->est_curr );
+	$t_bug_data->elapsed			= gpc_get_int( 'elapsed', $t_bug_data->elapsed );
+
+	# Check if more time elapsed than estimated (-> error)
+	if ($t_bug_data->elapsed > $t_bug_data->est_curr) {
+		# trigger_error( ERROR_MORE_ELAPSED_THAN_ESTIMATED, ERROR );
+		$t_bug_data->est_curr = $t_bug_data->elapsed;
+	};
+
+	# If OriginalEstimation is 0 (was not yet set) -> take value of CurrentEstimation
+	if ( $t_bug_data->est_orig == 0 ) {
+		$t_bug_data->est_orig = $t_bug_data->est_curr;
+	}
+
+
+
 	$t_bug_data->description		= gpc_get_string( 'description', $t_bug_data->description );
 	$t_bug_data->steps_to_reproduce	= gpc_get_string( 'steps_to_reproduce', $t_bug_data->steps_to_reproduce );
 	$t_bug_data->additional_information	= gpc_get_string( 'additional_information', $t_bug_data->additional_information );
@@ -106,7 +126,7 @@
 			continue;
 		}
 
-		# Only update the field if it is posted 
+		# Only update the field if it is posted
 		#  ( will fail in custom_field_set_value(), if it was required )
 		if ( $t_custom_field_value === null ) {
 			continue;
Index: bug_update_page.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/bug_update_page.php,v
retrieving revision 1.89
diff -u -r1.89 bug_update_page.php
--- bug_update_page.php	12 Jun 2005 21:04:43 -0000	1.89
+++ bug_update_page.php	6 Jul 2006 09:35:08 -0000
@@ -294,6 +294,46 @@
 </tr>
 */ ?>
 
+
+<!-- Sx: Time Tracker -->
+<tr <?php echo helper_alternate_class() ?>>
+
+	<!-- est_orig or est_curr -->
+	<td class="category">
+		<?php echo lang_get( 'est_curr' ) ?>
+	</td>
+
+	<td
+		<?php
+    		 # Color field if est_orig not yet set
+
+		     if ( $t_bug->est_orig == "0" ) {
+    	     #  echo "bgcolor=".get_status_color( $t_bug->status ); }
+    	       echo "bgcolor=#ffffb0"; }
+		?>
+	>
+
+		<input type="text" name="est_curr" value="<?php echo $t_bug->est_curr ?>" />
+	</td>
+
+	<!-- elapsed time -->
+	<td class="category">
+		<?php echo lang_get( 'elapsed' ) ?>
+	</td>
+	<td>
+		<input type="text" name="elapsed" value="<?php echo $t_bug->elapsed ?>" />
+	</td>
+
+	<!-- Remaining time -->
+	<td class="category">
+		<?php echo lang_get( 'remaining' ) ?>
+	</td>
+	<td>
+		<?php echo $t_bug->est_curr - $t_bug->elapsed ?>
+	</td>
+</tr>
+
+
 <!-- spacer -->
 <tr>
 	<td class="spacer" colspan="6">&nbsp;</td>
Index: bug_view_advanced_page.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/bug_view_advanced_page.php,v
retrieving revision 1.76.6.1
diff -u -r1.76.6.1 bug_view_advanced_page.php
--- bug_view_advanced_page.php	1 Jan 2006 02:58:50 -0000	1.76.6.1
+++ bug_view_advanced_page.php	25 Aug 2006 12:51:15 -0000
@@ -385,6 +385,14 @@
 	}
 ?>
 
+
+<!-- Sx: Time tracking -->
+<?php
+	$t_mantis_dir = dirname( __FILE__ ) . DIRECTORY_SEPARATOR;
+	include( $t_mantis_dir . 'bug_timetrack_view_inc.php' );
+?>
+
+
 <!-- spacer -->
 <tr height="5" class="spacer">
 	<td colspan="6"></td>
Index: bug_view_page.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/bug_view_page.php,v
retrieving revision 1.77.6.1
diff -u -r1.77.6.1 bug_view_page.php
--- bug_view_page.php	1 Jan 2006 02:58:50 -0000	1.77.6.1
+++ bug_view_page.php	25 Aug 2006 12:51:15 -0000
@@ -291,6 +291,13 @@
 </tr>
 
 
+<!-- Sx: Time tracking -->
+<?php
+	$t_mantis_dir = dirname( __FILE__ ) . DIRECTORY_SEPARATOR;
+	include( $t_mantis_dir . 'bug_timetrack_view_inc.php' );
+?>
+
+
 <!-- spacer -->
 <tr height="5" class="spacer">
 	<td colspan="6"></td>
Index: core/bug_api.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/bug_api.php,v
retrieving revision 1.95.8.1.6.1
diff -u -r1.95.8.1.6.1 bug_api.php
--- core/bug_api.php	18 Apr 2006 00:53:04 -0000	1.95.8.1.6.1
+++ core/bug_api.php	25 Aug 2006 12:51:20 -0000
@@ -53,6 +53,11 @@
 		var $sponsorship_total = 0;
 		var $sticky = 0;
 
+		# Sx: Time tracking
+		var $est_orig = 0;
+		var $est_curr = 0;
+		var $elapsed = 0;
+
 		# omitted:
 		# var $bug_text_id
 		var $profile_id;
@@ -745,6 +750,12 @@
 					reproducibility='$c_bug_data->reproducibility',
 					status='$c_bug_data->status',
 					resolution='$c_bug_data->resolution',
+
+					# Sx: Time tracking
+					est_orig='$c_bug_data->est_orig',
+					est_curr='$c_bug_data->est_curr',
+					elapsed='$c_bug_data->elapsed',
+
 					projection='$c_bug_data->projection',
 					category='$c_bug_data->category',
 					eta='$c_bug_data->eta',
@@ -787,6 +798,11 @@
 		history_log_event_direct( $p_bug_id, 'sponsorship_total', $t_old_data->sponsorship_total, $p_bug_data->sponsorship_total );
 		history_log_event_direct( $p_bug_id, 'sticky', $t_old_data->sticky, $p_bug_data->sticky );
 
+		# Sx: Time tracking
+		history_log_event_direct( $p_bug_id, 'est_orig', $t_old_data->est_orig, $p_bug_data->est_orig );
+		history_log_event_direct( $p_bug_id, 'est_curr', $t_old_data->est_curr, $p_bug_data->est_curr );
+		history_log_event_direct( $p_bug_id, 'elapsed', $t_old_data->elapsed, $p_bug_data->elapsed );
+
 		# Update extended info if requested
 		if ( $p_update_extended ) {
 			$t_bug_text_table = config_get( 'mantis_bug_text_table' );
@@ -1346,6 +1362,11 @@
 		$t_bug_data->sponsorship_total	= db_prepare_int( $p_bug_data->sponsorship_total );
 		$t_bug_data->sticky				= db_prepare_int( $p_bug_data->sticky );
 
+		# Sx: Time tracking
+		$t_bug_data->est_orig			= db_prepare_int( $p_bug_data->est_orig );
+		$t_bug_data->est_curr			= db_prepare_int( $p_bug_data->est_curr );
+		$t_bug_data->elapsed			= db_prepare_int( $p_bug_data->elapsed );
+
 		$t_bug_data->description		= db_prepare_string( $p_bug_data->description );
 		$t_bug_data->steps_to_reproduce	= db_prepare_string( $p_bug_data->steps_to_reproduce );
 		$t_bug_data->additional_information	= db_prepare_string( $p_bug_data->additional_information );
@@ -1370,6 +1391,11 @@
 		$p_bug_data->sponsorship_total	= string_attribute( $p_bug_data->sponsorship_total );
 		$p_bug_data->sticky				= string_attribute( $p_bug_data->sticky );
 
+		# Sx: Time tracking
+		$p_bug_data->est_orig			= string_attribute( $p_bug_data->est_orig );
+		$p_bug_data->est_curr			= string_attribute( $p_bug_data->est_curr );
+		$p_bug_data->elapsed			= string_attribute( $p_bug_data->elapsed );
+
 		$p_bug_data->description		= string_textarea( $p_bug_data->description );
 		$p_bug_data->steps_to_reproduce	= string_textarea( $p_bug_data->steps_to_reproduce );
 		$p_bug_data->additional_information	= string_textarea( $p_bug_data->additional_information );
@@ -1394,6 +1420,11 @@
 		$p_bug_data->sponsorship_total	= string_display( $p_bug_data->sponsorship_total );
 		$p_bug_data->sticky				= string_display( $p_bug_data->sticky );
 
+		# Sx: Time tracking
+		$p_bug_data->est_orig			= string_display( $p_bug_data->est_orig );
+		$p_bug_data->est_curr			= string_display( $p_bug_data->est_curr );
+		$p_bug_data->elapsed			= string_display( $p_bug_data->elapsed );
+
 		$p_bug_data->description		= string_display_links( $p_bug_data->description );
 		$p_bug_data->steps_to_reproduce	= string_display_links( $p_bug_data->steps_to_reproduce );
 		$p_bug_data->additional_information	= string_display_links( $p_bug_data->additional_information );
Index: core/constant_inc.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/constant_inc.php,v
retrieving revision 1.52.4.1.6.1
diff -u -r1.52.4.1.6.1 constant_inc.php
--- core/constant_inc.php	7 May 2006 05:56:22 -0000	1.52.4.1.6.1
+++ core/constant_inc.php	25 Aug 2006 12:55:49 -0000
@@ -277,6 +277,9 @@
 	define( 'ERROR_SIGNUP_NOT_MATCHING_CAPTCHA', 1904 );
 	define( 'ERROR_LOST_PASSWORD_MAX_IN_PROGRESS_ATTEMPTS_REACHED', 1905 );
 
+	# Sx: Time tracking
+	# define( 'ERROR_MORE_ELAPSED_THAN_ESTIMATED', 2500 );
+
 	# ERROR_FILTER_NOT_FOUND
 	define( 'ERROR_FILTER_NOT_FOUND', 2000 );
 	define( 'ERROR_FILTER_TOO_OLD', 2001 );
Index: core/relationship_api.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/relationship_api.php,v
retrieving revision 1.36
diff -u -r1.36 relationship_api.php
--- core/relationship_api.php	28 Jun 2005 11:04:06 -0000	1.36
+++ core/relationship_api.php	6 Jul 2006 10:03:15 -0000
@@ -497,6 +497,36 @@
 		return true;
 	}
 
+
+	# Sx: Time tracking
+	function outstanding_time( $p_bug_id ) {
+
+		# retrieve all the relationships in which the bug is the source bug
+		$t_relationship = relationship_get_all_src( $p_bug_id );
+		$t_relationship_count = count( $t_relationship );
+		if ( $t_relationship_count == 0 ) {
+			return '';
+		}
+
+		$sumall = 0;
+		$sumremain = 0;
+		for ( $i = 0 ; $i < $t_relationship_count ; $i++ ) {
+			if ( $t_relationship[$i]->type == BUG_DEPENDANT ) {
+				$t_dest_bug_id = $t_relationship[$i]->dest_bug_id;
+			    $sumall += bug_get_field( $t_dest_bug_id, 'est_curr' );
+				$t_status = bug_get_field( $t_dest_bug_id, 'status' );
+				if ( $t_status < config_get( 'bug_resolved_status_threshold' ) ) {
+					# the bug is NOT marked as resolved/closed
+					$sumremain += bug_get_field( $t_dest_bug_id, 'est_curr' ) - bug_get_field( $t_dest_bug_id, 'elapsed' );
+				}
+			}
+		}
+
+        return ' ' . $sumremain . ' units outstanding. (total of child issues : ' . $sumall . ')' ;
+	}
+
+
+
 	# --------------------
 	# return formatted string with all the details on the requested relationship
 	function relationship_get_details( $p_bug_id, $p_relationship, $p_html = false, $p_html_preview = false, $p_show_project = false ) {
@@ -560,6 +590,15 @@
 		}
 		$t_relationship_info_html .= '&nbsp;</td>';
 
+		# Sx: time tracker : show outstanding time
+		if (( $p_relationship->type == BUG_DEPENDANT ) && ($t_bug->est_orig != 0)) {
+		  $t_relationship_info_html .= $t_td .
+		              '<u><a title="' . lang_get( 'elapsed' ) . ' / ' . lang_get( 'est_curr' ) . '">'.
+		              $t_bug->elapsed . ' / ' . $t_bug->est_curr . '</a></u></td>';}
+		else
+		  { $t_relationship_info_html .= $t_td . '&nbsp;</td>'; };
+
+
 		# add project name
 		if( $p_show_project ) {
 			$t_relationship_info_html .= $t_td . $t_related_project_name . '&nbsp;</td>';
@@ -619,7 +658,7 @@
 
 		if ( !is_blank( $t_summary ) ) {
 			if ( relationship_can_resolve_bug( $p_bug_id ) == false ) {
-				$t_summary .= '<tr class="row-2"><td colspan=' . (5 + $t_show_project) . '><b>' . lang_get( 'relationship_warning_blocking_bugs_not_resolved' ) . '</b></td></tr>';
+				$t_summary .= '<tr class="row-2"><td colspan=' . (6 + $t_show_project) . '><b>' . lang_get( 'relationship_warning_blocking_bugs_not_resolved' ) . outstanding_time ( $p_bug_id ) . '</b></td></tr>';
 			}
 			$t_summary = '<table border="0" width="100%" cellpadding="0" cellspacing="1">' . $t_summary . '</table>';
 		}
@@ -643,7 +682,7 @@
 
 		if ( !is_blank( $t_summary ) ) {
 			if ( relationship_can_resolve_bug( $p_bug_id ) == false ) {
-				$t_summary .= '<tr class="print"><td class="print" colspan=' . (5 + $t_show_project) . '><b>' . lang_get( 'relationship_warning_blocking_bugs_not_resolved' ) . '</b></td></tr>';
+				$t_summary .= '<tr class="print"><td class="print" colspan=' . (6 + $t_show_project) . '><b>' . lang_get( 'relationship_warning_blocking_bugs_not_resolved' ) . outstanding_time ( $p_bug_id ) . '</b></td></tr>';
 			}
 			$t_summary = '<table border="0" width="100%" cellpadding="0" cellspacing="1">' . $t_summary . '</table>';
 		}
Index: lang/strings_english.txt
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/lang/strings_english.txt,v
retrieving revision 1.267.10.1
diff -u -r1.267.10.1 strings_english.txt
--- lang/strings_english.txt	7 May 2006 05:56:22 -0000	1.267.10.1
+++ lang/strings_english.txt	12 Oct 2006 10:02:05 -0000
@@ -257,6 +257,8 @@
 $MANTIS_ERROR[ERROR_LOST_PASSWORD_MAX_IN_PROGRESS_ATTEMPTS_REACHED] = 'Max. number of in-progress requests reached. Please contact the system administrator';
 $MANTIS_ERROR[ERROR_PROJECT_RECURSIVE_HIERARCHY] = 'That operation would create a loop in the subproject hierarchy.';
 $MANTIS_ERROR[ERROR_USER_CHANGE_LAST_ADMIN] = 'You cannot change the access level of the only ADMINISTRATOR in the system.';
+# Sx: Time tracking
+# $MANTIS_ERROR[ERROR_MORE_ELAPSED_THAN_ESTIMATED] = 'Elapsed time needs to be smaller or equal than estimated time!';
 $MANTIS_ERROR[ERROR_PAGE_REDIRECTION] = 'Page redirection error, ensure that there are no spaces outside the PHP block (&lt;?php ?&gt;) in config_inc.php or custom_*.php files.';
 
 #$s_login_error = 'Your account may be disabled or blocked (due to too many failed login attempts) or the username/password you entered is incorrect.';
@@ -574,6 +576,12 @@
 $s_sticky_issue = 'Sticky Issue';
 $s_profile = 'Profile';
 
+# Sx: Time tracking
+$s_est_orig = 'Initial';
+$s_est_curr = 'Est. Effort';
+$s_elapsed = 'Elapsed';
+$s_remaining = 'Remaining';
+
 # bug_update_page.php
 $s_update_advanced_link = 'Update Advanced';
 $s_updating_bug_simple_title = 'Updating Issue Information';
TimeTracking_patch_vs_105.patch (15,114 bytes)   
ralfiii

ralfiii

2006-10-12 06:14

reporter   ~0013610

I uploaded the changed files for V1.0.5

I generated a patchfile for 1.0.5. If you apply it, you also need to copy the file "bug_timetrack_view_inc.php" from the zip-file into the Mantis-folder.

vboctor

vboctor

2014-10-24 22:33

manager   ~0041648

This should be covered by time tracking. If that is not sufficient, then a plugin may be a good solution.

Issue History

Date Modified Username Field Change
2004-12-13 05:28 ralfiii New Issue
2004-12-13 08:56 mgerben Note Added: 0008593
2004-12-13 09:13 ralfiii Note Added: 0008595
2004-12-27 04:03 ralfiii Sponsorship Added ralfiii: US$ 10
2004-12-27 04:03 ralfiii Sponsorship Total 0 => 10
2004-12-29 00:35 stevemagruder Note Added: 0008821
2005-01-04 10:35 onad Note Added: 0008839
2005-04-29 09:10 ryandesign Note Added: 0009959
2005-06-06 10:04 ralfiii File Added: SumTask.png
2005-06-06 10:36 ralfiii Note Added: 0010371
2005-06-14 03:55 ralfiii Note Added: 0010503
2005-06-14 03:56 ralfiii Note Edited: 0010503
2005-06-14 08:59 ralfiii File Added: TimeTrackingChangedFiles_100a2.zip
2006-03-03 08:37 ryandesign Relationship added related to 0004428
2006-10-11 15:11 RyanR Note Added: 0013609
2006-10-12 06:07 ralfiii File Added: TimeTracking_ChangedFiles_105.zip
2006-10-12 06:11 ralfiii File Added: TimeTracking_patch_vs_105.patch
2006-10-12 06:14 ralfiii Note Added: 0013610
2014-10-24 22:33 vboctor Note Added: 0041648
2014-10-24 22:33 vboctor Status new => resolved
2014-10-24 22:33 vboctor Resolution open => won't fix
2014-10-24 22:33 vboctor Assigned To => vboctor
2014-11-05 01:53 atrol Status resolved => closed