how to get the time spent from Assigned to In Progress in jira?

my jira version is 4.4.1

my jira workflow is

i tried to use Scripted Field to get the time spent from Assigned to In Progres?

i can get the time Start Progress(4) (the time change Assigned status to In Progress Status) by

changeHistoryManager.getChangeItemsForField (issue, "status").reverse().each {ChangeItemBean item ->
 item.fromString=="Assigned" && item.toString=="In Progress"
}

my problem is how can i get the Assign time (some action like Assign761,Assign751,or Assign 741 whose destination step is Assigned).i.e. Start Progress(4) 's previous Action time

any one can give some ideas?

7 answers

1 accepted

This widget could not be displayed.

i have fix it myself.

import com.atlassian.core.util.DateUtils
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.history.ChangeItemBean
import com.atlassian.jira.issue.Issue 
  
def componentManager = ComponentManager.getInstance()
def changeHistoryManager = componentManager.getChangeHistoryManager()

log.warn("+++++++++++++++++++++++")

def getTimeSpent={  //define a closure to get transfered timeSpent
    if(it){
        return it
    }else{ //negative value or less than one minute
        return "<1m"
    }
}

def createTime=issue.getCreated().getTime() // getTime() tranfer to milliseconds
log.warn("create time:"+issue.getCreated().toString()+"to millisecond:"+issue.getCreated().getTime())

def firstAssign=changeHistoryManager.getChangeItemsForField(issue, "status").find{
it.fromString=="Open" && it.toString=="Assigned"
}?.getCreated()
log.warn("firstAssign:"+firstAssign)

def firstStart=changeHistoryManager.getChangeItemsForField(issue, "status").find{
it.fromString=="Assigned" && it.toString=="In Progress"
}?.getCreated()
log.warn("firstStart:"+firstStart)

if(firstAssign){ //has initially Assign
    if(firstStart){ //has execute Start Progress
        def Duration_A=[0] //Assigned->In Progress
        def Duration_R=[0] //Reopened->In Progress
        
        def items = [["","",""]]
        changeHistoryManager.getChangeItemsForField (issue, "status").each {
            if (it.toString == "Assigned" || (it.fromString == "Assigned" && it.toString == "In Progress")) { //filter specified status
                items << [it.fromString,it.toString,it.created]  
            }
        }
        items=items.drop(1)
        //log.warn("items:"+items)
        while(!(items.last().getAt(0)=="Assigned" && items.last().getAt(1)=="In Progress")){
            items.pop()
        }
        log.warn("items:"+items)
        for(int i=0;i<items.size();i++){
            if(items.getAt(i).getAt(0)=="Assigned" && items.getAt(i).getAt(1)=="In Progress"){ 
                Duration_A << items.getAt(i).getAt(2).getTime()
            }else if(items.getAt(i+1).getAt(0)=="Assigned" && items.getAt(i+1).getAt(1)=="In Progress"){
                Duration_A << -items.getAt(i).getAt(2).getTime()
            }
        }
        Duration_A=DateUtils.getDurationString(Math.round(Duration_A.sum()/1000))
        timeSpent_A=getTimeSpent(Duration_A)
    }else  //return the time from Assign to now
    {
        def Duration = System.currentTimeMillis() - firstAssign.getTime()
        def timeSpent=DateUtils.getDurationString(Math.round(Duration/1000))
        timeSpent=getTimeSpent(timeSpent)
    }
}else{ //there aren't workflow transitions executed yet.
    return "has not Assigned yet"
}

can anyone help me modify this to achieve the following:

if status = "Open"

calculate from "Open" to Now

else

calculate from "Open" to "Acknowledged"

Thank you!

This widget could not be displayed.

and below code is to get total time spent from Assigned->In Progress,and Reopened->In Progress

import com.atlassian.core.util.DateUtils
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.history.ChangeItemBean
import com.atlassian.jira.issue.Issue 
  
def componentManager = ComponentManager.getInstance()
def changeHistoryManager = componentManager.getChangeHistoryManager()

log.warn("+++++++++++++++++++++++")

def getTimeSpent={it->  //define a closure to get transfered timeSpent
    def timeSpent=DateUtils.getDurationString(Math.round(it/1000))
    if(timeSpent){
        return timeSpent
    }else{ //negative value or less than one minute
        return "<1m"
    }
}

