Assign a specific user based on the vaule of a Single Select Custom Field using Scriptrunner

Darren Fairweather June 16, 2020

Hi Guys and Gals,

 

Absolutely pulling my hair out with this. Have scoured the bowels of the internet and kinda cobbled a script together. It is as follows....

 

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

userName;switch(ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Overtime Type").toString()){

case "TOIL": userName = "user1";break;
case "PAID": userName = "user2";break;

}issue.setAssignee(ComponentAccessor.getUserManager().getUserByName(userName))

 

I am attempting to do this as a post-function on the create transition.

 

Please please can anyone help. I am using JIRA 8.5.4

 

Thanks in advance and hoping for a favourable reply,

 

Darren

3 answers

2 accepted

0 votes
Answer accepted
Darren Fairweather June 17, 2020

So with the correct usernames in there i still get the error and the assignee field is not populated. Any ideas?

Mathis Hellensberg
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.
June 17, 2020

the call should be .getUserByName("correct username")

...if that fails send me another screenshot :)

Darren Fairweather June 17, 2020

Its the same error with everything as it should be

Screenshot 2020-06-17 at 13.58.00.png

Mathis Hellensberg
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.
June 17, 2020

Can I see the code again? :)

Darren Fairweather June 17, 2020

import com.atlassian.jira.component.ComponentAccessor

def customFieldManager = ComponentAccessor.customFieldManager
def userManager = ComponentAccessor.userManager
def issueService = ComponentAccessor.issueService

def overtimeTypeField = customFieldManager.getCustomFieldObjectsByName("Overtime Type")[0]
def overtimeTypeValue = overtimeTypeField.getValue(issue)

def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def issueInputParameters = issueService.newIssueInputParameters()

def user

if (overtimeTypeValue.equals("TOIL")) {

user = userManager.getUserByName("user.user1")

}
else if (overtimeTypeValue.equals("PAID")) {

user = userManager.getUserByName("user.user2")

}

issueInputParameters.setAssigneeId(user.getUsername())

def validateUpdateResult = issueService.validateUpdate(currentUser, issue.id, issueInputParameters)

if (validateUpdateResult.isValid()) {

issueService.update(currentUser, validateUpdateResult)

}

Darren Fairweather June 17, 2020

I have to change the usernames for security reasons as cannot copy them directly to public internet

Mathis Hellensberg
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.
June 17, 2020

I understand :)

Do you really have users logging in to your Jira instance with?:

Username: user.user1   Password: ************* 

and not just something like:

Username: user1   Password: ************* 

It is telling you that it cannot find the user with username matching "user.user1" so you must have it wrong :(

Darren Fairweather June 17, 2020

all users have first name and surname.....

 

john.smith

darren.palmer

 

Is the code working perfectly for you?

 

I thought something would need to be in the brackets here.....

 

issueInputParameters.setAssigneeId(user.getUsername(SOMETHING HERE))

 

but i am only guessing!

Darren Fairweather June 17, 2020

very frustrating :(

Thanks for all your help thus far! :)

Mathis Hellensberg
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.
June 17, 2020

I just tried the script again and it works fine. If i put "user.user1" as the value, it fails giving me the same error as you are experiancing since I don't have a user called "user.user1" in my jira instance.

The function .getUsername() doesn't take any parameters so it should be empty, it is called on the ApplicationUser Object we have saved as the variable user.

Darren Fairweather June 17, 2020

ok :(

 

I guess we are at a brick wall. I even tried my own username and still get the same error. I'm not sure what else to do.

Is it something to do with the "create" transition? as this script is only executed when a brand new issue is created.

Darren Fairweather June 17, 2020

Thanks for all the help Mathis. A true gent :) I'll let you know if i can get it working

Mathis Hellensberg
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.
June 17, 2020

What version of Jira are you running?

Darren Fairweather June 17, 2020

8.5.4 the enterprise release (hoping you have had a brainwave?)

Mathis Hellensberg
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.
June 17, 2020

I have finally recreated the bug. I'm working on it :)

Like Darren Fairweather likes this
Mathis Hellensberg
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.
June 17, 2020

Okay. You probably have more than one field with the same name "Overtime Type" in your instance so we are most likely getting a reference to the wrong one. Try using the specific Custom Field ID as shown below. That worked for me. 

image.png

You can find this id by going to Custom Field and hovering over configure as shown below. Make sure you only change the number not the customfield_ part :)

