Need help with setting up a listener, to verify a field values and update the missing field value

Sreedevi Raman Pisharody December 15, 2022

Hello Team,

We want to configure a listener to trigger during Issue create and Issue update on a set of jira projects, to fetch for the field values say a system field value (Fix Version/ Affects version) field and a Custom field (request number)

My requirement is to find a way to search for the Version field values and find the corresponding jira tickets which has request number field updated. In case Request number field is empty but Version field is not empty, it should check the version number field and its linked request number field value and update in the jira tickets with the appropriate request number wherever the same version number exists.

Please help me to figure out the logic for this without causing much load on the server. I tried with the keyset option to get from the jql search but it is not working.

2 answers

1 accepted

Suggest an answer

Log in or Sign up to answer
0 votes
Answer accepted
Peter-Dave Sheehan
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 16, 2022

Can you elaborate on your requirement by showing a concrete example?

Sreedevi Raman Pisharody December 19, 2022

Hello Peter,

I am trying to get  field values of a system field and one custom field on a jira project for story issue types, and wherever the custom field associated to the respective fix version is not present, I will be using listener to update the respective custom field.

For eg.

In Project ABC on ABC-1 jira issue we have 

Fix versions : 1.1

Request Number field : ABC1234

On other issue ABC-2 we have 

Fix Version : 1.1

however the Request number is Empty.

I am planning to use the update script in order to update the Request number field

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

// the name of the custom field to update
final customFieldName = 'Request Number'
// the new value of the field
//final newValue = 'I love Groovy !'

def customFieldManager = ComponentAccessor.customFieldManager
def issue = event.issue
def customField = customFieldManager.getCustomFieldObjects(issue).findByName(customFieldName)
//assert customField : "Could not find custom field with name $customFieldName"
customField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(customField), newValue), new DefaultIssueChangeHolder())

 

But what I am failing to get is the list of jira fix version values and the mapped Request number values to be fed to this update script.

 

If I am able to list the jira tickets with jql, to get the impacted issues, but not able to get the way to fed this needful list into the update script.

 

Please let me know if you want me to explain further.

 

Thanks and Regards,

Sreedevi

Peter-Dave Sheehan
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 19, 2022

I am still not clear on what the trigger for this listener will be.

Is it when the Request Number is added to ABC-1, you want to find all other issues with FixVersion = 1.1 and "Request Number" is empty and apply the same request number? to all issues that match the JQL?

Or is it that every time a new issues is created with FixVersion = 1.1, you want to go find the correct Request Number (either via JQL or some other storage method) and apply that Request Number to the just-newly-created issue?

If the latter, one option is to include that Request Number in the Description of the Release.

Also, generally, using customField.updateValue is the least recommended method to update a custom field. IssueService is generally preferred, but IssueManager is also acceptable.

IssueService has the advantage of not needing to manually trigger a re-index.

Here is a sample script to grab the Request Number from the version description:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.index.IssueIndexingService

def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser

// the name of the custom field to update
final customFieldName = 'Request Number'
// the new value of the field
//final newValue = 'I love Groovy !'

def customFieldManager = ComponentAccessor.customFieldManager
def issue = event.issue as MutableIssue
if(!issue.fixVersions) return //nothing to do if there is no fixVersion
def requestNumber
issue.fixVersions.find{version->
if(!version.description.contains("Request Number=")) return null //no request number in this version
def matcher = version.description =~ $/Request Number=((.*?)\s|(.*$))/$
if(!matcher) return null //pattern didn't return a match
requestNumber = matcher[0][1]
return true //stop looking at other versions, we found a match
}
if(!requestNumber) return null //nothing more to do if we didn't find a request number
def requestNumberCf = customFieldManager.getCustomFieldObjects(issue).findByName(customFieldName)

issue.setCustomFieldValue(requestNumberCf, requestNumber)
ComponentAccessor.issueManager.updateIssue(currentUser, issue, EventDispatchOption.DO_NOT_DISPATCH, false)
ComponentAccessor.getComponent(IssueIndexingService).reIndex(issue)
Sreedevi Raman Pisharody December 19, 2022

My listener would need to be triggered in both cases (i.e. at Issue creation and Issue updation)

