Need help with listeners on a date field which tracks changes on a different date field

Aisha M October 25, 2019

Hi,

Can anyone please help me with how to use Script Listeners for the below scenario,

Field 1) DD

Field 2) Baseline Due Date (Date picker)

So, the field 1 must capture the dates on when the field 2 is entered and gets modified. Also FIELD 1 is not editable. It simply captures the dates when the Field 2 is modified and displays on the issue card.

 

Example> If Field 2 is modified today, then the Field 1 must display today s date and so on. 

And, if Field 2 is NULL, then Field 1 must be NULL too 

2 answers

1 accepted

1 vote
Answer accepted
Andrew
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.
October 25, 2019

Hi

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

def cfm = ComponentAccessor.getCustomFieldManager()
def cf = cfm.getCustomFieldObjectByName("DD")

if ((event.issue.getDueDate() != event.issue.getCustomFieldValue(cf)) && event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == 'duedate'}){
def changeHolder = new DefaultIssueChangeHolder()
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cf), event.issue.getDueDate()),changeHolder)
}

//log.error(event.issue.getCustomFieldValue(cf))

A.PNG

Script should sync only to one way duedate->dd, if change dd value in duedate value not changed.

B.R.

Aisha M October 25, 2019

@Andrew  Hi. Thank you for the comment. Will test it out and let you know :)

Andrew
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.
October 25, 2019

You mean FIELD 2 it is not system field? 

In that case use next:

def myField = cfm.getCustomFieldObjectByName("Your field name")
def valueMyField = event.issue.getCustomFieldValue(myField)

instead of 

event.issue.getDueDate()

Total

def cfm = ComponentAccessor.getCustomFieldManager() 
def cf = cfm.getCustomFieldObjectByName("DD")
def myField = cfm.getCustomFieldObjectByName("Your field name")
def valueMyField = event.issue.getCustomFieldValue(myField)

if ((valueMyField != event.issue.getCustomFieldValue(cf)) && event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == 'Your field name'})


log.error(event.getChangeLog().getRelated('ChildChangeItem'))// use that for find name of your field 

B.PNG

B.R.



 

Aisha M October 25, 2019

Hi @Andrew  I dunno if I m doing it wrong, but it aint working. . 

Also, forgot to mention earlier, The FIELD 1 is not editing. It simply captures the dates when the Field 2 is entered/modified and displays it on the issue card.

Andrew
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.
October 25, 2019

Could You please clarify 'not editing'? You are using some plugin to permit fields? Could You please show filed type of Field 1 (I used 'Date Picker')?

If user can't change field I'm not sure that it possible through scriptrunner because SR do changes as user.

B.R.

Aisha M October 25, 2019

@Andrew I meant, that field is non editable. I mean to say, the user wont able to edit it, so I have placed it only on the view screen. 

This field must only display and show the dates on while the "BASELINE DUE DATE" was last edited. 

Andrew
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.
October 25, 2019

Oh! I make mistake I suppose You need copy value from BASELINE DUE DATE to DD. 

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


def cfm = ComponentAccessor.getCustomFieldManager()

def cfDD = cfm.getCustomFieldObjectByName("DD")
def cfBLDD = cfm.getCustomFieldObjectByName("Your field name(Custom fields)")

def today = new java.sql.Timestamp(new Date().getTime())

if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == 'Your field name(check log)'}){
def changeHolder = new DefaultIssueChangeHolder()

if( event.issue.getDueDate() == null ){
//if clean baseline dd then clean DD
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cf), null),changeHolder)
}else{
//id change baseline dd then set today to DD
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cf), today),changeHolder)
}

}

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

I tested in my local instance work well. For system 'Due date' name in 

def cfBLDD = cfm.getCustomFieldObjectByName("Your field name(Custom fields)")

and in 