image.png

Hope this works for you! 

Darren Fairweather June 18, 2020

Hi Mathis,

 

Thanks again for helping me!

 

Unfortunately its the same error.

Screenshot 2020-06-18 at 08.22.24.pngScreenshot 2020-06-18 at 08.22.36.png

 

import com.atlassian.jira.component.ComponentAccessor

def customFieldManager = ComponentAccessor.customFieldManager
def userManager = ComponentAccessor.userManager
def issueService = ComponentAccessor.issueService

def overtimeTypeField = customFieldManager.getCustomFieldObject("customfield_18403")
def overtimeTypeValue = overtimeTypeField.getValue(issue)

def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def issueInputParameters = issueService.newIssueInputParameters()

def user

if (overtimeTypeValue.equals("TOIL")) {

user = userManager.getUserByName("john.smith")

}
else if (overtimeTypeValue.equals("PAID")) {

user = userManager.getUserByName("david.monk")

}

issueInputParameters.setAssigneeId(user.getUsername())

def validateUpdateResult = issueService.validateUpdate(currentUser, issue.id, issueInputParameters)

if (validateUpdateResult.isValid()) {

issueService.update(currentUser, validateUpdateResult)

}

 

 

I tried with a made up username and a valif username and get the same result.

 

As this script is between create and the first stage in the workflow i wondered whether this was as a result of the script thinking that "overtime type" value was empty? as its populated the same time as the username that i require? Could this be that even though i select "PAID" on the ticket it thinks nothing has been populated and can therefore NOT "invoke getusername"?

I genuinely feel we are close!

Darren Fairweather June 18, 2020

MATHIS!!!!

 

I have found the issue!!!

 

So the overtime field is a "single select" field NOT a free text field. When i use a free text field it works perfectly!

Can you help me modify the script for it to recognise that "Overtime Type" is a "single select" drop down?

 

Thanks you!!

Mathis Hellensberg
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.
June 18, 2020

Perfect! that makes sense much more sense. I'll drop you a modified script, but I have some work i need to finish first :)

Darren Fairweather June 18, 2020

Thank you buddy! :)

Mathis Hellensberg
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.
June 18, 2020

Okay so it should work if you just add .toString() after .getValue() :)

image.png

Since it is a select field .getValue() returns a LazyLoadedOption which we later try to call .equals() on. LazyLoadedOption != String("TOIL" or "PAID") therefore we need to cast it to a String before we compare the two :)

Mathis Hellensberg
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.
June 19, 2020

@Darren Fairweather Let me know how it turns out! :)

Darren Fairweather June 19, 2020

HI Mathis. Sorry got pulled onto something else. Works perfectly. Thanks for helping me every step of the way!!

Henry Lin April 7, 2021

hi @Mathis Hellensberg , I've a similar request, however I can't get the assignee on cloned  issue, could you please help take a look at it?

Objective:

Clone an issue from ProjectA to ProjectB, upon closing the issue from ProjectA, a single select list (None, User 1, User 2, User 3) shows up on close screen; if None is selected, nothing happens; otherwise, if User 1 or User2 or User3 is selected, the assignee on the cloned/new issue (projectB) will be the selected user (from single select list)  

Current Status:

Cloning is working; however assignee (on projectB) is not functional 

 

Post Function:

Condition:

cfValues['Design QA Owner']?.value

 

Additional issue actions:

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.event.type.EventDispatchOption
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
import com.atlassian.jira.issue.IssueInputParameters

