Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,297,601
Community Members
 
Community Events
165
Community Groups

How Add Value in Custom User Field base on Insight Object Selection?

Edited

Hi community,

I'm trying to add users in the multi-user picker custom field based on the selection of a value in the Insight Object field.

There is an "Asset" schema, it has many objects, one is "Operating System", under the OS we have child objects, like "Windows 10", "Windows Server",  "CentOS", "Red Hat" etc. I created an insight field and configured the Operating System object to display Name, and the field is associated with a Jira Software project. In the create screen I'm able to see all values from the "Operating System" insight dropdown field. I have a multi-user picker custom field (Approver). By default, it is adding 'user1' and 'user2' in the custom user field but I want it to change users based on value selection from the Operating System field. I wrote the below behaviour script, but it's not working with the if statement. How can I make it works?

 


import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectTypeFacade
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectTypeAttributeFacade

@WithPlugin('com.riadalabs.jira.plugins.insight')
@BaseScript FieldBehaviours fieldBehaviours

def oSystem= getFieldById('customfield_10403')

def custApr = 'projLead'

if(oSystem.value == 'Windows 10') {
custApr = 'wUser1, wUser2, wUser3'
}
def customAprFormField = getFieldById('customfield_10410')
customAprFormField.setFormValue(custApr)

Thank you

1 answer

1 accepted

0 votes
Answer accepted

For one thing, unless that has changed in recent versions of scriptrunner, oSystem.value will return the object Key for the selected object. You may need to use the objectFaced to retrieve an actual ObjectBean. Then you can look at the Label.

The other possible problem is that multi-user pickers expect an array of usernames

You could try it like this:

def custApr = ['projLead']

if(objSystem.labeel == 'Windows 10') {
custApr = ['wUser1', 'wUser2', 'wUser3']
}

But perhaps a better solution would be to actually store the list of users for approval in the insight object. This way you can easily maintain that list without changing the code.
But you will have to fetch the values for the "Approvers" attribute in your object. This will be user keys, so you will need to convert them to user names.

Hi @Peter-Dave Sheehan thank you for your response. I replaced value to label, but it didn't work. I don't know how ObjectFaced and ObjectBean work. Can you please help me out? I appreciate your help.

Here is an example with hardcoded approvers:

import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade

@WithPlugin('com.riadalabs.jira.plugins.insight')
@BaseScript FieldBehaviours fieldBehaviours

@PluginModule ObjectFacade objectFacade
def systemFld = getFieldById('customfield_10403')
def approversFld = getFieldById('customfield_10410')

def defaultApprovers = ['projLead']
def systemApproversMap = ['Windows 10':['wUser1', 'wUser2', 'wUser3']]
def systemVal = systemFld.value as List<String>
if(systemVal){
def systemObject = objectFacade.loadObjectBean(systemVal[0])
def approvers = systemApproversMap[systemObject.label]
if(!approvers) approvers = defaultApprovers
approversFld.setFormValue(approvers)
}

 

And here is the more complex example where the approvers are stored in the System Object using an attribute "System Approvers" (type user, allow multiple=true)

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.jira.groovy.user.FieldBehaviours
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeBean
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeValueBean
import groovy.transform.BaseScript
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectTypeAttributeFacade

@WithPlugin('com.riadalabs.jira.plugins.insight')
@BaseScript FieldBehaviours fieldBehaviours

@PluginModule ObjectFacade objectFacade
@PluginModule ObjectTypeAttributeFacade objectTypeAttributeFacade
def userManager = ComponentAccessor.userManager

def systemFld = getFieldById('customfield_10403')
def approversFld = getFieldById('customfield_10410')
def approverAtrtributeName = 'System Approvers'
def defaultApprovers = ['projLead']

