Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Next challenges

Recent achievements

  • Global
  • Personal

Recognition

  • Give kudos
  • Received
  • Given

Leaderboard

  • Global

Trophy case

Kudos (beta program)

Kudos logo

You've been invited into the Kudos (beta program) private group. Chat with others in the program, or give feedback to Atlassian.

View group

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Groovy set single select customfield

Dear community,

I wrote a script which will set an single select field to an specific value in dependency to the condition. I already studied other community entries which referred to the same problem. Unfortunately non of them seems to have a usable answer, at least for me.

Please do not look how clean the code is. Its a test and I may added to to much unneeded libraries, during the attempt to solve the problem. The problem I got is that Jira / Groovy seems not to know the method to finally set the single select field.

 

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.CustomFieldManager

// Set CustomFieldManager
def customFieldManager = ComponentAccessor.getCustomFieldManager()
// Set IssueManager
def issueManager = ComponentAccessor.getIssueManager()
// Set UserManager
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def optionsManager = ComponentAccessor.getOptionsManager()

def customField = customFieldManager.getCustomFieldObjectByName("Grenzwert")
def config = customField.getRelevantConfig(issue)
def options = optionsManager.getOptions(config)
def optionGruen = options.find { it.value == "<span class='status-macro aui-lozenge aui-lozenge-success'>grün</span>" }
def optionGelb = options.find { it.value == "<span class='status-macro aui-lozenge aui-lozenge-success'>grün</span>" }
def optionRot = options.find { it.value == "<span class='status-macro aui-lozenge aui-lozenge-success'>grün</span>" }

def ausfallzeit = customFieldManager.getCustomFieldObjectByName("Ausfallzeit")

def system = customFieldManager.getCustomFieldObjectByName("Betroffenes System")
def myIssue = issue

// grün
if ( ausfallzeit <= 15 && ( system == "NetApp Filer" || system == "VMWare" || system == "Internet" )) {
customField.setFormValue(optionGruen.optionId)
} else if ( ( ausfallzeit > 15 && ausfallzeit <= 30 ) && ( system == "IVIS" || system == "Oracle" || system == "MS SQL" )) {
customField.setFormValue(optionGruen.optionId)
// gelb
} else if ( ( ausfallzeit > 30 && ausfallzeit <= 60 ) && ( system == "NetApp Filer" || system == "VMWare" || system == "Internet")) {
customField.setFormValue(optionGelb.optionId)
} else if ( ( ausfallzeit > 60 && ausfallzeit <= 120 ) && ( system == "IVIS" || system == "Oracle" || system == "MS SQL" )) {
customField.setFormValue(optionGelb.optionId)
// rot
} else if ( ( ausfallzeit > 60 && ausfallzeit <= 120) && ( system == "NetApp Filer" || system == "VMWare" || system == "Internet")) {
customField.setFormValue(optionRot.optionId)
} else if ( ausfallzeit > 120 && ( system == "IVIS" || system == "Oracle" || system == "MS SQL")) {
customField.setFormValue(optionRot.optionId)
}

// Updates the issue without additional activity entries
issueManager.updateIssue(user, issue, EventDispatchOption.DO_NOT_DISPATCH, false)

 

1 answer

1 accepted

0 votes
Answer accepted
Hana Kučerová Community Leader Nov 23, 2020

Hi @Kristian Koniarz ,

when exactly do you want to execute this script? Is it a post function?