UserManager userMgr = ComponentAccessor.getUserManager()
IssueManager issueMgr = ComponentAccessor.getIssueManager()
ApplicationUser currUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def designQAOwner = ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_12818")
def selectedValue = designQAOwner.getValue(issue) as String

def user

if (selectedValue == "User 1"){
user = userMgr.getUserByName("test_user1")
}

else if (selectedValue == "User 2"){
user = userMgr.getUserByName("test_user2")
}

else if (selectedValue == "User 3"){
user = userMgr.getUserByName("test_user3")
}



issue.setAssignee(user)



Logs: 
2021-04-07 15:11:01,809 DEBUG [utils.ConditionUtils]: Condition did not return a boolean, coercing to true
2021-04-07 15:11:01,809 DEBUG [utils.AbstractCloneIssue]: System fields to copy: [description, summary]
2021-04-07 15:11:01,816 DEBUG [utils.AbstractCloneIssue]: Custom fields to copy: []
2021-04-07 15:11:01,885 DEBUG [utils.AbstractCloneIssue]: Run As User hlin(hlin)
2021-04-07 15:11:01,917 ERROR [recordparser.RecordParserUtils]: commentId is null

regards,

Henry

Mathis Hellensberg
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.
April 8, 2021

From what I can understand you need the cloned issue (B) to update with the assignee you select from the close screen on issue (A).

It should be a standard issue update for issue B, however you need to tell issue B that issue A was closed and an assignee was selected.

I'm afraid I don't have the time to write the code, but my approach would be something like:

Post-Function/Script Listener for issue A with condition on the assignee close field. Use LinkedIssueManager class to get a hold of linked cloned issue B and from there it is a standard update of issue B.

 

Hope that helps somewhat :)

Henry Lin April 8, 2021

Thanks for the suggestion! @Mathis Hellensberg I believe the problem is that it retrieves values from the wrong issue, so in stead of retrieving values from (issue), it should be sourceIssue, which it retrieves the values from the original issue. I changed my code to use LazyLoadedOption then switch case to perform action per case; Similar to code from Adaptavist library: 

https://library.adaptavist.com/entity/update-priority-based-on-a-custom-field 

 

 

def selectedValue = designQAOwner.getValue(issue) as String --> 

def selectedValue = designQAOwner.getValue(sourceIssue) as String

 


regards, 

Henry

0 votes
Answer accepted
Mathis Hellensberg
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.
June 16, 2020

Hi @Darren Fairweather 

You can't update an issue like that. You'll need to call 'issueService.validateUpdate()' after that you can call issueService.update() to actually update the value/s.

Hope this helps otherwise let me know :)

Mathis Hellensberg
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.
June 16, 2020

Also make sure that the scriptrunner post-function script is the last on the post-function list otherwise it wont work :)

Darren Fairweather June 17, 2020

Thanks for answering so quickly Mathis. I'm a bit lost to be honest. Is it possible you could help me with my code? Thanks so much.

Mathis Hellensberg
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.
June 17, 2020

Something like this, but then again i dont know which type the field you wanna update is. If its a user picker field and not a text field this code needs some correction.

import com.atlassian.jira.component.ComponentAccessor

def getCustomFieldManager = ComponentAccessor.customFieldManager
def userManager = ComponentAccessor.userManager
def issueService = ComponentAccessor.issueService

def overtimeTypeField = customFieldManager.getCustomFieldObjectByName("Overtime Type")
def overtimeTypeValue = overtimeTypeField.getValue().toString()

def theFieldYouWannaSet = customFieldManager.getCustomFieldObjectByName("Name of the field")

def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def issueInputParameters = new IssueInputParameters()

if (overtimeTypeValue.equals("TOIL")) {

    issueInputParameter.addCustomFieldValue(theFieldYouWannaSet.id, "user1")

}
else if (overtimeTypeValue.equals("PAID")) {

    issueInputParameter.addCustomFieldValue(theFieldYouWannaSet.id, "user2")

}

def validateUpdateResult = issueService.validateUpdate(currentUser, issue.id, issueInputParameters)