def systemVal = systemFld.value as List<String>
if(systemVal){
def systemObject = objectFacade.loadObjectBean(systemVal[0])
def approverAttributeBean = objectTypeAttributeFacade.loadObjectTypeAttribute(systemObject.objectTypeId, approverAtrtributeName)
def approverObjectAttribute = systemObject.objectAttributeBeans.find{ it.objectTypeAttributeId == approverAttributeBean.id }
def approverUsers = approverObjectAttribute.objectAttributeValueBeans.collect{ userManager.getUserByKey(it.value as String)}
def approvers = defaultApprovers
if(approverUsers){
approvers = approverUsers*.name
}
approversFld.setFormValue(approvers)
}

Hi @Peter-Dave Sheehan I tried both scripts. The first one is not working properly. In the issue create screen it won't display users, but when I create the issue and go to the edit screen I can see users there however there isn't a space between usernames so it won't be displayed on the viewscreen.  If I go to the edit screen and manually add space between users then it displays users in the view screen.  Also, it is not adding the default user to the approver's field if I leave oSystem field empty. Any idea?

For the second one, I used a different object (servers) and the "Affected Server" custom field.  I created the "System Approvers" attribute and added two users. I added the second script but it didn't work. I'm not sure I didn't configure it properly. Here are screenshots.

Thank you for your help.

 

insight_03.jpginsight_02.jpginsight_01.jpg

That's surprising behavior for me.

But I was able to replicate and confirm.

You can get around it with (in either script):

approversFld.setFormValue(approvers.join(', '))
Like Shah Baloch likes this

@Peter-Dave SheehanI noticed it works if I switch the issue type. For example on create issue screen if I select "Windows 10" from the OS field, then switch the issue type to a different issue type it'll display users in the approver fields. I also added the script in both the initializer and server-side. I tested with both the data center and server but had the same result. Any idea why it happening?

The second question about the first script is how can I map more OS values with different users? Currently "Windows 10" is mapped with wUser1,2 and 3. I would like to map another os with other users for example CentOS should map cUser1,2,3 and the same other Values with different users. 

Appreciate your help.

If you want to add more hardcoded users for different OS, you can just add them to the map:

def systemApproversMap = [
'Windows 10':['wUser1', 'wUser2', 'wUser3'],
'CentOS': ['cUser1', 'cUser2', 'cUser3']
]

You should only need to add the script to the server-side script on the System custom field. 

Like Shah Baloch likes this

I meant I tried both. Actually, I added in the server-side script from day one, but when I noticed the issue today I tried the initializer. Do you have any idea what is causing this? Thanks

I'm not sure what issue you are talking about.

I've already provided a solution for how to correctly fill-in the Approvers field with the correct spacing.

Can you describe what issue remains?

My apology I didn't explain it well. I was trying to say that the users are not populating in the Approver field if I select "Windows 10" from the field. There are two ways it is populating the users, first one is if I select the option and create the issue and then come back and edit the issue it shows the users in the field, but it won't display the user when I create the issue in the first place.

The second way it displays the users in the approver field is if I select the "Windows 10" option, then I switch to a different Issue type. For example, I click to create the issue and the Task issue type is already selected and I select the "Windows 10" option from the OS field, it won't add those mapped users in the approver field, however, if I switch the Task issue type to Story then I can see the mapped users.

I'm trying to say by default it is not working, either I have to create the issue first by filling fields then have to edit in order to see users and save the issue in order to see mapped users or I have to switch issue types while creating an issue and leaving "Windows 10" option selected from the field to see mapped users in the approver field. I hope it helps.

 

Thank you for your help.

insight_04192022.jpg

Edit: Added screenshot

Can you show me the behavior configuration for the Operating System field? 

Are you sure there is not more than one other behaviour mapping that includes a configuration for Operating System?

Also I'm noticing that the Operating System appears to allow multiple values. What should happen if the user selected both "Windows 10" and "CentOS"?  Should approvers be wUser1,2,3 and cUser1,2,3 ?

The current script I offered will only include the approvers for the first selected OS.

Hi @Peter-Dave Sheehan if uncheck the "Multiple" option it won't add users in the approver's field regardless of switching the issue type. But if I leave it checked then it can add the users if I switch the issue types from one to another after selecting the option "Windows 10" from the operating system field. or if I select two options then it adds users to the approver field, for example, I didn't map the "Windows Server" option with any users, if I select "Windows 10" then "Windows Server", then will add the users to the approver field.