Is it when the Request Number is added to ABC-1, you want to find all other issues with FixVersion = 1.1 and "Request Number" is empty and apply the same request number? to all issues that match the JQL? - Yes that what we are looking for, whenever a fix version field (say 1.1) is added to a ticket, may be at the time of creation or updation, we need to search for all the issue (i.e. story tickets) with same fix version and update the corresponding Request number which is available accordingly.

Whenever a user updates the fix version fields (it can be at the time of creation or updation) the listener should go and check if the Request number field is updated. In case it finds it to be empty it has to update, 

I will test out the script you have provided, will post the updates.

Also, generally, using customField.updateValue is the least recommended method to update a custom field. IssueService is generally preferred, but IssueManager is also acceptable. - What would be the recommended approach. - Thanks for this suggestion, we had been facing some challenges with IssueManager, so will try using IssueService.

Do let me know if you need any more information

Peter-Dave Sheehan
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 19, 2022

Here is another version of the script that might match your use case better... and it demonstrates the use of the issueService to update a single custom field.

import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.event.type.EventType
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.web.bean.PagerFilter

def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def searchService = ComponentAccessor.getComponent(SearchService)
def issueService = ComponentAccessor.issueService
def customFieldManager = ComponentAccessor.customFieldManager

// the name of the custom field to update
final customFieldName = 'Request Number'

def changeItems = ComponentAccessor.changeHistoryManager.getChangeHistoryById(event.changeLog.id as Long).changeItemBeans
if(event.eventTypeId == EventType.ISSUE_UPDATED_ID && changeItems.any{it.field == customFieldName}){
//don't run the listener if the user changed an unrelated field.
return null
}
def issue = event.issue as MutableIssue
if(!issue.fixVersions) return //nothing to do if there is no fixVersion
def requestNumberCf = customFieldManager.getCustomFieldObjects(issue).findByName(customFieldName)
def requestNumber = issue.getCustomFieldValue(requestNumberCf) as String
if(!requestNumber) return null //nothing more to do if we didn't find a request number

issue.fixVersions.each{version->
def jql = """project = $issue.projectObject.key and fixVersion = "$version.name" and "$customFieldName" IS EMPTY"""
def parseResult = searchService.parseQuery(currentUser, jql)
assert parseResult.valid, parseResult.errors
searchService.search(currentUser, parseResult.query, PagerFilter.unlimitedFilter).results.each{issueToUpdate->
def iip = issueService.newIssueInputParameters()
iip.setSkipScreenCheck(true)
iip.addCustomFieldValue(requestNumberCf.idAsLong, requestNumber)
def validateResult = issueService.validateUpdate(currentUser, issueToUpdate.id, iip)
if(!validateResult.valid){
log.error "Received a validation error when trying to apply $requestNumber to $issueToUpdate.key: $validateResult.errorCollection.errors"
return
}
def updateResult = issueService.update(currentUser,validateResult)
if(!updateResult.valid){
log.error "Received a update error when trying to apply $requestNumber to $issueToUpdate.key: $updateResult.errorCollection.errors"
return
}
log.info "Successfully added $requestNumber to $issueToUpdate.key"
}
}
Sreedevi Raman Pisharody December 19, 2022
2022-12-20 01:22:43,469 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2022-12-20 01:22:43,469 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: null
java.lang.NullPointerException: Cannot get property 'id' on null object
at Script716.run(Script716.groovy:18)
I get this above error when I run the listener with Events Issue created and Issue updated on the listeners.
Upon removing the Issue Created the error is gone, however the custom field is not getting updated
Are we missing something?
Peter-Dave Sheehan
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 19, 2022

Ah yes, I can fix the issue with the issueCreated event.

Also, let's put some more logging in the script:

import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.event.type.EventType
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.web.bean.PagerFilter

def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def searchService = ComponentAccessor.getComponent(SearchService)
def issueService = ComponentAccessor.issueService
def customFieldManager = ComponentAccessor.customFieldManager

// the name of the custom field to update
final customFieldName = 'Request Number'

if(event.eventTypeId == EventType.ISSUE_UPDATED_ID) {
def changeItems = ComponentAccessor.changeHistoryManager.getChangeHistoryById(event.changeLog.id as Long).changeItemBeans
if (!changeItems.any { it.field == customFieldName }) {
//don't run the listener if the user changed an unrelated field.
return null
}
}
def issue = event.issue as MutableIssue
if(!issue.fixVersions){
log.info "fixVersion field is empty for $issue.key. Listener will not try to make updates"
return null//nothing to do if there is no fixVersion
}
def requestNumberCf = customFieldManager.getCustomFieldObjects(issue).findByName(customFieldName)
def requestNumber = issue.getCustomFieldValue(requestNumberCf) as String
if(!requestNumber) {
log.info "Request Number field is empty for $issue.key. Listener will not try to make updates"
return null //nothing more to do if we didn't find a request number
}

