Scriptrunner update components based on another select list field

arama mihai
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 28, 2017

Hello,

 

We are trying to create a script which will add values to 'Components' based on another field that we have (called 'Tool/Area' and it is Select list type).

 

The following script does not show any errors, but it also does not actually add the values. (it is set as a script listener).

 

import com.atlassian.jira.bc.project.component.ProjectComponent
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.project.Project
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.util.JiraUtils
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.Project
import com.atlassian.jira.issue.customfields.option.Option;
import com.atlassian.jira.event.issue.AbstractIssueEventListener
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.crowd.embedded.api.User
import com.atlassian.event.api.EventListener
import com.atlassian.jira.util.ImportUtils
import com.atlassian.jira.user.ApplicationUser
import org.apache.log4j.Category


def projectComponentManager = ComponentAccessor.getProjectComponentManager()
ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().loggedInUser
IssueManager issueManager = ComponentAccessor.getIssueManager()
IssueService issueService = ComponentAccessor.getComponent(IssueService);
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters()
ComponentManager componentManager = ComponentManager.getInstance()
MutableIssue issue = (MutableIssue)event.issue
CustomFieldManager cManager = ComponentAccessor.getCustomFieldManager()
CustomField toolarea = cManager.getCustomFieldObjectByName("Tool/Area")
def values = issue.getCustomFieldValue(toolarea)
Project project = issue.getProjectObject()

ProjectComponent component = null

if(values == "Environment"){
    component = projectComponentManager.findByComponentName(project.getId(), "Tools Front Desk")
}
else if(values == "Docker"){
    component = projectComponentManager.findByComponentName(project.getId(),"Docker")
}
else if(values == "Bullseye / RTRT"){
    component = projectComponentManager.findByComponentName(project.getId(),"Bullseye")
}
else if(values == "Collaborator"){
    component = projectComponentManager.findByComponentName(project.getId(),"Collaborator")
}
else if(values == "Confluence"){
    component = projectComponentManager.findByComponentName(project.getId(),"Confluence")
}
else if(values == "Continuous Integration / Delivery"){
    component = projectComponentManager.findByComponentName(project.getId(),"Continuous Integration")
}
else if(values == "CS - Rational Change"){
    component = projectComponentManager.findByComponentName(project.getId(),"Change (CS)")
}
else if(values == "CM - Rational Synergy"){
    component = projectComponentManager.findByComponentName(project.getId(),"Synergy (CM)")
}
else if(values == "Data External Exchanges"){
    component = projectComponentManager.findByComponentName(project.getId(),"CS External Exchanges")
}
else if(values == "JIRA"){
    component = projectComponentManager.findByComponentName(project.getId(),"JIRA")
}
else if(values == "DOORS"){
    component = projectComponentManager.findByComponentName(project.getId(),"DOORS")
}

if (component) {
    issue.setComponent([component])
    issueManager.updateIssue(user, issue, EventDispatchOption.DO_NOT_DISPATCH, false)
}

1 answer

1 accepted

1 vote
Answer accepted
Thanos Batagiannis _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 5, 2017

Hi Arama, 

I'll make the assumption that the select list a single select list. So in that case your script will be similar to 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue

// a map with select list option to Component
def componentsMap = [
"AAA" : "Component A",
"BBB" : "Component B",
]

def issue = issue as MutableIssue

def selectList = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("SelectListA")
def selectListValue = issue.getCustomFieldValue(selectList)

// there is no value for the select list - therefore do nothing
if (! selectListValue) {
return
}

def componentManager = ComponentAccessor.projectComponentManager
def componentName = componentsMap.get(selectListValue.value)
def component = componentManager.findByComponentName(issue.projectObject.id, componentName)

if (component) {
componentManager.updateIssueProjectComponents(issue, [component])
}

 Please let me know if this does the trick. 

Regards, Thanos

arama mihai
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 5, 2017

Hello Thanos,

