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:
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)
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.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sure, but what is the problem? It's not counting, or not saving total value to parent issue?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.