Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Need help with listener that captures the date on when a date field is filled

I have the below listener script, 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def cfm = ComponentAccessor.getCustomFieldManager()
def watch = cfm.getCustomFieldObjectByName("Baseline Due Date")
def watchValue = event.issue.getCustomFieldValue(watch)
def updatedWatch = cfm.getCustomFieldObjectByName("Epic Baseline Captured Date")
def today = new java.sql.Timestamp(new Date().getTime())

if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == 'Baseline Due Date'}){

def changeHolder = new DefaultIssueChangeHolder()

updatedWatch.updateValue(null, event.issue, new ModifiedValue(null, today), changeHolder)

}

 

The above listener captures the Dates on when the "Baseline Due Date" is filled. And when the field is null, it shows null too. This set up has been working fine for a long time.

Recently, the field does not show up on the issue card. When looked at the logs, it shows no error, but has the below output,

 

23:23:28,659 ERROR [runner.ScriptBindingsManager]: [[GenericEntity:ChangeItem][newvalue,2020-09-24][field,duedate][oldstring,null][newstring,2020-09-24 00:00:00.0][id,30306603][fieldtype,jira][oldvalue,null][group,25006003]]

The output shows random custom field names like, [field,duedate], [field,Assignee] etc.

 

Can someone please help how to fix this ? Thank you 

2 answers

1 accepted

1 vote
Answer accepted
Antoine Berry Community Leader Oct 06, 2020

Hi @Aisha M ,

You may use this script : 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def issueType = issue.getIssueType().getName()
if (issueType == "Epic"){
def customFieldManager = ComponentAccessor.getCustomFieldManager()

def dueDateValue = issue.getDueDate()
int baselineDueDateId = 10001

def baselineDueDate = customFieldManager.getCustomFieldObject(baselineDueDateId)
def baselineDueDateValue = issue.getCustomFieldValue(baselineDueDate)

if (!baselineDueDateValue && dueDateValue){
baselineDueDate.updateValue(null, issue, new ModifiedValue(baselineDueDateValue, dueDateValue), new DefaultIssueChangeHolder())

int baselineCapturedDateId = 10002
def baselineCapturedDate = customFieldManager.getCustomFieldObject(baselineCapturedDateId)
def baselineCapturedDateValue = issue.getCustomFieldValue(baselineCapturedDate)
def today = new java.sql.Timestamp(new Date().getTime())

baselineCapturedDate.updateValue(null, issue, new ModifiedValue(baselineCapturedDateValue, today), new DefaultIssueChangeHolder())
}
}

It will copy the value of the due date in the baseline due date field, and set the baseline captured date with the datetime at which the due date was changed.

You may want to use this script in each transition (groovy post-function) or in each listener where the the due date might be changed.

@Antoine Berry  Thank you !!!! Works amazing . . .  The 'baseline captured date' correctly gets the time stamp of whenever the "Baseline Due Date" modifies . . 
But, for older issues which already has a "Baseline Due Date"  present, this wont reflect right ? Coz the event is not happening for the listener to capture ?

Antoine Berry Community Leader Oct 07, 2020

Absolutely, if you want to fix old issues, that is a whole différent story, since you cannot use "current time". That might be possible by playing around with the data.

Hello @Antoine Berry , Sorry for troubling you every time ;( Do you feel you can sense something wrong with my above listener ? There are no errors, so not able to guess why its failing

Nobody was able to help. Can I please have your thoughts on the setup. 

(FYI, had recently added some script to the Baseline Due Date to capture & lock the first Epic Due Date value - YOU had helped with this). So, was wondering if its failing becoz of that change.

Antoine Berry Community Leader Sep 16, 2020

Hi @Aisha M ,

Nothing seems blocking in your listener. Whenever you are debugging a script I would suggest to add some logs. Please try this script, update the Baseline Due Date and check the logs : 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def cfm = ComponentAccessor.getCustomFieldManager()
def watch = cfm.getCustomFieldObjectByName("Baseline Due Date")
def watchValue = event.issue.getCustomFieldValue(watch)
def updatedWatch = cfm.getCustomFieldObjectByName("Epic Baseline Captured Date")
def today = new java.sql.Timestamp(new Date().getTime())

log.error("current value of Baseline Due Date is : " + watchValue)
if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == 'Baseline Due Date'}){
log.error("baseline due date is being changed")
def changeHolder = new DefaultIssueChangeHolder()

updatedWatch.updateValue(null, event.issue, new ModifiedValue(null, today), changeHolder)
log.error("changing epic baseline captured date to date : " + today)
}
else {
log.error("the value is not being changed.")
}

Also have you upgraded Jira or changed custom field's name lately ?

@Antoine Berry I don't think the names changed, but I feel they did upgrade the Jira instances in Prod & Dev (affirmative). And out of the blue, the field stopped working, even thought its available in the View screens & everything seems unchanged. 

