Forums

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

ScriptRunner - Groovy: getting fields and adding them to store into another field

bSte March 7, 2018

Hi  - I am trying to write a script that gets values from custom fields, does a calculation on the value and then stores the calculation in a custom field. Also shows a message of what the new value is based on the calculation.

 

Here is what I have so far:

def bvField = getFieldById("customfield_11212")
def tcField = getFieldById("customfield_11214")
def rrField = getFieldById("customfield_11213")
def jobSizeField = getFieldById("customfield_11224")
def wsjfField = getFieldById("customfield_17616")
def editScreen = getFieldById("customfield_15321")
def createScreen = getFieldById("customfield_15320")
def bvValue = bvField.getValue()
def tcValue = tcField.getValue()
def rrValue = rrField.getValue()
def jobSizeValue = jobSizeField.getValue()
def wsjfValue = wsjfField.getValue()
def wsjfCalc = bvValue + tcValue + rrValue / jobSizeValue



if (createScreen && editScreen){
if (bvValue != 0 && tcValue != 0 && rrValue != 0 && jobSizeValue != 0){
return wsjfCalc
} else {
return "You must populate all number fields to calculate WSJF"
}
}

2 answers

1 accepted

3 votes
Answer accepted
Kyle Moseley
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.
March 8, 2018

It looks more like a Behaviours script right now. I would suggest trying to get custom field values by...

import com.atlassian.jira.component.ComponentAccessor

def field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("field name")
def value = issue.getCustomFieldValue(field)

 If it's a Number field.

bSte March 8, 2018

Thanks -- I am able to get the value of the custom field - what I am not able to figure out is how to add the value of the custom fields and store the calculated value to the show in a message.

bSte March 8, 2018

And, what is the difference in Jira between a behaviors script and a groovy script in scriptrunner?

Kyle Moseley
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.
March 8, 2018
if (createScreen && editScreen){
if (bvValue != 0 && tcValue != 0 && rrValue != 0 && jobSizeValue != 0){
return wsjfCalc
} else {
return "You must populate all number fields to calculate WSJF"
}
}

Remove the top level IF here. Script fields only display on the 'View' screen.

REturn that wsjfCalc value as you're doing right now. Your calculations are on the right track, but keep in mind order of operations is doing that division before your addition (you may have intended that).

 

Behaviours and Script Fields/other SR tools share much of the same syntax, but certain things are specific to Behaviours. The documentation is worth checking out: https://scriptrunner.adaptavist.com/latest/jira/scripted-fields.html

bSte March 8, 2018
import com.atlassian.jira.component.ComponentAccessor

def bvField = getFieldById("customfield_11212")
def tcField = getFieldById("customfield_11214")
def rrField = getFieldById("customfield_11213")
def jobSizeField = getFieldById("customfield_11224")
def wsjfField = getFieldById("customfield_17616")
def editScreen = getFieldById("customfield_15321")
def createScreen = getFieldById("customfield_15320")
def bvValue = bvField.getValue()
def tcValue = tcField.getValue()
def rrValue = rrField.getValue()
def jobSizeValue = jobSizeField.getValue()
def wsjfValue = wsjfField.getValue()
def jobSizeInt = Integer.parseInt("jobSizeValue")
def rrInt = Integer.parseInt("rrValue")
def tcInt = Integer.parseInt("tcValue")
def bvInt = Integer.parseInt("bvValue")
def wsjf = Integer.parseInt("wsjfValue")

def wsjfCalc = ("bvInt" + "tcInt" + "rrInt") / "jobSizeInt"
def errormsg = "You must populate all number fields to calculate WSJF"



if (createScreen && editScreen && bvValue != 0 && tcValue != 0 && rrValue != 0 && jobSizeValue != 0) {
return wsjfValue
} else {
errormsg
}
bSte March 8, 2018

Above is my updated script - it is still giving me an error about the / symbol -- I can't figure out why.  The error says: Cannot find matching method java.lang.String#div(java.lang.String)Please check if the declared type is right and if the method exists.

