It's all about the answers!

Ask a question

Defect Age by State


Ashwath G (6633951) | asked May 11 '15, 6:07 p.m.
hello,

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


permanent link
Ashwath G (6633951) | answered Jul 13 '15, 7:45 a.m.
Hello Donald,

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

Ralph Schoon selected this answer as the correct answer

5 other answers



permanent link
Ashwath G (6633951) | answered Jun 15 '16, 3:48 a.m.
edited Jun 15 '16, 3:53 a.m.
Hello,

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

permanent link
Donald Nong (14.5k614) | answered May 11 '15, 8:33 p.m.
Since it is specific to states unique to your environment, I doubt that any out-of-box implementation exists. You will need to get the history of the state changes and calculate the length of each period.

Comments
Donald Nong commented May 15 '15, 1:55 a.m. | edited May 28 '15, 7:21 p.m.

Ashwath G commented May 28 '15, 4:00 p.m. | edited May 28 '15, 7:19 p.m.

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;


    }
  });
})();


Donald Nong commented May 29 '15, 6:09 a.m. | edited May 29 '15, 6:10 a.m.

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.


Ashwath G commented Jul 03 '15, 3:21 a.m.

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





Donald Nong commented Jul 03 '15, 6:25 a.m.

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.


permanent link
Chidambaram L (23424390) | answered May 12 '15, 6:44 a.m.
Not possible out of the box.
You need java script. creating java script is simple & easy.

Comments
Ashwath G commented May 13 '15, 11:30 a.m. | edited May 28 '15, 7:18 p.m.

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....!



Ashwath G commented May 13 '15, 11:32 a.m.

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....!


permanent link
Ashwath G (6633951) | answered Jul 06 '15, 9:39 a.m.
Hello Donald,

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
Donald Nong commented Jul 06 '15, 8:09 p.m.

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.


Ashwath G commented Jul 08 '15, 9:13 a.m. | edited Jul 08 '15, 9:14 a.m.

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.


permanent link
Ashwath G (6633951) | answered Jul 08 '15, 9:12 a.m.
Hello Donald,

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
Donald Nong commented Jul 19 '15, 8:52 p.m.

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?

Your answer


Register or to post 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.