Forums

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

Auto-assign based on value selected in the custom field ONLY IF assignee field is left unassigned

John_Diaz March 9, 2020

I have a working script below on my custom field called Target System with two values JIRA and Confluence and will assign to the desired user based on what you select once you create the ticket.  However, I want to set another conditional that should the reporter know who to assign the issue to then it won't auto assigns.

Example 1: I select JIRA under the Target System field and assign to John Doe, then it will leave the assignee to John Doe.

Example 2: I select JIRA under the Target System field and leave assignee automatic then will automatically assign to JIRA TEAM. 

My post function script below:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.event.type.EventDispatchOption


String userName;
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf = customFieldManager.getCustomFieldObjectByName("Target System")
def cfTargetSystem = issue.getCustomFieldValue(cf)
switch(cfTargetSystem){
case "JIRA": userName = "JIRA Team";break;
case "Confluence)": userName = "Confluence Team";break;

}
log.error(userName)
log.error(cfTargetSystem);
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
issue.setAssignee(ComponentAccessor.getUserManager().getUser(userName))
ComponentAccessor.getIssueManager().updateIssue(user, issue, EventDispatchOption.ISSUE_UPDATED, false)

1 answer

1 accepted

0 votes
Answer accepted
PD Sheehan
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 9, 2020

First, I would be remiss not to mention that Components already provide this exact feature. If you create JIRA and Confluence as components in your project and set the component leads accordingly, the assignee will be set in this order 1) user-selected assignee, 2) Component Lead, 3) Project Lead

Assuming, you have a valid reason not to use components, let's proceed ...

None of my environments are set up to allow unassigned issues, so I can't test for sure, but wouldn't it be as simple as wrapping the whole script into an if(issue.assignee){  } block?

I would assume that an "unassigned" issue would have a null value for assignee field.

Also, I should point out that for most cases, post function don't need to run updateIssue if you use IssueInputParameters. This way you don't duplicate db transaction and will reduce the performance impact of your postfunction. Something like this:

import com.atlassian.jira.component.ComponentAccessor

if(issue.assignee){
String userName;
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf = customFieldManager.getCustomFieldObjectByName("Target System")
def cfTargetSystem = issue.getCustomFieldValue(cf)
switch(cfTargetSystem){
case "JIRA": userName = "JIRA Team";break;
case "Confluence)": userName = "Confluence Team";break;
}
log.error(userName)
log.error(cfTargetSystem);
def assignee = ComponentAccessor.getUserManager().getUser(userName)
issueInputParameters.setAssigneeId(assignee.id.toString())
}

I removed unused imports.

This function would need to be BEFORE the built-in function that stores the issue to the db.

In groovy, you can do without the switch construct. I'm a big fan of something like this:

import com.atlassian.jira.component.ComponentAccessor

def systemUserMap = [
JIRA: 'Jira Team',
Confluence: 'Confluence Team'
]
if(issue.assignee){
String userName;
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf = customFieldManager.getCustomFieldObjectByName("Target System")
def cfTargetSystem = issue.getCustomFieldValue(cf)
userName = systemUserMap[cfTargetSystem]
log.error(userName)
log.error(cfTargetSystem);
def assignee = ComponentAccessor.getUserManager().getUser(userName)
issueInputParameters.setAssigneeId(assignee.id.toString())
}
John_Diaz March 16, 2020

Hi @PD Sheehan first, thank you for responding to my post.  I tried adding your script and added an addition condition that if Splunk Correlation is selected then assign to Splunk Team and get an error.  Do you know what I'm doing wrong?

Scriptrunner SOCT Threat Detection.PNG

 

 

PD Sheehan
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 16, 2020

If you have spaces in the system name line "Splunk Correlation", you must put quotes around it.

John_Diaz March 16, 2020

@PD Sheehan It removed the error but unfortunately, it didn't work.  It still assigned to the project lead.  

PD Sheehan
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 16, 2020

Can you include a screenshot of your transition's post function configuration?

John_Diaz March 19, 2020

@PD Sheehan Sorry for the delay, here's the screenshot.  Just some context because I had to make a few tweaks.

