Scriptrunner update components based on another select list field

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
Accepted answer

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

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.

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.

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.

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

Awesome! It works just fine!

 

Thanks a lot.

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!

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
Community showcase
Posted Oct 16, 2018 in Jira

Looking for anyone who made the switch to Data Center

The Jira Marketing team is putting together an ebook on migrating to Data Center. We're looking for pro tips on how you staffed your project team and organized your Proof of Concept. Share yo...

1,385 views 17 10
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you