Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Value of Story Points field in Sub-task from Issue Create screen is not considered in Listener

Barys Harbacheuski January 25, 2021

I have a task to create a listener in ScriptRunner that sums up values in Story Points field in sub-tasks and pastes this sum into parent issue's SPs. It works fine on Issue Updated event: if I update SPs in a sub-task, sum is correct. However, it doesn't work when I create a new sub-task (no matter what type of event you choose): if I specify SPs in sub-task when I create a sub-task, this value is not added to sum of SPs of sub-tasks, eg:

Sub-task 1 has 1 SP, Sub-task 2 has 2 SP.
Sub-task 3 is created with 1 SP specified on issue create screen.
Expected result: parent issue has 4 SPs.
Actual result: parent issue has 3 SPs (Sub-task 3 SPs are ignored).

This is strange because event proceeded by listener is fired after the issue is created, so it should work fine in my understanding. I also tried to introduce workaround: on Create transition I added a postfunction which triggers another transition, and to this transition I added Issue Updated event (so it should trigger listener and sum SPs of sub-tasks) and postfunction to add label to sub-task to make sure transition has been triggered. As a result, label is added, but SPs of the sub-task specified on Issue Create screen are still not included in the sum. It seems that getSubTaskObjects() works only for sub-tasks that actually exist.

Does anyone know how to resolve the problem? My code is here:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption

// if value is 0, update to default value
public static <T> T getValueOrDefault(T value, T defaultValue) {
return value == 0 ? defaultValue : value;
}
def defaultValue = null

def issue = event.issue
if (issue.getIssueType().getName() == "Sub-task") {

final String fieldName = "Story Points"
// user that will make updates
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf = customFieldManager.getCustomFieldObjectsByName(fieldName)[0]
def issueManager = ComponentAccessor.getIssueManager()

Double sum = 0
def parentIssue = issue.getParentObject() as MutableIssue
def subTasks = parentIssue.getSubTaskObjects()
subTasks.each {
def cf_value = (Double) it.getCustomFieldValue(cf)
if (cf_value != null) {
sum += cf_value
}
}
parentIssue.setCustomFieldValue(cf, getValueOrDefault(sum, defaultValue))

issueManager.updateIssue(loggedInUser, parentIssue, EventDispatchOption.DO_NOT_DISPATCH, false)
}

 

1 answer

1 accepted

0 votes
Answer accepted
Barys Harbacheuski February 1, 2021

Hi everyone, I found myself how to do it by a workaround: if sub-task that I create has a value, then I put this value to initial sum variable and then add to it values of other sub-tasks.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.event.type.EventType
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.index.IssueIndexingService

public static <T> T setValueBaseOnEvent(T event, T sum, T issue, T cf) {
return event.getEventTypeId() == EventType.ISSUE_CREATED_ID ? getValueOrDefault(issue.getCustomFieldValue(cf), null, 0) : sum;
}

// if value is null, update to default value
public static <T> T getValueOrDefault(T value, T requiredValue, T defaultValue) {
return value == requiredValue ? defaultValue : value;
}

def issue = event.issue
if (issue.getIssueType().getName() == "Sub-task") {

// the name of the field to update
final String fieldName = "Story Points"
// user that will make updates
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf = customFieldManager.getCustomFieldObjectsByName(fieldName)[0]
def issueManager = ComponentAccessor.getIssueManager()

Double sum = 0
sum = setValueBaseOnEvent(event, sum, issue, cf)

def parentIssue = issue.getParentObject() as MutableIssue
def subTasks = parentIssue.getSubTaskObjects()
subTasks.each {
def cf_value = (Double) it.getCustomFieldValue(cf)
if (cf_value != null) {
sum += cf_value
}
}
parentIssue.setCustomFieldValue(cf, getValueOrDefault(sum, 0, null))
// important step - issue needs to be updated to save changes
issueManager.updateIssue(loggedInUser, parentIssue, EventDispatchOption.DO_NOT_DISPATCH, false)
// re-index issue
def indexManager = ComponentAccessor.getComponent(IssueIndexingService.class)
indexManager.reIndex(parentIssue)
}

Suggest an answer

Log in or Sign up to answer