Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Scripted field - get custom field aggrgate from linked issues

Christian Czaia _Decadis AG_
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.
May 2, 2013

Hey,

what I'm trying to do is this:

I have an issue with a number of epics linked to that issue. The epics use the Story Point field. Now I'd like to calculate the aggregated story points and show them in the main issue. Is this possible? I found example Codee from Jamie that seems to do kind of what I want...

import com.atlassian.jira.ComponentManager
 
def componentManager = ComponentManager.getInstance()
def issueLinkManager = componentManager.getIssueLinkManager()
 
def totalRemaining = 0
issueLinkManager.getOutwardLinks(issue.id).each {issueLink ->
    if (issueLink.issueLinkType.name == "Comprises") {
        def linkedIssue = issueLink.destinationObject
        totalRemaining += linkedIssue.getEstimate()
    }
}
return totalRemaining ? componentManager.getJiraDurationUtils().getFormattedDuration(totalRemaining) : null

Cheers Christian

8 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

1 vote
Answer accepted
Christian Czaia _Decadis AG_
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.
May 5, 2013
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.component.ComponentAccessor;

def componentManager = ComponentManager.getInstance()
def issueLinkManager = componentManager.getIssueLinkManager()
def cfManager = ComponentManager.getInstance().getCustomFieldManager()
double totalSP = 0


customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Story Points");
log.debug("${customField.id}")

issueLinkManager.getOutwardLinks(issue.id)?.each {issueLink ->
	if (issueLink.issueLinkType.name == "Logische Verbindung") {
        log.debug("Link of type ${issueLink.issueLinkType.name} from ${issueLink.sourceObject} to ${issueLink.destinationObject}")}
        log.debug("${issueLink.destinationObject.getCustomFieldValue(customField).toString()}")
        def SP = issueLink.destinationObject.getCustomFieldValue(customField) ?: 0
        totalSP += SP
	}
        
return totalSP

Jim Gould July 1, 2015

Hoping some body can help, I want to use the above script, but only sum as specific sub task like "BUILD". Any help would be much appreciated. Not sure how to make this Sub Task specific: issueLinkManager.getOutwardLinks(issue.id)?.each {issueLink -> if (issueLink.issueLinkType.name == "BUILD") { def SP = issueLink.destinationObject.getCustomFieldValue(customField) ?: 0 totalSP += SP } } return totalSP

Henning Tietgens
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.
July 1, 2015

If you are talking about all subtasks of issue type BUILD you can get them like this issue.subTaskObjects.findAll{it.statusObject.name == 'BUILD'}.each{ subtask -> def SP = subtask.getCustomFieldValue(customField) ?: 0 totalSP += SP }

Jim Gould July 2, 2015

Thank you for your answer. It did not quite work. I did not get a sum for the subset of subtasks defined. If I did this I got a sum of all the parents subtasks: issue.subTaskObjects.findAll{ subtask -> def SP = subtask.getCustomFieldValue(customField) ?: 0 totalSP += SP }

Jim Gould July 2, 2015

Still trying to figure out how to limit which type of subtasks I sum. Appreciate all your help. ~Thank you, Jim

Henning Tietgens
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.
July 2, 2015

Aah.. sorry, it's not statusObject (that's for the status...), it's issueTypeObject. So issue.subTaskObjects.findAll{it.issueTypeObject.name == 'BUILD'}.each{ subtask -> def SP = subtask.getCustomFieldValue(customField) ?: 0 totalSP += SP } should do the job.

Jim Gould July 6, 2015

Good Day Henning, That did not seem to work, any other suggestions are very appreciated. ~Thank you, Jim

Henning Tietgens
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.
July 6, 2015

Please provide the complete source of your script and what kind of error leads you to "did not seem to work". Is the custom field name correct? Is the issue type name correct? Are there any log file entries?

Jim Gould July 6, 2015

Hello Henning, This returns 0 although there are subtasks of type BUILD: import com.atlassian.jira.ComponentManager import com.atlassian.jira.issue.CustomFieldManager import com.atlassian.jira.component.ComponentAccessor; def componentManager = ComponentManager.getInstance() def issueLinkManager = componentManager.getIssueLinkManager() def cfManager = ComponentManager.getInstance().getCustomFieldManager() double totalSP = 0 customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Story Points"); issue.subTaskObjects.findAll{it.issueTypeObject.name == 'BUILD'}.each { subtask -> def SP = subtask.getCustomFieldValue(customField) ?: 0 totalSP += SP } return totalSP This returns 5, because it is summing all of the subtasks: import com.atlassian.jira.ComponentManager import com.atlassian.jira.issue.CustomFieldManager import com.atlassian.jira.component.ComponentAccessor; def componentManager = ComponentManager.getInstance() def issueLinkManager = componentManager.getIssueLinkManager() def cfManager = ComponentManager.getInstance().getCustomFieldManager() double totalSP = 0 customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Story Points"); issue.subTaskObjects.findAll { subtask -> def SP = subtask.getCustomFieldValue(customField) ?: 0 totalSP += SP } return totalSP Again, I appreciate your help.

Henning Tietgens
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.
July 6, 2015