The custom field is now called Target System Request

The drop-down values are: JIRA, Confluence, and Splunk API

If you select JIRA, it should assign to the JIRA Team

If you select Confluence, it should assign to the Confluence Team

If you select Splunk API, it should assign to the Splunk TeamTarget System Request.PNG

PD Sheehan
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 19, 2020

Hi @John_Diaz 

You need a comma after the confluence item in the systemUserMap

Like this:

def systemUserMap = [
'JIRA' : 'Jira Team',
'Confluence': 'Confluence Team', //<- comma was missing here
'Splunk API': 'Spluk Team'
]

Map objects are a bit like arrays in groovy:

def array = ['item1', 'item2', 'item3']
def map = [key1:"value1", key2:"value2", "key 3": "value 3"]

Each item in the map or in the array is delimited by commas. Groovy knows it's a map vs an array by the item key/pair being further separated by a colon (:).

You can define empty arrays and empty maps like this

def array = []
//then add item to the array with
array << "item1" 
arra.put("item2")

def map = [:]
//then add items to the map easily with
map.item1="value 1"
map["item2"] = "value 2"
John_Diaz March 19, 2020

@PD Sheehan This is what I see now.  Sorry, I'm a beginner at this.Target System Request.PNG

John_Diaz March 19, 2020

@PD Sheehan I also wanted to add that if I assign a user of my choice it should overrule the rule.

Ex. If I assign to John Doe and select JIRA as my Target System Request then click Create.  John Doe should still be the user assigned and not JIRA Team. 

PD Sheehan
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 19, 2020

Ah... yes... that error (just a warning really) was in your original script and I didn't validate it since I was focused on "how to add another condition"

This is letting you know that the getUser() method is no longer recommended and will disappear at some point. So might as well fix it now.

def assignee = ComponentAccessor.userManager.getUserByName(userName)

 This assumes that the actual username (the one that would be used for logging in to jira) are what you've specified in the sysmteUserMap ('Jira Team', 'Confluence Team' etc) .

If "Jira Team" is the display name for a user with a username like "jira_team_user" then the map needs to have those explicit usernames

def systemUserMap = [
JIRA: "jira_team_user",
Confluence: "confl_team_user",
"Splunk API: "splunk_team_user",
]

Also, another assumption you should verify, JIRA, Confluence and Splunk API should be the exact text values of the drop-down options for the "Target System Request" field (I'm assuming that's a single select field). 

John_Diaz March 19, 2020

@PD Sheehan I made some tweaks so we're on the same page.  I applied to my workflow and published without errors.  When I tested, it automatically assigns to me now regardless of what value I select under the Target System Request drop-down.  I also realized that the drop-down I'm using is an add-on called Deviniti [Dynamic Forms] - Dynamic Select.  Not sure if that could be the reason why it's not working?

import com.atlassian.jira.component.ComponentAccessor

def systemUserMap = [
"JIRA": 'jira_team_user',
"Confluence": 'confluence_team_user',
"Splunk API": 'splunk_team_user'
]
if(issue.assignee){
String userName;
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf = customFieldManager.getCustomFieldObjectByName("Target System")
def cfTargetSystem = issue.getCustomFieldValue(cf)
userName = systemUserMap[cfTargetSystem]
log.error(userName)
log.error(cfTargetSystem);
def assignee = ComponentAccessor.getUserManager().getUserByName(userName)
issueInputParameters.setAssigneeId(assignee.id.toString())
}

PD Sheehan
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 19, 2020

I had to look something up  on the detection of automatic assignee

This should work:

import com.atlassian.jira.component.ComponentAccessor

def systemUserMap = [
JIRA: "jira_team_user",
Confluence: "confl_team_user",
"Splunk API": "splunk_team_user",
]

if(webwork.action.ActionContext.getRequest().getParameter("assignee") == '-1'){
String userName;
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf = customFieldManager.getCustomFieldObjectByName("Target System Request")
def cfTargetSystem = issue.getCustomFieldValue(cf)
if(cfTargetSystem ) {
userName = systemUserMap[cfTargetSystem.value]
log.error(userName)
log.error(cfTargetSystem);
def assignee = ComponentAccessor.userManager.getUserByName(userName)
issue.setAssignee(assignee)
}
}