if (validateUpdateResult.isValid()) {

    issueService.update(currentUser, validateUpdateResult)

}

Darren Fairweather June 17, 2020

Thank Mathis.

The field i would like to set is the assignee field.

So assignee user1 is set if "TOIL" is selected in the "Overtime Type" field and assignee user2 is set if "PAID" is seleted in the "Overtime Type" field.

The "Overtime Type" field is a text field.

With the above in mind are you referencing the assignee field within this piece of code.....

def theFieldYouWannaSet = customFieldManager.getCustomFieldObjectByName("Name of the field")

is the assignee field a custom field?

Mathis Hellensberg
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.
June 17, 2020

Then this should work:

import com.atlassian.jira.component.ComponentAccessor

def getCustomFieldManager = ComponentAccessor.customFieldManager
def userManager = ComponentAccessor.userManager
def issueService = ComponentAccessor.issueService

def overtimeTypeField = customFieldManager.getCustomFieldObjectByName("Overtime Type")
def overtimeTypeValue = overtimeTypeField.getValue().toString()

def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def issueInputParameters = new IssueInputParameters()

def user

if (overtimeTypeValue.equals("TOIL")) {

    user = userManager.getUserByName("user1")


else if (overtimeTypeValue.equals("PAID")) {

    user = userManager.getUserByName("user2")

}

issueInputParameter.setAssignee(user)

def validateUpdateResult = issueService.validateUpdate(currentUser, issue.id, issueInputParameters)

if (validateUpdateResult.isValid()) {

    issueService.update(currentUser, validateUpdateResult)

}
Darren Fairweather June 17, 2020

Thanks for continued support! :)

Screenshot 2020-06-17 at 10.57.52.png

Mathis Hellensberg
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.
June 17, 2020

My bad. just add "import com.atlassian.jira.issue.IssueInputParameters" at the top :)

0 votes
Mathis Hellensberg
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.
June 17, 2020

Also i see a mistake i made.

def getCustomFieldManager = ComponentAccessor.customFieldManager

should be replaced with

def customFieldManager = ComponentAccessor.customFieldManager

Darren Fairweather June 17, 2020

I think we are close :)

Screenshot 2020-06-17 at 11.10.22.png

Mathis Hellensberg
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.
June 17, 2020

Sorry, I should have just tested it. This should work :)

import com.atlassian.jira.component.ComponentAccessor

def customFieldManager = ComponentAccessor.customFieldManager
def userManager = ComponentAccessor.userManager
def issueService = ComponentAccessor.issueService

def overtimeTypeField = customFieldManager.getCustomFieldObjectsByName("Overtime Type")[0]
def overtimeTypeValue = overtimeTypeField.getValue(issue)

def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def issueInputParameters = issueService.newIssueInputParameters()

def user

if (overtimeTypeValue.equals("TOIL")) {

user = userManager.getUserByName("user1")

}
else if (overtimeTypeValue.equals("PAID")) {

user = userManager.getUserByName("user2")

}

issueInputParameters.setAssigneeId(user.getUsername())

def validateUpdateResult = issueService.validateUpdate(currentUser, issue.id, issueInputParameters)

if (validateUpdateResult.isValid()) {

issueService.update(currentUser, validateUpdateResult)

}
Darren Fairweather June 17, 2020

Hi Mathis,

No errors in the code but the script is failing.. I think its to do with line 26?

Screenshot 2020-06-17 at 13.35.01.pngScreenshot 2020-06-17 at 13.35.58.png

Mathis Hellensberg
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.
June 17, 2020

It's basically telling you that you have no user named "user.user1" or "user.user2" depending of what part of the code is executing.

the value you need for the user you want to assign can be found under "User management" like so:

image.png

EDIT: Any reason you changed ".getUserByName("user2")" to ".getUserByKey("user.user2")"?

Darren Fairweather June 17, 2020

I thought it might need the actual username rather than display name. Should i change this back to how it was?

Suggest an answer

Log in or Sign up to answer