Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Listener that updates Epic custom "Start Date" field and system "Due Date" field dates

Ashley Border June 10, 2020

Hello. Listener newbie here.

I have the typical hierarchy structure -- Epic > Stories > Sub-tasks -- with all of the work happening at the Sub-task level.

Each Epic/Story/Sub-task has:

  • custom field "Start Date"
  • system field "Due Date"

I'm trying to write a custom listener:

  • if the Sub-task start dates/due dates move, the Story start dates/due dates get updated
  • if the Story start dates/due dates move, the Epic start dates/due dates get updated

I have the following script that looks at the Epic-Story relationship first. I figured out how to get the min and max dates of the stories, but I cannot figure out how to actually update the Epic Due Date. Can someone help, please?

 

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import java.sql.Timestamp
import org.apache.log4j.Logger
import org.apache.log4j.Level

def logFile = Logger.getLogger("")
logFile.setLevel(Level.DEBUG)

def issue = event.issue as Issue

//Check that current issue is an Epic
if(issue.issueType.name == "Epic")
{
//Initialize appropriate managers
def linkManager = ComponentAccessor.issueLinkManager
def cfm = ComponentAccessor.customFieldManager

//Get the story's date custom field and initialize a list to hold the date values
def storyStartDateField = cfm.getCustomFieldObjectByName("Start Date")
def storyStartDates = [] as List<Date>

//Get the story's due date and initialize a list to hold the date values
def storyDueDateField = issue.getDueDate()
def storyDueDates = [] as List<Date>

//Loop through all of Epic's stories and collect their date objects
linkManager.getOutwardLinks(issue.id).each{
if(it.issueLinkType.name == "Epic-Story Link")
{
def storyIssue = it.destinationObject
storyStartDates.add(storyIssue.getCustomFieldValue(storyStartDateField) as Date)
storyDueDates.add(storyIssue.getDueDate() as Date)
log.warn("storyStartDates: ${storyStartDates}");
log.warn("storyDueDates: ${storyDueDates}");
}
}

//Initialize min and max
def minDate = storyStartDates[0] as Date
def maxDate = storyDueDates[0] as Date

//Find actual min Dates
for(int i = 1; i < storyStartDates.size(); i++)
{
def currentDate = storyStartDates[i]
if(currentDate.before(minDate))
{
minDate = currentDate
}
}

//Find actual max Dates
for(int i = 1; i < storyDueDates.size(); i++)
{
def currentDate = storyDueDates[i]
if(currentDate.after(maxDate))
{
maxDate = currentDate
}
}

//You now have the overall maximum and minimum of all of the Story's custom Date fields
//From here on out you can do whatever you need with those minimums and maximums

log.warn("Min: " + minDate);
log.warn("Max: " + maxDate);

log.warn("issue.dueDate: " + issue.dueDate)

issue.setDueDate(maxDate); //<<<<< this is where I am getting an error

}
else //Return null if issue is not an Epic
{
return null
}

0 answers

Suggest an answer

Log in or Sign up to answer