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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.