I just want to say that the only time it works is if I leave multiple option checks from the field configuration and switch issueype or add multiple options in the system field. If I won't do it won't add users in the approver field.

Looks like it won't work if uncheck the multiple options. There is only behaviour for that project. Attaching screenshot.

 

Thank you for your help

insight_04202022.jpg

I'm on an older version of scriptrunner. I'll try to upgrade and see if I can get similar issues as you do and find a fix.

However, there might be a difference in our version of Jira as well. I only have access to 8.13.x at the moment.

Ah yes, I often tend to forget the following little fact:

formField.getValue() on an Insight object custom field will return either a string or an arrayList depending on whether this is the first value or one of many.

The way I test something like this is I add the following script to a field I want to examine:

def fld = getFieldById(fieldChanged)
fld.setHelpText("$fld.value (${fld.value.getClass()})")

This way each time you change the field value, you can see what the getValue() method returns and what type it returns.

Based on that, we can make a modification to the script like this:

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.jira.groovy.user.FieldBehaviours
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeBean
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeValueBean
import groovy.transform.BaseScript
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectTypeAttributeFacade

@WithPlugin('com.riadalabs.jira.plugins.insight')
@BaseScript FieldBehaviours fieldBehaviours

@PluginModule ObjectFacade objectFacade
@PluginModule ObjectTypeAttributeFacade objectTypeAttributeFacade
def userManager = ComponentAccessor.userManager

def systemFld = getFieldById('customfield_10403')
def approversFld = getFieldById('customfield_10410')
def approverAtrtributeName = 'System Approvers'
def defaultApprovers = ['projLead']

def systemVal = systemFld.value
if(!systemVal){
//nothing selected, nothing to do, exit the script
return
}
def selectedKey
if(systemVal instanceof List){
selectedKey = systemVal[0] //There are multiple. Get only the first one
} else {
selectedKey = systemVal //This is what we get where there is a single value (whether multiple are allowed of not)
}
if(systemVal){
def systemObject = objectFacade.loadObjectBean(selectedKey)
def approverAttributeBean = objectTypeAttributeFacade.loadObjectTypeAttribute(systemObject.objectTypeId, approverAtrtributeName)
def approverObjectAttribute = systemObject.objectAttributeBeans.find{ it.objectTypeAttributeId == approverAttributeBean.id }
def approverUsers = approverObjectAttribute.objectAttributeValueBeans.collect{ userManager.getUserByKey(it.value as String)}
def approvers = defaultApprovers
if(approverUsers){
approvers = approverUsers*.name
}
approversFld.setFormValue(approvers)
}
Like Shah Baloch likes this

Thank you, we are using the Jira server version 8.13.18 in production and v8.20.7 in a lower environment. Script runner v6.48.1, and 6.49.0. I tested in both environments and the result was the same.

Thank you for your help

Thank you so much @Peter-Dave Sheehan it is working as expected regardless of leaving the multiple option check or uncheck from the field configuration.

The only default user part is not working. If System Approvers attributes field doesn't have a user it won't add the default user in the approver field.

Second, can you please be able to update the shorter script that the user added manually? I mean where you mapped Windows 10 with users and so on. I would like to have both options in case leadership won't allow us to add system attributes in the insight.

I appreciate your help.

I recommend you try to understand what each of the two scripts does differently and figure out how to change one into the other. Remember, if you deploy this, someone may have to maintain it in the future.

But if you attempt the exercise yourself and want to check youself, here is a version of the first script with modifications  we worked out along the way:

import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade

@WithPlugin('com.riadalabs.jira.plugins.insight')
@BaseScript FieldBehaviours fieldBehaviours
@PluginModule ObjectFacade objectFacade

def systemFld = getFieldById('customfield_10403')
def approversFld = getFieldById('customfield_10410')
def defaultApprovers = ['projLead']