issue.fixVersions.each{version->
def jql = """project = $issue.projectObject.key and fixVersion = "$version.name" and "$customFieldName" IS EMPTY"""
log.info "Looking for other issues to apply Request Number ($requestNumber) using JQL: $jql"
def parseResult = searchService.parseQuery(currentUser, jql)
if(! parseResult.valid) {
log.error "Error parsing JQL: $jql\n$parseResult.errors"
}
searchService.search(currentUser, parseResult.query, PagerFilter.unlimitedFilter).results.each{issueToUpdate->
def iip = issueService.newIssueInputParameters()
iip.setSkipScreenCheck(true)
iip.addCustomFieldValue(requestNumberCf.idAsLong, requestNumber)
def validateResult = issueService.validateUpdate(currentUser, issueToUpdate.id, iip)
if(!validateResult.valid){
log.error "Received a validation error when trying to apply $requestNumber to $issueToUpdate.key: $validateResult.errorCollection.errors"
return
}
def updateResult = issueService.update(currentUser,validateResult)
if(!updateResult.valid){
log.error "Received a update error when trying to apply $requestNumber to $issueToUpdate.key: $updateResult.errorCollection.errors"
return
}
log.info "Successfully added $requestNumber to $issueToUpdate.key"
}
}

Let me know what the logs show.

Sreedevi Raman Pisharody December 20, 2022

We tried out few tweaks on the script you provided and found that the script stops at this part, and is not moving forward, as the request number field is empty at the time of creation/updation.

