Scriptrunner Listener: The logs show an update, but the field does not show the value

Alexander B. December 13, 2022

Hi all,

are you able to help me?

I have written a script for a listener. It is supposed to update a custom-field of an epic with the values from the linked stories.

The log shows me that the value has been calculated and updated:
... WARN [runner.ScriptBindingsManager]: setCustomFieldValue called with updateField: ABC, total: 468
... WARN [runner.ScriptBindingsManager]: Updating custom field with id customfield_123 for issue 456

But when I call Epic with the field and update it, the value is not displayed. What is going wrong?

Cheers,

Alexander

1 answer

1 accepted

1 vote
Answer accepted
Fabio Racobaldo _Herzum_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
December 13, 2022

Hi @Alexander B_ ,

please could you share your code?

Fabio

Alexander B. December 13, 2022

Sure. Here it is:


import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.link.IssueLink

// the ID of the custom field to sum
final sumFieldId = 10002

// the ID of the custom field to update
final updateFieldId = 14304

def customFieldManager = ComponentAccessor.getCustomFieldManager()
def sumField = customFieldManager.getCustomFieldObject(sumFieldId)
//def updateField = customFieldManager.getCustomFieldObjectByName("Fieldname")

// Use getCustomFieldObjectsByName() to get a list of all custom fields with the specified name
def customFields = customFieldManager.getCustomFieldObjectsByName("Fieldname")

// Use the find method to get the custom field with the specified name and ID
// def updateField = customFields.find { it.name == "Fieldname" && it.id == updateFieldId }
def updateField = customFieldManager.getCustomFieldObject(updateFieldId)

def issueEvent = event as IssueEvent
def issue = issueEvent.issue as MutableIssue

// Use getCustomFieldObjectsByName() to get a list of all custom fields with the specified name
def epicLinkFields = customFieldManager.getCustomFieldObjectsByName("Epic Link")
// If there are any custom fields with the specified name, use the first one
def epicLinkField = epicLinkFields?.find { it.name == "Epic Link" }
// Get the value of the Epic Link custom field
def epicLink = issue.getCustomFieldValue(epicLinkField)

// If the issue has an epic linked to it, use that as the target issue.
// Otherwise, use the current issue as the target.
def targetIssue = epicLink ?: issue

def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(targetIssue.getId())

def total = 0
for (l in links) {
  // Add a typecast to specify that l is of type IssueLink
  def linkedIssue = (l as IssueLink).getDestinationObject()
  def value = linkedIssue.getCustomFieldValue(sumField)
  if (value) {
    total += value as Integer
  }
}

// Set the value of custom field 14304 to the calculated total
def issueManager = ComponentAccessor.getIssueManager()
def mutableTargetIssue = issueManager.getIssueObject(targetIssue.getId())

if (epicLinkField && updateField) {
  mutableTargetIssue.setCustomFieldValue(updateField, total.toDouble())
}
Fabio Racobaldo _Herzum_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
December 13, 2022

Hey @Alexander B_ ,

after setting custom field value you need to perform an updateIssue using the following api https://docs.atlassian.com/software/jira/docs/api/8.0.1/index.html?com/atlassian/jira/issue/IssueManager.html

updateIssue

Issue updateIssue(ApplicationUser user,
                  MutableIssue issue,
                  EventDispatchOption eventDispatchOption,
                  boolean sendMail)
This method will store the provided issue to the JIRA datastore.

The issue will be saved and re-indexed unless EventDispatchOption.DO_NOT_DISPATCH is specified. This method performs no permission checks.

This method should be used if you want to exert more control over what happens when JIRA updates an issue. This method will allow you to specify if an event is dispatched and if so which event is dispatched, see EventDispatchOption. This method also allows you to specify if email notifications should be send to notify users of the update.

Parameters:
user - who is performing the operation
issue - the issue to update
eventDispatchOption - specifies if an event should be sent and if so which should be sent.
sendMail - if true mail notifications will be sent, otherwise mail notifications will be suppressed.
Returns:
the updated issue.
Alexander B. December 13, 2022

Thank you, it works now. I've added this to the script:

 

// Update the issue after setting its custom field value
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def eventDispatchOption = EventDispatchOption.ISSUE_UPDATED
def sendMail = false
issueManager.updateIssue(user, mutableTargetIssue, eventDispatchOption, sendMail)
Fabio Racobaldo _Herzum_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
December 13, 2022

you're welcome @Alexander B_ .

It is a common error ;)

Like Alexander B. likes this
Alexander B. December 13, 2022

But maybe you can still help me. I have deleted a few test tickets and would have expected the value to be reduced accordingly. What is here missing?

The value has remained the same.

Alexander B. December 13, 2022

Ok. It is because of the deletion. It creates a nullpointer.

Fabio Racobaldo _Herzum_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
December 13, 2022

did u solve?

Alexander B. December 13, 2022

I am still guessing around :-)

Fabio Racobaldo _Herzum_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
December 13, 2022

Issue Deleted is a different event from Issue Updated

Alexander B. December 13, 2022

I've added this but it won't work:

import com.atlassian.jira.event.type.EventType;

(plus)

if (issueEvent.getEventTypeId() == EventType.ISSUE_DELETED_ID) {
  // Subtract the value of the custom field from the total
  def value = issue.getCustomFieldValue(sumField)
  if (value) {
    total -= value as Integer
  }
}
2022-12-13 12:36:40,926 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: null java.lang.NullPointerException: Cannot invoke method setCustomFieldValue() on null object at com.atlassian.jira.issue.MutableIssue$setCustomFieldValue.call(Unknown Source) at Script194.run(Script194.groovy:70)
Fabio Racobaldo _Herzum_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
December 13, 2022

@Alexander B_ you cannot update a custom field on a deleted issue.

Suggest an answer

Log in or Sign up to answer