def systemApproversMap = [
'Windows 10':['wUser1', 'wUser2', 'wUser3'],
'CentOS': ['cUser1', 'cUser2', 'cUser3']
]

def systemVal = systemFld.value
if(!systemVal){
//nothing selected, nothing to do, exit the script
return
}
def selectedKey
if(systemVal instanceof List){
selectedKey = systemVal[0] //There are multiple. Get only the first one
} else {
selectedKey = systemVal //This is what we get where there is a single value (whether multiple are allowed of not)
}
if(systemVal){
def systemObject = objectFacade.loadObjectBean(selectedKey)
def approvers = systemApproversMap[systemObject.label]
if(!approvers) approvers = defaultApprovers
approversFld.setFormValue(approvers)
}
Like Shah Baloch likes this

Thank you so much @Peter-Dave Sheehan the last script works perfectly.

However, I'm trying to understand both of the scripts. I'm trying to figure out how I can add the default approver in the approver field if the "System Approvers" attribute from System Object doesn't have any users. Can you be able to help me one last time figure out how can I get the default user if there isn't a user in the System Approvers attribute?

 

greatly appreciated your help

On the Map-based script, this should already be happening with this line:

if(!approvers) approvers = defaultApprovers

When the  the "approvers" variable is "falsy" (this means it is empty, null, false or zero) then we set it to the defaultApprovers value.

So that in the following line:

approversFld.setFormValue(approvers.join(', '))

We set the form value to that variable. The variable will either contain the approvers we identified from the map or the defaultApprover if the approvers had been empty.

In the object attribute based script, this section should do it

def approverUsers = approverObjectAttribute.objectAttributeValueBeans.collect{ userManager.getUserByKey(it.value as String)}
def approvers = defaultApprovers
if(approverUsers){
approvers = approverUsers*.name
}
approversFld.setFormValue(approvers.join(', '))

1) We get user objects from the attribute values
2) We temporarily assign the approvers variable to the default approvers (just as above)
3) If approverUsers is truthy (reverse of falsy defined above), then
4) Set the approvers to the names of the approverUsers
5) So that we can set the form value to those names (joined together with a comma and a space)

Thank you @Peter-Dave Sheehan the mapping script is working fine. The system approver attribute one is not adding default users. I'll give it a shot and see if I can be able to figure it out.

Yesterday you said, "Remember, if you deploy this, someone may have to maintain it in the future". I just realize it might be an issue for someone to go make changes in script or System Attributes. I am thinking to use groups instead of individual users that no one needs to touch the script. They can just maintain the groups.

I was able to make changes to the simpler script (users mapped with a value (windows 10)). I created a custom group picker field and it worked with no issue with that script. However, it didn't work with other scripts where we have the System Approver attribute within the insight object. I changed the attribute type from user to group and added the group to the object but it didn't show in the group picker field.

I believe group attributes somewhere need to be defined. I was not able to figure it out. How can define groups instead of users for the system approver attribute? Also, where can I find all these system objects, attribute beans, etc code information? I am still learning I'm able to create a simple script that can define a field with a name or id, but these are complicated. Can you recommend something that I can find these kinds of code for the future?

 

Thank you for your help.

Are you talking about "Group" attribute type in Insight? Or group picker custom field in Jira?

Here is a version of the script that will look into a group attribute (named Approval Group) and retrieve all the active users from the selected group(s).

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.jira.groovy.user.FieldBehaviours
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeBean
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeValueBean
import groovy.transform.BaseScript
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectTypeAttributeFacade

@WithPlugin('com.riadalabs.jira.plugins.insight')
@BaseScript FieldBehaviours fieldBehaviours

@PluginModule ObjectFacade objectFacade
@PluginModule ObjectTypeAttributeFacade objectTypeAttributeFacade
def groupManager = ComponentAccessor.groupManager

def systemFld = getFieldById('customfield_10403')
def approversFld = getFieldById('customfield_10410')
def groupAttribute = "Approval Group"
def defaultApprovers = ['projLead']

