ScriptRunner Post-function add 1 month to date field and update date field

Chris Ghazanchian March 24, 2018

I would like to add 1 month to a custom date field (Next Cycle Date) and then update that date field upon a workflow transition (post-function).

I have the current script but it's not doing anything, not sure what I am doing wrong.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.UpdateIssueRequest
import java.text.SimpleDateFormat

CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()

SimpleDateFormat dateFormatter = new SimpleDateFormat("dd/MMM/yy");
java.sql.Timestamp nextCycleDate = (java.sql.Timestamp)issue.getCustomFieldValue(customFieldManager.getCustomFieldObject("customfield_10603")) //get current "next cycle date"

nextCycleDate.setMonth(nextCycleDate.getMonth() + 1) //add 1 month to current cycle date to get next cycle date

issue.setCustomFieldValue(customFieldManager.getCustomFieldObject("customfield_10603"), nextCycleDate) //update next cycle date

 

3 answers

1 accepted

2 votes
Answer accepted
Chris Ghazanchian March 31, 2018

**Please read through replies as well below**

I was trying many different things to get to the solution. After countless hours spent on testing and encountering many different errors, here is the correct code.

import com.atlassian.jira.component.ComponentAccessor
import java.sql.Date
import java.sql.Timestamp
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import org.apache.log4j.Logger
import org.apache.log4j.Level

// Manager
CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()

//Values
CustomField currentDate = customFieldManager.getCustomFieldObject("customfield_10603")
Timestamp currentDateValue = (Timestamp)issue.getCustomFieldValue(currentDate)


Date newDateValue = new Date(currentDateValue.getTime())

//Add 1 month
newDateValue.setMonth(currentDateValue.getMonth() + 1)

//Update custom field
issue.setCustomFieldValue(currentDate, newDateValue.toTimestamp())

There were many different issues I encountered via debugging (major thanks to Nic as I would not have even started with the logging if he had not mentioned it).

 

Thank you

1 vote
Alexey Matveev
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.
March 25, 2018

Could you have a look in the logs for errors? Also this script must be first in the list of the post functions for the transition. And this script will not work for the create issue transition.

Chris Ghazanchian March 25, 2018

Hi Alexey,

Script is first in the list, workflow transition is not on create issue.

Here's the error I found..

2018-03-24 18:14:47,977 ERROR [workflow.ScriptWorkflowFunction]: Script function failed on issue: RAR-5, actionId: 11, file: <inline script>
java.lang.NullPointerException: Cannot invoke method getMonth() on null object
 at Script101.run(Script101.groovy:12)
Nic Brough -Adaptavist-
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 25, 2018

That tells you that the object you are trying to use .getMonth on does not exist.  Which in turn means the call to populate it has returned nothing, so have a look at the like that is supposed to set nextCycleDate.  It's getting nothing from the issue.getCustomFieldValue call.  So it's either faulty code or the issue does not have the field set to a value.

Chris Ghazanchian March 25, 2018

I can definitely see that the field is set within the issue, and I can understand how it could be faulty code.. I'm pretty new to scriptrunner and Java so I do not understand it as well as someone else would.

I have also doublechecked to make sure customfield 10603 is the field that I am trying to get the value from (aka the field that has the value in it and is not blank).

Possibly something is wrong with my code here? I'm not sure.

java.sql.Timestamp nextCycleDate = (java.sql.Timestamp)issue.getCustomFieldValue(customFieldManager.getCustomFieldObject("customfield_10603"))
Nic Brough -Adaptavist-
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 25, 2018

Yeah, it's not that easy to read, let alone write!  Your code actually looks broadly right, and it's not throwing errors, so you must be doing it right here.

I'd head for a debugger in the IDE, but if you're not sure of that, the simplistic brute-force way to find it is to break down the multiple calls and log where it fails.

So:

  • def cf = customFieldManager.getCustomFieldObject("customfield_10603"))
  • log cf.getName()
  • def cfvalue = issue.getCustomFieldValue(cf)
  • log cfvalue
  • def nextCycleDate = (java.sql.Timestamp) cfvalue
  • log nextCycleDate

This will error somewhere, and that should tell you which bit is going wrong

Alexey Matveev
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.
March 25, 2018

Make sure that the id (10603) of the custom field is right.

Chris Ghazanchian March 26, 2018

Alexey,

10603 is correct, I have triple-checked.

 

Nic,

I'm having a bit of trouble with the logging method. Please see two screenshots showing errors.

error.PNGerror2.PNG

Chris Ghazanchian March 26, 2018

Fixed the logging problem by importing the logging package and changing log to log.debug throughout.

The three log debug lines are as follows:

2018-03-26 17:06:01,719 DEBUG [acme.CreateSubtask]: Next Cycle Date
2018-03-26 17:06:01,719 DEBUG [acme.CreateSubtask]: 2017-01-15 00:00:00.0
2018-03-26 17:06:01,719 DEBUG [acme.CreateSubtask]: 2017-01-15 00:00:00.0

Not getting any errors, so I'm not sure what I'm doing wrong here and why it isn't working.

Alexey Matveev
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.
March 26, 2018