if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == 'Your field name(check log)'}){

are different. For "Your field name(Custom fields)" see in 'custom fields' web admin panels and for 'Your field name(check log)' use log.error msg in listener web panel. I suppose your field also have different name.


B.R.

Aisha M October 29, 2019

@Andrew  Hi Andrew. Not copy the value from BASELINE DUE DATE . I need to know the dates on which the BASELINE DUE DATE  was edited. The field DD must capture the dates on which the BASELINE DUE DATE  was added and then edited. And, when at some point it is set to NULL, then the DD field must go to NULL as well.

 

Hope I made sense :( 

Andrew
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.
October 29, 2019

Hi,
Could You please check next script? Don't forget change "Your field name(Custom fields)" and 'Your field name(check log)'.

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


def cfm = ComponentAccessor.getCustomFieldManager()

def cfDD = cfm.getCustomFieldObjectByName("DD")
def cfBLDD = cfm.getCustomFieldObjectByName("Your field name(Custom fields)")

def today = new java.sql.Timestamp(new Date().getTime())

if (event.getChangeLog().getRelated('ChildChangeItem').find{ it.field == 'Your field name(check log)'}){
def changeHolder = new DefaultIssueChangeHolder()

if( event.issue.getCustomFieldValue(cfBLDD) == null ){
//if clean baseline dd then clean DD
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cfDD), null),changeHolder)
}else{
//id change baseline dd then set today to DD
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cfDD), today),changeHolder)
}

}

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

B.R.

Aisha M October 29, 2019

Hi @Andrew , Can you please verify if I had replaced the names correctly :)

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


def cfm = ComponentAccessor.getCustomFieldManager()

def cfDD = cfm.getCustomFieldObjectByName("Epic Baseline Edited Date")
def cfBLDD = cfm.getCustomFieldObjectByName("Baseline Due Date")

def today = new java.sql.Timestamp(new Date().getTime())

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

if( event.issue.getCustomFieldValue(cfBLDD) == null ){
//if clean baseline dd then clean DD
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cfDD), null),changeHolder)
}else{
//id change baseline dd then set today to DD
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cfDD), today),changeHolder)
}

}

log.error(event.getChangeLog().getRelated('ChildChangeItem'))
Andrew
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.
October 29, 2019
'Baseline Due Date(check log)'

- it is wrong.

You need find it here

A.PNG

You need find that name in output from logs. If You want You can call my in skype (AndrewDvizhok@gmail.com) or write in my linked (see my profile) I show in my instance.

B.R.

Aisha M October 30, 2019

Hi @Andrew , I get the below log,

2019-10-28 12:39:38,195 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2019-10-28 12:39:38,195 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: <inline script>
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script713.groovy: 12: unexpected token:  @ line 12, column 49.
   issue.getCustomFieldValue(cf))
                                 ^
1 error

 Also, the DD field doesn't show up on the issue card :(

Andrew
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.
October 30, 2019

Hi,
In last script no exist:

issue.getCustomFieldValue(cf)

Could You please copy script again?

You need change only 3 items:

"Epic Baseline Edited Date", "Baseline Due Date"

placed here

A.PNG

and last "Baseline Due Date(check log)" here

help.gif

B.R.

Aisha M October 31, 2019

Hi @Andrew ,

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


def cfm = ComponentAccessor.getCustomFieldManager()

def cfDD = cfm.getCustomFieldObjectByName("Epic Baseline Edited Date")
def cfBLDD = cfm.getCustomFieldObjectByName("Baseline Due 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(cfBLDD) == null ){
//if clean baseline dd then clean DD
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cfDD), null),changeHolder)
}else{
//id change baseline dd then set today to DD
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cfDD), today),changeHolder)
}

}

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

 

The script looks like it ran .

LOG

 

2019-10-30 19:28:28,257 ERROR [runner.AbstractScriptRunner]: [[GenericEntity:ChangeItem][newvalue,null][field,Fix Version][oldstring,Test Release-11202019][newstring,null][id,12973873][fieldtype,jira][oldvalue,54400][group,10027046]]

 

But I cannot find my  "Epic Baseline Edited Date" on the issue card. It does not even show up :(

Andrew
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.
October 31, 2019

Hi,

Script still not work?

"Epic Baseline Edited Date" - it is not readonly field?

Did You update field "Epic Baseline Edited Date" or field 'Fix Version'?

What happen with field "Epic Baseline Edited Date" if set "Baseline Due Date"?

What happen with field "Epic Baseline Edited Date" if set empty in "Baseline Due Date"?

p.s. feel free call, maybe it will be faster :-)

B.R.

Aisha M November 1, 2019

@Andrew  Hi. Actually due to compliance issues, I am unable to share my screen or send you a screenshot :(

Epic Baseline Edited date is a view only field. I mean the users should not be able to edit it, as it only captures the dates on which the Baseline Due Date was modified. So, I have added this field only to the VIEW screens.

At the listener page, the script is showing as run successfully, but I couldn't find the Epic Baseline Edited Date on the issue card. 

Dunno, what's going wrong 

Also, can you please copy paste the exact script you have used for the video :) Will be helpful for me to compare.

