Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

How do I insert new Custom Field options based on another single line custom field value.?

Stephen Higgins July 15, 2021

I am trying to take an incoming single line custom field value and insert it into several other single choice select list custom field values based on conditions. Any help would be appreciated. 

  • Incoming Custom Field Names and Options
    • Vendor Request Type
      • Add New Vendor
      • Update Existing Vendor
      • Remove/Archive Vendor
    • Vendor Type
      • Payroll
      • HRIS
      • COBRA
      • Direct Bill
    • Vendor Name - Actual 
      • Single Text Field
  • Outgoing Custom Field Lists to Update
    • Vendor Name
    • Payroll Vendor/s
    • HRIS Provider/s
    • Prior Administrator
    • COBRA Administrator
    • Direct Bill Administrator

Logic Being Requested:

  • If Vendor Request TypeAdd New Vendor 
    • If Vendor Name - Actual NOT IN Vendor Name
      • Add Vendor Name - Actual to Vendor Name
        • Alpha Sort List and Save
    • If Vendor Type = Payroll AND Vendor Name - Actual NOT IN Payroll Vendor/s
      • Add Vendor Name - Actual to Payroll Vendor/s
        • Alpha Sort List and Save
    • If Vendor Type = HRIS AND Vendor Name - Actual NOT IN HRIS Provider/s
      • Add Vendor Name - Actual to HRIS Provider/s
        • Alpha Sort List and Save
    • If Vendor Type = HRIS AND Vendor Name - Actual NOT IN Prior Administrator
      • Add Vendor Name - Actual to Prior Administrator
        • Alpha Sort List and Save
    • If Vendor Type = COBRA AND Vendor Name - Actual NOT IN COBRA Administrator 
      • Add Vendor Name - Actual to COBRA Administrator
        • Alpha Sort List and Save
    • If Vendor Type = Direct Bill AND Vendor Name - Actual NOT IN Direct Bill Administrator 
      • Add Vendor Name - Actual to Direct Bill Administrator
        • Alpha Sort List and Save

1 answer

1 accepted

0 votes
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.
July 16, 2021

Let me see if I understand... you want to have a JSM form to allow user to submit updates to some Custom Field options.

You probably want to run this from a scriptrunner postfunction.

If so, something like this might work:

import com.atlassian.jira.issue.customfields.option.LazyLoadedOption
import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.atlassian.servicedesk.api.requesttype.RequestTypeService
import com.atlassian.servicedesk.api.ServiceDeskManager
@WithPlugin("com.atlassian.servicedesk")
@PluginModule RequestTypeService requestTypeService
@PluginModule ServiceDeskManager serviceDeskManager

def cfm = ComponentAccessor.customFieldManager
def om = ComponentAccessor.optionsManager

//this map here is your critical logic ...
//it maps the values selected in the Vendor Type field with each Single Select that must be updated
//you could easily add new option/fields if you needed to
def vendorTypeFieldMap = [
'Payroll': ['Vendor Name','Payroll Vendor/s',''],
'HRIS': ['Vendor Name','HRIS Provider/s','Prior Administrator'],
'COBRA': ['Vendor Name','COBRA Administrator'],
'Direct Bill': ['Vendor Name','Direct Bill Administrator']
]

//custom fields objects that we'll use
def requestTypeCf = cfm.getCustomFieldObjectsByName('Customer Request Type')[0]
def vendorTypeCf = cfm.getCustomFieldObjectsByName('Vendor Type')[0]
def vendorNameCf = cfm.getCustomFieldObjectsByName('Vendor Name - Actual')[0]

//raw values from those custom fields in the correct type
def requestTypeKey = issue.getCustomFieldValue(requestTypeCf) as String
def newVendorType = issue.getCustomFieldValue(vendorTypeCf) as LazyLoadedOption
def newVendorName = issue.getCustomFieldValue(vendorNameCf) as String

//the Customer Request Type custom field returns the Request Type key which is GUID number
//first we need the service desk object
def serviceDesk = serviceDeskManager.getServiceDeskForProject(issue.projectObject)

//then we build a requestType query
def queryBuilder = requestTypeService.newQueryBuilder()
queryBuilder.requestOverrideSecurity(true)
queryBuilder.serviceDesk(serviceDesk.id)