if(event.eventTypeId == EventType.ISSUE_UPDATED_ID) {
def changeItems = ComponentAccessor.changeHistoryManager.getChangeHistoryById(event.changeLog.id as Long).changeItemBeans
if (!changeItems.any { it.field == customFieldName }) {
//don't run the listener if the user changed an unrelated field.
return null

 We commented this part of the code and tried out updating one jira ticket with request number field value and we could get the listener running to update the rest jira tickets with the request number value.

I am not sure if this approach is correct.  Please can you suggest.

Another quick question not related to the script, how much do you think would this listener put load on the system in case it is applied to multiple projects.

Peter-Dave Sheehan
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 20, 2022

If that section is commented out, and a user changes a random field on an issue, it will cause the rest of the script to run each time. 

Rather than just blindly commenting it out, I'd suggest we find out why it is blocking the script in your scenario.

if(event.eventTypeId == EventType.ISSUE_UPDATED_ID) {
def changeItems = ComponentAccessor.changeHistoryManager.getChangeHistoryById(event.changeLog.id as Long).changeItemBeans
log.info "Issue updated detected. Changed fields: ${changeItems*.field}"
if (!changeItems.any { it.field == customFieldName }) {
//don't run the listener if the user changed an unrelated field.
log.warn "$customFieldName was not found in the list of changed fields."
return null
}
}

Per your earlier explanation, I would expect that it is appropriate for the script to not make any changes if the Request Number is empty. But the first time a Request Number is added, then all other tickets with the same fixVersion will have the request number.

What might be missing is that when a new issue is created for that fixVersion, you want to find and add the correct Request Number.

So let's take this script to the next level... here is a much more elaborate version:

import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventType
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.project.version.Version
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.web.bean.PagerFilter
import groovy.transform.Field

// the name of the custom field to update
@Field String customFieldName = 'Request Number'

@Field ApplicationUser currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
@Field SearchService searchService = ComponentAccessor.getComponent(SearchService)
@Field CustomFieldManager customFieldManager = ComponentAccessor.customFieldManager
@Field CustomField requestNumberCf = customFieldManager.getCustomFieldObjectsByName(customFieldName)[0]

@Field Issue issue = event.issue as MutableIssue

if (!issue.fixVersions) {
log.info "fixVersion field is empty for $issue.key. Listener will not try to make updates"
return null//nothing to do if there is no fixVersion
}
if (event.eventTypeId == EventType.ISSUE_UPDATED_ID) {
def listOfFields = ['Fix Version', customFieldName]
def changeItems = ComponentAccessor.changeHistoryManager.getChangeHistoryById(event.changeLog.id as Long).changeItemBeans
log.info "Issue updated detected. Changed fields: ${changeItems*.field}"
if (!changeItems.any { it.field in listOfFields }) {
//don't run the listener if the user changed an unrelated field.
log.warn "$listOfFields were not found in the list of changed fields."
return null
}
}
//if we're still running, either this is an issue creation, or one of the fields we care about was changed

def
requestNumber = issue.getCustomFieldValue(requestNumberCf) as String
if (requestNumber) {
//a request number was found, see if there are other issues that need updated
issue.fixVersions.each { version ->
applyRequestNumberToFixVersion(version)
}
} else {
//request number is empty, try to find an issue with same fixVersion that has a request number and add it to the current issue
def version = issue.fixVersions.first()
log.info "Request Number field is empty for $issue.key. Look for other issues that have a Request Number for ${version.name}"
requestNumber = findRequestNumberByFixVersion(version)
if (requestNumber) {
addRequestNumberToIssue(requestNumber, issue)
}
}

/**
* Functions
*/
def applyRequestNumberToFixVersion(String requestNumber, Version version) {
def jql = """project = $issue.projectObject.key and fixVersion = "$version.name" and "$customFieldName" IS EMPTY"""
log.info "Looking for other issues to apply Request Number ($requestNumber) using JQL: $jql"
def parseResult = searchService.parseQuery(currentUser, jql)
if (!parseResult.valid) {
log.error "Error parsing JQL: $jql\n$parseResult.errors"
}
searchService.search(currentUser, parseResult.query, PagerFilter.unlimitedFilter).results.each { issueToUpdate ->
addRequestNumberToIssue(requestNumber, issueToUpdate as MutableIssue)
}
}

String findRequestNumberByFixVersion(Version version) {
def jql = """project = $issue.projectObject.key and fixVersion = "$version.name" and "$customFieldName" IS NOT EMPTY"""
log.info "Looking for issue Request Number for version ($version.name) using JQL: $jql"
def parseResult = searchService.parseQuery(currentUser, jql)
if (!parseResult.valid) {
log.error "Error parsing JQL: $jql\n$parseResult.errors"
}
if (searchService.searchCount(currentUser, parseResult.query) == 0) {
log.warn "Not issues found for this version ($version.name) with a Request Number already set"
return null
}
def issueWithRequestNumber = searchService.search(currentUser, parseResult.query, PagerFilter.unlimitedFilter).results.first()
return issueWithRequestNumber.getCustomFieldValue(requestNumberCf)
}

def addRequestNumberToIssue(String requestNumber, MutableIssue issueToUpdate) {
def issueService = ComponentAccessor.issueService
def iip = issueService.newIssueInputParameters()
iip.setSkipScreenCheck(true)
iip.addCustomFieldValue(requestNumberCf.idAsLong, requestNumber)
def validateResult = issueService.validateUpdate(currentUser, issueToUpdate.id, iip)
if (!validateResult.valid) {
log.error "Received a validation error when trying to apply $requestNumber to $issueToUpdate.key: $validateResult.errorCollection.errors"
return
}
def updateResult = issueService.update(currentUser, validateResult)
if (!updateResult.valid) {
log.error "Received a update error when trying to apply $requestNumber to $issueToUpdate.key: $updateResult.errorCollection.errors"
return
}
log.info "Successfully added $requestNumber to $issueToUpdate.key"
}

I extracted 3 functions/methods to make the main logic easier to parse.

Sreedevi Raman Pisharody December 20, 2022

Thanks Peter, yes I agree with you, just commenting out the part does not make Sense at all, however, my intention was to check if the rest part works with the updation when fix version and request numbers are updated on one ticket the listener triggers and updates others. It was good to see it was working.

From your explanation I understood what that part of the script does.

I will try out the revised part of the script you shared and will share the results with you.

Thank you so much for your quick response.

I am unable to add new reply so editing the error message here :-

We are getting Static type Checking error at 

applyRequestNumberToFixVersion(version) and 

addRequestNumberToIssue(requestNumber,issue)

We have rectified first one to 

applyRequestNumberToFixVersion(requestNumber,version) to eliminate the error by adding requestNumber 

But for the second part I am still facing below error:-

[Static type checking] - Cannot find matching method script1671600540267169314373#addRequestNumberToIssue(java.lang.String, com.atlassian.jira.issue.Issue). Please check if the declared type is correct and if the method exists.

Please help

Sreedevi Raman Pisharody December 20, 2022

There is a static type check error at two places 

applyRequestNumberToFixVersion(version) and 
addRequestNumberToIssue(requestNumber, issue)
[Static type checking] - Cannot find matching method script1671598388514665884511#applyRequestNumberToFixVersion(com.atlassian.jira.project.version.Version). Please check if the declared type is correct and if the method exists.
Upon checking this I see that, you have defined function as 
def applyRequestNumberToFixVersion(String requestNumber, Version version
so I added [Static type checking] - Cannot find matching method script1671598388514665884511#addRequestNumberToIssue(java.lang.String, com.atlassian.jira.issue.Issue). Please check if the declared type is correct and if the method exists. I was able to clear one error.
But the second one on addRequestNumberToIssue(requestNumber,issue) is showing error 
[Static type checking] - Cannot find matching method script1671598388514665884511#addRequestNumberToIssue(java.lang.String, com.atlassian.jira.issue.Issue). Please check if the declared type is correct and if the method exists.
Please can you check  and let me know what would be needed to rectify this errors
Sreedevi Raman Pisharody December 20, 2022

We are getting Static type checking error 

applyRequestNumberToFixVersion(version) and 
addRequestNumberToIssue(requestNumber,issue)
The first one we fixed by adding requestNumber
applyRequestNumberToFixVersion(requestNumber,version), however for the second one we are not able to removed the error
Error message is as below:
Static type checking] - Cannot find matching method script1671600540267169314373#addRequestNumberToIssue(java.lang.String, com.atlassian.jira.issue.Issue). Please check if the declared type is correct and if the method exists.
Please can you help to clear this error
Sreedevi Raman Pisharody December 20, 2022

We are getting Static type Checking error at 

applyRequestNumberToFixVersion(version) and 

addRequestNumberToIssue(requestNumber,issue)

We have rectified first one to 

applyRequestNumberToFixVersion(requestNumber,version) to eliminate the error by adding requestNumber 

But for the second part I am still facing below error:-

[Static type checking] - Cannot find matching method script1671600540267169314373#addRequestNumberToIssue(java.lang.String, com.atlassian.jira.issue.Issue). Please check if the declared type is correct and if the method exists.

Please help

Ramesh Penuballi December 20, 2022

I was also looking for similar feature, and was trying to used the piece of code you shared, but i am getting static type checking error on the 

addRequestNumberToIssue(requestNumber,issue)
[Static type checking] - Cannot find matching method script16716003104501919945368#addRequestNumberToIssue(java.lang.String, com.atlassian.jira.issue.Issue). Please check if the declared type is correct and if the method exists.
Can you please help
Sreedevi Raman Pisharody December 20, 2022

Some error coming for me as well.

getting Static type Checking error at 

applyRequestNumberToFixVersion(version) and 

addRequestNumberToIssue(requestNumber,issue)

We have rectified first one to 

applyRequestNumberToFixVersion(requestNumber,version) to eliminate the error by adding requestNumber 

But for the second part I am still facing below error:-

[Static type checking] - Cannot find matching method script1671600540267169314373#addRequestNumberToIssue(java.lang.String, com.atlassian.jira.issue.Issue). Please check if the declared type is correct and if the method exists.

Please help

Ramesh Penuballi December 20, 2022

I am getting error at addRequestNumberToIssue(requestNumber,issue)

[Static type checking] - Cannot find matching method script16716018762472120706490#addRequestNumberToIssue(java.lang.String, com.atlassian.jira.issue.Issue). Please check if the declared type is correct and if the method exists.

Please suggest....

Ramesh Penuballi December 20, 2022

I am getting the error at 

addRequestNumberToIssue(requestNumber, issue)
Static type checking] - Cannot find matching method script16716021695021998056224#addRequestNumberToIssue(java.lang.String, com.atlassian.jira.issue.Issue). Please check if the declared type is correct and if the method exists.
Please suggest.
Sreedevi Raman Pisharody December 21, 2022

This works, thank you so much for your help.

0 votes
Ramesh Penuballi December 20, 2022

Trying to set the request number field to null if there is any update on the fix versions field and used the below code..

 

if (event.eventTypeId == EventType.ISSUE_UPDATED_ID) {

    def listOfFields = ['Fix Version', customFieldName]

    def changeItems = ComponentAccessor.changeHistoryManager.getChangeHistoryById(event.changeLog.id as Long).changeItemBeans

 

    log.info "Issue updated detected. Changed fields: ${changeItems*.field}"

    log.warn "Issue updated detected. Changed fields: ${changeItems*.field}"

 

    if (!changeItems.any { it.field in listOfFields }) {

        //don't run the listener if the user changed an unrelated field.

        log.warn "$listOfFields were not found in the list of changed fields."

        return null

    }

  

    if ( changeItems.any { it.field == ‘Fix Version’ }).

    {

        issue.setCustomFieldValue(customField, null)

          customField.updateValue(null, issue, new ModifiedValue(customFieldValue, null), new DefaultIssueChangeHolder())

    }

}

 

Tried both customField.updateValu and issue.setCustomfield methods, but getting the syntax errors.

Please help.....

 

Ramesh Penuballi January 5, 2023

Hello Peter,

Thanks for quick response to my queries.

I could solved  the syntax errors and now the script is running fine as expected.

In my case I have to check two more scenarios where in when fix version is updated and the custom field (flagged) which is of single select type and when it is set to "Yes" then the request number shouldn't updated even if there is change in fix version else the request number should be cleared.

I could achieve the 2nd part of above requirement by adding the if condition as below.

 

if (changeItems.any {it.field == 'Fix Version'})
{
requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName, null), new DefaultIssueChangeHolder())
}