I'll test again with the above script & let you know the logs :) thank you so much for looking into the issue. 

Like Antoine Berry likes this

Hello @Antoine Berry , I'm getting the below error,

2020-09-17 01:13:35,398 ERROR [runner.ScriptBindingsManager]: current value of Baseline Due Date is : null
2020-09-17 01:13:35,403 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2020-09-17 01:13:35,403 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: <inline script>
java.lang.NullPointerException: Cannot invoke method getRelated() on null object
 at Script1546.run(Script1546.groovy:12)

Could it be because, the "Baseline Due Date" is not a user accessible field anymore ?? 

We recently changed the  "Baseline Due Date" field to capture & lock the first Epic Due Date value. So, could it because of this, that the listener is not working as expected ?

Like Antoine Berry likes this
Antoine Berry Community Leader Sep 18, 2020

What event is linked to that listener ? The event value seems to be null so that's weird.

You could replace line 12 with this : 

if (event?.getChangeLog()?.getRelated("ChildChangeItem")?.find{ it.field == 'Baseline Due Date'}){

to get rid of the error.

When you are saying ""Baseline Due Date" is not a user accessible field anymore", do you mean the user cannot change it ? Because this listener literally checks if the user updates the field. If not, the listener does nothing.

Hello @Antoine Berry , I have two listeners for two events - Issue Created & Issue Updated. The above script is for the Issue Created event 

Yes, initially, ""Baseline Due Date" was filled by users. And the "Epic Baseline Captured Date", captures the dates on when this "Baseline Due Date" is being filled. And, if the "Baseline Due Date" is empty, then this ""Epic Baseline Captured Date" returns an empty value too.

Now, the "Baseline Due Date" is a view only field, that simply displays the FIRST epic Due date value & locks it.

Hope i made sense . . lol, sorry

Like Antoine Berry likes this

Hi @Antoine Berry  I changed the line 12 as you had instructed, but nothing happened :'( Still the field doesn't show up. But, got the below logs,

2020-09-18 07:38:33,430 ERROR [runner.ScriptBindingsManager]: current value of Baseline Due Date is : null
2020-09-18 07:38:33,433 ERROR [runner.ScriptBindingsManager]: the value is not being changed.
Like Antoine Berry likes this
Antoine Berry Community Leader Sep 22, 2020

This line : 

if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == 'Baseline Due Date'}){

does not work for issue created event. So this is normal that nothing happens. Also, if the Baseline Due Date is a view only field, its value will never be updated manually and the above line will never return true, so again nothing will happen.

Now I am quite lost at understanding what you want to achieve, could you sum it up once again please?

@Antoine Berry Actually, the "Baseline Due Date" value is based off the Epic Due Date field now.

Remember, this - (I got this done with your help)

https://community.atlassian.com/t5/Jira-questions/Need-help-with-Script-Listeners-to-copy-and-lock-a-field-value/qaq-p/1198878#M439818 

After this above change, the field is not user editable anymore.

Now, I want to capture the date ("Epic Baseline Captured Date") during when this "Baseline Due Date" is copied & locked from this new setup . . .  

Lol, I'm sorry my explanation is more complicated than a Nolan movie :D

Hello @Antoine Berry , Sorry for troubling you . . .  Is there a possibility, the above issue could be fixed ? Or should a new listener be created :'(

Antoine Berry Community Leader Sep 25, 2020

It is a bit confusing sometimes as I don't know if your "due date" fields are system or custom...

I still have to go and watch the last Nolan movie though !

So If I understood it well you want the "Epic Baseline Captured Date" to be equal to the "Baseline due date" ? So basically have the same value for "Epic Baseline Captured Date" and "Epic due date" ?

Hello @Antoine Berry  I haven't watched anything good at all lately  :D

So, we have three dates for the Epic

Due Date - (Regular user input date field )

Baseline Due Date - Captures & locks the FIRST Due Date value & doesn't change (only on view screens) (And only gets cleared when an Epic moves back from Working status to Backlog)

Epic Baseline Captured Date - Captures the dates when the Baseline Due Date is getting filled

 

Example - Suppose I'm filling in the below values today,

Due Date - 10/15/2020

Baseline Due Date - 10/15/2020

Epic Baseline Captured Date - 9/28/2020 (Since, the above value got filled today)

Hope I made sense :D

Antoine Berry Community Leader Sep 30, 2020

Yes, it is tough to go to the movies with all the covid thing...

So this is perfectly clear now. It all has to be in the same script. Could you please share the exact script that copies the due date in the baseline again and I will tweak it. :)

@Antoine Berry  In my country, the cases are sky-rocketing, I have stopped following the news, coz I cannot deal with the anxiety. Hope everything gets back to usual soon 