I also added protection in the case "Target System Request" is empty. And cfTargetSystem.value to get the value of the option (assuming that field is a single select).

PD Sheehan
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 19, 2020

Ah, our messages crossed.

With the custom field being provided by an add-on, it's difficult to know what value will be returned by 

issue.getCustomFieldValue(cf)

Can you please try this in the console (replace the ticket number with a valid ticket that has a value in the custom field

import com.atlassian.jira.component.ComponentAccessor
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf = customFieldManager.getCustomFieldObjectByName("Target System Request")
def issue = ComponentAccessor.issueManager.getIssueObject('JSP-1922')
def cfTargetSystem = issue.getCustomFieldValue(cf)

"$cfTargetSystem (${cfTargetSystem.getClass()})""

 And let me know what the output is?

John_Diaz March 19, 2020

@PD Sheehan  Please see my screenshot Script Console.PNG

John_Diaz March 19, 2020

@PD Sheehan Good news, everything works.  If I assign the ticket to myself and hit create it's still assigned to me.  If I leave it unassigned and hit create, it will automatically assign to the right team per my script (with your help of course). Weird thing is...everything works fine but I see this error.  Thoughts? Target System Request.PNG

PD Sheehan
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 19, 2020

We're getting there....

Try the console code again but remove the extra double-quote we can make sure if .value is needed at the end of cfTragetSystemRequest.

But since it appears to work, that error can likely be ignored. These sorts of static type checking errors are not always indicative that something needs to change. They are there to help you identify POSSIBLE issues with the script.

In this case, the code editors can't know what type of object cfTargetSystemRequest is. It could be a string, or it could be some other class. So it doesn't know if .value is a valid property/method.

John_Diaz March 20, 2020

Script Console.PNG

This is what I get with Script Console.

John_Diaz March 20, 2020

@PD Sheehan May ask another question.  If I add another value to the field, let's call it "Splunk" and I just want that assigned to the Reporter when unassigned, how would I add that in the working script I have now? 

PD Sheehan
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 20, 2020

Hi @John_Diaz 

Looking at the console output, I see that the custom field contains "LazyLoadedOptions" object which is the same type of data that is stored in a build-in single select field. So since cfTargetSystem will be such an object, to get the actual text of the option, you would use cfTargetSystem.getValue() or cfTargetSystem.value for short (which is what I suggested in the last instance of the script).

 

Now, if you want to have additional logic such that a certain value from the field would cause the reporter to be the assignee, you could do it like this:

import com.atlassian.jira.component.ComponentAccessor

def systemUserMap = [
JIRA: "jira_team_user",
Confluence: "confl_team_user",
"Splunk API": "splunk_team_user",
"Splunk": issue.reporter.name
]

if(webwork.action.ActionContext.getRequest().getParameter("assignee") == '-1'){
String userName;
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf = customFieldManager.getCustomFieldObjectByName("Target System Request")
def cfTargetSystem = issue.getCustomFieldValue(cf)
if(cfTargetSystem ) {
userName = systemUserMap[cfTargetSystem.value]
log.error(userName)
log.error(cfTargetSystem);
def assignee = ComponentAccessor.userManager.getUserByName(userName)
issue.setAssignee(assignee)
}
}

 You'll see I added only a single line in the systemUserMap: "Splunk": issue.reporter.name 

This means that the "username" value for that value will be dynamically assigned to the reporter of the issue at runtime. Then, the same existing logic will be used to set the assignee.

John_Diaz March 20, 2020

@PD Sheehan Thank you for the explanation and sharing the script with me.  Everything looks good and is working as should.  Huge thanks for spending some time to work with me and teaching me few new things -- definitely going to document and share with my team. 

PD Sheehan
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 20, 2020

My pleasure and good luck.

Please be sure to accept the answer. I don't usually ask, but I think I've earned it ;)

Happy scripting!

John_Diaz March 20, 2020

@PD Sheehan Accepted and well earned.  Thank you again! 

Suggest an answer

Log in or Sign up to answer