I believe, there are two main problems now:

  • the variable "system" is not string (it's com.atlassian.jira.issue.fields.CustomField), it is not possible to compare it with string
  • there is no such method as setFormValue for custom field in this context (this method is used in behaviours with com.onresolve.jira.groovy.user.FormField)

Please look at this script, it could help you to finish your code.

Hi @Hana Kučerová

Thanks a lot for your hints.

Yes its a post function. I got less errors meanwhile but the last line seems not to work.

Further it was necessary to add "...first().getRelevantConfig(issue))" in availableOptions. 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

// the name of the custom field (single select list type)
final customFieldName = "Grenzwert"

// the value of the new option to set
final newValue = "<span class='status-macro aui-lozenge aui-lozenge-success'>grün</span>"

// the issue key to update
final issueKey = "UHD-1297"

def issue = ComponentAccessor.issueManager.getIssueByCurrentKey(issueKey)
assert issue: "Could not find issue with key $issueKey"

def customField = ComponentAccessor.customFieldManager.getCustomFieldObjectsByName(customFieldName)
assert customField: "Could not find custom field with name $customFieldName"

def availableOptions = ComponentAccessor.optionsManager.getOptions(customField.first().getRelevantConfig(issue))

def optionToSet = availableOptions.find { it.value == newValue }
assert optionToSet: "Could not find option with value $newValue. Available options are ${availableOptions*.value.join(",")}"

customField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(customField), optionToSet), new DefaultIssueChangeHolder())

Best,

Kristian

Hi @Hana Kučerová

I am almost through. Do you know how to use the setValue function for single select fields? The API documentation is not really helpful, at least for me.

I receive all options with

def value = ComponentAccessor.optionsManager.getOptions(cfConfig)
return value

But how to set a value?

Best,

Kristian

Hi @Kristian Koniarz ,

which types your custom fields with names Grenzwert, Ausfallzeit and Betroffenes System have?

It seems to me, that:

  • Grenzwert = Select List (Single Choice)
  • Ausfallzeit = Number field
  • Betroffenes System = Select List (Single Choice)

I will try to improve your original code, but I need to know the types to handle the custom fields correctly. Thank you.

Hi @Hana Kučerová

Thanks for your reply.

  • Grenzwert (threshold) is an single select yes
  • Ausfallzeit (downtime) is an number yes
  • Betroffenes System (affected system) is an multi select

I only need to automatically set Grenzwert, the rest must be done manually for now.

I may found the problem, which implicates it would never work. Could it be that I need to set / manipulate behaviour of those fields with third party apps like Scriptrunner before I can actually set them?

I only have "MyGroovy" installed, seems those app wouldn´t do the job.

Best,

Kristian

Hana Kučerová Community Leader Nov 25, 2020

Hi @Kristian Koniarz ,

something like this could work for you, please try. I've tested with MyGroovy and it worked, but I didn't test it much. You need to insert it as a post function to your workflow. It assumes that Ausfallzeit and Betroffenes System custom fields are already set in the issue. The script get the values of these two fields and based on them set the third one, Grenzwert.

I'm not sure what you mean by "I need to set / manipulate behaviour of those fields with third party apps like Scriptrunner before I can actually set them?"

Both applications (ScriptRunner and MyGroovy) enables you to add some groovy scripts to your Jira. ScriptRunner has many, many more functionalities, but the basic one is the same.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.fields.config.FieldConfig
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.customfields.option.Option

final String limitCustomFieldName = "Grenzwert"
final String downTimeCustomFieldName = "Ausfallzeit"
final String affectedSystemCustomFieldName = "Betroffenes System"
final String limitOptionGreenValue = "grün"
final String limitOptionYellowValue = "gelb"
final String limitOptionRedValue = "rot"
final List<String> affectedSystemsList1 = ["NetApp Filer", "VMWare", "Internet"]
final List<String> affectedSystemsList2 = ["IVIS", "Oracle", "MS SQL"]

MutableIssue issue = issue
CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()
OptionsManager optionsManager = ComponentAccessor.getOptionsManager()

// get custom fields
CustomField limitCustomField = customFieldManager.getCustomFieldObjectsByName(limitCustomFieldName).first()
CustomField downTimeCustomField = customFieldManager.getCustomFieldObjectsByName(downTimeCustomFieldName).first()
CustomField affectedSystemCustomField = customFieldManager.getCustomFieldObjectsByName(affectedSystemCustomFieldName).first()

// get config for limit custom field
FieldConfig customFieldConfig = limitCustomField.getRelevantConfig(issue)
Options options = optionsManager.getOptions(customFieldConfig)

// get possible options for affected system custom field
Option optionGreen = options.find { it.value == limitOptionGreenValue }
Option optionYellow = options.find { it.value == limitOptionYellowValue }
Option optionRed = options.find { it.value == limitOptionRedValue }

