Scripted Field to get percent complete based on estimates of subtasks

Alex Christensen Community Champion Sep 16, 2015

I'm trying to create a scripted field on a parent task that gives me a percentage of the work completed based on the Time Spent and Remaining Estimate fields of the sub-tasks associated with that parent tasks. For example:

  • Parent Task
    • Sub-Task 1
      • Logged: 2h
      • Remaining: 0h
    • Sub-Task 2
      • Logged: 2h
      • Remaining: 0h
    • Sub-Task 3
      • Logged: 1h
      • Remaining: 1h

The percentage of work completed in this case would be 83.3%. I want this number to appear on the parent task.

I've created a scripted field to calculate this, but I'm having issues pulling the information I want. Please note that I'm very new to coding in general, so I've built this by combining and toying with multiple examples I've found online. Here's what I have so far:

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.Issue
import org.apache.log4j.Category
import com.atlassian.jira.config.SubTaskManager

SubTaskManager subTaskManager = ComponentManager.getInstance().getSubTaskManager();
Collection subTasks = issue.getSubTasks()
Double timeSpentTotal = 0
Double remainingEstimate = 0


if (subTaskManager.subTasksEnabled && !subTasks.empty) {
    subTasks.each {
        timeSpentTotal += it.getTimeSpent()
		// used .getTimeSpent because issue.getTimeSpent() works to retrieve Logged hours, but doesn't seem to work for subtasks
        remainingEstimate += it.estimate 
		// used .estimate because issue.estimate works to retrieve the remaining estimate, but doesn't seem to work for subtasks
        }
    }
Double progress = ( timeSpentTotal / ( timeSpentTotal + remainingEstimate ) ) * 100
return progress

Whenever I preview this using Script Runner, I get these errors: [GenericEntity.get] "getTimeSpent" is not a field of Issue and [GenericEntity.get] "estimate" is not a field of Issue. How can I adjust my script to get what I'm looking for? Is there a better way to do this that isn't based on the above script?

Thanks in advance for your help!

2 answers

1 accepted

This widget could not be displayed.

Alex,

Try this:

import com.atlassian.jira.component.ComponentAccessor
  
def timeWorked = issue.getTimeSpent()
double progress = 0
if (timeWorked == null) timeWorked = 0
  
def timeEstimated = issue.getEstimate()
if (timeEstimated == null) timeEstimated = 0
  
def subTaskManager = ComponentAccessor.getSubTaskManager();
  
Collection subTasks = subTaskManager.getSubTaskObjects(issue)
  
if (subTaskManager.subTasksEnabled && !subTasks.empty) {
    subTasks.each {
        if (it.getTimeSpent() != null) {
            timeWorked += it.getTimeSpent()
        }
       if (it.getEstimate() != null) {
            timeEstimated += it.getEstimate()
        }
    }
}
  
progress = (timeWorked / (timeWorked + timeEstimated)) * 100
return progress.round(2)
Alex Christensen Community Champion Sep 17, 2015

Thanks for the help, Mark! This helped point me in the right direction. The value returned here is a Big Decimal, so I rounded the value to the nearest two decimal places - I needed a Double since I wanted to go with Jamie's other suggestion here of creating a custom template to display the value in an actual percentage, but store as a number so we can search on the value. Appreciate your help, Mark!

This widget could not be displayed.

Out of interest I pasted your code in SR in 4.1 and it shows me:

image2015-9-17 12:42:14.png

The issue is that you're using issue.getSubtasks(), which is deprecated and returns a list of GenericValues. You should use issue.getSubtaskObjects().

My other suggestion would be to use a custom template that truncates the value to 1dp and shows the % sign, but would index the value as a number, which would allow you to search on this calculated value.

 

Alex Christensen Community Champion Sep 17, 2015

Thanks, Jamie. That helped. I took your suggestion and created a custom template, as well. Appreciate it!

How do you actually make that custom template?  I am still learning about that.

Alex Christensen Community Champion Oct 17, 2016

Hi, Therese - when editing the custom field script, you can choose a template. Choose "Custom" from the list of options.

template.PNG

Here's the template I ended up using for this scripted field:

#if($value == 0)
    <div><strong>[<span style="color:green;font-weight:bolder"></span></strong>>>>>>>>>>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value > 0 && $value <= 10)
    <div><strong>[<span style="color:green;font-weight:bolder">></span></strong>>>>>>>>>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value > 10 && $value <= 20)
    <div><strong>[<span style="color:green;font-weight:bolder">>></span></strong>>>>>>>>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value > 20 && $value <= 30)
    <div><strong>[<span style="color:green;font-weight:bolder">>>></span></strong>>>>>>>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value > 30 && $value <= 40)
    <div><strong>[<span style="color:green;font-weight:bolder">>>>></span></strong>>>>>>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value > 40 && $value <= 50)
    <div><strong>[<span style="color:green;font-weight:bolder">>>>>></span></strong>>>>>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value > 50 && $value <= 60)
    <div><strong>[<span style="color:green;font-weight:bolder">>>>>></span></strong>>>>>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value > 60 && $value <= 70)
    <div><strong>[<span style="color:green;font-weight:bolder">>>>>>></span></strong>>>>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value > 70 && $value <= 80)
    <div><strong>[<span style="color:green;font-weight:bolder">>>>>>>></span></strong>>>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value > 80 && $value <= 90)
    <div><strong>[<span style="color:green;font-weight:bolder">>>>>>>>></span></strong>>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value > 90 && $value < 100)
    <div><strong>[<span style="color:green;font-weight:bolder">>>>>>>>>></span></strong>><strong>]</strong> $numberTool.format('integer',$value)%</div>
#elseif($value == 100)
    <div><strong>[<span style="color:green;font-weight:bolder">>>>>>>>>>></span></strong><strong>]</strong> $numberTool.format('integer',$value)%</div>
#else
    <div></div>
#end

Suggest an answer

Log in or Sign up to answer
Atlassian Summit 2018

Meet the community IRL

Atlassian Summit is an excellent opportunity for in-person support, training, and networking.

Learn more
Community showcase
Posted Wednesday in New to Jira

Are you planning to trial, or are currently trialling Jira Software? - We want to talk to you!

Hello! I'm Rayen, a product manager at Atlassian. My team and I are working hard to improve the trial experience for Jira Software Cloud. We are interested in   talking to 20 people planning t...

143 views 2 0
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you