My 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
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 ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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 ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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 ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@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)
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello @Antoine Berry , Sorry for troubling you . . . Is there a possibility, the above issue could be fixed ? Or should a new listener be created :'(
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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" ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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. :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@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'))
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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())
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@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 :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Great news ! Sure, I will gladly accept an answer :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@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 :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.