def getDuration={x,y-> //difine a closure to get Duration
    def Duration=[0]
    def items = [["","",""]]
    changeHistoryManager.getChangeItemsForField (issue, "status").each {
        if (it.toString == x || (it.fromString == x && it.toString == y)) { //filter specified status
            items << [it.fromString,it.toString,it.created]  
        }
    }
    items=items.drop(1)
    //log.warn("items:"+items)
    while(!(items.last().getAt(0)==x && items.last().getAt(1)==y)){
        items.pop()
    }
    log.warn("items:"+items)
    for(int i=0;i<items.size();i++){
        if(items.getAt(i).getAt(0)==x && items.getAt(i).getAt(1)==y){ 
            Duration << items.getAt(i).getAt(2).getTime()
        }else if(items.getAt(i+1).getAt(0)==x && items.getAt(i+1).getAt(1)==y){
            Duration << -items.getAt(i).getAt(2).getTime()
        }
    }
    return Duration
}

def createTime=issue.getCreated().getTime() // getTime() tranfer to milliseconds
log.warn("create time:"+issue.getCreated().toString()+"to millisecond:"+issue.getCreated().getTime())

def firstAssign=changeHistoryManager.getChangeItemsForField(issue, "status").find{
it.fromString=="Open" && it.toString=="Assigned"
}?.getCreated()
log.warn("firstAssign:"+firstAssign)

def firstStart=changeHistoryManager.getChangeItemsForField(issue, "status").find{
it.fromString=="Assigned" && it.toString=="In Progress"
}?.getCreated()
log.warn("firstStart:"+firstStart)

//get first (Reopened -> In Progress)
def firstReopentoInProgress=changeHistoryManager.getChangeItemsForField(issue, "status").find{
it.fromString=="Reopened" && it.toString=="In Progress"
}?.getCreated()
log.warn("firstReopentoInProgress:"+firstReopentoInProgress)

if(firstAssign){ //has initially Assign
    if(firstStart){ //has execute Start Progress
        def Duration_A=getDuration("Assigned","In Progress")
        log.warn("Duration_A"+Duration_A+" class:"+Duration_A.sum().class)
        def timeSpent_A=getTimeSpent(Duration_A.sum())
        log.warn("timeSpent_A:"+timeSpent_A)
        def Duration_R,timeSpent_R,timeSpent_total
        if(firstReopentoInProgress){  //exist (Reopened -> In Progress)
            Duration_R=getDuration("Reopened","In Progress").sum()
            log.warn("Duration_R:"+Duration_R)
            timeSpent_R=getTimeSpent(Duration_R)
        }else{ //not exist (Reopened -> In Progress)
            Duration_R=0
        }
        timeSpent_total=getTimeSpent(Duration_A.sum()+Duration_R)
        return "timeSpent_A:${timeSpent_A},timeSpent_R:${timeSpent_R},timeSpent_total:${timeSpent_total}"
    }else  //return the time from Assign to now
    {
        def Duration = System.currentTimeMillis() - firstAssign.getTime()
        log.warn("Duration:"+Duration+"class:"+Duration.class)
        timeSpent=getTimeSpent(Duration)
    }
}else{ //there aren't workflow transitions executed yet.
    return "has not Assigned yet"
}

Hi Fabby Chen i have similar kind of request, where user want to know how long the issue is in current status, for e.g Issue is in "In Progress" status, how long it has been in this status, like wise for other statuses of other issues, how to get this kind of report, manager wants to track, which status is bottleneck to resolve the issue. Appreciate your help on this. Thanks alot Raj

This widget could not be displayed.

below is to get time spent In Progress->Resolved

import com.atlassian.core.util.DateUtils
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.history.ChangeItemBean
import com.atlassian.jira.issue.Issue 
  
def componentManager = ComponentManager.getInstance()
def changeHistoryManager = componentManager.getChangeHistoryManager()

log.warn("+++++++++++++++++++++++")

def getTimeSpent={it->  //define a closure to get transfered timeSpent
    def timeSpent=DateUtils.getDurationString(Math.round(it/1000))
    if(timeSpent){
        return timeSpent
    }else{ //negative value or less than one minute
        return "<1m"
    }
}

def getDuration={x,y-> //difine a closure to get Duration
    def Duration=[0]
    def items = [["","",""]]
    changeHistoryManager.getChangeItemsForField (issue, "status").each {
        if (it.toString == x || (it.fromString == x && it.toString == y)) { //filter specified status
            items << [it.fromString,it.toString,it.created]  
        }
    }
    items=items.drop(1)
    //log.warn("items:"+items)
    while(!(items.last().getAt(0)==x && items.last().getAt(1)==y)){
        items.pop()
    }
    log.warn("items:"+items)
    for(int i=0;i<items.size();i++){
        if(items.getAt(i).getAt(0)==x && items.getAt(i).getAt(1)==y){ 
            Duration << items.getAt(i).getAt(2).getTime()
        }else if(items.getAt(i+1).getAt(0)==x && items.getAt(i+1).getAt(1)==y){
            Duration << -items.getAt(i).getAt(2).getTime()
        }
    }
    return Duration
}