Kyle Moseley
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.
March 8, 2018

Yes you're still getting the custom field values the Behaviours way. Use the code provided in my first reply.

bSte March 8, 2018

Hi - Ok, I have updated my code and it is know in a script field. I am having an issue with getting the value to an integer.

 

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.Issue

def bvValue = getCustomFieldValue("BV")
def tcValue = getCustomFieldValue("TC")
def rrValue = getCustomFieldValue("RR")
def jobSizeValue = getCustomFieldValue("Job Size")
def jobSizeInt = Integer.parseInt("jobSizeValue")
def rrInt = Integer.parseInt("rrValue")
def tcInt = Integer.parseInt("tcValue")
def bvInt = Integer.parseInt("bvValue")



if (bvValue!=0 && tcValue!=0 && rrValue!=0 && jobSizeValue!=0) {
return Integer.parseInt(bvValue) + Integer.parseInt(tcValue) + Integer.parseInt(rrValue) / jobSizeInt
}
Kyle Moseley
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.
March 8, 2018

There's a few problems. You need to changes lines like

def bvValue = getCustomFieldValue("BV")

to

def bvField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("BV")
def bvValue = issue.getCustomFieldValue(bvField)

Note the first line is defining the bv field as a field object. You are telling JIRA's API you want to interact with that particular custom field. Then the next line, you are telling JIRA's API that you want that particular field's value for your specific issue.

The script field will know that "issue" means the issue you're looking at, at the moment. Repeat this solution for each field value.

As long as your custom field values are strings, I think parseInt will work. But check because they may arrive as another variable type (double, float?).

At the bottom, you have already defined rrInt, tcInt, etc -- so use those and calculate your total for return. But define that in a variable and the return just that variable. Often I am not able to return very complex lines.

So

return Integer.parseInt(bvValue) + Integer.parseInt(tcValue) + Integer.parseInt(rrValue) / jobSizeInt

becomes

def total = bvInt + tcInt + rrInt / jobSizeInt
return
total
Like Stefan Salzl likes this
Kyle Moseley
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.
March 8, 2018

Also if you put quotes around the variable name it's treated as a string so you won't get the results you expect. Check all your methods for that (such as parseInt).

bSte March 8, 2018
import com.atlassian.jira.ComponentAccessor
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.Issue

def bvField = ComponentAccessor().getCustomFieldManager().getCustomfFieldObjectbyName("BV")
def bvValue = getCustomFieldValue(bvfield)
def tcField = ComponentAccessor().getCustomFieldManager().getCustomfFieldObjectbyName("TC")
def tcValue = getCustomFieldValue(tcField)
def rrField = ComponentAccessor().getCustomFieldManager().getCustomfFieldObjectbyName("RR")
def rrValue = getCustomFieldValue(rrField)
def jobSizeField = ComponentAccessor().getCustomFieldManager().getCustomfFieldObjectbyName("Job Size Field")
def jobSizeValue = getCustomFieldValue(jobSizeField)

def jobSizeInt = Integer.parseInt(jobSizeValue)
def rrInt = Integer.parseInt(rrValue)
def tcInt = Integer.parseInt(tcValue)
def bvInt = Integer.parseInt(bvValue)

def total = (bvInt + tcInt + rrInt) / jobSizeInt


if (bvValue!="none" && tcValue!="none" && rrValue!="none" && jobSizeValue!="none") {
return total
} else {
return 85
}
Kyle Moseley
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.
March 8, 2018
def bvValue = issue.getCustomFieldValue(bvField)

Still missing that "issue" for the field values.

Also, what field types are the custom fields bv, tc, rr? Number? Single select? 

bSte March 8, 2018

Above is what I have now, it still doesn't work and it has a lot of errors just within the script runner.  

 

I am getting errors on the component accessor -- its says "cannot find matching method"

And

errors on the Integer.ParseInt

 

* I am doing this on a script field in Jira - not sure if that changes anything.

 

Thanks for much for your help!

bSte March 8, 2018

They are single select fields

