Groovy script to append current user to multi-user picker

I have an approval-style workflow post-function that appends the current user to a multi-user picker custom field. So far I've used the non-groovy "Update Issue Custom Field" post-function to append "%%CURRENT_USER%%", which doesn't behave reliably for all types of usernames. Since that method has no flexibility, I'd like to switch over to a groovy script.

The behavior ultimately relies on comparing two multi-user picker fields, "Required Approvers" and "Approved by". An "Approve" transition has been set up expecting two conditions and two post-functions:

  1. Condition - the current user is listed in "Required Approvers".
  2. Condition - the current user is not listed in "Approved by".
  3. Post-function - append the current user to "Approved by".
  4. Post-function - ScriptRunner fast-track transition to the next phase of the workflow if the following condition is met:

    cfValues['Approved by'] as Set == cfValues['Required Approvers'] as Set

The comparison in (4) breaks down because certain usernames (mixed case) aren't stored by "Update Issue Custom Field" (3) the same way they're stored when manually entered into the "Required Approvers" field.

In trying to re-do (3) with ScriptRunner, I'm struggling to find any up-to-date examples of appending currentUser to this type of field. The closest I've found has ultimately boiled down to using an operation like this:

Approvers.updateValue(null, issue, new ModifiedValue("", user), changeHolder);

(based on code found here)

However, the ModifiedValue() part doesn't seem to be valid code anymore in the latest versions of JIRA+SR. Or at least, every example of it that I've been able to find throughout the community now returns errors.

Is there a newer, more recommended way to do this?

Thanks in advance for any help!

1 answer

1 accepted

Here is code example to do this:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.user.ApplicationUser

CustomField multiUser = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("fieldName")
List<ApplicationUser> users = issue.getCustomFieldValue(multiUser)
users.add(ComponentAccessor.getUserManager().getUserByName("username"))

issue.setCustomFieldValue(multiUser, users);

Thanks @Vasiliy Zverev! Starting from this, I was able to end up with something that seems to be working the way I hoped. I ran into a type checking error on line 7, but appending "as List" cleared it. The only other problem was that add() fails when users is null, but that was a simple fix, too. All in all, very happy -- thank you!

This code doesn't work if the multiuser picker field "fieldname" doesn't contain anything. I'm getting this error: 

ERROR [workflow.ScriptWorkflowFunction]: Script function failed on issue: null, actionId: 1, file: <inline script>
java.lang.NullPointerException: Cannot invoke method add() on null object

 

Any idea? Thanks!

Lets try this one

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.user.ApplicationUser

CustomField multiUser = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("fieldName")
List&lt;ApplicationUser&gt; users = issue.getCustomFieldValue(multiUser)
if(users == null)
    users = new ArrayList&lt;&gt;();

users.add(ComponentAccessor.getUserManager().getUserByName("username"))

issue.setCustomFieldValue(multiUser, users);

Hi Vasiliy,

Thanks for sharing this scripts, works well for us to copy a Jira issue Reporter name into multi user customfield value. In multi user, we are not appending the value as it's having one name only as of now.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.user.ApplicationUser

def componentCF2 = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("ITG To Test")
String selectedComponents2 = issue.getCustomFieldValue(componentCF2)

def componentCF1 = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Defect Source")
String selectedComponents1 = issue.getCustomFieldValue(componentCF1)

if(selectedComponents1 == "Design Server" && selectedComponents2 == "NO")
{
String reporter = issue.reporter?.name
issue.setAssigneeId(reporter)

String reporter1 = issue.reporter?.name
CustomField multiUser = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Test Managers")
List<ApplicationUser> users;
//= (List<ApplicationUser>) issue.getCustomFieldValue(multiUser)
if(users == null)
    users = new ArrayList<>();

users.add(ComponentAccessor.getUserManager().getUserByName(reporter1))

issue.setCustomFieldValue(multiUser, users);
}    

Same postfunction working script doen's work in when we use in Fast-track transition - not sure why?

ScriptRunner workflow function - Fast-track transition an issue (condition & additional actions apply

- Manju

Thanks for sharing the above script Vasiliy Zverev,

I customized your script to copy/overwrite Reporter of the Jira issue to other multi user picker custom field i,e Test Managers value in my post function, it working as expected for our usage.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.user.ApplicationUser

def componentCF2 = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("ITG To Test")
String selectedComponents2 = issue.getCustomFieldValue(componentCF2)

def componentCF1 = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Defect Source")
String selectedComponents1 = issue.getCustomFieldValue(componentCF1)

if(selectedComponents1 == "Design Server" && selectedComponents2 == "NO")
{
String reporter = issue.reporter?.name
issue.setAssigneeId(reporter)

String reporter1 = issue.reporter?.name
CustomField multiUser = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Test Managers")
List<ApplicationUser> users;
//= (List<ApplicationUser>) issue.getCustomFieldValue(multiUser)
if(users == null)
    users = new ArrayList<>();

users.add(ComponentAccessor.getUserManager().getUserByName(reporter1))

issue.setCustomFieldValue(multiUser, users);
}    

Suggest an answer

Log in or Join to answer
Community showcase
Sarah Schuster
Posted Jan 29, 2018 in Jira

What are common themes you've seen across successful & failed Jira Software implementations?

Hey everyone! My name is Sarah Schuster, and I'm a Customer Success Manager in Atlassian specializing in Jira Software Cloud. Over the next few weeks I will be posting discussion topics (8 total) to ...

2,981 views 12 18
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
Atlassian Team Tour

Join us on the Team Tour

We're bringing product updates and pro tips on teamwork to ten cities around the world.

Save your spot