def createTime=issue.getCreated().getTime() // getTime() tranfer to milliseconds
log.warn("create time:"+issue.getCreated().toString()+"to millisecond:"+issue.getCreated().getTime())

def firstAssign=changeHistoryManager.getChangeItemsForField(issue, "status").find{
it.fromString=="Open" && it.toString=="Assigned"
}?.getCreated()
log.warn("firstAssign:"+firstAssign)

def firstStart=changeHistoryManager.getChangeItemsForField(issue, "status").find{
it.fromString=="Assigned" && it.toString=="In Progress"
}?.getCreated()
log.warn("firstStart:"+firstStart)

//get first (In Progress -> Resolved)
def firstResolve=changeHistoryManager.getChangeItemsForField(issue, "status").find{
it.fromString=="In Progress" && it.toString=="Resolved"
}?.getCreated()
log.warn("firstResolve:"+firstResolve)

if(firstAssign){ //has initially Assign
    if(firstStart){ //has execute Start Progress
        if(firstResolve){  //exist (In Progress -> Resolved)
            def Duration=getDuration("In Progress","Resolved")
            log.warn("Duration"+Duration+" class:"+Duration.sum().class)
            def timeSpent=getTimeSpent(Duration.sum())
        }else{ //not exist (In Progress -> Resolved)
            def Duration = System.currentTimeMillis() - firstStart.getTime()
            log.warn("Duration:"+Duration+"class:"+Duration.class)
            def timeSpent=getTimeSpent(Duration)
        }
    }else  //return the time from Assign to now
    {
        return "has not Start Progress yet."
    }
}else{ //there aren't workflow transitions executed yet.
    return "has not Assigned yet"
}

This widget could not be displayed.

Have you looked at the transitions tab on the issue (assuming you have jira suite utilities plugin). This tab tells you amount of time spent on each status.

Otherwise, you can install plugin vertyGo SLA which can provide detailed information on amount of time spent on each status.

https://marketplace.atlassian.com/plugins/com.valiantys.jira.plugins.vertygo.jira-vertygosla-plugin

Rahul

hi,Rahul

i have already installed jira suite utilities plugin,i just can 'see' the 'Time In Source Status' value.

what i want is obtain the value and store it in one field.and then we can make a statistic on dashboard.

This widget could not be displayed.

i'm urgent to fix this issue.anyone can give help?

This widget could not be displayed.

You are not very clear with explanation what you want to compute.At least for me.

Anyway with your proposed method you should be able to find the time where issue was "assigned", e.g. when item.toString=="Assigned", shouldn't you?

More precisely item.fromString!="Open" && item.toString=="Assigned"

hi Jozef,

one issue's lifecycle may be open -> Assigned -> In Progress...

there also exists other possibilities:

if one issue's lifecycle is like open(a) -> Assigned(b) -> Assigned(c) -> In Progress(d)...

1 when tester create the issue,issue is in open(a) status,

2 then leader assign the issue to Tom,issue is in Assigned(b) status,

3 later the leader find he has wrong assigned ,so he reassign the issue to Jim,issue is in Assigned(c) status,

4 jim Start Progress,issue is in In Progress(d) status.

so item.fromString!="Open" && item.toString=="Assigned" may not correctly reflect the time Jim spent on responding the issue,i.e. the time spent from Assigned(c) -> In Progress(d)

Well, you know your workflow better ;-)

This widget could not be displayed.

Hi,

I’m the product manager of VertygoSLA

As Rahul says, it seems that you can solve your problem using VertygoSLA.

You can create an issue to get some helps in our support system : https://jira.valiantys.com.

You can also have a look on the documentation : https://confluence.valiantys.com/display/VSLA/VertygoSLA


Best regards,

Suggest an answer

Log in or Sign up to answer
Atlassian Summit 2018

Meet the community IRL

Atlassian Summit is an excellent opportunity for in-person support, training, and networking.

Learn more
Community showcase
Posted Wednesday in New to Jira

Are you planning to trial, or are currently trialling Jira Software? - We want to talk to you!

Hello! I'm Rayen, a product manager at Atlassian. My team and I are working hard to improve the trial experience for Jira Software Cloud. We are interested in   talking to 20 people planning t...

169 views 2 0
Join discussion

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