def systemVal = systemFld.value
if(!systemVal){
//nothing selected, nothing to do, exit the script
return
}
def selectedKey
if(systemVal instanceof List){
selectedKey = systemVal[0] //There are multiple. Get only the first one
} else {
selectedKey = systemVal //This is what we get where there is a single value (whether multiple are allowed of not)
}
if(systemVal){
def systemObject = objectFacade.loadObjectBean(selectedKey)
def groupAttributeBean = objectTypeAttributeFacade.loadObjectTypeAttribute(systemObject.objectTypeId, groupAttribute)
def groupObjectAttribute = systemObject.objectAttributeBeans.find{ it.objectTypeAttributeId == groupAttributeBean.id }
def approverUsers = groupObjectAttribute.objectAttributeValueBeans.collect{
groupManager.getUsersInGroup(it.value as String).findAll{it.active}
}.flatten().unique()
def approvers = defaultApprovers
if(approverUsers){
approvers = approverUsers*.name
}
approversFld.setFormValue(approvers.join(', '))
}

Hi @Peter-Dave Sheehan yes I was asking about Group attribute type in Insight. I created the "Approval Group" attribute associated with a group and it works fine. However, the default user part is not working. I mean if the "Approval Group" attribute is empty for an object like if there is no group added in "Approval Group" for the "Windows Server" object then it is not taking the default user that mentions in the script. How can I fix that? Thank you so much for your help.

Try like this:

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.jira.groovy.user.FieldBehaviours
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeBean
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeValueBean
import groovy.transform.BaseScript
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectTypeAttributeFacade

@WithPlugin('com.riadalabs.jira.plugins.insight')
@BaseScript FieldBehaviours fieldBehaviours

@PluginModule ObjectFacade objectFacade
@PluginModule ObjectTypeAttributeFacade objectTypeAttributeFacade
def groupManager = ComponentAccessor.groupManager

def systemFld = getFieldById('customfield_10403')
def approversFld = getFieldById('customfield_10410')
def groupAttribute = "Approval Group"
def defaultApprovers = ['projLead']

def systemVal = systemFld.value
if(!systemVal){
//nothing selected, nothing to do, exit the script
return
}
def selectedKey
if(systemVal instanceof List){
selectedKey = systemVal[0] //There are multiple. Get only the first one
} else {
selectedKey = systemVal //This is what we get where there is a single value (whether multiple are allowed of not)
}
if(systemVal){
def systemObject = objectFacade.loadObjectBean(selectedKey)
def groupAttributeBean = objectTypeAttributeFacade.loadObjectTypeAttribute(systemObject.objectTypeId, groupAttribute)
def groupObjectAttribute = systemObject.objectAttributeBeans.find{ it.objectTypeAttributeId == groupAttributeBean.id }
def approvers = defaultApprovers
def approverUsers
if(groupObjectAttribute && groupObjectAttribute.objectAttributeValueBeans) {
approverUsers = groupObjectAttribute.objectAttributeValueBeans.collect {
groupManager.getUsersInGroup(it.value as String).findAll { it.active }
}.flatten().unique()
}
if(approverUsers){
approvers = approverUsers*.name
}
approversFld.setFormValue(approvers.join(', '))
}
Like Shah Baloch likes this

It works, thank you so much @Peter-Dave Sheehan 

Do you have any recommendations? how can learn about all this scripting stuff? Thanks

Glad I was able to help.

Please be sure to mark the response as accepted.

As for learning scripting, having some coding background helps.

Adaptavist (the maker of scriptrunner) offer this on their site.

Beyond that, I think there is no better learning than by doing. You have to experiment and fail and try again until you build the experience of what works and what doesn't.

Start by taking existing scripts either from here in the community or from the library.adaptivist.com and then change them to suit your different requirements.

Throw various statements to the log and inspect the results as you change a keyword or line.

Like Shah Baloch likes this

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Confluence

An update on Confluence Cloud customer feedback – June 2022

Hi everyone, We’re always looking at how to improve Confluence and customer feedback plays an important role in making sure we're investing in the areas that will bring the most value to the most c...

71 views 0 0
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you