I want to add a custom field to my epics which sums up the time spent logged across all of the epic child issues plus all of the time spent logged on the sub-issues of those epic child issues.
I figured out the first part (immediate children) but don't know how to extend this to include the sub-issues under the child issues as well.
Here's the script I have for just the immediate children:
// Get the field ids
def fields = get('/rest/api/2/field')
.asObject(List)
.body as List<Map>
// Get the Time Spent field to use in the script
def timespentField = fields.find { it.name == "Time Spent" }?.id
// Handle if the Time Spent Field does not exist
if (timespentField == null) {
logger.info("Time Spent field does not exist ");
return;
}
// Get all issues below the the Epic Issue
def allStories = get("/rest/agile/1.0/epic/${issue.key}/issue?maxResults=300")
// The JQL query to return all stories, modify this if you wish to return other issue types inside of the epic as well.
.queryString("jql", """'parent' =${issue.key}""")
.queryString("fields", "parent,$timespentField")
.asObject(Map)
.body
.issues as List<Map>
// Sum the Time Spent for all the Story issues returned
def estimate = allStories.collect { Map story ->
story.fields[timespentField] ?: 0
}.sum()
// return the estimate value if it is not null and return 0 if it has no value
return estimate ?: 0;
To extend the script to include the sub-issues under the child issues, you can use a recursive function to traverse the issue hierarchy. Below is an example script that should accomplish this:
import groovy.json.JsonSlurper
// Function to recursively get the time spent for an issue and its sub-issues
def getTimeSpent(issueKey) {
// Get the field ids
def fields = get('/rest/api/2/field').asObject(List).body as List<Map>
// Get the Time Spent field to use in the script
def timespentField = fields.find { it.name == "Time Spent" }?.id
// Handle if the Time Spent Field does not exist
if (timespentField == null) {
logger.info("Time Spent field does not exist ");
return 0;
}
// Get the issue details
def issueDetails = get("/rest/api/2/issue/${issueKey}?fields=parent,issuetype,subtasks,${timespentField}")
.asObject(Map)
.body
// Get the Time Spent for the current issue
def timeSpent = issueDetails.fields[timespentField] ?: 0
// Recursively get the Time Spent for all sub-issues
def subtaskTimeSpent = issueDetails.fields.subtasks.collect { subtask ->
getTimeSpent(subtask.key)
}.sum()
// Return the total Time Spent for the issue and its sub-issues
return timeSpent + subtaskTimeSpent
}
// Get the total Time Spent for the Epic and its sub-issues
def totalTimeSpent = getTimeSpent(issue.key)
// Return the total Time Spent
return totalTimeSpent ?: 0;
This script defines a getTimeSpent function that takes an issue key as a parameter, retrieves the issue details, calculates the time spent for the current issue, and then recursively calls itself for all sub-issues. The total time spent is the sum of the time spent for the current issue and its sub-issues.
Make sure to test this script thoroughly in a safe environment before applying it to your production instance. Additionally, keep in mind that fetching sub-tasks and their details may lead to performance considerations, especially for epics with a large number of sub-tasks. Adjust the maxResults parameter in the JQL query or consider implementing additional optimizations based on your specific use case.
Thank you.
Spend the day sharpening your skills in Atlassian Cloud Organization Admin or Jira Administration, then take the exam onsite. Already ready? Take one - or more - of 12 different certification exams while you’re in Anaheim at Team' 25.
Learn more
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.