I tried to update a condition to check where fix versions is updated and the flagged field value is set to "Yes" where is my script shouldn't make any changes in the request number field.However this logic seems to break the other conditions.

Could you please advice how I could handle this scenario.The part of the code where I made  changes to the above script shared by you is as below.

 

@field String flagged = 'flagged'
@field CustomField flaggedCf = customFieldManager.getCustomFieldObjectsByName(flagged)[0]
def flaggedCfval = issue.getCustomFieldValue(flaggedCf)
if (event.eventTypeId == EventType.ISSUE_UPDATED_ID) {
def listOfFields = ['Fix Version', customFieldName,flagged]
def changeItems = ComponentAccessor.changeHistoryManager.getChangeHistoryById(event.changeLog.id as Long).changeItemBeans
log.info "Issue updated detected. Changed fields: ${changeItems*.field}"
if (!changeItems.any { it.field in listOfFields }) {
//don't run the listener if the user changed an unrelated field.
log.warn "$listOfFields were not found in the list of changed fields."
return null
}

if ((changeItems.any {it.field == 'Fix Version'}) && ("$flaggedCfval" == 'Yes')) 

{

                log.warn "Automated field set to Yes and $customFieldName and $flaggedCfval"

                 //requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName,customFieldName), new DefaultIssueChangeHolder())

                 return "$customFieldName"

        }


if (changeItems.any {it.field == 'Fix Version'})
{
requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName, null), new DefaultIssueChangeHolder())
}

}

 