Thank you very much for your reply. Your version is much cleaner and simpler. However I do get two errors:

the variable issue is not declared for

def issue = issue as MutableIssue

 and "no such property: value for class java.lang.object" at:

def componentName = componentsMap.get(selectListValue.value)

 

I tried  using MutableIssue issue = (MutableIssue)event.issue instead of def issue = issue as MutableIssue

 

and simply removed .value from def componentName, leaving only:

def componentName = componentsMap.get(selectListValue)

The code shows no errors this way, but when create a ticket and select one of the options, it does not do anything.

Thanos Batagiannis _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 6, 2017

Hey Arama, 

Both the "errors" you get in the UI are because of the Static Type Checking and in that case is safe to ignore them.

What I will recommend is to run the original script as is, of course add in the componentsMap your values, and then check if the listener works or not. 

If not then it will be good to check your application logs for any errors. 

PS. If you do not want those error indications in your script then your script will be 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.customfields.option.LazyLoadedOption

// a map with select list option to Component
def componentsMap = [
"AAA" : "Component A",
"BBB" : "Component B",
]

def issue = issue as MutableIssue

def selectList = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("SelectListA")
def selectListValue = issue.getCustomFieldValue(selectList) as LazyLoadedOption

// there is no value for the select list - therefore do nothing
if (! selectListValue) {
return
}

def componentManager = ComponentAccessor.projectComponentManager
def componentName = componentsMap.get(selectListValue.value)
def component = componentManager.findByComponentName(issue.projectObject.id, componentName)

if (component) {
componentManager.updateIssueProjectComponents(issue, [component])
}

Please let me know how this went.

arama mihai
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 6, 2017

Thanks a lot! It's working.

 

One more question, please. Currently, the script can add one value to component. If I would need to add let's say the following:

for one value of the select list, two or multiple components

(clear example: for the "Data External Exchanges" option in the select list field, two components would be needed: "CS External Exchange" and "JIRA Data Exchange")

 

Thank you.

Thanos Batagiannis _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 6, 2017

In that case the script will need some changes and eventually will be 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.customfields.option.LazyLoadedOption

// a map with select list option to Component
def componentsMap = [
"AAA": ["Component A"],
"BBB": ["Component B", "Component A"],
]

def issue = issue as MutableIssue

def selectList = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("SelectListA")
def selectListValue = issue.getCustomFieldValue(selectList) as LazyLoadedOption

// there is no value for the select list - therefore do nothing
if (!selectListValue) {
return
}

def componentManager = ComponentAccessor.projectComponentManager

def components = componentsMap.get(selectListValue.value)?.collect {
componentManager.findByComponentName(issue.projectObject.id, it)
}

if (components) {
componentManager.updateIssueProjectComponents(issue, components)
}

Give it a try and please let me know how that went.

Regards, Thanos

arama mihai
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 6, 2017

Awesome! It works just fine!

 

Thanks a lot.

arama mihai
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 2, 2018

Hi @Thanos Batagiannis _Adaptavist_

Sorry to bother you for the same thing after such a long time.

When using this script, if somebody also happens to select some values for components, they will get replaced by whatever is mapped in the script.

So in this case it could be better if it would append values to components instead of replacing them.

Could you please let me know how that would look like?

Thank you!

arama mihai
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 12, 2018

def issue = issue as MutableIssue

def selectList = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("Tool/Area")
def selectListValue = issue.getCustomFieldValue(selectList) as LazyLoadedOption

// there is no value for the select list - therefore do nothing
if (!selectListValue) {
return
}

def componentManager = ComponentAccessor.projectComponentManager

def components = componentsMap.get(selectListValue.value)?.collect {
componentManager.findByComponentName(issue.projectObject.id, it)
}

def existing_components = issue.getComponentObjects();

def newValue = existing_components + components

if (newValue) {
componentManager.updateIssueProjectComponents(issue, newValue)
}

Suggest an answer

Log in or Sign up to answer