Scripted Field - Count All Issues in Epic with a status of X

This is my first shot at a scripted field and I have no clue where to start. An answer to the subject will go a long way in getting me where I'm trying to go.

Ultimately, I want to count all issues within an epic or all subtasks within an issue. Then I want to count all issues with a specific status - lets assume closed - and divide this by the total number of subtasks to get a rough % Complete.

6 answers

1 accepted

5 votes
Henning Tietgens Community Champion Nov 12, 2013

For Stories linked to the Epics try this:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.link.IssueLinkManager
import com.atlassian.jira.issue.link.IssueLinkType
import com.atlassian.jira.issue.link.IssueLinkTypeManager

Issue issue = issue

IssueLinkTypeManager issueLinkTypeManager = ComponentAccessor.getComponent(IssueLinkTypeManager)
IssueLinkManager issueLinkManager = ComponentAccessor.issueLinkManager
Collection<IssueLinkType> storyLinkTypes = issueLinkTypeManager.getIssueLinkTypesByName('Epic-Story Link')
if (storyLinkTypes) {
    Long storyLinkTypeId = storyLinkTypes[0].id
    def linkedStories = issueLinkManager.getOutwardLinks(issue.id).findAll{it.linkTypeId==storyLinkTypeId}*.destinationObject

    int numStories = linkedStories?.size()?:0
    if (numStories>0) {
        int numClosedStories = linkedStories?.count{it?.statusObject?.name=='Closed'}?:0
        return (numClosedStories/numStories) as Double
    } else {
        return 0 as Double
    }
} else {
    return 0 as Double
}

This is not tested by me, so you should try this in a test environment first.

The first part, getting the linkTypeId could be replaced by the id of the link type in your system if you don't want to use the script in different systems (test, live, etc.).

I just noticed some strange behavior. When I close or reopen an issue, the modal/transition window that pops up doesn't go away when clicking the button.

Any idea what might be causing this? I removed the scripted field to confirm it's the cause.

Rather than this, why dont you use the Epic Charts?

Unfortunately, I need to be able to report on this field.

Thanks for this goes out to Henning Tietgens.

I'm sure i've mangled his code, but here's what I ended up with.

Goal: calculate a % of Tasks Complete on the host issue by looking at sub-tasks in the case of stories/issues and stories within an epic in the case of Epics.

First I'm checking whether if the host issue is an Epic or not. If it is, use the linked stories approach to calculate the %Complete. Otherwise, use the sub-task approach:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.link.IssueLinkManager
import com.atlassian.jira.issue.link.IssueLinkType
import com.atlassian.jira.issue.link.IssueLinkTypeManager

Issue issue = issue
IssueLinkTypeManager issueLinkTypeManager = ComponentAccessor.getComponent(IssueLinkTypeManager)
IssueLinkManager issueLinkManager = ComponentAccessor.issueLinkManager
Collection<IssueLinkType> storyLinkTypes = issueLinkTypeManager.getIssueLinkTypesByName('Epic-Story Link')

if (issue.issueTypeObject.name == "Epic"){
    if (storyLinkTypes) {
        Long storyLinkTypeId = storyLinkTypes[0].id
        def linkedStories = issueLinkManager.getOutwardLinks(issue.id).findAll{it.linkTypeId==storyLinkTypeId}*.destinationObject
     
        double numStories = linkedStories?.size()?:0
        if (numStories>0) {
            double numClosedStories = linkedStories?.count{it?.statusObject?.name=='Closed'}?:0
            double percentcomplete = (numClosedStories/numStories)*100
            return percentcomplete.round(2) as double
        } else {
            return 0 as double
        }
    }
    
} else{
    double numSubtasks = issue.getSubTaskObjects()?.size()?:0
    if (numSubtasks>0) {
        double numClosedSubtasks = issue.getSubTaskObjects()?.count{it?.statusObject?.name=='Closed'}?:0
        double percentcomplete = (numClosedSubtasks/numSubtasks)*100
        return percentcomplete.round(2) as double
    } else {
        return 0 as double
    }
}

Henning Tietgens Community Champion Nov 12, 2013

Does this work? You return object of different classes: String, Double and int.

If you want to use the field for reports it should be a number field (so return a Double).

Henning Tietgens Community Champion Nov 12, 2013

Did you get any errors in the log?

Unfortunately, I have no access to the logs.

Current field config is:

Template: Number Field
Configured searcher: Number Searcher

It works, but I'll be happy to "fix" anything that's wrong. I did find that when I transition an issue to closed the modal just stays up when I have this scripted field enabled.

Henning Tietgens Community Champion Nov 12, 2013

What's the config of the custom field searcher and template for your scripted field?

Found the answer. I thought re-indexing might help so I ran one and got an error that referenced doubles. I just needed to ensure I set both sections to return doubles as you pointed out above.

0 vote
Henning Tietgens Community Champion Nov 11, 2013

For a Script Runner scripted field you can try this:

int numSubtasks = issue.getSubTaskObjects()?.size()?:0
if (numSubtasks>0) {
    int numClosedSubtasks = issue.getSubTaskObjects()?.count{it?.statusObject?.name=='Closed'}?:0
    return (numClosedSubtasks/numSubtasks) as Double
} else {
    return 0 as Double
}

Configure as nuber template and searcher.

Very close... it doesn't appear to work for epics and their sub issues.

Is the above script based on Groovy?

Henning Tietgens Community Champion Nov 12, 2013

Yes, it's groovy. Ok, so your talking about Stories linked to Epics, not subtasks?

You can also make an Issue Statistics gadget based on the JQL that uses Epic Link.

For example see https://jira.atlassian.com/issues/?jql=%22Epic%20Link%22%20%3D%20GHS-5232%20and%20status%20%3D%20Resolved

Thanks for the suggestion! This is an approach I use in dashboards and sometimes in Confluence pages. The problem I'm tasked with is providing a field that's reportable so it can be included on an excel export.

Ah alright. In that case the scripted field solution from Henning Tietgens is the best solution.

Unfortunately, no access to logs at the moment.

I made the changes you recommended:

Template: Number Field
Configured searcher: Number Searcher

Suggest an answer

Log in or Sign up to answer
Atlassian Community Anniversary

Happy Anniversary, Atlassian Community!

This community is celebrating its one-year anniversary and Atlassian co-founder Mike Cannon-Brookes has all the feels.

Read more
Community showcase
Julia Dillon
Posted Tuesday in Jira

Tell us how your team runs on Jira!

Hey Atlassian Community! Today we are launching a bunch of customer stories about the amazing work teams, like Dropbox and Twilio, are doing with Jira. You can check out the stories here. The thi...

207 views 1 18
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