Thanks,

Ramesh  

Ramesh Penuballi January 5, 2023

I tried  adding if else conditions at two places below but  it works only for one case and fails for other.

Can you please help rectify this issue.

 

if (!issue.fixVersions)
{
log.info "fixVersion field is empty for $issue.key. Listener will not try to make updates"
requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName, null), new DefaultIssueChangeHolder())
return null //nothing to do if there is no fixVersion
}
if ((!issue.fixVersions) && ("$flaggedCfval" == 'Yes'))
{
 def val1 = issue.getCustomFieldValue(requestNumberCf)
requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName,val1), new DefaultIssueChangeHolder())
}
else
{
requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName, null), new DefaultIssueChangeHolder())
}
if (event.eventTypeId == EventType.ISSUE_UPDATED_ID) {
def listOfFields = ['Fix Version', customFieldName,flagged]
def changeItems = ComponentAccessor.changeHistoryManager.getChangeHistoryById(event.changeLog.id as Long).changeItemBeans
log.info "Issue updated detected. Changed fields: ${changeItems*.field}"
if (!changeItems.any { it.field in listOfFields }) {
//don't run the listener if the user changed an unrelated field.
log.warn "$listOfFields were not found in the list of changed fields."
return null
}
if ((changeItems.any {it.field == 'Fix Version'}) && ("$flaggedCfval" == 'Yes'))
{
def val = issue.getCustomFieldValue(requestNumberCf)
requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName,val), new DefaultIssueChangeHolder())
}
else
{
requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName, null), new DefaultIssueChangeHolder())
}
}
Thanks,
Ramesh Penuballi
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 5, 2023

