Attribute Configuration: Calculated timestamp being set unexpectantly
Chris Schaubach (6●2●1)
| asked Jun 03 '12, 3:32 p.m.
edited Mar 26 '13, 4:23 a.m. by Ralph Schoon (63.6k●3●36●46)
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; } }); })(); |
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; } }); })(); Comments Thanks Filip..... There is only one thing that concerns me with your suggestion: Recursion. I'm implementing a getValue method for this Closed date attribute. Inside my method, I make a call to getValue on the same attribute. Won't I get into an infinite recursive loop? Side note: We now have this QA style forum, please use the "Add comment" functionality if you are not posting an answer. You can convert this "answer" to a comment using the "more" menu. No, it should not cause any recursive issues. Every access in the script is already resolved (at this point you will simply have the old value). I have also tested the script before I posted it :). I also filed a work item for returning "null" dates under: Work Item 213940
Chris Schaubach
commented Jun 04 '12, 11:09 a.m.
Thanks Filip....It works like a champ....thanks for opening that workitem..... nvm wrong question Hi Filip and Chris
priya sekar
commented Jun 13 '13, 6:43 a.m.
Hi Gayathri, Could you pls let me know if you were able to fix this issue? I am also facing the same.
showing 5 of 6
show 1 more comments
|
Couldn't you also use the Attribute dependency and say that timestamp attribute is dependent on Status? Then if Status doesn't change, the script never gets called.
|
Your answer
Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.
Comments
Does anyone have the code to set the values of all States/Status?? I want to create a date field for each State/Status, and set them as those states get set. Then if they get set again, i.e. the work item went back in the workflow, it would reset the date the the latest one. So if the work item got to Resolved, and Resolved Date was set to 11 June 2012, then went back to some previous state and came back through and got resolved again on 1 December 2012, it would reset to the latest date? I know this can get very complicated, with work items going back/forth in the workflow, but any suggestions?
Anyone using some other method to capture this information, i.e. it's in the history?
thanks
Ken