I am trying to populate the JIRA checklist plugin with a bunch of hard coded values using Post Functions, i think I have the necessary code to make it work, but I am trying to figure out what kind of Object the CheckList Plugin takes so it can be populated.
def cf = customFieldManager.getCustomFieldObjectByName("Checklist_Field") def cfConfig = cf.getRelevantConfig(issue) value = // JIRA CHECKLIST OBJECT? issue.setCustomFieldValue(cf, value)
It doesn't seem to work when i use a List with string values. I am aware it needs a checked, and mandatory boolean along with a String for the name of the option, but I am not sure how to format it. I have tried using the OptionsManager using similar code to this:
import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.Issue import com.atlassian.jira.issue.fields.CustomField def optionManager = ComponentAccessor.getOptionsManager() def option = optionManager.allOptions.find {it.value == request_type_value6} if (option) { // this option already exists } else { def newOption = optionManager.createOption(request_type7.getRelevantConfig(issue), null, 100, request_type_value6) }
but that didnt work either.
Any suggestions would be great.
Hi Joshi,
The value returned by the customfield is of a specific type (ChecklistItem) which means that pure strings will not work. When creating an item, to convert a json string to a CheklistItem, you need to get the customefieldType from the customfield and call getSingularObjectFromString. The string needs to be a json notation in the form
{"name" : "My Checklist Item", "checked" : true, "mandatory" : false}
You can then save the customfield value. When saving the customfield value, it needs to be a collection of ChecklistItems.
If you simply need to edit a checklist item, keep it in its ChecklistItem form and use its accessors.
By the way, not sure if you are aware but Checklist offers Post Workflow functions to change a checklist.
Just a quick question, how would you go about adding multiple items to the checklist?
I tried doing this:
{"name" : "My Checklist Item", "checked" : true, "mandatory" : false},{"name" : "Another Item", "checked" : true, "mandatory" : false},{"name" : "A Third Item", "checked" : true, "mandatory" : false}
I passed the above json into the getSingularObjectFromString, but that didnt work. Is there another method to use?
cheers
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Instead try to call getSingularObjectFromString for each json item and add the returned object to a collection. Then pass the collection to setCustomfieldValue.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Excellent thank you @Whyves it worked,
This was the code I used to get it working:
import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.CustomFieldManager def customFieldManager = ComponentAccessor.getCustomFieldManager(); def cf = customFieldManager.getCustomFieldObjectByName("Pre-Release Task"); def cfConfig = cf.getRelevantConfig(issue) def cfType = cf.getCustomFieldType() def value = cfType.getSingularObjectFromString('{"name" : "My Checklist Item", "checked" : true, "mandatory" : false}') issue.setCustomFieldValue(cf, [value])
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Joshi Shushruth do you think it's possible to show the code you used to add multiple items to the checklist?
Thanks a lot in advance, this is really useful!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
def value1 = cfType.getSingularObjectFromString('{"name" : "Item1", "checked" : true, "mandatory" : false}') def value2 = cfType.getSingularObjectFromString('{"name" : "Item2", "checked" : true, "mandatory" : true}') def value3 = cfType.getSingularObjectFromString('{"name" : "Item3", "checked" : true, "mandatory" : false}') def value4 = cfType.getSingularObjectFromString('{"name" : "Item4", "checked" : true, "mandatory" : false}') log.warn " CRT value = ${crt_value} and CRT = ${crt}" if (crt_value == "Request type") { log.warn " CRT value = ${crt_value}" issue.setCustomFieldValue(cf, [value1,value2,value3,value4]) }
Above code is working for adding multiple values in check list but issue is it is not maintaning order of each values.
It is changing order of items randomly
I tried with ArrayList also but still not able to maintain order
Please help in knowing how to maintain order of items like
item1
item2
item3
...
..
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Usually, it will rank them in the order they are received. I'm surprised that an array list didn't work.
If you want to force a rank, add the "rank" property to the json string.
{"name" : "Item4", "checked" : true, "mandatory" : false, "rank": 0}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Whyves,
Thanks for your help and I appriciate your quick turnaround
It is working fine. Just adding code for others to help
I am new to Groovy scripting, since i worked as only Jira Admin , so kindly provide any document link in which, it has all properties and syntex etc like you mentioned above for rank.
Thanks in advance
Balvant
def value1 = cfType.getSingularObjectFromString('{"name" : "Item1", "checked" : true, "mandatory" : false , "rank" : 0}') def value2 = cfType.getSingularObjectFromString('{"name" : "Item2", "checked" : true, "mandatory" : true , "rank" : 1}') def value3 = cfType.getSingularObjectFromString('{"name" : "Item3", "checked" : true, "mandatory" : false , "rank" : 2}') def value4 = cfType.getSingularObjectFromString('{"name" : "Item4", "checked" : true, "mandatory" : false , "rank" : 3}') def value5 = cfType.getSingularObjectFromString('{"name" : "Item5", "checked" : true, "mandatory" : false , "rank" : 4}') def value6 = cfType.getSingularObjectFromString('{"name" : "Item6", "checked" : true, "mandatory" : true , "rank" : 5}') def value7 = cfType.getSingularObjectFromString('{"name" : "Item7", "checked" : true, "mandatory" : false , "rank" : 6}') def value8 = cfType.getSingularObjectFromString('{"name" : "Item8", "checked" : true, "mandatory" : false , "rank" : 7}') List item = new ArrayList(); item.add(value1) item.add(value2) item.add(value3) item.add(value4) item.add(value5) item.add(value6) item.add(value7) item.add(value8) log.warn " CRT value = ${crt_value} and CRT = ${crt} before insert" if (crt_value == "Request_Type") { issue.setCustomFieldValue(cf, item) log.warn "done with adding items ${item}" }
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Whyves,
One small doubt, If we want to append few more values to existing Checklist because setCustomFieldValue is deleting all existing values and adding new values.
Suppose if i want to add item9, Item10, Item11 in next transition
Thanks in advance
Balvant
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
If you want to manipulate an existing list, you should get the customfield value first via its standard API (see other example on the forum) and then manipulate the list. You should avoid always rewriting the entire list.
So in essence:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Yves,
Please could you help on how to add checklist from create event
I am not able to add checklist for create event, but using same below script I am able to add for other workflow transitions like open to In Progress.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
def customFieldManager = ComponentAccessor.getCustomFieldManager();
def cf = customFieldManager.getCustomFieldObjectByName("Checklist");
def cfConfig = cf.getRelevantConfig(issue)
def cfType = cf.getCustomFieldType()
def value1 = cfType.getSingularObjectFromString('{"name" : "Item1", "checked" : true, "mandatory" : false , "rank" : 0}')
def value2 = cfType.getSingularObjectFromString('{"name" : "Item2", "checked" : true, "mandatory" : true , "rank" : 1}')
def value3 = cfType.getSingularObjectFromString('{"name" : "Item3", "checked" : true, "mandatory" : false , "rank" : 2}')
def value4 = cfType.getSingularObjectFromString('{"name" : "Item4", "checked" : true, "mandatory" : false , "rank" : 3}')
log.warn "In side scripttttttttttttttttttt"
List item = new ArrayList();
item.add(value1)
item.add(value2)
item.add(value3)
item.add(value4)
issue.setCustomFieldValue(cf, item)
log.warn "END of script -------------------------------"
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
Maybe it's due to the order of your script? If your scripts somehow runs before Jira saves the issue, it will most likely be overridden by the issue which should also save the checklist data. In any case, accessing and saving the checklist data should be the same in any transition. I really think it's due to somehow Jira overwriting the Checklist data after you.
Yves
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi all,
Did I miss something or, as said in API doc for issue.setCustomFieldValue() :
Sets a custom field value on this Issue Object, but does not write it to the database. This is highly misleading.
Are you making updates to issues but not storing these updates ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Eddie,
Just noticed the description myself now but I thought that the data was persisted to the DB. We would have to validate but to my knowledge this methods calls the custom field type method which updates the data. Otherwise, you can call the updateIssue or updateValue on the custom field type to persist the data.
Yves
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I've tried both of these code suggestions (with Array and without), but I'm getting the error, note it's for the Array example but get similar error with other example):
{code}
[Static type checking] - Cannot find matching method com.atlassian.jira.issue.Issue#setCustomFieldValue(com.atlassian.jira.java.util.ArrayList). Please check if the declared type is correct and if the method exists.
{code}
Has anyone had this problem or have an idea how to fix it?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Barb!
Your error message seems to indicate that you are passing only one parameter (the array) to the `setCustomFieldValue` function, but this function receives two parameters: The Custom Field and the Value.
Could you validate the method call and possibly link us the part of your code that has the error.
Regards,
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sorry I used the code as exactly above with only a substitution of my custom field name, which is "DoD"
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
def customFieldManager = ComponentAccessor.getCustomFieldManager();
def cf = customFieldManager.getCustomFieldObjectByName("DoD");
def cfConfig = cf.getRelevantConfig(issue)
def cfType = cf.getCustomFieldType()
def value1 = cfType.getSingularObjectFromString('{"name" : "Item1", "checked" : true, "mandatory" : false , "rank" : 0}')
def value2 = cfType.getSingularObjectFromString('{"name" : "Item2", "checked" : true, "mandatory" : true , "rank" : 1}')
def value3 = cfType.getSingularObjectFromString('{"name" : "Item3", "checked" : true, "mandatory" : false , "rank" : 2}')
def value4 = cfType.getSingularObjectFromString('{"name" : "Item4", "checked" : true, "mandatory" : false , "rank" : 3}')
log.warn "In side scripttttttttttttttttttt"
List item = new ArrayList();
item.add(value1)
item.add(value2)
item.add(value3)
item.add(value4)
issue.setCustomFieldValue(cf, item)
log.warn "END of script -------------------------------"
Error is on the second to last line:
issue.setCustomFieldValue(cf, item)
I didn't alter it much because this looked like a good test which I could alter later once working.
Thanks for your help!
-Barb
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Barb!
I believe I understand what is happening. The issue provided by your scope (by ScriptRunner?) is not a MutableIssue, so it cannot be modified.
The first thing I would try is to cast your issue as a MutableIssue or IssueImpl but this would only work if the Issue is of that type already.
import com.atlassian.jira.issue.MutableIssue
...
((MutableIssue) issue).setCustomFieldValue(cf, item);
If this error is showing in your Script Editor only, I would suggest you to still save that code and try it out, since sometimes the code runs properly even if the Script Editor tells it won't.
Regards,
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks Maxime. Using MutableIssue has removed the error message but sadly the outcome doesn't update the checklist. I'll keep experimenting.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Barb,
Using setCustomFieldValue does not update the Issue by itself, an IssueService must be used to save the changes. Usually ScriptRunner does that automatically at the end of an Issue Listener.
If you are inside a Listener, can you tell me which one? If you are using Behaviors, I believe you are not using the right tool and you should take a look at Listeners. (Both comes with ScriptRunner).
Regards,
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you ... I'm using Project Automation add-on. The trigger is ticket transition and the action is this scriptrunner script.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I got a little help locally and wanted to post the final version if it can be of help to others. Thanks Maxime for your patience.
{code}
import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.CustomFieldManager import com.atlassian.jira.issue.MutableIssue import com.atlassian.jira.event.type.EventDispatchOption def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() def customFieldManager = ComponentAccessor.getCustomFieldManager(); def cf = customFieldManager.getCustomFieldObjectByName("Checklist"); def cfConfig = cf.getRelevantConfig(issue) def cfType = cf.getCustomFieldType() def value = cfType.getSingularObjectFromString('{"name" : "something", "checked" : false, "mandatory" : false}') ((MutableIssue) issue).setCustomFieldValue(cf, [value]) ComponentAccessor.getIssueManager().updateIssue(user, issue, EventDispatchOption.ISSUE_UPDATED, false)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
I wanted to do the same thing, have checklist items populated through the create subtask post script function.
I tried your script but I get that error message for the line:
def customFieldManager = ComponentAccessor.getCustomFieldManager();
Error is: Variable "customFieldManager" masks a binding variable of the same name. Please choose a different name for variable: "customFIeldManager".
I tried a different name but then I get other errors...
Any hints?
Thanks!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Looks like you already have a `customFieldManager` variable in your script environment, probably automatically added by Scriptrunner for you, so you can potentially just remove that line of code.
So we will need to know about other errors you have when you changed its name.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
First, if I removed the line : def customFieldManager = ComponentAccessor.getCustomFieldManager();
Then I get this warning for line:
def cf = customFieldManager.getCustomFieldObjectByName("Checklist");
"use CustomFieldManager.getCustomFieldObjectsByName(string) instead"
... So it says to add an "s" to Object. But doing this brings a couple of errors:
For line: def cfConfig = cf.getRelevantConfig(issue):
"Static type checking - Cannot find matching method java.util.Collection#getRelevantConfig (com.atlassian.jira.issue.Mutable. Please check if the decalred type is correct and if the method exists."
Got this static error also with lines:
def cfType = cf.getCustomFieldType()
def value = cfType.getSingularObjectFromString('{"name" : "something", "checked" : false, "mandatory" : false}')
((MutableIssue) issue).setCustomFieldValue(cf, [value])
ComponentAccessor.getIssueManager().updateIssue(user, issue, EventDispatchOption.ISSUE_UPDATED, false)
So then I tried to rename the variable to custFieldManager:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.event.type.EventDispatchOption
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def custFieldManager = ComponentAccessor.getCustomFieldManager();
def cf = custFieldManager.getCustomFieldObjectByName("Checklist");
def cfConfig = cf.getRelevantConfig(issue)
def cfType = cf.getCustomFieldType()
def value = cfType.getSingularObjectFromString('{"name" : "something", "checked" : false, "mandatory" : false}')
((MutableIssue) issue).setCustomFieldValue(cf, [value])
ComponentAccessor.getIssueManager().updateIssue(user, issue, EventDispatchOption.ISSUE_UPDATED, false)
Then again on the line:
def cf = custFieldManager.getCustomFieldObjectByName("Checklist");
I get this message: "use CustomFieldManager.getCustomFieldObjetsByName(String) instead
So it wants me to add an "s" after Object in there... And to use "CustomFieldManager" lol.
So by doing this, again get the static type errors mentioned above.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you for the detailed explanation!
If you look at documentation of the Custom Field Manager, you will see there is a getCustomFieldObjectByName method but it is deprecated.
What you are seeing is potentially only a warning (and not an actual error that prevents the code from executing at run time).
In Jira, many custom fields can have the same name, so Atlassian did not consider safe to retrieve a custom field by name, that is why they deprecated it in favor of using a method that returns All custom fields with that name (getCustomFieldObjectsByName).
But the best would be to actually use another method getCustomFieldObject(Long id) instead, which is safe since it retrieves your Custom Field by unique ID. You can find out your custom field ID by looking at the browser URL parameters while configuring your field (secure/admin/ConfigureCustomField!default.jspa?customFieldId=10101). So in that example, you would replace the line for:
I hope this helps :)
Regards,
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I used the FieldObject with the custom field ID and it validated without errors or warnings.
But then when trying to switch to my status that creates the subtasks (the code below is in my create subtask post script function), I then get this workflow error:
org.ofbiz.core.entity.GenericTransactionException: Commit failed, rollback previously requested by nested transaction.
It seems that you have tried to perform an illegal workflow operation.
If you think this message is wrong, please contact your Jira administrators.
Code used:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.event.type.EventDispatchOption
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def CustomFieldManager = ComponentAccessor.getCustomFieldManager();
def cf = CustomFieldManager.getCustomFieldObject("customfield_19900");
def cfConfig = cf.getRelevantConfig(issue)
def cfType = cf.getCustomFieldType()
def value = cfType.getSingularObjectFromString('{"name" : "something", "checked" : false, "mandatory" : false}')
((MutableIssue) issue).setCustomFieldValue(cf, [value])
ComponentAccessor.getIssueManager().updateIssue(user, issue, EventDispatchOption.ISSUE_UPDATED, false)
Thanks for your patience :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
The error message is unfortunately not specific enough to indicate to what is happening. You could check your Jira logs and see if there is a more complete error message in it.
Where is your script running? A Listener, a Post Function? Depending on when the script is executed, you might want to try removing the last line of the script that causes the update and see if the issue still gets updated and the error prevented.
Also, we've got a bunch of Script Examples now in our documentation, one of those might work better.
If your use-case is very simple (adding items on transition), you might be better off with a Checklist Post Function.
Regards
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
To find the object type I usually retrieve an existing value and call getClass().getName() on that object
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.