Defect Age by State
I have placed a standard script for the defect age calculation, typically calculates the dafect age from creation date to closed date.
But we would like to calculate the age by each state. Example defect OPEN and assigned to developer and when moves to FIXED state , we would like to capture the time spent till time stamp of FIXED from creation.
so is there any solution already implemented with such scenario.
Thank You....!
Accepted answer
I was able to fix the issue now. Please find the working code below. In the above code missed to provide string formatted input to date.dojo.diff() function Caused by: org.mozilla.javascript.EcmaError: TypeError: Cannot find function difference in object [object Object]. (defectage_fix2.js#18).
Here is the working code for Defect Age. We can use "weekday" for only weekday calculations and "day" for week calculation.
-------------------------------------------------------------------------------------------------------------------------------------------
dojo.provide("com.example.common.GetTurnAroundTime");
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("dojo.date");
dojo.require("dojo.date.stamp");
(function() {
var WorkItemAttributes= com.ibm.team.workitem.api.common.WorkItemAttributes;
dojo.declare("com.example.common.GetTurnAroundTime", null, {
getValue: function(attributeId, workItem, configuration) {
var resoTime= 0;
var endDateTimestamp = Date.now();
var iniDateTimestamp = workItem.getValue(WorkItemAttributes.CREATION_DATE);
if ((endDateTimestamp != null) && (iniDateTimestamp != null)) {
var iniDate= dojo.date.stamp.fromISOString(iniDateTimestamp);
var resoDate = dojo.date.stamp.fromISOString(endDateTimestamp);
var resoTime= dojo.date.difference(iniDate, resoDate, "weekday");
}
console.log("GetTurnAroundTime End - resoTime:" + resoTime);
return resoTime;
}
});
})();
5 other answers
I have changed the dependency of the attribute from creation date to state and also checked with modified date too. And found below errors in the eclipse log. What could be the cause and how to fix this.
!ENTRY com.ibm.team.rtc.common.scriptengine 1 0 2015-07-08 18:39:39.809
!MESSAGE LOG: '-------status entered into script------'
!ENTRY com.ibm.team.rtc.common.scriptengine 1 0 2015-07-08 18:39:39.809
!MESSAGE LOG: {}
!ENTRY com.ibm.team.workitem.common 4 0 2015-07-08 18:39:39.819
!MESSAGE Error invoking value provider 'com.ibm.team.workitem.valueproviders.VALUE_PROVIDER._Y2UX4CVMEeWqVPl8dLspjA'
!STACK 0
com.ibm.team.repository.common.TeamRepositoryException: Unexpected exception type
at com.ibm.team.workitem.shared.common.internal.valueProviders.ScriptAttributeValueProvider.handleException(ScriptAttributeValueProvider.java:281)
at com.ibm.team.workitem.shared.common.internal.valueProviders.ScriptAttributeValueProvider.getValue(ScriptAttributeValueProvider.java:69)
at com.ibm.team.workitem.common.internal.attributeValueProviders.AttributeValueProviderRegistry$SafeValueProvider.getValue(AttributeValueProviderRegistry.java:42)
at com.ibm.team.workitem.common.internal.model.impl.AttributeImpl.getValue(AttributeImpl.java:899)
at sun.reflect.GeneratedMethodAccessor154.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.team.repository.common.internal.util.ItemStore$ItemInvocationHandler.invoke(ItemStore.java:597)
at com.sun.proxy.$Proxy46.getValue(Unknown Source)
at com.ibm.team.workitem.client.internal.DependencyHandler$Worker.runProtected(DependencyHandler.java:51)
at com.ibm.team.foundation.client.util.FoundationJob.run(FoundationJob.java:68)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
Caused by: org.mozilla.javascript.EcmaError: TypeError: Cannot find function difference in object [object Object]. (defectage_fix2.js#18)
at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3557)
at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3535)
at org.mozilla.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3563)
at org.mozilla.javascript.ScriptRuntime.typeError2(ScriptRuntime.java:3582)
at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3646)
at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2186)
at org.mozilla.javascript.gen.c55._c2(defectage_fix2.js:18)
at org.mozilla.javascript.gen.c55.call(defectage_fix2.js)
at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:401)
at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3003)
at org.mozilla.javascript.gen.c55.call(defectage_fix2.js)
at com.ibm.team.rtc.common.scriptengine.internal.bridge.proxy.AbstractInvocationHandler$MethodHandler$1.run(AbstractInvocationHandler.java:160)
at com.ibm.team.rtc.common.scriptengine.environment.AbstractScriptEnvironment.execute(AbstractScriptEnvironment.java:74)
at com.ibm.team.rtc.common.scriptengine.internal.bridge.proxy.AbstractInvocationHandler$MethodHandler.invoke(AbstractInvocationHandler.java:156)
at com.ibm.team.rtc.common.scriptengine.internal.bridge.proxy.AbstractInvocationHandler.invokeGeneric(AbstractInvocationHandler.java:141)
at com.ibm.team.rtc.common.scriptengine.internal.bridge.proxy.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:95)
at com.sun.proxy.$Proxy63.getValue(Unknown Source)
at com.ibm.team.workitem.shared.common.internal.valueProviders.ScriptAttributeValueProvider.getValue(ScriptAttributeValueProvider.java:67)
... 10 more
!ENTRY com.ibm.team.workitem.common 4 0 2015-07-08 18:39:42.231
!MESSAGE Error invoking work item filter 'com.ibm.team.workitem.valueproviders.CONDITION._yv7VIMmBEeSRb4PmPBgPIQ'
!STACK 0
com.ibm.team.rtc.common.scriptengine.UnknownTypeException: 'com.ibm.team.workitem.DevelopmentReject' is not a constructor
at com.ibm.team.rtc.common.scriptengine.environment.ScriptingHelperImplementation.getConstructor(ScriptingHelperImplementation.java:162)
at com.ibm.team.rtc.common.scriptengine.ScriptUtilities$1.run(ScriptUtilities.java:30)
at com.ibm.team.rtc.common.scriptengine.environment.AbstractScriptEnvironment.execute(AbstractScriptEnvironment.java:74)
at com.ibm.team.rtc.common.scriptengine.ScriptUtilities.newInstance(ScriptUtilities.java:27)
at com.ibm.team.workitem.shared.common.internal.valueProviders.ScriptAttributeValueProvider$ProviderCall.getProvider(ScriptAttributeValueProvider.java:203)
at com.ibm.team.workitem.shared.common.internal.valueProviders.ScriptAttributeValueProvider$ProviderCall.<init>(ScriptAttributeValueProvider.java:188)
at com.ibm.team.workitem.shared.common.internal.valueProviders.ScriptAttributeValueProvider.matches(ScriptAttributeValueProvider.java:156)
at com.ibm.team.workitem.common.internal.attributeValueProviders.AttributeValueProviderRegistry$SafeWorkItemFilter.matches(AttributeValueProviderRegistry.java:151)
at com.ibm.team.workitem.common.internal.RequiredAttributesByConditionAdvisor.getRequiredAttributes(RequiredAttributesByConditionAdvisor.java:92)
at com.ibm.team.workitem.common.internal.PropertiesManager.findRequiredAttributes(PropertiesManager.java:101)
at com.ibm.team.workitem.common.internal.WorkItemCommon.findRequiredAttributes(WorkItemCommon.java:583)
at com.ibm.team.workitem.ide.ui.internal.editor.presentations.presentationhandler.RequiredPropertiesHandler$RequiredUpdaterJob.runInBackground(RequiredPropertiesHandler.java:73)
at com.ibm.team.jface.internal.util.UIUpdateManager$BackgroundJob.runProtected(UIUpdateManager.java:58)
at com.ibm.team.foundation.client.util.FoundationJob.run(FoundationJob.java:68)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
Comments
There are two errors.
1. The first one is probably my fault as I suggested using the function "dojo.date.difference". I have not figured out the exact version of bundled Dojo. It could be too old to support this function - the reference that I provided was for version 1.10.
2. The second one is about the condition script 'com.ibm.team.workitem.DevelopmentReject', which I have no idea about. But the error suggests that the function/script is ill-formed, and you need to double-check - for example, do the "dojo.declare" and "dojo.provide" match each other?
I have tried with your reference code and API suggested. And for defect age attribute i have created dependency on creation date.Could you please check this code once ....
dojo.provide("example.calculated.defectAgeValueProviderfix3");
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("dojo.date.stamp");
(function() {
var WorkItemAttributes = com.ibm.team.workitem.api.common.WorkItemAttributes;
var fromISOString = dojo.date.stamp.fromISOString;
dojo.declare("example.calculated.defectAgeValueProviderfix3", null, {
getValue: function(attribute, workItem, configuration) {
var creationDate = dojo.date.stamp.fromISOString(workItem.getValue(WorkItemAttributes.CREATION_DATE));
var currentDate = new Date();
//var dayDiff = dojo.date.difference(currentDate, creationDate, "day");
var dayDiff = dojo.date.difference(creationDate);
var result = 0;
console.log("--status enter after diff---");
if (dayDiff > 0) result=dayDiff;
return result;
}
});
})();
Comments
The code looks OK but the dependency sounds strange. Why don't you use the "state" as the dependency? The "creation date" will change once only - that's when the work item is created, and you will always get 0 for dayDiff in this case.
Hello Donald,
Could you please check the below update in my answer after changes as you suggested. The errors from log file is provided too.
You need java script. creating java script is simple & easy.
Comments
Hello Donald, Chidambaram,
Thanks for your guidelines . Currently i am writing the java script for this and one more requirement is the customer expecting to implement is out of the defect age , they would like to calculate the weekdays time only.
So is it possible to do this, if yes how to read the day & date from server. like get getTime() do we have getDay() also can be used.
Please guide me, this is important for us if we could able to implement.
dojo.provide("example.calculated.defectAgeValueProvider");
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("dojo.date.stamp");
(function() {
var WorkItemAttributes = com.ibm.team.workitem.api.common.WorkItemAttributes;
var fromISOString = dojo.date.stamp.fromISOString;
dojo.declare("example.calculated.defectAgeValueProvider", null, {
getValue: function(attribute, workItem, configuration) {
var dDate1 = fromISOString(workItem.getValue(WorkItemAttributes.CREATION_DATE));
if creationDate{
var ageInSeconds = (Date.now() - creationDate.getTime()) / 1000;
var days = parseInt(ageInSeconds / 86400);
var hours = parseInt((ageInSeconds-days * 86400) / 3600);
var minutes = parseInt((ageInSeconds-days * 86400 - hours * 3600) / 60);
return days + " d, " + hours + " hr, " + minutes + " min";
}
return "";
}
});
})();
Thank you....!
Hello Donald, Chidambaram,
Thanks for your guidelines . Currently i am writing the java script for this and one more requirement is the customer expecting to implement is out of the defect age , they would like to calculate the weekdays time only.
So is it possible to do this, if yes how to read the day & date from server. like get getTime() do we have getDay() also can be used.
Please guide me, this is important for us if we could able to implement.
Please find the code i added below and advice us.
Thank you....!
Comments
Here is a good blog that you can use as a reference.
Hi Donald,
I tried this code, but unfortunately some thing is defined wrong or creationdate.getDay() function is not supported i am not sure . The script is not getting executed ...ca you please have a look where the code is incorrect.
dojo.provide("example.calculated.defectAgingValueProvider");
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("dojo.date.stamp");
(function(startDate, endDate) {
var WorkItemAttributes = com.ibm.team.workitem.api.common.WorkItemAttributes;
var fromISOString = dojo.date.stamp.fromISOString;
dojo.declare("example.calculated.defectAgingValueProvider", null, {
getValue: function(attribute, workItem, configuration) {
var creationDate = fromISOString(workItem.getValue(WorkItemAttributes.CREATION_DATE));
var startDate = creationDate
var endDate = Date.now()
// Validate input
if (endDate < startDate)
return 0;
// Calculate days between dates
var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
startDate.setHours(0,0,0,1); // Start just after midnight
endDate.setHours(23,59,59,999); // End just before midnight
var diff = endDate - startDate; // Milliseconds between datetime objects
var days = Math.ceil(diff / millisecondsPerDay);
// Subtract two weekend days for every week in between
var weeks = Math.floor(days / 7);
days = days - (weeks * 2);
// Handle special cases
var startDay = startDate.getDay();
var endDay = endDate.getDay();
// Remove weekend not previously removed.
if (startDay - endDay > 1)
days = days - 2;
// Remove start day if span starts on Sunday but ends before Saturday
if (startDay == 0 && endDay != 6)
days = days - 1
// Remove end day if span ends on Saturday but starts after Sunday
if (endDay == 6 && startDay != 0)
days = days - 1
return days;
}
});
})();
You need to learn how to debug the scripts. There are a few things to consider.
1. If the script does not get executed, make sure that the advanced server property "Enable Process Attachment Scripts" is set to true.
2. The JavaScript function usually does not take parameters, so you don't define it as function(startDate, endDate).
3. There is an easier way to get the day difference using Dojo.
// Get the creation date and the current date and compute the difference in days. var creationDate= dojo.date.stamp.fromISOString(workItem.getValue(WorkItemAttributes.CREATION_DATE)); var currentDate= new Date(); var dayDiff= dojo.date.difference(currentDate, creationDate, "day");https://jazz.net/wiki/bin/view/Main/AttributeCustomization
4. The real issue - the "creationDate" attribute cannot be retrieved using the above script, so the variable "creationDate" is null.The "dueDate" attribute also has the same problem, while "modified" works just fine. I have not figured out what's going on yet.
Hi Donald,
Thanks for your inputs. This is really straight to calculate the diff ,but some how my script not working.Could you please verify where am i doing wrong.
(function() {
var WorkItemAttributes = com.ibm.team.workitem.api.common.WorkItemAttributes;
var fromISOString = dojo.date.stamp.fromISOString;
dojo.declare("example.calculated.defectAgeValueProviderfix3", null, {
getValue: function(attribute, workItem, configuration) {
var creationDate = dojo.date.stamp.fromISOString(workItem.getValue(WorkItemAttributes.CREATION_DATE));
var currentDate = new Date();
var dayDiff = dojo.date.difference(currentDate, creationDate, "day");
var result = 0;
if (dayDiff > 0)
{
result=dayDiff;
}
return result;
}
});
})();
You put the two dates in the difference() function the wrong way round, so you most likely get a negative value. It's always a good idea to read the API reference when developing codes.
http://dojotoolkit.org/reference-guide/1.10/dojo/date.html
As you can see in the API reference, you can do without the "currentDate" variable by this
var dayDiff = dojo.date.difference(creationDate);Also make sure that the script does get "triggered". For example, set the dependency on an attribute that will more likely get changed first.
This is a perfect code for defect age calculation based on date change for weekdays. Even we can exclude and include weekend with this dojo.data.difference functionality like below.
dojo.date.difference(iniDate, resoDate, "weekday"); - Working days only calculation
dojo.date.difference(iniDate, resoDate, "day"); - Entire Week calculation
******************************************************************************************************************
Java Script to associate to work items for defect age calculation for working days
******************************************************************************************************************
dojo.provide("com.example.common.GetTurnAroundTime");
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("dojo.date");
dojo.require("dojo.date.stamp");
(function() {
var WorkItemAttributes= com.ibm.team.workitem.api.common.WorkItemAttributes;
dojo.declare("com.example.common.GetTurnAroundTime", null, {
getValue: function(attributeId, workItem, configuration) {
var resoTime= 0;
var endDateTimestamp = Date.now();
var iniDateTimestamp = workItem.getValue(WorkItemAttributes.CREATION_DATE);
if ((endDateTimestamp != null) && (iniDateTimestamp != null)) {
var iniDate= dojo.date.stamp.fromISOString(iniDateTimestamp);
var resoDate = dojo.date.stamp.fromISOString(endDateTimestamp);
var resoTime= dojo.date.difference(iniDate, resoDate, "weekday");
}
console.log("GetTurnAroundTime End - resoTime:" + resoTime);
return resoTime;
}
});
})();