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

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

2 votes
Kyle Moseley Community Champion Mar 08, 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.

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.

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

Kyle Moseley Community Champion Mar 08, 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

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
}

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 Community Champion Mar 08, 2018

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

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 Community Champion Mar 08, 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
Kyle Moseley Community Champion Mar 08, 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).

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 Community Champion Mar 08, 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? 

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!

They are single select fields

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 Community Champion Mar 08, 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.

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.

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(). 

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
How to earn badges on the Atlassian Community

How to earn badges on the Atlassian Community

Badges are a great way to show off community activity, whether you’re a newbie or a Champion.

Learn more
Community showcase
Published Jun 14, 2018 in Jira Service Desk

How the Telegram Integration for Jira helps Sergey's team take their support efficiency to the bank

...+ reading Fantasy). The same is true for him at the bank he works for: Efficiency is key when time literally equals money. Read on to learn how Sergey makes most of the time he has by...

496 views 2 5
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you