//fetch all the request types and filter for the one that match the key
def requestType = requestTypeService.getRequestTypes(null, queryBuilder.build()).find{requestTypeKey.contains(it.properties.key as String)}

//the main logic starts here
if(requestType.name == 'Add New Vendor'){
//find the map item that matches the selection and loop through each fieldname to update
vendorTypeFieldMap[newVendorType.value].each{targetFieldName ->
def targetField = cfm.getCustomFieldObjectsByName(targetFieldName)[0]
def config = targetField.getRelevantConfig(issue)
def options = om.getOptions(config)
if(!options.any{it.value == newVendorName}){
om.createOption(config, null, 0, newVendorName)
//reload the options including the new one
options = om.getOptions(config)
//sort them and update the sequence
options.sort{it.value}.eachWithIndex{opt, i-> opt.sequence = i }
//store the new sequence
om.updateOptions(options)
}
}
}
Stephen Higgins July 19, 2021

@PD Sheehan, thank you so much for the quick response to this. Unfortunately, we do not have Service Desk as a result I am getting the following error:

The script could not be compiled:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during conversion: Requested plugin com.atlassian.servicedesk was not installed/enabled, compiling source unit Script38.groovy.

 Is there any other method to extract the Vendor Request type selection?

Everything else look like it would work. 

Thank you for the help!

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 19, 2021

ah... then if vendor request type is a standard "single select" field, then we can simplify the script

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

def cfm = ComponentAccessor.customFieldManager
def om = ComponentAccessor.optionsManager

//this map here is your critical logic ...
//it maps the values selected in the Vendor Type field with each Single Select that must be updated
//you could easily add new option/fields if you needed to
def vendorTypeFieldMap = [
'Payroll': ['Vendor Name','Payroll Vendor/s',''],
'HRIS': ['Vendor Name','HRIS Provider/s','Prior Administrator'],
'COBRA': ['Vendor Name','COBRA Administrator'],
'Direct Bill': ['Vendor Name','Direct Bill Administrator']
]

//custom fields objects that we'll use
def requestTypeCf = cfm.getCustomFieldObjectsByName('Vendor Request Type')[0]
def vendorTypeCf = cfm.getCustomFieldObjectsByName('Vendor Type')[0]
def vendorNameCf = cfm.getCustomFieldObjectsByName('Vendor Name - Actual')[0]

//raw values from those custom fields in the correct type
def requestType = issue.getCustomFieldValue(requestTypeCf) as LazyLoadedOption
def newVendorType = issue.getCustomFieldValue(vendorTypeCf) as LazyLoadedOption
def newVendorName = issue.getCustomFieldValue(vendorNameCf) as String

//the main logic starts here
if(requestType.value == 'Add New Vendor'){
//find the map item that matches the selection and loop through each fieldname to update
vendorTypeFieldMap[newVendorType.value].each{targetFieldName ->
def targetField = cfm.getCustomFieldObjectsByName(targetFieldName)[0]
def config = targetField.getRelevantConfig(issue)
def options = om.getOptions(config)
if(!options.any{it.value == newVendorName}){
om.createOption(config, null, 0, newVendorName)
//reload the options including the new one
options = om.getOptions(config)
//sort them and update the sequence
options.sort{it.value}.eachWithIndex{opt, i-> opt.sequence = i }
//store the new sequence
om.updateOptions(options)
}
}
}
Stephen Higgins July 19, 2021

@PD Sheehan I am receiving the following error when executed in post function. 

 

2021-07-19 15:09:09,423 ERROR [workflow.AbstractScriptWorkflowFunction]: Workflow script has failed on issue CO-6 for user 'shiggins'. 
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '[Payroll, HRIS, COBRA, Direct Bill]' with class 'java.util.ArrayList' to class 'com.atlassian.jira.issue.customfields.option.LazyLoadedOption' due to: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: com.atlassian.jira.issue.customfields.option.LazyLoadedOption(com.atlassian.jira.issue.customfields.option.LazyLoadedOption, com.atlassian.jira.issue.customfields.option.LazyLoadedOption, com.atlassian.jira.issue.customfields.option.LazyLoadedOption, com.atlassian.jira.issue.customfields.option.LazyLoadedOption)
at Script40.run(Script40.groovy:24)

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 19, 2021

