Hello,
I want the Story Points field for the parent story to be the sum of the sub-tasks. In my jira server instance we are using Script runner plugin and is it possible to sum up all sub task story points to parent issue story point. Please help me how to achieve this issue.
For example:
If parent issue had 2 story points and sub task had 1 story point and I need sum up both 2+1=3 on Parent.
Thanks,
Siva.
Hi @siva,
I changed the code as follows:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.index.IssueIndexingService
def issue = event.issue
def eventName = ComponentAccessor.eventTypeManager.getEventType(event.eventTypeId).name
def cfStoryPoints = ComponentAccessor.customFieldManager.getCustomFieldObjectsByName("Estimated Story Points").first()
if (issue.parentObject != null) {
def subTasks = ComponentAccessor.subTaskManager.getSubTaskObjects(issue.parentObject)
int intStoryPoints = (issue.parentObject.getCustomFieldValue(cfStoryPoints) != null ? ((issue.parentObject.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0) + (eventName == "Issue Created" ? (issue.getCustomFieldValue(cfStoryPoints) != null ? ((issue.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0) : 0)
/*subTasks.each {
intStoryPoints += (it.getCustomFieldValue(cfStoryPoints) != null ? ((it.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0)
}*/
cfStoryPoints.updateValue(null, issue.parentObject, new ModifiedValue(issue.parentObject.getCustomFieldValue(cfStoryPoints), intStoryPoints as Double), new DefaultIssueChangeHolder())
ComponentAccessor.getComponent(IssueIndexingService).reIndex(issue.parentObject)
} else {
def subTasks = ComponentAccessor.subTaskManager.getSubTaskObjects(issue)
int intStoryPoints = (issue.getCustomFieldValue(cfStoryPoints) != null ? ((issue.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0)
subTasks.each {
intStoryPoints += (it.getCustomFieldValue(cfStoryPoints) != null ? ((it.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0)
}
cfStoryPoints.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(cfStoryPoints), intStoryPoints as Double), new DefaultIssueChangeHolder())
ComponentAccessor.getComponent(IssueIndexingService).reIndex(issue)
}
Tested the above script this also performed like previous script calculates the all subtask story points again when 2nd subtask created.
Once again will explain it
I had created issue story and story point was 2 under story created subtask-1 and story point is 1. So far the script working fine it calculated 2+1=3.
Now this time created 2nd subtask-2 and story point is 2 now suppose to calculate parent + subtask-2 i.e 3+2=5. But our script calculates parent + subtask-1 +subtask-2 i.e 3+1+2=6
Thank,
Siva
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I've commented out a few lines in the code above; can you check if the behavior is what you expect?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you very much finally it start working as i expert and finally one more last modification in the script is it any possibility to update Estimated Story Points in parent when existing subtasks story points are updated and also when subtask is deleted. As of now the present script working fine when subtask is created and also I'm attaching the screen shot how I configure the script in listener. Once again thank you very much for your help and very appreciated.
Thanks,
Siva.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Please help me on this issue the whole team waiting for your response
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @siva,
from what you wrote in your last post, I thought the problem was completely solved.
Thank you very much for appreciating the help I have given you but I don't think I can devote myself further to this issue.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @siva,
replace this line:
int intStoryPoints = 0 + (eventName == "Issue Created" ? (issue.getCustomFieldValue(cfStoryPoints) != null ? ((issue.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0) : 0)
with the following:
int intStoryPoints = (issue.parentObject.getCustomFieldValue(cfStoryPoints) as Integer) + (eventName == "Issue Created" ? (issue.getCustomFieldValue(cfStoryPoints) != null ? ((issue.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0) : 0)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for the reply and changes done on the script what you mention in above comment and it start working now it calculates parent story points also. But coming to script it works perfectly only when single Sub Task and if parent had two subtasks it counts twice.
For example:
If we created Sub Task-1 and story point is 2 here it counts well (assume parent story point is 2) Parent+2=4
Now if we created another Sub Task-2 and story point is 2 and it suppose to count 4+2=6 but our script counts parent+ 'Sub Task-1'+ 'Sub Task-2' that is 4+2+2=8. It can't calculate individual Sub Task it counts the all Sub Task to parent when 2nd Sub Task is created. Here the modified script below.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.index.IssueIndexingService
def issue = event.issue
def eventName = ComponentAccessor.eventTypeManager.getEventType(event.eventTypeId).name
def cfStoryPoints = ComponentAccessor.customFieldManager.getCustomFieldObjectsByName("Estimated Story Points").first()
if (issue.parentObject != null) {
def subTasks = ComponentAccessor.subTaskManager.getSubTaskObjects(issue.parentObject)
int intStoryPoints = (issue.parentObject.getCustomFieldValue(cfStoryPoints) as Integer) + (eventName == "Issue Created" ? (issue.getCustomFieldValue(cfStoryPoints) != null ? ((issue.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0) : 0)
subTasks.each {
intStoryPoints += (it.getCustomFieldValue(cfStoryPoints) != null ? ((it.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0)
}
cfStoryPoints.updateValue(null, issue.parentObject, new ModifiedValue(issue.parentObject.getCustomFieldValue(cfStoryPoints), intStoryPoints as Double), new DefaultIssueChangeHolder())
ComponentAccessor.getComponent(IssueIndexingService).reIndex(event.issue)
}
Thanks,
Siva
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.
Hi @siva,
to solve your issue you could add a Script Listener to your project on Issue Created and Issue Updated events with the following code:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.index.IssueIndexingService
def issue = event.issue
def eventName = ComponentAccessor.eventTypeManager.getEventType(event.eventTypeId).name
def cfStoryPoints = ComponentAccessor.customFieldManager.getCustomFieldObjectsByName("Original Story points").first()
if (issue.parentObject != null) {
def subTasks = ComponentAccessor.subTaskManager.getSubTaskObjects(issue.parentObject)
int intStoryPoints = 0 + (eventName == "Issue Created" ? (issue.getCustomFieldValue(cfStoryPoints) != null ? ((issue.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0) : 0)
subTasks.each {
intStoryPoints += (it.getCustomFieldValue(cfStoryPoints) != null ? ((it.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0)
}
cfStoryPoints.updateValue(null, issue.parentObject, new ModifiedValue(issue.parentObject.getCustomFieldValue(cfStoryPoints), intStoryPoints as Double), new DefaultIssueChangeHolder())
ComponentAccessor.getComponent(IssueIndexingService).reIndex(event.issue)
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for your reply and I created Script Listener with Created and Issue Updated events with the following code:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.index.IssueIndexingService
def issue = event.issue
def eventName = ComponentAccessor.eventTypeManager.getEventType(event.eventTypeId).name
def cfStoryPoints = ComponentAccessor.customFieldManager.getCustomFieldObjectsByName("Estimated Story points").first()
if (issue.parentObject != null) {
def subTasks = ComponentAccessor.subTaskManager.getSubTaskObjects(issue.parentObject)
int intStoryPoints = 0 + (eventName == "Issue Created" ? (issue.getCustomFieldValue(cfStoryPoints) != null ? ((issue.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0) : 0)
subTasks.each {
intStoryPoints += (it.getCustomFieldValue(cfStoryPoints) != null ? ((it.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0)
}
cfStoryPoints.updateValue(null, issue.parentObject, new ModifiedValue(issue.parentObject.getCustomFieldValue(cfStoryPoints), intStoryPoints as Double), new DefaultIssueChangeHolder())
ComponentAccessor.getComponent(IssueIndexingService).reIndex(event.issue)
}
But I'm getting the error on implementing the script here the error logs below
2022-06-24 21:11:52,007 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2022-06-24 21:11:52,007 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: null
java.util.NoSuchElementException: Cannot access first() element from an empty List
at Script58.run(Script58.groovy:8)
Please suggest me where i modified the script and just letting you the field name you are using for story point is Estimated Story Points.
Thanks,
Siva
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @siva,
the issue could depends by the fact that the custom field name is "Estimated Story Points" but you writed "Estimated Story points" in the code. Upper and lower cases are importants.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for the reply and I updated "Estimated Story Points" field with correct lettering in the script and it is start working. But the present script sum up only Sub-Tasks Estimated Story Points and didn't calculate the Parent one.
For example:
If parent had 3 Estimated Story Points and Sub-Task-1 had 5 Story Points and Sub-Task-2 had 6 story points then normally calculates 3+5+6=14 story points but our present script calculates only Sub-Tasks 5+6=11 and this 11 updated on Parent "Estimated Story Points" where as 3 parent story point totally gone. Please help me where i modified the script and your help very appreciated. Here the script below
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.index.IssueIndexingService
def issue = event.issue
def eventName = ComponentAccessor.eventTypeManager.getEventType(event.eventTypeId).name
def cfStoryPoints = ComponentAccessor.customFieldManager.getCustomFieldObjectsByName("Estimated Story Points").first()
if (issue.parentObject != null) {
def subTasks = ComponentAccessor.subTaskManager.getSubTaskObjects(issue.parentObject)
int intStoryPoints = 0 + (eventName == "Issue Created" ? (issue.getCustomFieldValue(cfStoryPoints) != null ? ((issue.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0) : 0)
subTasks.each {
intStoryPoints += (it.getCustomFieldValue(cfStoryPoints) != null ? ((it.getCustomFieldValue(cfStoryPoints).toString() as Double) as Integer) : 0)
}
cfStoryPoints.updateValue(null, issue.parentObject, new ModifiedValue(issue.parentObject.getCustomFieldValue(cfStoryPoints), intStoryPoints as Double), new DefaultIssueChangeHolder())
ComponentAccessor.getComponent(IssueIndexingService).reIndex(event.issue)
}
Thanks,
Siva.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
How are you doing? I believe you are doing well. This is an old post, and you have resolved it, but I need your assistance. The current script sum up all all Estimated story points to the parent, and here is the script.
I had a scenario (which I did not know was a possibility) that we need to make an adjustment to the script.
There can be a possibility where sub-tasks are created with 0 story points (as they have not been sized yet) but the parent story has existing story points and this is being overwritten with a value of 0.
The change needs to evaluate the total of the sub-task's story points and if the value is 0 do not overwrite the value in the parent issue's story point field.
Thanks,
Siva.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Before you do this, it's important to understand if you are trying to use Jira to support an Agile way of working. If you are, then you don't want to be adding story points up to the parent.
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.