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.
Sure. I added reply in topic about cloud version with link to this post.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.