Just a heads up: On March 24, 2025, starting at 4:30pm CDT / 19:30 UTC, the site will be undergoing scheduled maintenance for a few hours. During this time, the site might be unavailable for a short while. Thanks for your patience.

×
Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

I'm trying to create a custom field based on custom fields of all child issues connected.

Tristan_Willis April 13, 2020

I keep getting the error: ERROR [runner.ScriptFieldPreviewRunner]: Script field preview failed for field that has not yet been created

java.lang.NumberFormatException: For input string: "null"

 

My code is below.. Sorry very new to this so feel free to point out all my mistakes.

 

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.component.pico.ComponentManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.CustomFieldManager

def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def componentManager = ComponentManager.getInstance()
def customFieldManager = ComponentAccessor.getCustomFieldManager()

def url = ComponentAccessor.getApplicationProperties().getString("jira.baseurl")
def estimateRollup = 0
issueLinkManager.getOutwardLinks(issue.id)?.each
{
outLink->
def firstLevelChildIssue = outLink.destinationObject
def customField = customFieldManager.getCustomFieldObjectByName("Cumulative Epic Estimation in Numbers")
def estimateRoll = issue.getCustomFieldValue(customField)
def estimateRollString = estimateRoll.toString()
def estimateRollInt = Integer.parseInt(estimateRollString)

if(outLink.getIssueLinkType().getName().equals("Parent-Child Link"))
{
estimateRollup += estimateRollInt
}

}

return estimateRollup

1 answer

0 votes
Nic Brough -Adaptavist-
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.
April 13, 2020

My guess is that you have set the output template to be a string, but you are returning a number.

There are some errors in your loop as well.  I would

  • Move the def customField line to before the loop, you don't need to fetch the field every time (just the contents)
  • Change the issue.getCustomFieldValue to read the issue at the end of the link, not the current issue
  • Look at the field type of "Cumulative Epic Estimation in numbers" - is it really a string?  Also, you'll want to catch empty values and not process them further.
Tristan_Willis April 13, 2020

How would I change it to read the issue at the end of the link?

Nic Brough -Adaptavist-
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.
April 13, 2020
Tristan_Willis April 13, 2020

That's exactly what I was looking for. Thanks!

Tristan_Willis April 13, 2020

So any ideas why I'm only returning null values now? I restructured similarily to the link you provided with no errors, but it must be hitting one of the exceptions. I believe its the last one.

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.component.pico.ComponentManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.CustomFieldManager

def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def componentManager = ComponentManager.getInstance()
def customFieldManager = ComponentAccessor.getCustomFieldManager()

final String issueTypeName = "RD"
final String linkedIssueType = "Epic"
final String customFieldName ="RCI Time Spent Rollup"

if(issue.issueType.name != issueTypeName){
return null
}

def linkedIssues = ComponentAccessor.issueLinkManager.getInwardLinks(issue.id).findAll {
it.destinationObject.issueType.name == linkedIssueType
}
if(!linkedIssues){
return null
}

def customField = customFieldManager.getCustomFieldObjects(linkedIssues.first().destinationObject).findByName(customFieldName)
if(!customField){
log.debug "Custom Field not configured in this context"
return null
}

linkedIssues*.destinationObject.sum {
Issue it -> it.getCustomFieldValue(customField) ?: 0
}

Nic Brough -Adaptavist-
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.
April 13, 2020

I'd check the setup by using a dummy return value while coding for the field and use the preview to see where they come out.

Replace each "return null" line with an incrementing number to start with.  So if the issue type name does not match, return 1, linked issues is empty, return 2, customfield return 3 and then add return 4 right at the end of the script.  This should at least tell us how far through you are getting when the preview runs.  I'd also add a "log.warn it.getCustomFieldValue(customField) ?: 0" inside the last loop to see what numbers it is fetching from linked issues.

Tristan_Willis April 13, 2020

Looks like I'm getting stuck on 2, the linked issues. 

Tristan_Willis April 16, 2020

@Nic Brough -Adaptavist- I got it working finally, but it is picking up issues that are either related or blocking it, but I only want child issues. How would I go about creating an exception for them.

Nic Brough -Adaptavist-
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.
April 16, 2020

You know, I completely missed the "sub-task" part of the question while I was trying to work out what else might be the problem, I'm sorry!

I would replace

def linkedIssues = ComponentAccessor.issueLinkManager.getInwardLinks(issue.id).findAll {
it.destinationObject.issueType.name == linkedIssueType
}

with

def linkedIssues = issue.getSubTaskObjects()

(although I'd rename linkedIssues variable to something a bit more indicative of what it really is, like subtasksOfThisIssue)

Tristan_Willis April 16, 2020

Actually, I'm not looking for subtasks but in this case, we have created our own custom issue that goes above Epics. So I am actually looking to rollup estimates all the way to that top level above. I created a script that rolls up every estimate in an epic but could not get it to work correctly for the custom issue level. So I decided to create a seperate script that would just add up the sum of all epics within the custom top level. And that's where I am stuck again.

Tristan_Willis April 21, 2020

@Nic Brough -Adaptavist- any ideas on. how to sort for just parent-child links?

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue

// the issue type for which we want the scripted field to be displayed

// the linked issues with that issue type will used
final String linkedIssueType = "Epic"

// the values of that custom field - of type number - we want to sum up
final String customFieldName = "Epic Estimation"




def linkedIssues = ComponentAccessor.issueLinkManager.getOutwardLinks(issue.id).findAll { it.destinationObject.issueType.name.equals(linkedIssueType) }
if (!linkedIssues) {
return 1
}

def customField = ComponentAccessor.customFieldManager.getCustomFieldObjects(linkedIssues.first().destinationObject).findByName(customFieldName)
if (!customField) {
log.debug "Custom field is not configured for that context"
return 2
}

linkedIssues*.destinationObject.sum { Issue it -> it.getCustomFieldValue(customField) ?: 0 }

Suggest an answer

Log in or Sign up to answer