How can I create a Scripted Field to pull date from Parent Link (used by Jira Portfolio)?

Anthony Cardone August 16, 2017

Hello, 

I'm looking to create a custom scripted field called 'Initiative End Date'. It would show on the Epic level the 'End Date' field value of the parent Initiative, which is accessible through the 'Parent Link' field that comes with Jira Portfolio.

My end goal here is JQL queries that show me when the Epic end date is later than the Initiative end date so we can adjust accordingly, and the only way I can think to do this is use Scriptrunner to pull this in as a field on the same (Epic) level, and then do a datecompare. If there are other ways, I'm open.

There are similar requests out there to pull in fields through Epic Link or subtask, but no idea where to start or the code regarding Parent Link.

Any help you can provide is much appreciated. Thank you!

-Anthony

2 answers

0 votes
Pranitha Gaddam November 6, 2017

Solved above two errors in my code by changing

def value = issue.getCustomFieldValue(parentLink)

to

String value = issue.getCustomFieldValue(parentLink)

and

def parentIssue = ComponentAccessor.issueManager.getIssueByCurrentKey(parentKey)

to

def parentIssue = ComponentAccessor.getIssueManager().getIssueByCurrentKey(value)

0 votes
Joshua Yamdogo @ 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.
August 16, 2017

This is the script I came up with for a scripted field:

  • If the issue type is "Epic", begin calculations (we only want this field to show up at the Epic level)
  • Access the parent link of the Epic
  • Get the value of the parent link
  • From the value of the parent link, get the key of the parent
  • Get the parent issue from the parent key
  • Get the value of the 'Initiative End Date' custom field from the parent
  • Return the date
import com.atlassian.jira.component.ComponentAccessor
if (issue.issueType.name == "Epic") {
def customFieldManager = ComponentAccessor.getCustomFieldManager()

def parentLink = customFieldManager.getCustomFieldObjectByName("Parent Link")
def value = issue.getCustomFieldValue(parentLink)
def parentKey = value.key
def parentIssue = ComponentAccessor.issueManager.getIssueByCurrentKey(parentKey)

def endDate = customFieldManager.getCustomFieldObjectByName("Initiative End Date")
def endDateValue = parentIssue.getCustomFieldValue(endDate)

return endDateValue
}
Anthony Cardone August 16, 2017

Joshua, thank you for the quick response!! I'm getting a few errors when I try to put in that code.. Can you let me know what you think? Am I missing a declaration? I'm on Jira 7.3Screen Shot 2017-08-16 at 12.31.12 PM.pngScreen Shot 2017-08-16 at 12.30.46 PM.png

Joshua Yamdogo @ 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.
August 16, 2017

Hi Anthony, 

The static type checker for ScriptRunner can be wrong. Sometimes, it will tell you a matching method cannot be found even if it does exist. I think that's happening here. Try to just ignore the errors, save the script field, and go visit an Epic issue to see if anything is being displayed for the field.

Anthony Cardone August 16, 2017

No luck... I don't see an error, but the field isn't bringing back dates using existing or new Epics. When I preview using a new Epic I just created (associated to an initiative with end dates), the Preview comes back as 'null' (no result, null log)

Anthony Cardone August 16, 2017

I was able to find an error:

2017-08-16 14:58:26,009 ERROR [customfield.GroovyCustomField]: *************************************************************************************
2017-08-16 14:58:26,009 ERROR [customfield.GroovyCustomField]: Script field failed on issue: LIC-1724, field: Initiative End Date
java.lang.NullPointerException: Cannot get property 'key' on null object
at Script147.run(Script147.groovy:7)

  
Joshua Yamdogo @ 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.
August 17, 2017

I think I slightly misread your question. I just realized you wanted the value of the "End Date" field on the Epic. The name of this scripted field will be "End Date Initiative".

So we should change the script to get the value of "End Date":

import com.atlassian.jira.component.ComponentAccessor
if (issue.issueType.name == "Epic") {
def customFieldManager = ComponentAccessor.getCustomFieldManager()

def parentLink = customFieldManager.getCustomFieldObjectByName("Parent Link")
def value = issue.getCustomFieldValue(parentLink)
def parentKey = value.key
def parentIssue = ComponentAccessor.issueManager.getIssueByCurrentKey(parentKey)

def endDate = customFieldManager.getCustomFieldObjectByName("End Date")
def endDateValue = parentIssue.getCustomFieldValue(endDate)

return endDateValue
}
Anthony Cardone August 17, 2017

Hi Joshua! 

Thank you! So I actually caught that yesterday and changed it to End Date... but I figured out what I did wrong. 

the field I needed is called 'End date' with a lowercase 'd', and in an odd coincidence a plugin I installed on Tuesday auto-created a competing custom field called 'End Date' with a capital D... so it was not exactly an error, is was a legit Null value.

So this now brings back the date!! One issue though is still happening. 

It's pulling in the date in this format: 2017-07-21 00:00:00.0

Which is not working in a datecompare function, bringing back this error: 
Field name: Initiative End Date not found or not a date or datetime.

I realized this was because the Script Template was set to Text Field, however when I changed it, none of the other options render the date. 

Text Field: 2017-07-21 00:00:00.0
Date Time Picker: Invalid date
Absolute Date Time: $datePickerFormatter.format($value)

Is there something I can put in 'Custom' to read it as a date, etc...?

Anthony Cardone August 17, 2017

Update! I changed the script field to be use the Search Template to 'Date Time Range picker' and the Template as Date Time Picker, and it now looks like

Initiative End Date: 21/Jul/17 12:00 AM

When I run a the date compare I still get this message

Initiative End Date not found or not a date or datetime.

and when I run the field as a preview, get this error:

The indexer for this field expects a java.util.Date but the script returned a java.sql.Timestamp

Can you advise what options I should try?

Thank you again for all your help!

PhillipS October 20, 2017

I'm looking for the opposite.  In groovy script how can I query child issues (from a parent that is defined via portfolio).  I'll be able to figure out the rest once I can get a Collection<Issue> object.  Getting the custom field "Child issues" returns a null object =-(

PhillipS November 9, 2017

I was able to solve my issue, but in a very messy way.  Essentially I needed to inject a JQL call into the code to get the code.  There are a lot of imports I'm not listing here:

String jqlSearch = "issueFunction in portfolioChildrenOf(\"key = " + issue.getKey() + "\")"
SearchService searchService = ComponentAccessor.getComponent(SearchService.class)
ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
List<Issue> issues = null
IssueManager issueManager = ComponentAccessor.getIssueManager()
SearchService.ParseResult parseResult = searchService.parseQuery(user, jqlSearch)

if (parseResult.isValid()) {
def searchResult = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
// Transform issues from DocumentIssueImpl to the "pure" form IssueImpl (some methods don't work with DocumentIssueImps)
issues = searchResult.getIssues() // This only returns the first page of results of 100 issues...I think, would an initiative ever have more than 100 issues?
} else {
log.error("Invalid JQL: " + jqlSearch);
return "error in JQL search"
}

 This only returns the first "page" of issues (epics in an initiative for my purposes), but it works.

Suggest an answer

Log in or Sign up to answer