The trick with single select custom field is understanding that the getCustomFieldValue will return an object of class "Option".

So rather than comparing the option object as a string, it is best to use its "value" property.

So instead of 

" $flaggedCfval " == 'Yes'

Try

flaggedCfval.value == 'Yes'
Ramesh Penuballi January 5, 2023

Hi Peter,

Tried the options suggested by you and it gives below error.

Picture123.png

The flaggedcf variable has defined below.

@field String flagged = 'Flagged'

@field CustomField flaggedCf = customFieldManager.getCustomFieldObjectsByName(flagged)[0]
def flaggedCfval = issue.getCustomFieldValue(flaggedCf)

Please advice if this is correct approach to get the customfield value.

Thanks,

Ramesh

Sreedevi Raman Pisharody January 6, 2023

I tried out from my end and made the below changes to the script marked in Bold to identify

You can try as below

import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventType
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.project.version.Version
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import groovy.transform.Field

// the name of the custom field to update
@fieldString customFieldName = 'Request Number'

@fieldApplicationUser currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
@fieldSearchService searchService = ComponentAccessor.getComponent(SearchService)
@fieldCustomFieldManager customFieldManager = ComponentAccessor.customFieldManager
@fieldCustomField requestNumberCf = customFieldManager.getCustomFieldObjectsByName(customFieldName)[0]
//CustomField flaggedCf = customFieldManager.getCustomFieldObjectsByName(flagged)[0]
def flaggedCf = customFieldManager.getCustomFieldObject("customfield_12345")
@fieldIssue issue = event.issue as MutableIssue
def flaggedCfval = issue.getCustomFieldValue(flaggedCf)

if (!issue.fixVersions)
{
log.info "fixVersion field is empty for $issue.key. Listener will not try to make updates"
log.warn "fixVersion field is empty for $issue.key. Listener will not try to make updates"
if ("$flaggedCfval" == 'No')
{
requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName, null), new DefaultIssueChangeHolder())
}
return null //nothing to do if there is no fixVersion
}
if (event.eventTypeId == EventType.ISSUE_UPDATED_ID) {
def listOfFields = ['Fix Version', customFieldName,flaggedCf]
def changeItems = ComponentAccessor.changeHistoryManager.getChangeHistoryById(event.changeLog.id as Long).changeItemBeans
log.info "Issue updated detected. Changed fields: ${changeItems*.field}"
if (!changeItems.any { it.field in listOfFields }) {
//don't run the listener if the user changed an unrelated field.
log.warn "$listOfFields were not found in the list of changed fields."
return null
}
if ((changeItems.any {it.field == 'Fix Version'}) && ("$flaggedCfval" == 'Yes'))
{
def val = issue.getCustomFieldValue(requestNumberCf)
requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName,val), new DefaultIssueChangeHolder())
}
else if ((changeItems.any {it.field == 'Fix Version'}) && ("$flaggedCfval" == 'No'))
{
requestNumberCf.updateValue(null, event.issue, new ModifiedValue(customFieldName, null), new DefaultIssueChangeHolder())
}
}
This logic seemed to work for me, when I tested.
I considered that the flagged value to be checked is only two options Yes / No.
Peter can you suggest if this is the right approach for what Ramesh is trying to deal with.
Thanks and Regards,
Sreedevi
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 6, 2023

"static type checking" is not always fatal.

It just means that the code editor can't be sure if it will work.

In this case, the following line can retrun a String, an Integer, or a sincel instance of an Option class or an ArrayList of Option class depending on what type the custom field is

issue.getCustomFieldValue(flaggedCf)

In this case, the code below doesn't know it's an Option and that option can have a "value" property.

You can tell the editor what to expect:

import com.atlassian.jira.issue.customfields.option.Option

def flaggedCfval = issue.getCustomFieldValue(flaggedCf) as Option
Like # people like this
TAGS
AUG Leaders

Atlassian Community Events