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
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
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 @Peter-Dave 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.

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
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

@Peter-Dave 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

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
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 @Peter-Dave 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 July 14, 2020

@Peter-Dave 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. 

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
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 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.

 

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
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

@Peter-Dave 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