New custom field using the lessor of two SLA fields Edited

We have an SLA with two fields "Time to resolution" and "Time to first response", id like to order my support queue by the lessor of the two. 

 

I have created a custom number field but it is always blank, it looks like the SLA fields might be a custom type.  Has anyone gotten around this? 

 

<!-- @@Formula:

if (issue.get("Time to first response") == null || issue.get("Time to resolution") == null)
return null;

if( issue.get("Time to first response") < issue.get("Time to resolution"))
return issue.get("Time to first response");

return issue.get("Time to resolution");

-->

 

this is what im getting in the log file

 

Navigate to the following URL to edit the formula: http://example.com/secure/admin/EditCustomField!default.jspa?id=11201
2017-09-18 15:07:03,658 http-nio-8080-exec-2 ERROR user 906x46436x1 1yl6lom 10.243.1.24,0:0:0:0:0:0:0:1 /rest/api/2/search [c.i.jmcf.fields.CalculatedNumberField] CalculatedNumberField: error evaluating formula of field "Queue Rank" of issue CSS-5777:
Sourced file: inline evaluation of: `` if (issue.get("Time to first response") == null || issue.get("Time to resolut . . . '' : Operator: '"<"' inappropriate for objects : at Line: 6 : in file: inline evaluation of: `` if (issue.get("Time to first response") == null || issue.get("Time to resolut . . . '' : ) return issue .get ( "Time to first response" ) ;

1 answer

0 votes

I didn't try it but even assuming SLA fields just contain a Date object, it's still an object so you can't use "<" on them (JMCF uses BeanShell, not Groovy which adds Date comparison operators).

Try adding ".getTime()" to the getters:

<!-- @@Formula:

if (issue.get("Time to first response") == null || issue.get("Time to resolution") == null)
return null;

if( issue.get("Time to first response").getTime() < issue.get("Time to resolution").getTime())
return issue.get("Time to first response");

return issue.get("Time to resolution");

-->

Unfortunately it looks like its not just a date, it is a complex type. I may need to look at a way to parse it. 

 

SLAValue{ 
completeSLAData= [
CompleteSLAData {
calendarName=Standard Hours,
succeeded=false,
goalTime=2088000000,
goalTimeUnits=some(SLAGoalRemainingTimeUnits {
weeks=13,
remainingDaysWithinWeek=2,
remainingMillisWithinDay=14400000,
breached=false
} ),
elapsedTime=4388667813,
remainingTime=some(-2300667813),
remainingTimeUnits=some(SLAGoalRemainingTimeUnits {
weeks=14,
remainingDaysWithinWeek=0,
remainingMillisWithinDay=32667813,
breached=true
} ),
startTime=2017-03-07T21:43:02.001 Z,
stopTime=2017-09-18T02:04:27.813 Z
}
],
timeline=Timeline {
events= [
TimelineEvent {
date=2017-03-07T21:43:02.001 Z,
types= [
START
]
},
TimelineEvent {
date=2017-09-18T02:04:27.813 Z,
types= [
STOP
]
}
]
},
ongoingSLAData=null,
metricId=1,
definitionChangeDate=2017-01-10T23:42:32.963 Z,
definitionChangeMsEpoch=1484091752963,
goalsChangeDate=null,
goalsChangeMsEpoch=null,
goalTimeUpdatedDate=null,
goalTimeUpdatedMsEpoch=null,
metricCreatedDate=null,
updatedDate=some(1505706037410)
}

That's actually just the output of the "toString" Java method applied to an SLAValue object. There are methods you can call on these objects to get the information you want. 

What is it you want to get from that object? I can then give you the right method to call.

In our SLA, we have time to resolution and time to first response, I am trying to find what is due next in a numeric or date form for queue ordering. 

So I am trying to get what is due next out of the two sla fields.  So time remaining for each field and some way to know if that sla is already completed ie. First response is completed so just need time to resolution. 

That's a little complex.

issue.get("Time to first response") will return an SLAValue object. This object has a getOngoingSLAData() method that returns an OngoingSLAData object, and a getLastCompletedCycle() method that returns an Option<CompleteSLAData>. These two methods look promising but I don't know which one holds the data for the currently active cycle.

Can you post the output of the value of your SLA field for a currently active issue (one for which the SLA clock is ticking)?

Thanks for all your help, its appreciated. 

Here is an in progress SLA 

 

SLAValue{ 
completeSLAData= [

],
timeline=Timeline {
events= [
TimelineEvent {
date=2017-02-27T22:38:31.437 Z,
types= [
START
]
},
TimelineEvent {
date=2017-03-06T05:52:53.203 Z,
types= [
PAUSE
]
},
TimelineEvent {
date=2017-03-09T20:40:59.310 Z,
types= [
UNPAUSE
]
},
TimelineEvent {
date=2017-03-22T01:11:55.890 Z,
types= [
PAUSE
]
},
TimelineEvent {
date=2017-03-22T01:25:45.350 Z,
types= [
UNPAUSE
]
},
TimelineEvent {
date=2017-03-31T01:42:04.970 Z,
types= [
PAUSE
]
},
TimelineEvent {
date=2017-03-31T02:51:37.450 Z,
types= [
UNPAUSE
]
}
]
},
ongoingSLAData=OngoingSLAData {
goalId=218,
startTime=2017-02-27T22:38:31.437 Z,
paused=false,
thresholdData=some(ThresholdData {
calculatedAt=2017-06-12T04:48:47.939 Z,
remainingTime=some(-175187765),
thresholdsConfigChangeDate=2016-09-15T05:54:25.843 Z,
thresholdsConfigChangeMsEpoch=1473918865844
} )
},
metricId=1,
definitionChangeDate=2017-01-10T23:42:32.963 Z,
definitionChangeMsEpoch=1484091752963,
goalsChangeDate=2017-06-12T04:48:44.703 Z,
goalsChangeMsEpoch=1497242924704,
goalTimeUpdatedDate=2017-01-10T23:38:30.533 Z,
goalTimeUpdatedMsEpoch=1484091510534,
metricCreatedDate=null,
updatedDate=none()

I think i am pretty close now, I think i just need to work out how to read the remaining time as a number 

 

<!-- @@Formula: 
log.error("Value of field Time to resolution is: "+issue.get("Time to resolution"));
log.error("Value of field Time to first response is: "+issue.get("Time to first response"));


if (issue.get("Time to first response") == null || issue.get("Time to resolution") == null)
return null;

if( issue.get("Time to first response").getOngoingSLAData() != null)
{
log.error("FR: "+issue.get("Time to first response").getOngoingSLAData());
return issue.get("Time to first response").getOngoingSLAData().remainingTime;
}

if( issue.get("Time to resolution").getOngoingSLAData() != null)
{
log.error("TR: "+issue.get("Time to resolution").getOngoingSLAData());
return issue.get("Time to resolution").getOngoingSLAData().remainingTime;
}

return 0;


-->



 Sourced file: inline evaluation of: ``   log.error("Value of field Time to resolution is: "+issue.get("Time to resolut . . . '' : reflection error: bsh.ReflectError: No such field: remainingTime : at Line: 18 : in file: inline evaluation of: ``

Good :)

You'll need to use the getRemainingTime() method, but that might return an Option object instead of directly the Long value.  And I don't remember the syntax of Fugue's Option class but you can look it up. 

Yeah I had tried that, method does not seem to exist

 

Error in method invocation: Method getRemainingTime() not found in class'com.atlassian.servicedesk.internal.sla.model.OngoingSLAData' 

 

log.error("FR: "+issue.get("Time to first response").getOngoingSLAData().getRemainingTime());

I'll look it up tomorrow if you don't mind - it's 2am in my time zone :)

Thanks,

I think i have it now, the data in the timeRemaining field is not consistent to the actual time renaming on the SLA, heaps of issues seem to ge the exact same figures even though different SLA left. But that will be something strange in the SLA data. Ill play with that down the track

 

<!-- @@Formula: 


if (issue.get("Time to first response") == null || issue.get("Time to resolution") == null)
return null;

if( issue.get("Time to first response").getOngoingSLAData() != null)
{
return issue.get("Time to first response").getOngoingSLAData().getThresholdData().get().getRemainingTime().get();
}

if( issue.get("Time to resolution").getOngoingSLAData() != null)
{
return issue.get("Time to resolution").getOngoingSLAData().getThresholdData().get().getRemainingTime().get();
}

return 1;


--> 

 

queue.png

 

Thanks for your help. Very much appreciated. 

Hi @David Fischer [Innovalog]

 

I have spoken to Atlassian support regarding the remainingTime on the SLAData, they have advised it should represent the milliseconds totalling the time remaining. 

Do you have any idea why in the above screenshot they are all showing up s 162,000,000 even though the actual  sla on the left are different?  image.png

Are you certain you're looking at the right field (method)? Did you show your code to Atlassian?

Also, did you re-index Jira after updating the formula?

Suggest an answer

Log in or Sign up to answer
Community showcase
Published Nov 29, 2018 in Marketplace Apps

How to set up an incident workflow from the VP of Engineering at Sentry

Hey Atlassian community, I help lead engineering at Sentry, an open-source error-tracking and monitoring tool that integrates with Jira. We started using Jira Software Cloud internally last year, a...

1,407 views 0 8
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you