Scripted field to sum story points of issues linked to an epic in closed status

Colleen Adams February 7, 2017

I am trying to create a scripted field that will sum the story points of issues linked to an epic that are in closed status.

JIRA version: 7.1.6 server

Scriptrunner version: 4.3.12

Searcher: Number searcher

Template: Number field

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.component.ComponentAccessor;
def componentManager = ComponentManager.getInstance()
def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def cfManager = ComponentAccessor.getCustomFieldManager()
double totalSP = 0
customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_12110");
enableCache = {-> false}

issueLinkManager.getOutwardLinks(issue.id)?.each {issueLink ->
if ((issueLink.issueLinkType.name == "Epic-Story Link" ) && (issue.getStatus() == "Closed")){
double SP = (double)(issueLink.destinationObject.getCustomFieldValue(customField) ?: 0)
totalSP = SP + totalSP;
}}
return totalSP

It is returning a result of 0. 

I am new to scripted fields and need help troubleshooting. Thanks!

2 answers

1 vote
Thanos Batagiannis _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 7, 2017

Hi Colleen,

I think what you miss (apart form the first import that does not exist) is the 

issue.getStatus() == "Closed"

it should be 

issue.getStatus().name == "Done" 
// or if you need the category and not just the name of the status
issue.getStatus().statusCategory.name == "Closed"

apart from that your script seems fine. And one more thing, I suppose the customfield_12110 is the Story Points, wouldn't be more clear If it was 

def customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Story Points")


regards, Thanos

Nina Zolotova May 23, 2019

@Thanos Batagiannis _Adaptavist_, thanks a lot for your help! 

This is a script, that worked for me (without conditions of particular issue status and link type)

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.component.ComponentAccessor;
def componentManager = ComponentManager.getInstance()
def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def cfManager = ComponentAccessor.getCustomFieldManager()
double totalSP = 0
customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Story Points");
enableCache = {-> false}

issueLinkManager.getOutwardLinks(issue.id)?.each {issueLink ->

double SP = (double)(issueLink.destinationObject.getCustomFieldValue(customField) ?: 0)
totalSP = SP + totalSP;
}
return totalSP
Like Chris_Fortuin likes this
Deleted user July 4, 2019

Hi @Thanos Batagiannis _Adaptavist_ , just wondering why using the suggested one still not able to recognize the EPIC link story status? it seem it is only recognize on the EPIC status only.

issue.getStatus().name == "Done" 
// or if you need the category and not just the name of the status
issue.getStatus().statusCategory.name == "Closed"
0 votes
Santhosh Kumar Arogyaswamy March 15, 2023

Please try this script:

This script helps in sum up all the Story Points from Story to EPIC 

import com.atlassian.jira.component.ComponentAccessor

import com.atlassian.jira.bc.issue.search.SearchService

import com.atlassian.jira.jql.parser.JqlQueryParser

import com.atlassian.jira.web.bean.PagerFilter

import com.atlassian.jira.issue.MutableIssue

import com.atlassian.jira.event.type.EventDispatchOption

def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)

def searchService = ComponentAccessor.getComponent(SearchService)

def issueManager = ComponentAccessor.getIssueManager()

def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

 

def issue = event.issue

if (issue.getIssueType().getName() == "Story"){

   

    log.warn(issue.getIssueType().getName())

    def epiclinkname = issue.getCustomFieldValue(ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Epic Link"))

    log.warn("Epiclinkname :" + epiclinkname)

    def jql = "'Epic Link' = $epiclinkname and issuetype = Story"

    log.warn(jql)

    // edit this query to suit

    def query = jqlQueryParser.parseQuery("'Epic Link' = $epiclinkname and issuetype = Story")

   

    def search = searchService.search(user, query, PagerFilter.getUnlimitedFilter())

   

    log.debug("Total Stories Linked Epic: ${search.total}")

    // Initialize the total story points to 0

    Double total_story_points = 0

    search.results.each { documentIssue ->

        log.debug(documentIssue.key)

   

        // if you need a mutable issue you can do:

        issue = issueManager.getIssueObject(documentIssue.id)

   

        // do something to the issue...

        log.debug(issue.summary)

        def story_points = issue.getCustomFieldValue(ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Story Points"))

        if (story_points != null ){

            total_story_points = total_story_points.toInteger() + story_points.toInteger()

            log.warn(story_points)

        }

    }

    log.warn("total_story_points : " + total_story_points)

    MutableIssue epicIssue = issueManager.getIssueObject(epiclinkname.key)

    def epicStoryPoint = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Story Points")

    log.warn("epicIssue:" + epicIssue.key.toString())

    //Update the Epic's "Total Story Points" custom field

    log.warn("EPIC Summary :" + epicIssue.summary)

    log.warn "Story Point value Before updated: " + epicStoryPoint.getValue(epicIssue).toString()

    epicIssue.setCustomFieldValue(epicStoryPoint, total_story_points)  

    issueManager.updateIssue(event.user, epicIssue, EventDispatchOption.ISSUE_UPDATED, false)

    log.warn "total_story_points_field value After updated: " + epicStoryPoint.getValue(epicIssue).toString()

}


Suggest an answer

Log in or Sign up to answer