Example Scripted Fields
Along with the example Scripted Fields outlined below, we have added a demo video to help you understand how this feature works in ScriptRunner for Jira Cloud:
You can see below some examples that show how to use Jira APIs. The Scripted Fields feature in Cloud works differently for Sever/Data Center, where you must use one of the return types specified.
Groovy Scripts
Remember, our scripts are written in Groovy! Check out our page on Scripting in ScriptRunner for Jira Cloud for tips.
Currency Conversion Number Field
The following example shows the conversion of a field value, into a specific currency using a publicly available currency conversion API. A Jira custom field (number) called Cost (USD) has already been set up in the target project. The following script takes the Cost (USD) value, converts it to EUR, and displays the result in a scripted field:
groovy// Get the custom field ID for an existing "currency" field def costField = get("/rest/api/2/field") .asObject(List) .body .find { (it as Map).name == 'Cost (USD)' } .id // Extract the value of that field from the issue being viewed def usdValue = issue.fields[costField] // Use a 3rd-party currency conversion REST API def conversionResult = get("https://api.exchangeratesapi.io/latest?base=USD&symbols=EUR") .asObject(Map) .body // Return the new currency value if (usdValue != null && conversionResult != null) { return usdValue * conversionResult.rates.EUR } else { return 0 }
Last Comment Scripted Field
The following example shows how you can extract the last comment of an issue and to display the value of it inside a script field on the issue sidebar.
This then allows you to easily see what was added to the last comment on the issue without having to scroll through all of the comments on the issue.
This field should be configured to have a Text Field return type and should be configured to display in the Issue sidebar location.
groovy// Get the comments off the issue as a list def commentsList = issue.fields?.comment?.comments // Check if the last comment is not null. if (commentsList) { // If comments exists return the last comment and remove any new line characters to make it a valid return type return commentsList.last()?.body.toString().replaceAll("\r", " ").replaceAll("\n", " "); } else { // If no comments exist then display some default text. return "No comments exist on the issue" }
Sum up Story Points Below An Epic Issue Scripted Field
The following example shows how you can return all the Story issues below an Epic issue and to sum up the Story Points field for these and then display this value inside a script field on the Epic issue.
This then allows you to easily see how many story points you have set for all stories inside of your Epic issue.
This field should be configured to display for just the Epic issue type and to have a Number return type as well as to be configured to display in the Issue sidebar location.
groovy// Check if the issue is an Epic issue if (issue.fields.issuetype.name == "Epic") { // Get the field ids def fields = get('/rest/api/2/field') .asObject(List) .body as List<Map> // Get the Story Points custom field to use in the script def storyPointsField = fields.find { it.name == "Story Points" }?.id // Handle if the Story Points Field does not exist if (storyPointsField == null) { logger.info("Story Points field does not exist "); return; } // Get all issues below the the Epic Issue def allStories = get("/rest/agile/1.0/epic/${issue.key}/issue") // The JQL query to return all stories, modify this if you wish to return other issue types inside of the epic as well. .queryString("jql", "parentEpic =${issue.key} and issuetype = 'Story'") .queryString("fields", "parent,$storyPointsField") .asObject(Map) .body .issues as List<Map> // Sum the Story Points for all the Story issues returned def estimate = allStories.collect { Map story -> story.fields[storyPointsField] ?: 0 }.sum() // return the estimate value if it is not null and return 0 if it has no value return estimate ?: 0; }
Date of the first transition
groovydef result = get('/rest/api/3/issue/' + issue.key + '/changelog') .header('Content-Type', 'application/json') .asObject(Map) // Replace 'In Progress' with the status name def firstTransitionDateTime = result.body.values.find {it['items']['field'].toString().contains('status') && it['items']['toString'].toString().contains('In Progress') } firstTransitionDateTime ? firstTransitionDateTime['created'] : "-"
Time of Last status Change
groovydef result = get('/rest/api/3/issue/' + issue.key + '/changelog') .header('Content-Type', 'application/json') .asObject(Map) // Replace 'In Progress' with the status name def firstTransitionDateTime = result.body.values.findAll {it['items']['field'].toString().contains('status') && it['items']['toString'].toString().contains('In Progress') }.last() firstTransitionDateTime ? firstTransitionDateTime['created'] : "-"