Please try this and report back what subTasks it reports in the log. import com.atlassian.jira.component.ComponentAccessor def cfManager = ComponentAccessor.getCustomFieldManager() double totalSP = 0 def customField = cfManager.getCustomFieldObjectByName("Story Points") def subTasks = issue.subTaskObjects log.error "subTasks: ${subTasks.issueTypeObject.name}" subTasks.findAll{it.issueTypeObject.name == 'BUILD'}.each{ subtask -> def SP = subtask.getCustomFieldValue(customField) ?: 0 totalSP += SP } return totalSP

Jim Gould July 8, 2015

Hello Henning, I dont have access to the logs on the server. Is there anyway to push this information into a results field?

Henning Tietgens
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.
July 8, 2015

First, you should get access to the log files because this is a important resource of information if you are scripting your system... In the meantime try import com.atlassian.jira.component.ComponentAccessor def issue = ComponentAccessor.issueManager.getIssueObject('ABC-123') def subTasks = issue.subTaskObjects return "subTasks: ${subTasks.issueTypeObject.name}" within the Script Console after replacing ABC-123 with a meaningful issue key on your system.

Jim Gould July 8, 2015

That WORKED! Thank you, my stupid mistake as the IssueType was "Build" not "BUILD". I have two more conditions if you can help me with... #1 - add Story Points if the sub-task has not been resolved (check that the resolved date has a value) #2 - Validate that the Fixversion is a specific value Thank you Henning for all your help!

Henning Tietgens
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.
July 8, 2015

Hi James, glad it's working now. Should should take a look at the API documentation (https://developer.atlassian.com/static/) where you can get useful information about the possibilities. Regarding your conditions take a look at the Issue object (https://developer.atlassian.com/static/javadoc/jira/6.4.1/reference/com/atlassian/jira/issue/Issue.html). Here you see that you can get the resolution date via getResolutionDate(). In Groovy you can omit the "get" at the beginning and the () at end if the method don't has any arguments. So you can write if (!issue?.resolutionDate) { // the conditional code her } The question mark is to ensure that you don't get a NullPointerException. For the FixVersions the method is getFixVersions() and returns a collection of Version objects. If you have a Version (https://developer.atlassian.com/static/javadoc/jira/6.4.1/reference/com/atlassian/jira/project/version/Version.html), you can get its name through getName(). In Groovy you don't have to go though every returned version on its own, you can write if (issue?.fixVersions?.name?.contains('Your Version 1.2')) { // the conditional code her } issue?.fixVersions?.name returns a collection of names of the FixVersions of the issue. Have fun, Henning

Jim Gould July 13, 2015

This all worked great! I have been able to accomplish what I wanted and create some great real time dashboards for my leadership. I had another question =) What if I want to compare that the subtask DueDate is less than the release date of a particular FixVersion? I'm not sure how to return the Release Date for a specific FixVersion even if it is not the same as the subtask. Henning you have been a wealth of information, and I really appreciate all the help. ~Jim

JamieA
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.
July 13, 2015

It's kind of hard for other people to help on this question because it requires reading and understanding a long history. I recommend you create a new question, with just your new question.

Henning Tietgens
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.
July 13, 2015

Jamie is right, please create a new question.

Jim Gould July 14, 2015

Will do, thank you

0 votes
JamieA
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.
May 2, 2013

Your cf could also be null, and note that getCustomFieldValue will be null if not set, and if you add that you will get an npe. So use:

def SP = linkedIssue.getCustomFieldValue(cf) ?: 0

0 votes
Henning Tietgens
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.
May 2, 2013

For wich row is the NPE? First thing could be getOutwardLinks(), this should be secured wit a "?" before the dot (...getOutwardLinks(issue.id)?.each...).

0 votes
Christian Czaia _Decadis AG_
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.
May 2, 2013

That's what I have now resulting in a null pointer:

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager

def componentManager = ComponentManager.getInstance()
def issueLinkManager = componentManager.getIssueLinkManager()
def cfManager = ComponentManager.getInstance().getCustomFieldManager()

def totalSP = 0
issueLinkManager.getOutwardLinks(issue.id).each {issueLink ->
    if (issueLink.issueLinkType.name == "Logische Verbindung") {
        def linkedIssue = issueLink.destinationObject
        cf = cfManager.getCustomFieldObjects(issue).find {it.name == 'Story Points'}
        def SP = linkedIssue.getCustomFieldValue(cf)
        totalSP += SP
    }
}
return totalSP

0 votes
Henning Tietgens
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.
May 2, 2013

You have to get the customfield through the CustomfieldManager like this

cf = cfManager.getCustomFieldObjects(issue).find {it.name == 'Story Points'}

and use this for getCustomFieldValue().

Henning

0 votes
Christian Czaia _Decadis AG_
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.
May 2, 2013

Looks like this right now

import com.atlassian.jira.ComponentManager

def componentManager = ComponentManager.getInstance()
def issueLinkManager = componentManager.getIssueLinkManager()

def totalSP = 0
issueLinkManager.getOutwardLinks(issue.id).each {issueLink ->
if (issueLink.issueLinkType.name == "Logische Verbindung") {
def linkedIssue = issueLink.destinationObject
def SP = linkedIssue.getCustomFieldValue("customfield_10002")
totalSP += SP
}
}
return totalSP

0 votes
Christian Czaia _Decadis AG_
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.
May 2, 2013

Getting the custom field value. It's the customfield_10002

0 votes
JamieA
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.
May 2, 2013

So you just need to make some minor changes to sum the story point custom field, and remove the duration formatting... which bit are you stuck on?

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

TAGS
AUG Leaders

Atlassian Community Events