Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Scripted field for Time in Multiple Statuses

I am trying to create a field called Time in Engineering using a scripted field.  I have done this based off the example script provided to get the time of a particular status.

 

MY problem stems from the fact that if I try to use a particular status, and only that status it does not return a value it is always blank

This status is generally the first status of any issue (however some issuetypes bypass it) but the status can also be used on a reopen or it can be sent back to from a variety of other statuses.  I know plugins can assist further with this but those options are not short terms solutions.  I can get all other statuses to report correctly.  

Any assistance would be greatly appreciated.  The script I am using is below.  The status with the issue is "Awaiting Triage"  If this status is included the return value is blank.  If it is removed from the script the sum of the other statues are returned.

import com.atlassian.core.util.DateUtils
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.history.ChangeItemBean

def componentManager = ComponentManager.getInstance()
def changeHistoryManager = componentManager.getChangeHistoryManager()

def inProgressName = "Awaiting Triage"
def inClosed = "Closed"
def inAssigned = "Assigned"
def inFix = "Fix"
def inRFT = "Ready for Test"
def inPromote = "Approved to Promote"
def inInvestigation = "Investigation"

def rt = [0]
changeHistoryManager.getChangeItemsForField (issue, "status").reverse().each {ChangeItemBean item ->

def timeDiff = System.currentTimeMillis() - item.created.getTime()

if (item.fromString == inAssigned) {
rt << -timeDiff
}
if (item.toString == inAssigned){
rt << timeDiff
}
if (item.fromString == inFix){
rt << -timeDiff
}
if (item.toString == inFix){
rt << timeDiff
}
if (item.fromString == inRFT){
rt << -timeDiff
}
// if (item.toString == inRFT){
// rt << timeDiff
// }
// if (item.fromString == inPromote){
// rt <<-timeDiff
// }
if (item.toString == inPromote){
rt <<timeDiff
}
if (item.fromString == inInvestigation){
rt << -timeDiff
}
if (item.toString == inInvestigation){
rt << timeDiff
}
if (item.fromString == inProgressName) {
rt << -timeDiff
}
if (item.toString == inProgressName){
rt << timeDiff
}

}

// NOTE: doesn't show anything if less than 60 seconds
DateUtils.getDurationString(Math.round(rt.sum() / 1000))

 

2 answers

@Jonny Carter @Donald Kelley 

The script works!

Any chance we can count the time in week days, excluding weekends ?

Sure! Most Java solutions to the problem can be easily adapted to Groovy. See, for example, https://stackoverflow.com/questions/8171968/calculating-dates-given-two-dates-excluding-weekend .

The Java LocalDate API is pretty useful for things of this nature.

Side note: one thing I notice is that you're using the ComponentManager class to get the change history manager. Might switch to the ComponentAccessor, per the docs. Even if you're not on JIRA 7 yet, this will help future-proof you.

Anyway, the example script for determining how long something is in progress presumes that the status isn't the first one in your workflow. If that's the case, you'll need to add the time from when the issue gets created to the first time the status changes. Also, if an issue has never had its status updated, you'll need to add the time in.

Something like

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

def issueService = ComponentAccessor.issueService
def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def issue = issueService.getIssue(user, "SSPA-26").issue
def changeHistoryManager = ComponentAccessor.getChangeHistoryManager()
def awaitingTriageStatus  = "Awaiting Triage"
def rt = [0L]
def changeItems = changeHistoryManager.getChangeItemsForField(issue, "status")

changeItems.reverse().each { ChangeItemBean item ->
    log.debug("Change item: from ${item.fromString} to ${item.toString}")
    def timeDiff = System.currentTimeMillis() - item.created.getTime()

    if (item.fromString == awaitingTriageStatus ) {
        rt << -timeDiff
    }
    if (item.toString == awaitingTriageStatus ) {
        rt << timeDiff
    }
}

if (! changeItems) {
    rt << (System.currentTimeMillis() - issue.getCreated().getTime())
}

// NOTE: doesn't show anything if less than 60 seconds
def total = DateUtils.getDurationString(Math.round(rt.sum() / 1000))
log.debug(total)
return total

 

Thank you that worked.  What if I wanted to get something that showed me all time except for a set of statuses.  For example we have 4 statuses that we consider outside of development time and want to calculate only time in development.  Could we use something to calculate the total time and subtract time spent in a specific status?

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Apps & Integrations

🍂📹 Apptoberfest demo contest roundup: vote for your favorite demos!

Hi Community! The submissions are in (and listed below) for the 🍻🍂Apptoberfest🍂🍻 Demo Competition and it’s time for you to place your votes for the best: Analytics & reporting app demo ...

135 views 2 12
Read article

Community Events

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

Find an event

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

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you