bSte March 8, 2018

I added that: 

 

import com.atlassian.jira.ComponentAccessor
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.Issue


def bvField = ComponentAccessor().getCustomFieldManager().getCustomfFieldObjectbyName("BV")
def bvValue = issue.getCustomFieldValue(bvfield)
def tcField = ComponentAccessor().getCustomFieldManager().getCustomfFieldObjectbyName("TC")
def tcValue = issue.getCustomFieldValue(tcField)
def rrField = ComponentAccessor().getCustomFieldManager().getCustomfFieldObjectbyName("RR")
def rrValue = issue.getCustomFieldValue(rrField)
def jobSizeField = ComponentAccessor().getCustomFieldManager().getCustomfFieldObjectbyName("Job Size Field")
def jobSizeValue = issue.getCustomFieldValue(jobSizeField)

def jobSizeInt = Integer.parseInt(jobSizeValue)
def rrInt = Integer.parseInt(rrValue)
def tcInt = Integer.parseInt(tcValue)
def bvInt = Integer.parseInt(bvValue)

def total = (bvInt + tcInt + rrInt) / jobSizeInt


if (bvValue!="none" && tcValue!="none" && rrValue!="none" && jobSizeValue!="none") {
return total
} else {
return 85
}
Kyle Moseley
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.
March 8, 2018

okay. Since they are single selects, also add to lines like...

def bvValue = issue.getCustomFieldValue(bvfield)

an extra

def bvValue = issue.getCustomFieldValue(bvfield)?.getValue()

 

Also remove the () on the ComponentAccessor throughout the script.

def bvField = ComponentAccessor().getCustomFieldManager().getCustomfFieldObjectbyName("BV")

becomes

def bvField = ComponentAccessor.getCustomFieldManager().getCustomfFieldObjectbyName("BV")

 

 Also make sure your variable names match up. For instance, you declare bvField but reference bvfield (lowercase) in the next line. This will break things.

 

You also have typos in "getCustomFieldObjectByName" -- two F's and a lowercase B. Change those or it will break as well.

bSte March 8, 2018

All that worked - thanks so much!  The only thing that is still causing the issue is the Integer.parseInt()



def jobSizeInt = Integer.parseInt(jobSizeValue)
def rrInt = Integer.parseInt(rrValue)
def tcInt = Integer.parseInt(tcValue)
def bvInt = Integer.parseInt(bvValue)

def total = (bvInt + tcInt + rrInt) / jobSizeInt

 

Error:  java.lang.Integer#parseInt(java.lang.Object). Please check if the declared type is right and if the method exists.

Kyle Moseley
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.
March 8, 2018

You're welcome. Please mark the answer as accepted using the checkmark.

As for the integers... I think it's interpreting the cfVals as generic Java objects rather than string -- so that could probably be fixed by adding .toString() at the end of each .getValue(). 

Like # people like this
2 votes
bSte March 9, 2018

Here is what ended up working in the end: 

 

import com.atlassian.jira.ComponentAccessor
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.Issue


CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()
CustomField bvField = customFieldManager.getCustomFieldObject("customfield_11212");
CustomField tcField = customFieldManager.getCustomFieldObject("customfield_11214");
CustomField rrField = customFieldManager.getCustomFieldObject("customfield_11213");
CustomField jobSizeField = customFieldManager.getCustomFieldObject("customfield_11224");

String bvValue = issue.getCustomFieldValue(bvField).toString();
String tcValue = issue.getCustomFieldValue(tcField).toString();
String rrValue = issue.getCustomFieldValue(rrField).toString();
String jobSizeValue = issue.getCustomFieldValue(jobSizeField).toString();

int jobSizeInt = Integer.parseInt(jobSizeValue);
int rrInt = Integer.parseInt(rrValue);
int tcInt = Integer.parseInt(tcValue);
int bvInt = Integer.parseInt(bvValue);

def total = (bvInt + tcInt + rrInt) / jobSizeInt

return total

Suggest an answer

Log in or Sign up to answer