Jira Server Scriptrunner: Set Due Date based on Custom Field Selection, Excluding Weekends
Asked by Megan D:

What I need: {#toc-hId--350511668}
----------------------------------

A due date to be auto-filled based on what custom dropdown field already says, but to also account for our weekend.

Dropdown selection is:

**Request Complexity:**(custom field: 14220)

* Simple*(3 days)*
* Average *(7 days)*
* Complex *(14 days)*

*The days in italics (above) are how much time to add to the current date for the due date.*

**Due Date** (custom field: 14233)

* Needs to account for the weekend (ours is **Friday-Sunday** ).
  * *Example: if a user starts this process on a Thursday, and the request is a "Simple" complexity, it would actually be due on Tuesday since we "skip" Friday-Sunday.*

What I have: {#toc-hId-2137001165}
----------------------------------

This is my current code, but it doesn't account for the weekend, but it also doesn't work as-is. I would greatly appreciate any help or code you can provide. Thank you!

```
import com.atlassian.jira.component.ComponentAccessorimport java.text.SimpleDateFormatdef customFieldManager = ComponentAccessor.customFieldManagerdef duedate = customFieldManager.getCustomFieldObjects(14233)def complexityField = customFieldManager.getCustomFieldObjects(14220)def complexityFieldValue = issue.getCustomFieldValue(complexityField).value.toString()def dateFormat = new SimpleDateFormat("d/MMM/yy")def duedateValue = dateFormat.parse(issue.getCustomFieldValue(duedate).toString())if(complexityFieldValue == "Simple"){    duedateValue + 3} else if(complexityFieldValue == "Average"){    duedateValue + 7} else if(complexityFieldValue == "Complex"){    duedateValue + 14}
```


Answers:
author: Tuncay Senturk
body: Hi [@Megan D](/t5/user/viewprofilepage/user-id/5436003)

First of all, I must admit I'm a bit envious that you have 3-day weekends including Fridays :D

Below, I tried to write some code/functions that could provide some help, please be aware that I haven't tested the code, this is just a sample code that might help you achieve your goal.

```
// function which return how many days it should add based on the selection of the complexity custom field.
def daysToAdd
   if (complexityFieldValue == "Simple") {
      daysToAdd = 3
   } else if (complexityFieldValue == "Average") {
      daysToAdd = 7
   } else if (complexityFieldValue == "Complex") {
      daysToAdd = 14
   } else {
      return
}

// function that finds the final datetime adding n-days
def addDaysExcludingWeekends(startDate, days) {
   Calendar cal = Calendar.getInstance()
   cal.setTime(startDate)
   while (days > 0) {
     cal.add(Calendar.DAY_OF_MONTH, 1)
     if (cal.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY &&
       cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY &&
       cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
        days--
     }
   }
   return cal.getTime()
}

// calculated dueDate
def dueDate = addDaysExcludingWeekends(currentDate, daysToAdd)

// update the issue
issue.setCustomFieldValue(duedateField, dueDate)
```

I hope it helps!

Best!

comments: author: Megan D
body: Thank you so much for the wright up and code! However this didn't end up working. Errors come up on the following snippets:

cal.setTime(startDate) {#toc-hId--349675499}
--------------------------------------------

"Cannot find matching method java.util.Calendar#setTime(java.lang.Object)."

while (days\>0) { {#toc-hId-2137837334}
---------------------------------------

"Cannot find matching method java.lang.Object#compareTo(int)"

days-- {#toc-hId-330382871}
---------------------------

"Cannot find matching method java.lang.Object#previous()"

def dueDate = addDaysExcludingWeekends(currentDate, daysToAdd) {#toc-hId--1477071592}
-------------------------------------------------------------------------------------

"The varable \[currentDate\] is undeclared"

issue.setCustomFieldValue(duedateField, dueDate) {#toc-hId-1010441241}
----------------------------------------------------------------------

"The variable \[dueDateField\] is undeclared."

"Cannot find matching method com.atlassian.jira.issue.MutableIssue#setCustomFieldValue(java.lang.Object, javalang.Object)."

Any more help would be appreciated! Thanks again =)


author: Tuncay Senturk
body: Hi,

Sorry for the late response, I was away!

Did you add the import line for Calendar?  

```
import java.util.Calendar
```

Also, could you please use this one?

```
def addDaysExcludingWeekends(Date startDate, int days) {
Calendar cal = Calendar.getInstance()
cal.setTime(startDate)
while (days > 0) {
   cal.add(Calendar.DAY_OF_MONTH, 1)
   if (cal.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY &&
      cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY &&
      cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
      days--
   }
}
return cal.getTime()
}


// calculated dueDate
Date currentDate = new Date()
def dueDate = addDaysExcludingWeekends(currentDate, daysToAdd)

```

For the duedatefield problem, you have to change duedate definition

```
def duedate = customFieldManager.getCustomFieldObjects(14233)
```

to duedateField

```
def duedateField = customFieldManager.getCustomFieldObjects(14233L)
```

also, you have to replace other duedate usages with duedateField, as below

```
def duedateValue = dateFormat.parse(issue.getCustomFieldValue(duedateField).toString())
```

I hope it helps


author: Tuncay Senturk
body: Hi [@Megan D](/t5/user/viewprofilepage/user-id/5436003)

Have you had a chance to try the updated code?


author: Megan D
body: Hi there, finally saw your reply - so it looks like it MIGHT work. Two things:

* I didn't know where to put (from your last comment)

```
def duedateValue = dateFormat.parse(issue.getCustomFieldValue(duedateField).toString())
```

* When I try to run the script (without the above line, lol), I get this error:

No signature of method: Script2042.addDaysExcludingWeekends() is applicable for argument types: (Date, null) values: \[*today's date/time*, null\]

Possible solutions:

```
addDaysExcludingWeekends(java.util.Date, int)
```

*** ** * ** ***

#### My current script is this (set in the Post Function of the transition) {#toc-hId-372543575}

```
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.util.DateFieldFormat
import com.atlassian.jira.timezone.TimeZoneManager
import java.util.Calendar
import java.util.Date*
import java.sql.Timestamp
import java.time.DayOfWeek
import java.time.LocalDateTime
import java.text.SimpleDateFormat

// gets "due date" custom field
def customFieldManager = ComponentAccessor.customFieldManager
def duedateField = customFieldManager.getCustomFieldObject(14233L)

//gets "request complexity" custom field
def complexityField = customFieldManager.getCustomFieldOjbect(14220)
def complexityValue = issue.getCustomFieldValue(complexityField).toString()


// function which return how many days it should add based on the selection of the complexity custom field.
def daysToAdd
   if (complexityFieldValue == "Simple") {
      daysToAdd = 3
   } else if (complexityFieldValue == "Average") {
      daysToAdd = 7
   } else if (complexityFieldValue == "Complex") {
      daysToAdd = 14
   } else {
      return
}

// calculated dueDateDate currentDate = new Date()def dueDate = addDaysExcludingWeekends(currentDate, daysToAdd)

// function that finds the final datetime adding n-days
def addDaysExcludingWeekends(Date startDate, int days) {
   Calendar cal = Calendar.getInstance()
   cal.setTime(startDate)
   while (days > 0) {
     cal.add(Calendar.DAY_OF_MONTH, 1)
     if (cal.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY &&
       cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY &&
       cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
        days--
     }
   }
   return cal.getTime()
}

// update the issue
issue.setCustomFieldValue(duedateField, dueDate)
```


author: Tuncay Senturk
body: Hello again, below is the usage of dueDateField and dueDateValue. Let me know if you have any problems

```
def duedateField = customFieldManager.getCustomFieldObjects(14233L)

def duedateValue = dateFormat.parse(issue.getCustomFieldValue(duedateField).toString())

def dueDate = addDaysExcludingWeekends(duedateValue, daysToAdd)
```


author: Chris Melville
body: You can use it as a post function also, just remove the event handling code, e.g.

```
IssueEvent issueEvent = event as IssueEvent
Issue issue = issueEvent.issue
```

and

```
if (!issueEvent?.getChangeLog()?.getRelated("ChildChangeItem")?.find { it.field == complexityFieldName }) {
    return
}
```


author: Chris Melville
body: Here is a script you can use. Set it up as a listener. Anytime your complexity field changes the duedate will be adjusted as you wish. It also accommodates adding any holidays you might want to declare 'non-working' days.

```
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.event.issue.IssueEvent
import java.sql.Timestamp
import java.text.SimpleDateFormat
import org.apache.log4j.Level
log.setLevel(Level.DEBUG)

IssueEvent issueEvent = event as IssueEvent
Issue issue = issueEvent.issue

def complexityFieldName = "Complexity"
if (!issueEvent?.getChangeLog()?.getRelated("ChildChangeItem")?.find { it.field == complexityFieldName }) {
    return
}

def complexity = [
    "Simple" : 3,
    "Average" : 7,
    "Complex" : 14
]

def complexityFieldValue = issue.getCustomFieldValue(complexityFieldName)?.value.toString()
if (!complexity.containsKey(complexityFieldValue)) {
    log.debug("Complexity value is unknown: $complexityFieldValue")
    return
}

Timestamp dueDate = issue.dueDate
Timestamp newDueDate = addOffset(dueDate, complexity[complexityFieldValue])
log.debug("Changing duedate from $dueDate to $newDueDate")
issue.update {
    setDueDate {
       set(newDueDate)
    }
}

def Timestamp addOffset(date, int offset) {
    def nonWorkingDays = [
        Calendar.FRIDAY, Calendar.SATURDAY, Calendar.SUNDAY
    ]
    def holidays = [ 
        '01/01/2025', '01/02/2025', '01/03/2025', '01/04/2025', '01/05/2025'
    ]

    Calendar cal = Calendar.getInstance()
    cal.setTime(date)
    int businessDayCount = 0
    SimpleDateFormat fmt = new SimpleDateFormat('MM/dd/yyyy')
    while (businessDayCount < offset) {
        cal.add(Calendar.DATE, 1)
        if (cal.get(Calendar.DAY_OF_WEEK) in nonWorkingDays || fmt.format(cal.getTime()) in holidays)
            continue
        businessDayCount++
    }
    return new Timestamp(cal.getTimeInMillis())
}
```


Tags: data-center

due-date

jira-data-center

jira-server

scriptrunner

weekend