ScriptRunner Post-function: Setting Component Lead to a custom single user picker field?

Matt Bausher August 26, 2019

As stated in the summary, during the creation of the issue a component is set based on a list custom field and assigned to the reporter.  Each component lead is a manager and I'm attempting/failing at trying to have the component lead populated to a manager field (custom user picker field).  Unfortunately, I'm having a really hard time figuring out how to set a custom user picker field based on a component lead.  In this situation, the list option is the same as the component's name.

import com.atlassian.jira.bc.project.component.ProjectComponent
import com.atlassian.jira.bc.project.component.ProjectComponentManager
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.fields.CustomField


CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()
ProjectComponentManager componentManager = ComponentAccessor.projectComponentManager

def userCf = customFieldManager.getCustomFieldObject(10094)

CustomField selectList = customFieldManager.getCustomFieldObject(14760L)
Option selectListValue = issue.getCustomFieldValue(selectList) as Option

if (selectListValue)
{
String componentName = selectListValue.getValue()
ProjectComponent component = componentManager.findByComponentName(issue.projectObject.getId(), componentName)

if (component)
{
issue.setComponent([component])
def Lead = issue.getComponents().getAt(0)?.getLead()
issue.setCustomFieldValue(userCf, Lead)
}
}

 I would really appreciate any help or anything that could point me in the right direction.  Also, if there are any related issues on how to set a custom user picker field or getting a user, I would be very thankful.

3 answers

1 accepted

1 vote
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.
August 26, 2019

I don't see anything wrong with your code.

Let me make sure I understand your intention:

  • When the user selects a value in custom select 14760
    • The component field will be set to the component with component.name == option.value
    • The user picker field 10094 will be set to component.lead

So a few questions:

  1. What part is working and what part isn't?
  2. Are you getting any errors?
  3. Is the component field populated to the component selected in the 14760 select list?
  4. Where in the list of post functions is your scripted post function in terms of sequence? For the script to work, it must be ABOVE "Update change history and store the issue to the database"
  5. Have you tried setting some debug messages and looking in the log? 

 

Since your code looked rather like pure java ... I thought you might appreciate a simplified version:

import com.atlassian.jira.component.ComponentAccessor

def customFieldManager = ComponentAccessor.customFieldManager
def componentManager = ComponentAccessor.projectComponentManager

def userCf = customFieldManager.getCustomFieldObject(10094L)
def selectListCf = customFieldManager.getCustomFieldObject(14760L)
def selectListValue = issue.getCustomFieldValue(selectListCf)

if (selectListValue)
{
def component = componentManager.findByComponentName(issue.projectObject.id, selectListValue.value)

if (component)
{
issue.setComponent([component])
issue.setCustomFieldValue(userCf, component.lead)
}
}

You may get some static type checking errors, but those are normal with the scriptrunner static type checker. The code should still run without issue

Matt Bausher August 27, 2019

Hello @PD Sheehan

Your understanding of my intentions are correct and thank you for taking the time to reply to this post.

  1. With both sets of code, I have been able to successfully set the component based on the custom list value. Thank you for supplying a more simplified version of my code!
  2. I am not receiving any errors or post-function fails;  However, I've been failing at populating the custom single user picker field with the component lead. 
  3. This post-function comes directly after the Create the issue originally in the Create transition of the workflow.
  4. I can confirm that "component.lead" does return only the username of the component lead.  Which should be the correct format and value for the user field. 

Additionally, I doubled checked to make sure the user picker id was correct and the screen/field permissions were correct.

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.
August 27, 2019

Try to put the post function before the create the issue originally.

The scripted postfunction will still receive a "temporary" issue object (that exists just in memory). Then your script will update that object's attribute with the new custom field data and pass that the "create issue originally" which will store that updated information to the database.

Matt Bausher August 27, 2019

@PD Sheehan , when I put the custom scriptrunner post-function in front of the "create issue originally" post-function, I received the following error.

