Hello,
Usually, we run groovy script on workflow's post function.
On my case, I am calling a groovy script each day from a scheduler (Systems-> Services)
On this script I have to update a value of a custom field.
I am able to update a value from a post function, but how to do in this case?
Thanks
Hi Robi,
This depends on the type of your custom field, but for a test field should be something like
import com.atlassian.jira.issue.Issue import com.atlassian.jira.issue.ModifiedValue import com.atlassian.jira.issue.util.DefaultIssueChangeHolder import com.atlassian.jira.component.ComponentAccessor def customFieldManager = ComponentAccessor.getCustomFieldManager() def tgtField = customFieldManager.getCustomFieldObjects(issue).find {it.name == "testString"} if (tgtField) { def changeHolder = new DefaultIssueChangeHolder(); tgtField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(tgtField), "new value"),changeHolder); }
@Thanos Batagiannis [Adaptavist]
I don't want to call my script from my workflow, but from scheduler...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi robi anton,
how u create a new custom field in JIRA with groovy script runner .
can u help on this .
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
When your script is run from scheduler, there is no proper authentication context (no one is logged in), so you need to replace your code
def user = ComponentAccessor.getJiraAuthenticationContext().getUser().directoryUser
with
def USER_NAME = "jira-automation" // replace with existing user def user = ComponentAccessor.getUserManager().getUserByName(USER_NAME)?.getDirectoryUser()
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Thanos Batagiannis [Adaptavist]
This is my script that I call from my wf postfunction.
When I call it from the scheduler, it fails for the variable user, also for the jquery, etc.
Could someone correct my script ?
The script should be ran by scheduler . Thanks
import com.atlassian.jira.bc.issue.search.SearchService import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.search.SearchException import com.atlassian.jira.web.bean.PagerFilter def jqlSearch = "project = 'AISC - Suivi des demandes' and ('Date de livraison' >= startOfMonth(-1) and 'Date de livraison' <=endOfMonth(-1))" //If you are going to use a JIRA version => 7 then you should get the ApplicationUser instead of User, to do that remove the .directoryUser def user = ComponentAccessor.getJiraAuthenticationContext().getUser().directoryUser def searchService = ComponentAccessor.getComponentOfType(SearchService.class) SearchService.ParseResult parseResult = searchService.parseQuery(user, jqlSearch) def value = 0 def customFieldManager = ComponentAccessor.getCustomFieldManager() def myCustomField = customFieldManager.getCustomFieldObjectByName("Temps d'intervention") if (parseResult.isValid()) { try { def results = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()) def issues = results.getIssues() issues.each { if (it.getCustomFieldValue(myCustomField)) value += it.getCustomFieldValue(myCustomField).toInteger() } } catch (SearchException e) { e.printStackTrace() } } else { log.warn("Invalid query") return null } return value
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
JIRA version ? Also how this script connects to the 'update custom field' question ? Also more information (maybe a screenshot) on the service configuration and any errors in your log files... Help me to help you
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Thanos Batagiannis [Adaptavist]
My JIRA version is 6.2.6
Script Runner Version: 2.1.16
Maybe my question was not so clear. I will explain properly
I want to use the same groovy script that I was using from my workflow (on a transition).
As I want to run it all the first of month, I need to call this script from a scheduler.
What does my script do?
It executes a jqlquery, then for each issue, it calculates a sum of values contained on a custom value.
Then I update the calculated value on an other custom field.
From a workflow post-function, It works properly, but when I call it form a scheduler, I have some ERRORS.
When I am running the script by the scheduler:
2016-04-14 10:07:06,171 QuartzScheduler_Worker-3 ERROR ServiceRunner Statistiques [onresolve.jira.gr oovy.GroovyRunner] The script failed : javax.script.ScriptException: javax.script.ScriptException: java .lang.NullPointerException: Cannot get property 'directoryUser' on null object
2016-04-14 10:07:06,171 QuartzScheduler_Worker-3 ERROR ServiceRunner Statistiques [onresolve.jira.gr oovy.GroovyService] Script service failed: /app/jira/jira_data/scripts/scriptSommeCourant.groovy
javax.script.ScriptException: javax.script.ScriptException: java.lang.NullPointerException: Cannot get property 'directoryUser' on null object
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:117)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:103)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:212)
at com.onresolve.jira.groovy.GroovyRunner.runFile(GroovyRunner.java:102)
at com.onresolve.jira.groovy.GroovyRunner.run(GroovyRunner.java:62)
at com.onresolve.jira.groovy.GroovyService.run(GroovyService.java:52)
at com.atlassian.jira.service.JiraServiceContainerImpl.run(JiraServiceContainerImpl.java:61)
at com.atlassian.jira.service.ServiceRunner.execute(ServiceRunner.java:48)
at org.quartz.core.JobRunShell.run(JobRunShell.java:195)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)
Caused by: javax.script.ScriptException: java.lang.NullPointerException: Cannot get property 'directory User' on null object
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:318)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:111)
... 9 more
Caused by: java.lang.NullPointerException: Cannot get property 'directoryUser' on null object
at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:56)
at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:156)
at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty(NullCallSite.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java: 227)
at Script97.run(Script97.groovy:27)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:315)
... 10 more
For the error of directoryUser, the script search a current user executing the script. But there is no user running this..only the scheduler. I have tried to give the id of variable "user" manually like:
def user = "yk3520:10100"
Second error:
2016-04-14 10:31:06,053 QuartzScheduler_Worker-2 ERROR ServiceRunner Statistiques [onresolve.jira.groovy.GroovyRunner] The script failed : javax.script.ScriptException: javax.script.ScriptException: groovy.lang.MissingMethodException: No signature of method: com.atlassian.jira.bc.issue.search.DefaultSearchService.parseQuery() is applicable for argument types: (java.lang.String, java.lang.String) values: [yk3520:10100, project = 'AISC - Suivi des demandes' and ('Date de livraison' >= startOfMonth() and 'Date de livraison' <=now()) and status = Validation]
Possible solutions: parseQuery(com.atlassian.crowd.embedded.api.User, java.lang.String)
2016-04-14 10:31:06,055 QuartzScheduler_Worker-2 ERROR ServiceRunner Statistiques [onresolve.jira.groovy.GroovyService] Script service failed: /app/jira/jira_data/scripts/scriptSommeCourant.groovy
javax.script.ScriptException: javax.script.ScriptException: groovy.lang.MissingMethodException: No signature of method: com.atlassian.jira.bc.issue.search.DefaultSearchService.parseQuery() is applicable for argument types: (java.lang.String, java.lang.String) values: [yk3520:10100, project = 'AISC - Suivi des demandes' and ('Date de livraison' >= startOfMonth() and 'Date de livraison' <=now()) and status = Validation]
Possible solutions: parseQuery(com.atlassian.crowd.embedded.api.User, java.lang.String)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:117)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:103)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:212)
at com.onresolve.jira.groovy.GroovyRunner.runFile(GroovyRunner.java:102)
at com.onresolve.jira.groovy.GroovyRunner.run(GroovyRunner.java:62)
at com.onresolve.jira.groovy.GroovyService.run(GroovyService.java:52)
at com.atlassian.jira.service.JiraServiceContainerImpl.run(JiraServiceContainerImpl.java:61)
at com.atlassian.jira.service.ServiceRunner.execute(ServiceRunner.java:48)
at org.quartz.core.JobRunShell.run(JobRunShell.java:195)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)
Caused by: javax.script.ScriptException: groovy.lang.MissingMethodException: No signature of method: com.atlassian.jira.bc.issue.search.DefaultSearchService.parseQuery() is applicable for argument types: (java.lang.String, java.lang.String) values: [yk3520:10100, project = 'AISC - Suivi des demandes' and ('Date de livraison' >= startOfMonth() and 'Date de livraison' <=now()) and status = Validation]
Possible solutions: parseQuery(com.atlassian.crowd.embedded.api.User, java.lang.String)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:318)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:111)
... 9 more
Caused by: groovy.lang.MissingMethodException: No signature of method: com.atlassian.jira.bc.issue.search.DefaultSearchService.parseQuery() is applicable for argument types: (java.lang.String, java.lang.String) values: [yk3520:10100, project = 'AISC - Suivi des demandes' and ('Date de livraison' >= startOfMonth() and 'Date de livraison' <=now()) and status = Validation]
Possible solutions: parseQuery(com.atlassian.crowd.embedded.api.User, java.lang.String)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)
at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:46)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
at Script96.run(Script96.groovy:30)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:315)
... 10 more
For resume:
I want to get a sum of values from custom fields of issues.
The value of this sum should be updated on a another custom field.
And this script should be ran by a scheduler.
Hope you can help me now @Thanos Batagiannis [Adaptavist]
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Robi,
What Jozef spotted plus the latest part where you should get the custom field of the issue that you want to save the result.
import com.atlassian.jira.bc.issue.search.SearchService import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.ModifiedValue import com.atlassian.jira.issue.search.SearchException import com.atlassian.jira.issue.util.DefaultIssueChangeHolder import com.atlassian.jira.web.bean.PagerFilter def jqlSearch = "project = 'AISC - Suivi des demandes' and ('Date de livraison' >= startOfMonth(-1) and 'Date de livraison' <=endOfMonth(-1))" def userManager = ComponentAccessor.getUserManager() def issueManager = ComponentAccessor.getIssueManager() def searchService = ComponentAccessor.getComponentOfType(SearchService) def user = userManager.getUserByName("admin").directoryUser SearchService.ParseResult parseResult = searchService.parseQuery(user, jqlSearch) def value = 0 def customFieldManager = ComponentAccessor.getCustomFieldManager() def myCustomField = customFieldManager.getCustomFieldObjectByName("Number Field") if (parseResult.isValid()) { try { def results = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()) results.getIssues().each { value += it.getCustomFieldValue(myCustomField) ?: 0 } } catch (SearchException e) { e.printStackTrace() } } else { log.warn("Invalid query") return null } // Save the value at custom field with name A number custom field of issue with key TEST-1 def targetIssue = issueManager.getIssueByCurrentKey("TEST-1") def customField = customFieldManager.getCustomFieldObjects(targetIssue).find {it.name == "A number custom field"} if (customField) { def changeHolder = new DefaultIssueChangeHolder() customField.updateValue(null, targetIssue, new ModifiedValue(targetIssue.getCustomFieldValue(customField), value),changeHolder) log.debug "Custom field $customField.name} updated with value ${value}" return } log.warn "Custom field ${customField?.name} was not updated"
Maybe there should be a couple of checks that you should take care (such as if the jql returned any issues) in order to know exactly what went wrong. But the script above is a tested and is a good start.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks a lot @Thanos Batagiannis [Adaptavist]
It works very well.
As you said, I have to make a couple of checks to run the script.
I had to replace the first if condition my my own script.
Then in the line "new
ModifiedValue(targetIssue.getCustomFieldValue(customField), value),changeHolder)", I have to add value.toString().
Here is my script:
import org.apache.log4j.Category import com.atlassian.jira.bc.issue.search.SearchService import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.search.SearchException import com.atlassian.jira.web.bean.PagerFilter import com.atlassian.jira.issue.util.IssueChangeHolder import com.atlassian.jira.issue.util.DefaultIssueChangeHolder; import com.atlassian.jira.issue.ModifiedValue import com.atlassian.jira.issue.CustomFieldManager import com.atlassian.jira.ComponentManager; import com.atlassian.jira.issue.fields.CustomField import com.atlassian.jira.issue.customfields.manager.OptionsManager import com.atlassian.jira.issue.customfields.option.Option import com.atlassian.jira.issue.*; import java.sql.Timestamp Calendar localCalendar = Calendar.getInstance(TimeZone.getDefault()); int currentDay = localCalendar.get(Calendar.DATE); println currentDay def jqlSearch = "project = 'AISC - Suivi des demandes' and status was in (Validation) and ('Date de livraison' >= startOfMonth(-1) and 'Date de livraison' <=endOfMonth(-1))" def userManager = ComponentAccessor.getUserManager() def issueManager = ComponentAccessor.getIssueManager() def searchService = ComponentAccessor.getComponentOfType(SearchService) def user = userManager.getUserByName("yk3520").directoryUser SearchService.ParseResult parseResult = searchService.parseQuery(user, jqlSearch) def value = 0 def customFieldManager = ComponentAccessor.getCustomFieldManager() def myCustomField = customFieldManager.getCustomFieldObjectByName("Temps d'intervention") if (parseResult.isValid()) { try { def results = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()) def issues = results.getIssues() issues.each { if (it.getCustomFieldValue(myCustomField)) value += it.getCustomFieldValue(myCustomField).toInteger() } } catch (SearchException e) { e.printStackTrace() } } else { log.warn("Invalid query") return null } // Save the value at custom field with name A number custom field of issue with key TEST-1 def targetIssue = issueManager.getIssueByCurrentKey("SL-8") def customField = customFieldManager.getCustomFieldObjects(targetIssue).find {it.name == "Total intervention M-1"} if (customField) { def changeHolder = new DefaultIssueChangeHolder() customField.updateValue(null, targetIssue, new ModifiedValue(targetIssue.getCustomFieldValue(customField), value.toString()),changeHolder) log.debug "Custom field $customField.name} updated with value ${value}" return } log.warn "Custom field ${customField?.name} was not updated"
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Thanos Batagiannis [Adaptavist]
@Jamie Echlin [Adaptavist]
Hi,
In the above script, I was able to get the value of custom fields. But now, I want to get the values of system fields like "Orignal estimate".
I have tried to change this line :
def myCustomField = customFieldManager.getCustomFieldObjectByName("Temps d'intervention")
by
def myCustomField = customFieldManager.getEstimate()
But I have error like:
No signature of method: com.atlassian.jira.issue.managers.DefaultCustomFieldManager.getEstimate() is applicable for
Am I correct?
Or is there other way to do that?
Thanks!!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
issue.estimate
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Jamie Echlin [Adaptavist]
Could you give me the full line please?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
that was the full line, to get the issue estimate. It's not a custom field, so don't use the custom field manager.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Jamie Echlin [Adaptavist]
But how to use it on my script?
It returns a value who is not the original estimated time.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
try issue.originalEstimate
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Jamie Echlin [Adaptavist]
Thanks a lot, it works!
Here is my correction :
if (parseResult.isValid()) { try { def results = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()) def issues = results.getIssues() issues.each { if (it.originalEstimate) //60 beacause it.originalEstimate returns the value in seconds value += (it.originalEstimate)/60 } } catch (SearchException e) { e.printStackTrace() } } else { log.warn("Invalid query") return null }
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Here is script for updating one cf depending on another :
import com.atlassian.jira.issue.CustomFieldManager; import com.atlassian.jira.issue.fields.CustomField; import com.atlassian.jira.issue.util.DefaultIssueChangeHolder; import com.atlassian.jira.ComponentManager; import com.atlassian.jira.issue.customfields.option.Options; import com.atlassian.jira.issue.customfields.option.Option; import com.atlassian.jira.issue.ModifiedValue; import com.atlassian.jira.component.ComponentAccessor; // Custom field ID's int sourceCfID = 10101; int targetCfID = 10102; // Option ID's of target custom field int optionFirst = 99998; int optionSecond = 99999; CustomFieldManager customFieldManager = ComponentManager.getInstance().getCustomFieldManager(); String sourceCfValue = customFieldManager.getCustomFieldObject(sourceCfID).getValue(issue).toString(); CustomField targetCf = customFieldManager.getCustomFieldObject(targetCfID); // If value of source custom field is XXX, then select first option, if NOT select second option // This can be replaced by switch statement if you need to check more options!!!! int targetCfOption = (sourceCfValue == 'XXX') ? optionFirst : optionSecond; Options targetCfOptions = ComponentAccessor.getOptionsManager().getOptions(targetCf.getRelevantConfig(issue)); Option ChoosenOption = targetCfOptions.getOptionById(targetCfOption); targetCf.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValu
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Why source/target??? And I dont have option son my custom field
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi robi,
are you updating the custom field values for multi level or single level ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.