What type of field is the "Vendor Type?

Based on the error, it would appear that maybe it's a Multi Select or Checkbox.

If so, the logic needs to be adjusted to account for that.

 

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

def cfm = ComponentAccessor.customFieldManager
def om = ComponentAccessor.optionsManager

//this map here is your critical logic ...
//it maps the values selected in the Vendor Type field with each Single Select that must be updated
//you could easily add new option/fields if you needed to
def vendorTypeFieldMap = [
'Payroll': ['Vendor Name','Payroll Vendor/s',''],
'HRIS': ['Vendor Name','HRIS Provider/s','Prior Administrator'],
'COBRA': ['Vendor Name','COBRA Administrator'],
'Direct Bill': ['Vendor Name','Direct Bill Administrator']
]

//custom fields objects that we'll use
def requestTypeCf = cfm.getCustomFieldObjectsByName('Vendor Request Type')[0]
def vendorTypeCf = cfm.getCustomFieldObjectsByName('Vendor Type')[0]
def vendorNameCf = cfm.getCustomFieldObjectsByName('Vendor Name - Actual')[0]

//raw values from those custom fields in the correct type
def requestType = issue.getCustomFieldValue(requestTypeCf) as LazyLoadedOption
def newVendorTypes = issue.getCustomFieldValue(vendorTypeCf) as ArrayList<LazyLoadedOption>
def newVendorName = issue.getCustomFieldValue(vendorNameCf) as String

//the main logic starts here
if(requestType.value == 'Add New Vendor'){
//find the map item that matches the selection and loop through each fieldname to update
newVendorTypes.each{newVendorType ->
vendorTypeFieldMap[newVendorType.value].each{targetFieldName ->
def targetField = cfm.getCustomFieldObjectsByName(targetFieldName)[0]
def config = targetField.getRelevantConfig(issue)
def options = om.getOptions(config)
if(!options.any{it.value == newVendorName}){
om.createOption(config, null, 0, newVendorName)
//reload the options including the new one
options = om.getOptions(config)
//sort them and update the sequence
options.sort{it.value}.eachWithIndex{opt, i-> opt.sequence = i }
//store the new sequence
om.updateOptions(options)
}
}
}
}
Stephen Higgins July 19, 2021

@PD Sheehan it is a multiselect issue type. It looks like it starts to update the lists now but fails once it get's past Vendor Name and Payroll. 

Custom field types:

  • Vendor Request Type = Select list (multiple choices)
  • Vendor Type = Select list (single choice)
  • Vendor Name - Actual = Text Field (single line)

Test Case used:

  • Vendor Request Type = Add New Vendor
  • Vendor Name - Actual = TEST1
  • Vendor Type = 
    • Payroll
    • HRIS
    • COBRA
    • Direct Bill

Error:

2021-07-19 15:22:29,486 ERROR [workflow.AbstractScriptWorkflowFunction]: Workflow script has failed on issue CO-6 for user 'shiggins'. 
java.lang.NullPointerException: Cannot invoke method getRelevantConfig() on null object
at com.atlassian.jira.issue.fields.CustomField$getRelevantConfig$9.call(Unknown Source)
at Script44$_run_closure1$_closure2.doCall(Script44.groovy:33)
at Script44$_run_closure1.doCall(Script44.groovy:31)
at Script44.run(Script44.groovy:30)

Stephen Higgins July 19, 2021

Found the issue it was with the extra ' ' at the end. It works perfectly now! Thank you so much for your help @PD Sheehan

'Payroll': ['Vendor Name','Payroll Vendor/s',''],

 

Like PD Sheehan likes this
Stephen Higgins January 31, 2022

@PD Sheehan after I have been using this script for sometime now, I have started to notice that the sort function is operating strangely. It isn't fully sorting in alphabetical order, but doing things like sorting words in all CAPs then Alpha. Is there an update I need to make to the options.sort{it.value}.eachWithIndex{opt, i-> opt.sequence = i } portion to correctly sort the options in alpha order before updating?

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.
January 31, 2022

You can try:

options.sort{it.value.toLowerCase()}.eachWithIndex{opt, i-> opt.sequence = i }
Stephen Higgins February 1, 2022

Thank you @PD Sheehan , I think that did the trick!

Suggest an answer

Log in or Sign up to answer