Post-Error.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.
August 27, 2019

Ok, I had to set up this test in one of my workflow with some additional log outputs ... but I figured it out.

The "component.lead" doesn't actually return a user object, so we can't apply that value directly to the custom field.

Try this instead:

import com.atlassian.jira.component.ComponentAccessor

def customFieldManager = ComponentAccessor.customFieldManager
def componentManager = ComponentAccessor.projectComponentManager

def userCf = customFieldManager.getCustomFieldObject(10094L)
def selectListCf = customFieldManager.getCustomFieldObject(14760L)
def selectListValue = issue.getCustomFieldValue(selectListCf)

if (selectListValue)
{
def component = componentManager.findByComponentName(issue.projectObject.id, selectListValue.value)

if (component)
{
issue.setComponent([component])
def leadUser = ComponentAccessor.userManager.getUserByName(component.lead)
issue.setCustomFieldValue(userCf, leadUser)
}
}
Matt Bausher August 27, 2019

Thank you @PD Sheehan, that was exactly it and I was able to successfully populate a custom single user picker field with the component lead. 

The custom scriptrunner post-function as the first task in the Create transition.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.customfields.option.Option

def customFieldManager = ComponentAccessor.getCustomFieldManager()
def componentManager = ComponentAccessor.projectComponentManager

def userCf = customFieldManager.getCustomFieldObject(10094L)

def selectListCf = customFieldManager.getCustomFieldObject(14760L)
Option selectListValue = issue.getCustomFieldValue(selectListCf) as Option

if (selectListValue)
{
String componentName = selectListValue.getValue()
def component = componentManager.findByComponentName(issue.projectObject.id, componentName)

if (component)
{
issue.setComponent([component])
def leadUser = ComponentAccessor.userManager.getUserByName(component.lead)
issue.setCustomFieldValue(userCf, leadUser)
}
}
Like Sara Lam likes this
0 votes
Ankit Patel
Contributor
July 14, 2020

@PD Sheehan  How do I copy Component lead to a custom user field? I tried using a modified version but was not able to get it to work. 

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.
July 14, 2020

I'll assume your custom field is a User Picker.

First you get the component leads from your issue (there may be more than one)

def leadKeys =  issue.components*.lead

Then get an ApplicationUser representing the lead, possibly using first 

if (leadKeys){
def leadUser = ComponentAccessor.userManager.getUserByKey(leadKeys[0])
}

 or as an array if your custom field is a multi-user picker

if (leadKeys){
def leadUsers = leadKeys.collect{ ComponentAccessor.userManager.getUserByKey(it)}
}

Then you can just apply the user to the custom field like you would any other custom field (there are many examples on how to do that)

def cf = ComponentAccessor.customFieldManager.getCustomFieldObject(customFieldId)
issue.setCustomFieldValue(cf, leadUser)

And of course, if this is not in a postfunction (but a listener or other script), now you need to actually store the issue and index it. 

0 votes
Tomasz Bryła
Contributor
August 26, 2019

Where are You put your script, as first in post function list? Try put this script as last position of post functions and add this to your script:

ApplicationUser currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser

ComponentAccessor.getIssueManager().updateIssue(currentUser, EventDispatchOptions.UPDATE_ISSUE, false)

Check syntax before you try this code.

 

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.
August 26, 2019

You don't need to call updateIssue if the postFunction is before the "store the issue in the database" built-in post function. That part will do that work for you.

You only need to call this if you make the change after for some reason (maybe you need to wait until the issue is fully created such as when you want to add a watcher) or if you run this code as a listener.

Matt Bausher August 27, 2019

@PD Sheehan &  @Tomasz Bryła, since this post-function occurs in the Create transition that only contains the Create the issue originally vs the Update change history for an issue and store the issue in the database step, do I still need to update the issue due to how the post-function can not go before the creation of the issue?

Suggest an answer

Log in or Sign up to answer