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

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
Joshua Yamdogo Community Champion Aug 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
}

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 Community Champion Aug 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.

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)

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 Community Champion Aug 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
}

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...?

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!

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 =-(

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.

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)

Suggest an answer

Log in or Join to answer
Community showcase
Sarah Schuster
Posted Jan 29, 2018 in Jira

What are common themes you've seen across successful & failed Jira Software implementations?

Hey everyone! My name is Sarah Schuster, and I'm a Customer Success Manager in Atlassian specializing in Jira Software Cloud. Over the next few weeks I will be posting discussion topics (8 total) to ...

2,887 views 12 18
Join discussion

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
Atlassian Team Tour

Join us on the Team Tour

We're bringing product updates and pro tips on teamwork to ten cities around the world.

Save your spot