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 preceeding 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

46 Comments
  • almo
    Posted at 22:33h, 14 February Reply

    Nice, but I still can’t see my Total Remaining Estimate on my Sprint board

    • mpfuetze
      Posted at 10:02h, 16 February Reply

      Same for me, Using Jira 6.3.14 and got no “Total Remaining Estimate” on the Board Configuration Screen: Estimation.
      (did reindexing …)

      • Sana Safai
        Posted at 10:55h, 20 February Reply

        Hi, did you add Total Remaining Estimate as a number field? You should have two fields, one that is a scripted field, and one that is a number field.The number field should show up in that list.

  • Sana Safai
    Posted at 01:01h, 15 February Reply

    Hi almo, have you done reindexing? If you can’t get it to work, feel free to email me with some screenshots.

  • Lior
    Posted at 11:34h, 15 February Reply

    Hi,

    Doesn’t look to works for me.
    I’ve reindexed, but i still see ‘0’ for the parent while the sub-task does have the ‘original estimation’.

    Any ideas?

  • Sana Safai
    Posted at 09:55h, 16 February Reply

    Hi, just a general response if you have problems with the numbers showing: Sometimes you need to disable and enable the Script Runner plugin. If you still can’t make it work, feel free to get in touch!

  • Daniel Puyau
    Posted at 22:39h, 16 February Reply

    This has worked fantastically with only one caveat. On Parent tickets
    that already have a value in the “Original Estimate” field, it isn’t
    calculating the total of the sub tasks and said parent and updating the
    value as you can see in this screenshot. I did figure out that if you simply click within that Estimate field (that says “10” in the screenshot below) you can “Delete” the value (in this case the “10”) and then it will update the correct total. Only cumbersome if you have a lot of tickets in your Sprint/Backlog.

    Forgot to mention: we are on v6.3.10 running JIRA Agile 6.6.51

  • Sana Safai
    Posted at 10:32h, 17 February Reply

    Hi Daniel, did you install the add-on that was provided in the blog post? The reason for a slow update of that number is usually that you have to reindex the issue after you update the info. You can either just reload the page, or install the add-on, which should do some of the updating work for you.
    EDIT: If you still have problems, just send me an email and I can try to figure it out with you.

    • Daniel Puyau
      Posted at 18:17h, 17 February Reply

      Ahhhh. I did not. I will do that now. Thank you Sana! This truly is awesome!

    • Daniel Puyau
      Posted at 22:24h, 17 February Reply

      I have now installed the plugin and performed a reindex. But there still seems to be a delay to the update. To level expectations, if I add a sub task to a ticket with a 10hr Original Estimate, how quickly should the new total be reflected in my Plan View of Agile? Right now it seems to auto-update the values in the Estimate / Remaining fields noted in my screenshot below, but the value inside the grey oval (where the red arrow begins in my screenshot) is not updating. I have refreshed the page a number of times over a period of 15min and it still doesn’t seem to have updated.

      • Sana Safai
        Posted at 23:38h, 17 February Reply

        Hi Daniel,
        It shouldn’t take that long, please email me and I will help you out. It could be reindexing problems or something wrong with the script or the plugins.

  • lilou__b
    Posted at 12:29h, 25 February Reply

    Hi Sana

    can i clarify, does your code allow you to run concurrently issues types estimated in time (i have created one called ‘spike’ which contains subtasks) and issue types estimated in points (stories) or one has to choose between the two?

    i would have both kinds in a sprint, and i want to ensure velocity is calculated in points (estimation=story points), but having ticked “Remaining Estimate and Time Spent” i can still use the burndown to track time. or in other words, i am only interested in your ‘fix’ in so far as it allows ‘spikes’ to have ‘total remaining estimate’ in the grey circle, and lets stories have points in the grey circle.

    • Sana Safai
      Posted at 14:43h, 26 February Reply

      Hi Lilou__b,
      It is possible to do so but you need to modify the code a little bit. If you want to check whether the issuetype is a story you can use the following: if(issue.issueTypeObject.name == “Story”)
      Based on your result you can use story points or remaining estimate for the “compoundsum”-number which is what is used for the Total Remaining Estimate. If you want further help, feel free to email me.

      • lilou__b
        Posted at 13:10h, 27 February Reply

        Hi Sana, I would, but i can’t find your email address 🙂 I am not a dev, but trying to do a draft of the rewritten code for you to review

        • Sana Safai
          Posted at 13:13h, 27 February Reply

          In the very last line of the blog post there’s a link to my email address, just click it and send me an email and I will try to help you out 🙂

          • lilou__b
            Posted at 16:48h, 27 February

            thanks 🙂 email should be with you now

  • adaptavist
    Posted at 14:57h, 28 April Reply

    Hi there – thanks for blogging about ScriptRunner. ScriptRunner is now part of the Adaptavist portfolio – you can find out more here: http://www.adaptavist.com/w/announcing-scriptrunner-for-jira-standard-edition/

    • Sana Safai
      Posted at 16:47h, 25 June Reply

      ScriptRunner is one of the best plugins for Jira without a doubt, I love it to death and use it every day!

      • Alexey Zimarev
        Posted at 16:06h, 30 November Reply

        The only issue is that you wrote it’s “free” when now it is not

        • Sana Safai
          Posted at 19:21h, 01 December Reply

          It was free when I wrote it, I will update the post.

  • Linus
    Posted at 11:21h, 04 June Reply

    Thank you Sana, I guess the re-index plugin was the part I helped you with right? I’m glad if I could contribute. And I’m glad you have posted a code of how to get a scripted field to be selectable in the Estimate configuration of JIRA Agile. My version was to copy everything to the Business Value field which isn’t as nice. Thx.

    • Sana Safai
      Posted at 16:47h, 25 June Reply

      Hi Linus, thanks a million for the re-index plugin, you are correct it was your contribution 100%.
      I have not noticed any performance degradation, due to the indexing is taking place on one issue at a time. However, I have not tested this in a larger (200k+) instance either.

      • Linus
        Posted at 17:29h, 11 August Reply

        Sana, it doesn’t seem to refresh the values immediately if I add a sub-task with original estimate set. Have you seen that? I have to re-rank the issues or edit the parent issue for the re-index to occur. Seems like the parent doesn’t detect if I add sub-tasks to it.

  • Linus
    Posted at 15:46h, 26 June Reply

    Hi again
    I might have found a flaw with the solution. Since the Remaining Estimate is the field that is copied to the Estimate field it gets cracy in the Velocity Chart when ending a sprint if I log time. Logging time actually decrease remaining estimate and thus also the Estimate. It seems like JIRA Agile take the Estimate value of the sprint when I end it instead of using the Estimate used when starting the sprint.
    So for the Sprint report it show the original value (correct one) but the velocity says that my commitment is a lot lower. How should we overcome this obstacle??

    • Sana Safai
      Posted at 00:42h, 11 August Reply

      Hi Linus,
      Nice catch there. What you can do is use the Original Estimate instead of the remaining, and thus get the accurate velocity number. However, you will lose some flexibility elsewhere. It’s hard to find a perfect solution, but hopefully with some scripting we can get closer.

      • Linus
        Posted at 10:03h, 11 August Reply

        Ok so I guess replacinig issue.getEstimate() with issue.getOriginalEstimate() then?

  • Ti Nguyen
    Posted at 12:25h, 04 August Reply

    Thanks for the guide.
    Is it possible to show/transform the result of “Total Remaining Estimate” in weeks or days and not only just a number?

    • Sana Safai
      Posted at 00:43h, 11 August Reply

      Hi,
      Yes it is possible, please contact me for more information on how to do it and with more specifics.

      • KIVagant
        Posted at 19:02h, 17 November Reply

        Thank you, Sana, this is a great trick! You are really help me!

        Please, if you have time, add the hint for transforming hours to human-readable format like ‘1d 3h’ etc.

        • Sana Safai
          Posted at 20:42h, 17 November Reply

          Try intdiv and modulus… if you have 30 hours you can do:

          def hours = 30
          def hoursDay = 8

          def days = hours.intdiv( hoursDay ) (should give you 3)

          def remainingHours = hours % hoursDay (should give you 6)

          • KIVagant
            Posted at 21:18h, 17 November

            I already wrote a function, that can convert hours to readable string, but I don’t have any ideas, how to attach this format to Agile Backlog estimate column? If I make return “1h 30m” from script for “Compound Estimate” field, it will not used in backlog. (I attached the screen in mail)

          • Sana Safai
            Posted at 18:04h, 24 November

            This is a tip for everyone reading. Agile has a “Card Layout” section where you can add the scripted field and use it to display the human readable format. This way you can have both the estimation and the human readable format at the same time.

          • Abraham
            Posted at 09:50h, 26 September

            Hi
            Can you please post the function to display hours in human readable form.
            Script is working fine for me.

            I did change as follows:
            compoundsum = compoundsum / 8;
            def compound = cfManager.getCustomFieldObjectByName(“Total Remaining Estimate”);
            compound.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(compound), compoundsum), new DefaultIssueChangeHolder());
            return compoundsum.toString() + ” d”;

            When I look in card layout it wont show me “d” at the end.

  • Stewart
    Posted at 04:53h, 28 August Reply

    When estimating hours for a task instead of doing sub tasks like this we found it easier to split each task into areas (dev,test,design). We ended up creating an add-on to put different roles into the one task.

    https://marketplace.atlassian.com/plugins/com.adweb.estimations.estimationUpdate

    Seemed like an obvious change but maybe not.

  • Alex Cordero
    Posted at 12:46h, 31 August Reply

    Hi Sana, I’m trying this script in my board, for Story Points. The compound estimate is correctly calculated, but I can’t see a decrement in Burndown chart, until the entire story goes in “done” state and all the subtasks are in “done” state. I would like to see the story points burned out also by subtask completion. The configuration of the board Estimation is done by choosing the “Total Remaining Estimation” field and “None” as Time Tracking (since I don’t want to use time as a completion statistics).

    • Sana Safai
      Posted at 17:47h, 18 September Reply

      Hi Alex, sorry for the slow reply. The way the burndown works in Agile is that you can either burn the entire value or using the remaining estimate value and the time spent, which are both in hours. Unfortunately it does not seem possible to burn down the story points based on sub-tasks at the moment.

  • KIVagant
    Posted at 10:09h, 10 December Reply

    I recommend to add this condition in your script:

    if (it.statusObject.name != “Closed” && it.statusObject.name != “Resolved”) {
    // && it.statusObject.name != “Verified” && it.statusObject.name != “In Review”
    compoundsum += getRemainingEstimate(it);
    //compoundsum += getStoryPoints(it);
    }

  • Pedro Santos
    Posted at 13:46h, 13 January Reply

    This looks really interesting but maybe I’m missing something regarding the Story Points.
    JIRA doesn’t allow story points in subtasks, so what’s the point? is there any workaround for allowing it?

    • Sana Safai
      Posted at 15:21h, 14 January Reply

      Hi Pedro, you can modify that if you are a system administrator, so it should work once that has been done.

      • Pedro Santos
        Posted at 17:49h, 14 January Reply

        Hi Sana,
        I was able to add the field Story Points to subtask screen and thus make it available, but in Plan mode it’s still not possible. User always have to edit the issue. Was this what you meant?

        Thanks

        • Sana Safai
          Posted at 18:22h, 14 January Reply

          Hi, yes this was what I meant, this is the reason behind this blog post as well, the problem with the estimation being unavailable for sub-tasks.

  • Kumar
    Posted at 19:28h, 08 June Reply

    Hi
    I have added what is described in this page.

    Here are steps:
    – I created issue put no original estimate.
    – I created subtask and put original estimate (1 day). I did not see in the scrum board. I reindexed and it now showed up as 8.
    – I added another subtask to the same issue put original estimate (3 days), now I do not see it rolledup on scrum board even if I reindex.
    – I added the addon which indexes immediately as mentioned, assigned both tasks to myself, still it shows 8 on scrum board

    Any thoughts.
    Please let me know.

    Kumar

    • Deepali
      Posted at 15:16h, 12 August Reply

      I am trying to figure where to put in the estimate for a subtask, I don’t see the estimate field on my subtask window, could you please help?

  • Kumar
    Posted at 06:15h, 09 June Reply

    Hi Sana

    Found the issue why values in board are not updating.
    The scripted field only updates when there is a change in the parent issue, so I have added a comment on parent issue now it i calculating value properly from all its sub tasks.
    Need to figure out a way to update parent every time estimate is changed on subtask.

    Thanks

  • Aleksandr Valuev
    Posted at 07:46h, 16 June Reply

    Hi Sana,
    I’ve added special types of sub-tasks to my issue type template for JIRA Project:
    – Bussiness Analysis
    – QA
    – Dev
    – DevOps
    – Technical Writer

    And some of my tickets has a several sub-tasks of each type. And I want at least to sum estimation for overall QA sub-tasks and overall Dev sub-tasks inside one parent ticket.
    Could you help my to find a good receipt ?

    Many thanks!

  • Riada Admin
    Posted at 10:43h, 21 September Reply

    Dear visitors,
    The comment section for this blog post written in February 2015 is no longer monitored or answered. If you need expert help in this area, feel free to engage one of our experts by contacting sales@riada.se

    Best Regards
    Team Riada

Post A Comment