Using Scriptrunner to sum sub-tasks story points to parent issue

Evgeniy
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.
January 18, 2021

I am trying to find a way to sum story points of sub-tasks into their parent issue. Some more info:

Issues (Stories, Tasks) have sub-tasks under them. I can add story points to appropriate fields of sub-tasks.

For example, we have an issue called "Large Story" and under it, there are two sub-tasks with 2 and 3 story points. The aim is that "Large Story" "Story Points" must be automatically set to 5 story points.

I found script for "ScriptRunner for Jira Cloud", which makes exactly what I need, but I didn't succeded in adapting it for Jira Server. 

Script for Cloud:

http://scriptrunner-docs.connect.adaptavist.com/jiracloud/script-listeners.html#_store_subtask_estimates_in_parent_issue_on_issue_events

This is what I made so far:

/*
* This listener must be set to fire on the issue updated event and the field specified
* to store the value must be on the issue screens
* "All right, title and interest in this code snippet shall remain the exclusive intellectual property of Adaptavist Group Ltd and its affiliates. Customers with a valid ScriptRunner
* license shall be granted a non-exclusive, non-transferable, freely revocable right to use this code snippet only within their own instance of Atlassian products. This licensing notice cannot be removed or
* amended and must be included in any circumstances where the code snippet is shared by You or a third party."
*/

if (!issue.issueType.subTask) {
return
}

// Retrieve all the subtasks of this issue's parent
def parentKey = issue.getParentObject().getKey()
def allSubtasks = get("/rest/api/2/search")
.queryString("jql", "parent=${parentKey}")
.queryString("fields", "parent,customfield_10106") // Update this line with the ID of the story points field for your instance.
.asObject(Map)
.body
.issues as List<Map>
logger.info("Total subtasks for ${parentKey}: ${allSubtasks.size()}")

// Sum the estimates
def estimate = allSubtasks.collect { Map subtask ->
subtask.fields.customfield_10106 ?: 0 // Update this line with the ID of the story points field for your instance.
}.sum()
logger.info("Summed estimate: ${estimate}")

// Get the field ids
def fields = get('/rest/api/2/field')
.asObject(List)
.body as List<Map>

// Note - The custom field specified here must be a number field as it returns a number type
def summedEstimateField = fields.find { it.name == "Story Points" }.id // Update this Line with the name of your Custom Number field that will store the value on your parent issue.

logger.info("Custom field ID to update: ${summedEstimateField}")

// Now update the parent issue
def result = put("/rest/api/2/issue/${parentKey}")
.header('Content-Type', 'application/json')
.body([
fields: [
(summedEstimateField): estimate
]
])
.asString()

// check that updating the parent issue worked
assert result.status >= 200 && result.status < 300

Can you help with updating it? 

Current error is:

2021-01-18 13:51:02,415 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2021-01-18 13:51:02,416 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: null
groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.get() is applicable for argument types: (String) values: [/rest/api/2/search]
Possible solutions: get(java.lang.String), getAt(java.lang.String), grep(), put(java.lang.String, java.lang.Object), grep(java.lang.Object), wait()
	at Script376.run(Script376.groovy:15) 

1 answer

1 accepted

5 votes
Answer accepted
Evgeniy
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.
January 18, 2021

Well, I solved my question by myself. 

This code makes what I looked for:

import com.atlassian.jira.issue.Issue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

//MutableIssue issue = ComponentAccessor.issueManager.getIssueByCurrentKey("TESTCASE-110") // used for debug

if (!issue.issueType.subTask) {
return
}

final String customFieldName = "Story Points"

Issue parentIssue = issue.getParentObject()
Collection<Issue> subtasks = parentIssue.getSubTaskObjects()
CustomField parentIssueStoryPoints = ComponentAccessor.customFieldManager.getCustomFieldObjects(parentIssue).findByName(customFieldName)
DefaultIssueChangeHolder changeHolder = new DefaultIssueChangeHolder()
CustomField subTaskStoryPoints
Integer storyPointsTotal = 0

subtasks.each { Issue subTask ->
subTaskStoryPoints = ComponentAccessor.customFieldManager.getCustomFieldObjects(subTask).findByName(customFieldName)
storyPointsTotal += subTaskStoryPoints ? subTask.getCustomFieldValue(subTaskStoryPoints) : 0
}

parentIssueStoryPoints.updateValue(null, parentIssue, new ModifiedValue(parentIssue.getCustomFieldValue(parentIssueStoryPoints), storyPointsTotal), changeHolder)

 UPD. Lite refactoring and fixes, because script worked only with first subtask.

Kristian Walker _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 18, 2021

Hi UdJin,

Thank you for sharing your completed solution.

Could I please ask you to link this answer to your original post on the cloud question so that users who look there can see this question shows a solution for Jira Server.

Regards,

Kristian

Evgeniy
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.
January 18, 2021

Sure. I added reply in topic about cloud version with link to this post. 

Ramashry Ramashry April 12, 2024

I tried using your script but it seems it is not working for me. have you update anything else inside your script for jira server?

Evgeniy
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.
April 12, 2024

Hi @Ramashry Ramashry 

Sure, but what is the problem? It's not counting, or not saving total value to parent issue?

Suggest an answer

Log in or Sign up to answer