Thank you !

Andrew
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.
November 3, 2019

Hi,

I provided full video https://www.youtube.com/watch?v=UJvYuNT3Peg

B.R.

Aisha M November 6, 2019

@Andrew Hi. The video was wonderful ! Thank you. so helpful. You should definitely do more videos :)

Can you please help with one question, How do I make sure the Epic Baseline Edited date is filled in at the time when the issue is created ? Now it gets updated only when the issue is updated ?

Thank you ! 

Andrew
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.
November 10, 2019

Hi,

Sorry for long answer, I had a vacation.

I suppose You need make new listener with event 'Issue created'.

Something like next:

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


def cfm = ComponentAccessor.getCustomFieldManager()

def cfDD = cfm.getCustomFieldObjectByName("Epic Baseline Edited Date")
def cfBLDD = cfm.getCustomFieldObjectByName("Baseline Due Date")

def today = new java.sql.Timestamp(new Date().getTime())

def changeHolder = new DefaultIssueChangeHolder()

if( event.issue.getCustomFieldValue(cfBLDD) == null ){
//if clean baseline dd then clean DD
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cfDD), null),changeHolder)
}else{
//id change baseline dd then set today to DD
cf.updateValue(null, event.issue, new ModifiedValue(event.issue.getCustomFieldValue(cfDD), today),changeHolder)
}
 

Or You can add postfunction in workflow.

B.R.

Aisha M November 11, 2019

@Andrew Please don't apologize :) You have helped me so much :) Thank you so much !!!

Actually, do I need to make any changes to the above script, so that it captures the current date at the time of Issue creation ? I really don't know what needs to be done :(

Andrew
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.
November 11, 2019

Hi,

You need create second listener. 

A.PNG

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 Edited Date")
def today = new java.sql.Timestamp(new Date().getTime())

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)
}

In sum You need two listeners. The first works on the update event (from video), the second works on the creation event (current comment).

B.R.

Aisha M November 12, 2019

@Andrew  Thank you soooooooo much Andrew !!! The listener works perfectly for both 'Issue created' & 'Issue updated' events ! You have been so helpful. Really grateful for your help with this request. 

Like Andrew likes this
Aisha M November 12, 2019

@Andrew Hi Andrew, Just a quick final question please, can you please help me with how to change the "Issue updated" listener to capture the date at which the Baseline Due Date is updated as NULL as well ? At this point, it simply changes the other field to NULL as well, and my users want to capture anytime the Baseline Due date is edited

Andrew
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.
November 12, 2019

Hi,

Just remove condition where check null value in script. Fixed 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 Edited 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)

}


B.R.

Aisha M December 4, 2019

TEST

Aisha M April 23, 2020

Hi @Andrew , Hope you are doing well ! :) You had helped me long ago with this above script. I'm facing a small issue, and don't know how to fix. Can you please help.

The script is running with no error, but the field is not getting displayed on the issue card page. Can you please me with what could be the reason for this ? Thank you 

0 votes
fjodors
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.
October 25, 2019

Hi

You need custom script listener at "Issue Updated" event. Your listener should contain code that checks field2 and field1 values and if field1!=field2, then update field1. If field1=field2, nothing to do
Here is an example, try something like this


import com.atlassian.jira.event.issue.AbstractIssueEventListener;

import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import java.text.SimpleDateFormat;
import java.sql.Timestamp

IssueManager issueManager = ComponentAccessor.getIssueManager();
def customFieldManager = ComponentAccessor.getCustomFieldManager();
MutableIssue issueToUpdate = (MutableIssue) event.issue;



Timestamp issueDueDateValue = event.issue.getDueDate();

def customDateFieldID = <customfieldID>;
CustomField customDateFieldObj = customFieldManager.getCustomFieldObject(customDateFieldID);

def issueCustomDateFieldValueObj = event.issue.getCustomFieldValue(customDateFieldObj)

// at this point now you have datecustomfield value and duedate value
// you can convert them to unique format (e.g. timestamp), than compare issueCustomDateFieldValueObj and issueDueDateValue
// and update custom field if you need. example:
// issueToUpdate.setCustomFieldValue(customDateFieldObj, <yourValueInProperFormat>);
// issueManager.updateIssue(event.getUser(), issueToUpdate, EventDispatchOption.ISSUE_UPDATED, false);

Suggest an answer

Log in or Sign up to answer