// get current custom fields values
Option limitOption = issue.getCustomFieldValue(limitCustomField) as Option
Double downTime = issue.getCustomFieldValue(downTimeCustomField) as Double
List<Option> affectedSystemOptions = issue.getCustomFieldValue(affectedSystemCustomField) as List<Option>
List<String> affectedSystems = affectedSystemOptions.collect {Option affectedSystem ->
affectedSystem.getValue()
}

if (affectedSystems.size() > 0 && downTime > 0) {
// try to find the option based on the current custom field values
Boolean oneOfSystemsIsInList1 = affectedSystems.any { affectedSystemsList1.contains(it) }
Boolean oneOfSystemsIsInList2 = affectedSystems.any { affectedSystemsList2.contains(it) }
Option newLimitOption
if ( (downTime <= 15 && oneOfSystemsIsInList1) || (downTime > 15 && downTime <= 30 && oneOfSystemsIsInList2) ) {
newLimitOption = optionGreen
} else if ( (downTime > 30 && downTime <= 60 && oneOfSystemsIsInList1) || (downTime > 60 && downTime <= 120 && oneOfSystemsIsInList2) ) {
newLimitOption = optionYellow
} else if ( (downTime > 60 && downTime <= 120 && oneOfSystemsIsInList1) || (downTime > 120 && oneOfSystemsIsInList2) ) {
newLimitOption = optionRed
}
// if we've found the option, set it to limit custom field
if (newLimitOption) {
limitCustomField.updateValue(null, issue, new ModifiedValue(limitOption, newLimitOption), new DefaultIssueChangeHolder())
}
}
Like Kristian Koniarz likes this

Hello @Hana Kučerová

Let me take the opportunity to thank you for your time and effort your invest to help me.

I implemented your code as a post function, lucky us no syntax error or similar but unfortunately also not working after the first attempt. I am receiving the error below, which I can´t understand. Because each created list was initialised by you.

Cannot access first() element from an empty List

Further I did a quick test and removed the .first() for limit and downTime initialisation, to utilize the deprecated method.

CustomField limitCustomField = customFieldManager.getCustomFieldObjectByName(limitCustomFieldName)
CustomField downTimeCustomField = customFieldManager.getCustomFieldObjectByName(downTimeCustomFieldName)
CustomField affectedSystemCustomField = customFieldManager.getCustomFieldObjectsByName(affectedSystemCustomFieldName).first()

So I did another try with those changes and received a null pointer exception. Seems to be harder as I thought to implement such a easy post function.

Regarding the behaviours which I mentioned before, i was talking about those. As several community threads containing a similar question and all of them got it done with the help of scriptrunner and setting behaviours.

https://scriptrunner.adaptavist.com/5.3.9/jira/behaviours-overview.html

Best,

Kristian

Hana Kučerová Community Leader Nov 25, 2020

Hi @Kristian Koniarz ,

the error you mention is about not beeing able to find your custom field(s).

Please check the names of custom fields used in the config section of the script, if they are correct.

Alternatively you can replace

CustomField limitCustomField = customFieldManager.getCustomFieldObjectsByName(limitCustomFieldName).first()

with 


CustomField limitCustomField = customFieldManager.getCustomFieldObject("customfield_10400")

where 10400 needs to be replaced with the correct id of your customfield. 

Same thing could be done for all the three customfields. It is better to use id instead of names, because these ids don't change in time and they are unique.

About the second part. It depends on your use case. Behaviours typicall use case looks like this: when I edit my issue and change two fields, I want another one to became mandatory and prepopulated with some value. But the user needs to store these values manually. You've mentioned, that you need to set the value of select list during transition. So I thought your use case is: values of my two custom fields were already stored in the issue, I need to set the third one based on them after some transition (without the interaction with user).

Like Kristian Koniarz likes this

Hello @Hana Kučerová 

It worked with the ID´s.

Thanks so much, you definitely made my day.

Best,

Kristian

Suggest an answer

Log in or Sign up to answer
TAGS

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