We have the below old two listeners for the "Epic Baseline Captured Date",

ISSUE CREATED EVENT

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def cfm = ComponentAccessor.getCustomFieldManager()
def watch = cfm.getCustomFieldObjectByName("Baseline Due Date")
def watchValue = event.issue.getCustomFieldValue(watch)
def updatedWatch = cfm.getCustomFieldObjectByName("Epic Baseline Captured Date")
def today = new java.sql.Timestamp(new Date().getTime())

if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == 'Baseline Due Date'}){

def changeHolder = new DefaultIssueChangeHolder()

updatedWatch.updateValue(null, event.issue, new ModifiedValue(null, today), changeHolder)

}

 

ISSUE UPDATED EVENT

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder


def cfm = ComponentAccessor.getCustomFieldManager()
def watch = cfm.getCustomFieldObjectByName("Baseline Due Date")
def watchValue = event.issue.getCustomFieldValue(watch)
def updatedWatch = cfm.getCustomFieldObjectByName("Epic Baseline Captured Date")
def today = new java.sql.Timestamp(new Date().getTime())

if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == 'Baseline Due Date'}){
def changeHolder = new DefaultIssueChangeHolder()

if( event.issue.getCustomFieldValue(watch) == null ){
updatedWatch.updateValue(null, event.issue, new ModifiedValue(null, null), changeHolder)
}else{
updatedWatch.updateValue(null, event.issue, new ModifiedValue(null, today), changeHolder)
}

}

log.error(event.getChangeLog().getRelated('ChildChangeItem'))

Also, we have below listener script for the "Baseline Due Date" to copy & locks the FIRST Due Date value

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def issueType = issue.getIssueType().getName()
if (issueType == "Epic"){
def customFieldManager = ComponentAccessor.getCustomFieldManager()

def dueDateValue = issue.getDueDate()
int date1id = 15105

def date1 = customFieldManager.getCustomFieldObject(date1id)
def date1Value = issue.getCustomFieldValue(date1)

if (!date1Value && dueDateValue){
date1.updateValue(null, issue, new ModifiedValue(date1Value, dueDateValue), new DefaultIssueChangeHolder())
}
}

@Antoine Berry  No matter what, dunno how to fix it :'( 

Like Antoine Berry likes this
Antoine Berry Community Leader Oct 06, 2020

Hi @Aisha M ,

Sorry I was very busy lately... Too many problems I cannot fix either ! :D 

I would suggest to update the second script with : 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def issueType = issue.getIssueType().getName()
if (issueType == "Epic"){
def customFieldManager = ComponentAccessor.getCustomFieldManager()

def dueDateValue = issue.getDueDate()
int baselineDueDateId = 15105

def baselineDueDate = customFieldManager.getCustomFieldObject(baselineDueDateId)
def baselineDueDateValue = issue.getCustomFieldValue(baselineDueDate)

if (!baselineDueDateValue && dueDateValue){
baselineDueDate.updateValue(null, issue, new ModifiedValue(baselineDueDateValue, dueDateValue), new DefaultIssueChangeHolder())

int baselineCapturedDateId = 12345
def baselineCapturedDate = customFieldManager.getCustomFieldObject(baselineCapturedDateId)
def baselineCapturedDateValue = issue.getCustomFieldValue(baselineCapturedDate)
def today = new java.sql.Timestamp(new Date().getTime())

baselineCapturedDate.updateValue(null, issue, new ModifiedValue(baselineCapturedDateValue, today), new DefaultIssueChangeHolder())
}
}

(change the baselineCapturedDateId with the correct field id)

Keep the configuration of the listener as is. You can remove the first two listeners.

Let me know if that helped.

Like Aisha M likes this

@Antoine Berry  *YIPPPEEEE* The field is working now :D Will test a little more to see if its working as expected :D Thank you million million more much ^_^ 

Can you post your comment as a separate comment, so I can mark as answer :)

Like Antoine Berry likes this
Antoine Berry Community Leader Oct 06, 2020

Great news ! Sure, I will gladly accept an answer :)

@Antoine Berry I just noticed few folks with thousands of accepted answers :O So, want you to get lots of accepted answers as well, coz you always help everyone until they get a solution, & don't leave anyone mid-way :)

Antoine Berry Community Leader Oct 07, 2020

Ah thanks :) Of course I like to find a solution to a complex problem, but unfortunately I do not have much time to help other users at the moment...

Like Aisha M likes this

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
CLOUD
PRODUCT PLAN
FREE
PERMISSIONS LEVEL
Site Admin
TAGS
Community showcase
Published in Jira

Admins, notify your Jira instance of system-wide changes with the new admin announcement banner

Hi All! We’re excited to share the launch of an announcement banner that lets Jira site administrators communicate directly to their users across their  Jira Cloud instance.  ...

807 views 17 21
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you