Consulting | 5 MIN READ

Estimate Your Sub-tasks in Jira Agile!

Introduction

The question of whether a sprint can be planned using sub-task estimates is a controversial one, and one that Atlassian themselves have answered in their Answers page:

https://answers.atlassian.com/questions/84349/rapid-board-time-estimates-with-sub-tasks?page=1#84605.

Being able to plan and estimate sub-tasks is a desired feature, with over 400 votes (see https://jira.atlassian.com/browse/GHS-9167) for the feature request in Atlassian's own Jira instance. Many users/companies want their sub-task estimates to accumulate to the main story during sprint planning, and the way their companies/projects/groups are working is currently not provided by Agile boards in Jira. Out of the box, that is. With the help of some scripting it is possible to have sub-task estimates show up in plan mode in your scrum boards! You need to have the download version of Jira and have system administrator access to implement this yourself, or you need to get a hold of someone who does. 

Solution

Note: This solution is only applicable for the download version of Jira since it requires the Script Runner plugin which is not available for the Cloud/OnDemand version of Jira.
1. Do note that you must have System Administration access to do this.

2. This solution requires the free Script Runner plugin, you can download it hereUPDATE: The ScriptRunner plugin is no longer free from Jira 7 onward.

3. Go to Custom Fields (press g+g and then “custom fields”). Create a scripted field (under the advanced tab), call it something like “Compound Estimate”.

4. Still at Custom Fields, create another field, this time a number field. Call this “Total Remaining Estimate”.

5. Go to Script Fields under the add-on tab in the admin section (or press g+g and then write “Script Fields”), find the “Compound Estimate” field and click edit.
a. Change the Template option to “Number Field”.
b. Add the code snippet below in the “Inline Script” field.
Warning! If you named your numeric field something other than “Total Remaining Estimate” you must change that in the code snippet too!

 

import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.ModifiedValue;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder;
import com.atlassian.jira.util.ImportUtils;
import com.atlassian.jira.config.SubTaskManager;
def cfManager = ComponentAccessor.getCustomFieldManager();
def compoundsum = 0;
compoundsum += getRemainingEstimate(issue);
//compoundsum += getStoryPoints(issue);

SubTaskManager subTaskManager = ComponentAccessor.getSubTaskManager();
Collection subTasks = issue.getSubTaskObjects();

if (subTaskManager.subTasksEnabled && !subTasks.empty) {
subTasks.each {
compoundsum += getRemainingEstimate(it);
//compoundsum += getStoryPoints(it);
}
}
def compound = cfManager.getCustomFieldObjectByName("Total Remaining Estimate");
compound.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(compound), compoundsum), new DefaultIssueChangeHolder());
return compoundsum.toString();

//returns the remaining estimate (in hours) for an issue and returns 0 if there is none.
double getRemainingEstimate(Issue issue) {
double d = 0;
def rfValue = issue.getEstimate();
if(rfValue > 0){
def rfDouble = (double) rfValue;
d = rfDouble / 3600;
return d;
}else{
return 0;
}
}

//returns the story points for an issue, or 0 if it's not set.
double getStoryPoints(Issue issue) {
def cf = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Story Points");
def sp = issue.getCustomFieldValue(cf) ?: 0
return sp;
}

 

This code is for using time, as opposed to story points, for estimating your work. If you want to use story points instead, you need to modify the lines of code above. The following lines need to get uncommented (by removing the preceding forward-slashes '//'):

//compoundsum += getStoryPoints(it); --> compoundsum += getStoryPoints(it);
//compoundsum += getStoryPoints(issue); --> compoundsum += getStoryPoints(issue);
 

The lines above them must be commented as follows:

compoundsum += getRemainingEstimate(it); --> //compoundsum += getRemainingEstimate(it);
compoundsum += getRemainingEstimate(issue); --> //compoundsum += getRemainingEstimate(issue);

6. Configure your Scrum Board. Go to Estimation and change the field to your newly created numeric field. We called it Total Remaining Estimate, and it is named as such in the code snippet.

a. For nicer burndown charts you can select the “Remaining Estimate and Time Spent” option for Time Tracking in the same screen.

7. It is a good time to do some reindexing now so that all our values are updated and that the scripted field can recalculate and set the numeric field in all the relevant issues. For convenience, you can use this very simple add-on that will automatically reindex an issue after it has been updated. Download it here, and upload it manually under the Manage Add-Ons page (press g+g and then "Manage Add-Ons").

8. Now go back to your scrum board and start testing it out. If values sometimes seem to not get updated, reload your browser page, and you should see the correct data/numbers.

 

Results

Below you can see some results from an example scrum board.

issue with estimates

This first picture shows the estimates and what numbers you can expect. The number in the circle to the left is our new estimate (that we called "Total Remaining Estimate"), which normally only includes the main issue's remaining estimate. Do note that the "Remaining" and the "Estimate" numbers are the same, which is great! To the right in that image is the issue detail view.

example sprint planning

The marked issue has no remaining estimate. Only its two sub-tasks have been estimated. See the right hand side for the sums.

subtask burndown

This picture above is from the burndown chart, you can see that the sub-tasks are there and the remaining estimate will be the same as the numbers in the estimate during plan mode.

velocity chart

This is from the velocity chart; the y-axis is the Total Remaining Estimate, and the numbers include estimates from the sub-tasks.

 

If you want help setting this up or customize a similar solution, feel free to send an email to me or my colleagues and we will get you all set up!

Other blog posts by Sana:

Automate Asset Management in your Service Desk

Originally published Feb 13, 2015 8:54:24 AM

Topics: Consulting