Do you mean, that there is no NullPointerException anymore? If so, then where did you attach the post function? Is it the create transition? Is it last of first in the list of postfunctions?

Chris Ghazanchian March 27, 2018

The NullPointerException error came only one time.. I'm not sure why that error occurred.

Now it is working fine, and it is in the first of the postfunctions, and the transition is not create.. The transition is in the middle of the workflow.

postfunction1.PNG

Alexey Matveev
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.
March 27, 2018

Try like this and put the post function last in the list of post functions.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.UpdateIssueRequest
import java.text.SimpleDateFormat
import com.atlassian.jira.event.type.EventDispatchOption

def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()

SimpleDateFormat dateFormatter = new SimpleDateFormat("dd/MMM/yy");
java.sql.Timestamp nextCycleDate = (java.sql.Timestamp)issue.getCustomFieldValue(customFieldManager.getCustomFieldObject("customfield_10603")) //get current "next cycle date"

nextCycleDate.setMonth(nextCycleDate.getMonth() + 1) //add 1 month to current cycle date to get next cycle date

issue.setCustomFieldValue(customFieldManager.getCustomFieldObject("customfield_10603"), nextCycleDate)
ComponentAccessor.getIssueManager().updateIssue(user, issue, EventDispatchOption.ISSUE_UPDATED, false)
Chris Ghazanchian March 27, 2018

Did that, and the custom field still does not change. Tried it as last in the postfunction list and first, but no difference. No errors found in the scriptrunner logs either.

Alexey Matveev
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.
March 27, 2018

Are you sure that the post function is executed?

Chris Ghazanchian March 28, 2018

I added this code:

def log = Logger.getLogger("com.acme.CreateSubtask")
log.setLevel(Level.DEBUG)

log.debug "foo bar"

Then I re-ran the workflow transition to check if foo bar was logged in the scriptrunner logs, which would ensure that the workflow postfunction executed, and it did:

2018-03-28 09:39:36,714 DEBUG [acme.CreateSubtask]: foo bar

 

Chris Ghazanchian March 30, 2018

I have made some modifications, but I would appreciate the community's help here.

I am using the following code:

CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()

CustomField csDate1 = customFieldManager.getCustomFieldObject("customfield_10603")

Timestamp csDate1Value = (Timestamp)getCustomFieldValue(customFieldManager.getCustomFieldObject("customfield_10603"))
Date csNewDateValue = new Date(csDate1Value.getMonth() + 1)
issue.setCustomFieldValue(csDate1, csNewDateValue) 

Now I am getting an error as follows:

2018-03-30 14:21:36,648 ERROR [workflow.ScriptWorkflowFunction]: Script function failed on issue: RAR-4, actionId: 11, file: <inline script>
java.lang.NullPointerException: Cannot invoke method getCustomFieldValue() on null object
 at Script229.run(Script229.groovy:27)

I am not sure how it sees it as null.. I go to http://myjirainstance:8080/rest/api/latest/issue/RAR-4 and have the value there:

customfield10603.PNG

Alexey Matveev
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.
March 30, 2018

I am not sure, how you call the script. But it seems to me that there is a error. You call getCustomFieldValue, but you should call issue.getCustomFieldValue.

Chris Ghazanchian March 31, 2018

I was trying many different things to get to the solution. After countless hours spent on testing and encountering many different errors, here is the correct code.

import com.atlassian.jira.component.ComponentAccessor
import java.sql.Date
import java.sql.Timestamp
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import org.apache.log4j.Logger
import org.apache.log4j.Level

// Manager
CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()

//Values
CustomField currentDate = customFieldManager.getCustomFieldObject("customfield_10603")
Timestamp currentDateValue = (Timestamp)issue.getCustomFieldValue(currentDate)


Date newDateValue = new Date(currentDateValue.getTime())

//Add 1 month
newDateValue.setMonth(currentDateValue.getMonth() + 1)

//Update custom field
issue.setCustomFieldValue(currentDate, newDateValue.toTimestamp())

There were many different issues I encountered via debugging (major thanks to Nic as I would not have even started with the logging if he had not mentioned it).

 

Thank you

0 votes
Azfar Masut
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.
May 23, 2023

Just sharing a full script. If you want to add further condition based on certain fields, certain months are added to the date field (in my case, its based on priority field)

 

import com.atlassian.jira.component.ComponentAccessor
import java.sql.Timestamp

def focusIssue = issue
def customFieldManager = ComponentAccessor.getCustomFieldManager()

def issueStartDate = customFieldManager.getCustomFieldObjectsByName("Issue Start Date").first()?:null
def priority = issue.getPriority()?:null

Timestamp currentDateValue = (Timestamp)issue.getCustomFieldValue(issueStartDate)?:null
Date maxDate = new Date(currentDateValue.getTime())?:null

if (priority.name == 'Low'){
    maxDate.setMonth(currentDateValue.getMonth() + 24)}
    
    else if (priority.name == 'Medium'){
        maxDate.setMonth(currentDateValue.getMonth() + 24)
        }
        
        else if (priority.name == 'High'){
            maxDate.setMonth(currentDateValue.getMonth() + 12)
            }



return maxDate

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events