Calculate time in multiple statuses (cont.)

Ian Balas February 12, 2021

Hi all,

This post is a continuation/repost of my recent blog post, but I'm looking to figure out how to calculate the amount of time that an issue has been under a select group of statuses.

I'm aware that Scriptrunner Library has a solution that enables you to create a scripted field with the duration template that records the time that an issue has been under a certain status, referenced here: 

Count the time an issue was in a particular status

What I want to do is use this code and change it up to where it can calculate the time that the issue has been under not just one status, but a certain collection of statuses.

Since my last post, I've edited the code a bit myself. Pretty much all I could think of for now was to duplicate the block that covers the changeItems object, but replicate it for another status...and then in the end, take the two arrays that store the total time that the issue was in said statuses, use addAll(), and then sum up the values in the newly-expanded array. See below:

import com.atlassian.core.util.DateUtils
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.history.ChangeItemBean
def changeHistoryManager = ComponentAccessor.changeHistoryManager


// Status to be counted
def toDo = 'On Hold'
def totalStatusTime = [0L]

// Every status change is checked
def changeItems = changeHistoryManager.getChangeItemsForField(issue, "status")
changeItems.reverse().each { ChangeItemBean item ->
def timeDiff = System.currentTimeMillis() - item.created.time
// Subtract time if the "from" status is equal to the status to be checked and from and to statuses are different.
// This allows to count the time the issue is in the state for the first time
if (item.fromString == toDo && item.fromString != item.toString) {
totalStatusTime << -timeDiff
}
// Add time if the "to" status is equal to the status to be checked
if (item.toString == toDo) {
totalStatusTime << timeDiff
}
}

def intakeReview = "Intake Review"
def totalStatusTime2 = [0L]

changeHistoryManager.getChangeItemsForField (issue, "status")
changeItems.reverse().each {ChangeItemBean item ->
def timeDiff = System.currentTimeMillis() - item.created.time

if (item.fromString == intakeReview && item.fromString != item.toString) {
totalStatusTime << -timeDiff
}
if (item.toString == intakeReview) {
totalStatusTime << timeDiff
}
}

totalStatusTime.addAll(totalStatusTime2)

def total = totalStatusTime.sum() as Long
(total / 1000) as long ?: 0L

 

This seemed to have worked for these two statuses in particular when previewing the code over an issue in our system. This issue was created and set by default to the Open status. In exactly 4 days, 18 hours, and 53 minutes after the issue was created, the issue was then moved to the Intake Review status. I was only in the Intake Review status for 4 minutes, and it was then moved to the On Hold status...and the issue has been On Hold for the past 35 weeks, 4 days, 6 hours, 57 minutes and counting.

Previewing the above code for the same issue, the amount of time that the issue was in On Hold will be added to the 4 minutes that it was Intake Review and the result will come up as 35 weeks, 4 days, 7 hours, 1 minute. This is the result I want, which is great.

However...for some reason,  when I want to find out the time in the Open status, the code only returns null. And worse yet, when I want to find how long the issue has been in both Open and On Hold statuses, instead of doing [35 weeks, 4 days, 6 hours, 57 minutes] + [4 days, 18 hours, and 53 minutes] ...it'll still return null :(

Any reason why this is happening?

-----

Also, if anyone has suggestions on how to clean this up and have the script iterate through the time the issue has been in a selection of statuses (say Open, Intake ReviewOn Hold, and In Progress) rather than just copying and pasting a block for each status, that'd be awesome too.

As always, any tips or advice is highly appreciated! Let me know if there's any other info you need from my end.

Thanks,

 

Ian

  

 

2 answers

0 votes
M0214104 January 5, 2023

Hi @Ian Balas 

I would be really interested, if you figured out how to adapt the script in the meantime as we are loooking for something similar as well but I am not a coder at all...

KR
Kathrin

0 votes
Bill Sheboy
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 12, 2021

Hi @Ian Balas 

A couple of FYIs first:

  • You may want to post something like this in the Questions area to get more eyes on it rather than in Discussions
  • You may want to check out the developer community area for ideas: https://community.developer.atlassian.com/

Regarding the Open measure which you indicate evaluates to NULL...  If you are not handling that NULL and just adding it to an actual value might it not collapse to NULL?  That could explain what you are seeing.

And, your measurement scenario seems pretty complex.  Using this code, I think you will need to continue what you are trying: evaluate, status by status, and then doing the math for what you want. In your earlier post there are some suggestions to try; how did those help?

Your other options are to purchase an add-on product with lots of flexibility for time measurement or to use the Automation for Jira features and custom fields to build your own.

Best regards,

Bill

Suggest an answer

Log in or Sign up to answer