Attribute Configuration: Calculated timestamp being set unexpectantly
I defined a dojo script to calculate the "Closed" timestamp of a defect. The script has very simple logic; it simply looks if the Status is set to Closed, then returns the current timestamp. (BTW, if the Status is set to anything else, I really WISH to be able to set the Closed timestamp to unassigned, but I don't see any documentation on how to do this, so I had no choice but to set the timestamp to some bogus value....).
This all works great. HOWEVER.... I noticed that after the defect is set to Closed, and then you change some other attribute (such as....need to add a little bit more text to the "Description" to clarify the resolution): The new Closed attribute gets set the current date again! If this update to the defect was days/weeks/months later, then the Closed field is not trusted!
I put debug statements in my script. And here is the bizarre thing. As the Status changes, my script gets called and the console log messages really do get generated. HOWEVER, when the status was previously Closed, and the update to the defect is to some other field with the status remaining as Closed, my debug console log messages aren't generated??? Yet the Closed attribute gets a new current timestamp. Confusing! Any ideas why? Any workaround available?
I'm on RTC V3. Here is how I configured RTC:
Under "Configuration Data -> Attribute Customization", I defined a new "Calculated Values" dojo script of type "Script Based Calculated Value".
I defined a new attribute for defects that is a "Timestamp", with a "Calculated Value" set to the above script name, with "Dependencies" set to "Status".
Here's my script:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
dojo.provide("com.ibm.ism.calculateClosedTimestamp");
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("dojo.date.stamp");
// --------------------------------------------------------------------------------
// Calculate the Closed Date. When a defect goes into Closed status, then set
// the date to the current timestamp.
// If the defect has any other status, then set the Close Date to some bogus value.
// --------------------------------------------------------------------------------
(function() {
var WorkItemAttributes= com.ibm.team.workitem.api.common.WorkItemAttributes;
dojo.declare("com.ibm.ism.calculateClosedTimestamp", null, {
getValue: function(attributeId, workItem, configuration) {
// Log messages go to: Eclipse client: client/eclipse/workspace/.metadata/.log
console.log("com.ibm.ism.calculateClosedTimestamp - Entry");
// Default value, which is a bogus timestamp
var result = "1111-11-11T16:11:11.111Z";
// Get the current timestamp, and convert it to an ISO-8601 string
var currentDate = new Date();
var currentDateString= dojo.date.stamp.toISOString(currentDate, {milliseconds:true, zulu:true});
// console.log("com.ibm.ism.calculateClosedTimestamp: currentDate: '" + currentDate + "' currentDateString: '" + currentDateString + "'");
var defectStatus = workItem.getValue(WorkItemAttributes.STATE);
// console.log("com.ibm.ism.calculateClosedTimestamp: defectStatus: '" + defectStatus + "'");
// If the state is closed
if ( defectStatus == "DefectWorkflow.state.s1" )
{
result = currentDateString
console.log("com.ibm.ism.calculateClosedTimestamp: The state is closed. Set close date to '" + result + "'");
}
else
{
console.log("com.ibm.ism.calculateClosedTimestamp: The state is NOT closed. Set close date to '" + result + "'")
}
console.log("com.ibm.ism.calculateClosedTimestamp - Exit: Closed date returned is '" + result + "'")
return result;
}
});
})();
This all works great. HOWEVER.... I noticed that after the defect is set to Closed, and then you change some other attribute (such as....need to add a little bit more text to the "Description" to clarify the resolution): The new Closed attribute gets set the current date again! If this update to the defect was days/weeks/months later, then the Closed field is not trusted!
I put debug statements in my script. And here is the bizarre thing. As the Status changes, my script gets called and the console log messages really do get generated. HOWEVER, when the status was previously Closed, and the update to the defect is to some other field with the status remaining as Closed, my debug console log messages aren't generated??? Yet the Closed attribute gets a new current timestamp. Confusing! Any ideas why? Any workaround available?
I'm on RTC V3. Here is how I configured RTC:
Under "Configuration Data -> Attribute Customization", I defined a new "Calculated Values" dojo script of type "Script Based Calculated Value".
I defined a new attribute for defects that is a "Timestamp", with a "Calculated Value" set to the above script name, with "Dependencies" set to "Status".
Here's my script:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
dojo.provide("com.ibm.ism.calculateClosedTimestamp");
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("dojo.date.stamp");
// --------------------------------------------------------------------------------
// Calculate the Closed Date. When a defect goes into Closed status, then set
// the date to the current timestamp.
// If the defect has any other status, then set the Close Date to some bogus value.
// --------------------------------------------------------------------------------
(function() {
var WorkItemAttributes= com.ibm.team.workitem.api.common.WorkItemAttributes;
dojo.declare("com.ibm.ism.calculateClosedTimestamp", null, {
getValue: function(attributeId, workItem, configuration) {
// Log messages go to: Eclipse client: client/eclipse/workspace/.metadata/.log
console.log("com.ibm.ism.calculateClosedTimestamp - Entry");
// Default value, which is a bogus timestamp
var result = "1111-11-11T16:11:11.111Z";
// Get the current timestamp, and convert it to an ISO-8601 string
var currentDate = new Date();
var currentDateString= dojo.date.stamp.toISOString(currentDate, {milliseconds:true, zulu:true});
// console.log("com.ibm.ism.calculateClosedTimestamp: currentDate: '" + currentDate + "' currentDateString: '" + currentDateString + "'");
var defectStatus = workItem.getValue(WorkItemAttributes.STATE);
// console.log("com.ibm.ism.calculateClosedTimestamp: defectStatus: '" + defectStatus + "'");
// If the state is closed
if ( defectStatus == "DefectWorkflow.state.s1" )
{
result = currentDateString
console.log("com.ibm.ism.calculateClosedTimestamp: The state is closed. Set close date to '" + result + "'");
}
else
{
console.log("com.ibm.ism.calculateClosedTimestamp: The state is NOT closed. Set close date to '" + result + "'")
}
console.log("com.ibm.ism.calculateClosedTimestamp - Exit: Closed date returned is '" + result + "'")
return result;
}
});
})();
2 answers
You are right. It is currently not possible to return a "null" value for timestamps. You can return "0" which would be the time "1 Jan 1970" and could be treated as null for now.
The calculated value scripts are executed on every save operation (on the server side). This causes your issue. It is however very easy to fix on your side. Instead of simply saving the value every time, you can check if a valid closed value is already saved.
e.g.
<pre>
dojo.provide("com.ibm.ism.calculateClosedTimestamp");
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("dojo.date.stamp");
// --------------------------------------------------------------------------------
// Calculate the Closed Date. When a defect goes into Closed status, then set
// the date to the current timestamp.
// If the defect has any other status, then set the Close Date to some bogus value.
// --------------------------------------------------------------------------------
(function() {
var WorkItemAttributes= com.ibm.team.workitem.api.common.WorkItemAttributes;
dojo.declare("com.ibm.ism.calculateClosedTimestamp", null, {
getValue: function(attributeId, workItem, configuration) {
// Log messages go to: Eclipse client: client/eclipse/workspace/.metadata/.log
console.log("com.ibm.ism.calculateClosedTimestamp - Entry");
// Default value, which is a bogus timestamp
var result = "0";
// Get the current timestamp, and convert it to an ISO-8601 string
var currentDate = new Date();
var currentDateString= dojo.date.stamp.toISOString(currentDate, {milliseconds:true, zulu:true});
// console.log("com.ibm.ism.calculateClosedTimestamp: currentDate: '" + currentDate + "' currentDateString: '" + currentDateString + "'");
var defectStatus = workItem.getValue(WorkItemAttributes.STATE);
console.log("com.ibm.ism.calculateClosedTimestamp: defectStatus: '" + defectStatus + "'");
// If the state is closed
if ( defectStatus == "DefectWorkflow.state.s1" )
{
var closedDate= dojo.date.stamp.fromISOString(workItem.getValue(attributeId));
console.log("com.ibm.ism.calculateClosedTimestamp: The current closed date is '" + closedDate +"'");
if (closedDate.getTime() == 0) {
result = currentDateString
console.log("com.ibm.ism.calculateClosedTimestamp: The state is closed. Set close date to '" + result + "'");
} else {
console.log("com.ibm.ism.calculateClosedTimestamp: The state is closed. But has already a closed Date. Use that instead");
result= dojo.date.stamp.toISOString(closedDate, {milliseconds:true, zulu:true});
}
}
else
{
console.log("com.ibm.ism.calculateClosedTimestamp: The state is NOT closed. Set close date to '" + result + "'")
}
console.log("com.ibm.ism.calculateClosedTimestamp - Exit: Closed date returned is '" + result + "'")
return result;
}
});
})();
The calculated value scripts are executed on every save operation (on the server side). This causes your issue. It is however very easy to fix on your side. Instead of simply saving the value every time, you can check if a valid closed value is already saved.
e.g.
<pre>
dojo.provide("com.ibm.ism.calculateClosedTimestamp");
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("dojo.date.stamp");
// --------------------------------------------------------------------------------
// Calculate the Closed Date. When a defect goes into Closed status, then set
// the date to the current timestamp.
// If the defect has any other status, then set the Close Date to some bogus value.
// --------------------------------------------------------------------------------
(function() {
var WorkItemAttributes= com.ibm.team.workitem.api.common.WorkItemAttributes;
dojo.declare("com.ibm.ism.calculateClosedTimestamp", null, {
getValue: function(attributeId, workItem, configuration) {
// Log messages go to: Eclipse client: client/eclipse/workspace/.metadata/.log
console.log("com.ibm.ism.calculateClosedTimestamp - Entry");
// Default value, which is a bogus timestamp
var result = "0";
// Get the current timestamp, and convert it to an ISO-8601 string
var currentDate = new Date();
var currentDateString= dojo.date.stamp.toISOString(currentDate, {milliseconds:true, zulu:true});
// console.log("com.ibm.ism.calculateClosedTimestamp: currentDate: '" + currentDate + "' currentDateString: '" + currentDateString + "'");
var defectStatus = workItem.getValue(WorkItemAttributes.STATE);
console.log("com.ibm.ism.calculateClosedTimestamp: defectStatus: '" + defectStatus + "'");
// If the state is closed
if ( defectStatus == "DefectWorkflow.state.s1" )
{
var closedDate= dojo.date.stamp.fromISOString(workItem.getValue(attributeId));
console.log("com.ibm.ism.calculateClosedTimestamp: The current closed date is '" + closedDate +"'");
if (closedDate.getTime() == 0) {
result = currentDateString
console.log("com.ibm.ism.calculateClosedTimestamp: The state is closed. Set close date to '" + result + "'");
} else {
console.log("com.ibm.ism.calculateClosedTimestamp: The state is closed. But has already a closed Date. Use that instead");
result= dojo.date.stamp.toISOString(closedDate, {milliseconds:true, zulu:true});
}
}
else
{
console.log("com.ibm.ism.calculateClosedTimestamp: The state is NOT closed. Set close date to '" + result + "'")
}
console.log("com.ibm.ism.calculateClosedTimestamp - Exit: Closed date returned is '" + result + "'")
return result;
}
});
})();
Comments
showing 5 of 6
show 1 more comments
Comments
Ken Creager
Dec 04 '12, 11:37 a.m.