What is missing from this Groovy script when creating a script to find time between/held in status?

Matthew Nico February 3, 2023

I am testing and trying to query to use Scriptrunner to find issues and time frames in between different status. I feel like I am close, but I'm getting null value. Would I have to define dates that it was in one status totaled into another? What am I missing here? Any tips or help is appreciated!  

 

import com.atlassian.jira.issue.Issue
import static java.lang.Math.*
import com.atlassian.jira.util.JiraKeyUtils
import java.lang.String


def startTime = System.currentTimeMillis();
def query = JiraKeyUtils.getIssueKeysFromString("project = DAFCEE AND status = Initial Customer Outreach")

def totalIssues = 0;
def totalTime = 0;

for ( issue in query )
{totalIssues += 1;
    def workflowAction = issue.getActions();
    def timeSpent = workflowAction.getTimeSpent();
    totalTime += timeSpent;
    }

def endTime = System.currentTimeMillis();
def totalTimeinMinutes = totalTime /60000;
def totalTimeInHours = totalTimeinMinutes / 60;

println("It takes " + totalTimeInHours + " hours and " + totalTimeinMinutes / 60 + " minutes for " + totalIssues + " issues with the project DAFCEE to move from the status as Initial Customer Outreach to In Evaluation in a workflow.");
println("Time Elapsed: " + (endTime - startTime) + "ms");

1 answer

0 votes
Tuncay Senturk
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
February 5, 2023

Hi @Matthew Nico 

I don't think you're that close. If you want to calculate time spent in each status for an issue you have to use ChangeHistoryManager to retrieve all transitions and then calculate the time passed accordingly.

I am sharing a sample code which collects all durations in statuses in a map statusTimes. In this map, the keys are the status names and the values are the start/end dates.

You can calculate times per issue, or you can sum them and keep the total values among the JQL.

I hope it helps

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.status.Status
import com.atlassian.jira.issue.changehistory.ChangeHistoryManager
import java.util.Date

def changeHistoryManager = ComponentAccessor.getChangeHistoryManager()

def issue = // assuming you run below code for each issue

def statusTimes = [:]

def changeHistoryManager = changeHistoryManager.getChangeHistoriesForUser(issue, null)
changeHistoryManager.each { change ->
def fromStatus = change.getFromStatus()
def toStatus = change.getToStatus()
def date = change.getCreated()
if (!statusTimes[fromStatus.name]) {
statusTimes[fromStatus.name] = [start: date, end: null]
} else {
statusTimes[fromStatus.name].end = date
}
if (!statusTimes[toStatus.name]) {
statusTimes[toStatus.name] = [start: date, end: null]
}
}

for (def status : statusTimes.keySet()) {
def statusDuration = statusTimes[status]
def start = statusDuration.start
def end = statusDuration.end ?: new Date()
def duration = end.getTime() - start.getTime()
log.info("Time spent in status '$status': ${duration/1000} seconds")
}
Matthew Nico February 7, 2023

I was unable to execute this script you provided and anything else I tried.

//This script will automate the task of tracking the time each issue spends in a particular status in JIRA.

// Load the necessary libraries
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.status.Status
import com.atlassian.jira.issue.history.ChangeItemBean
import com.atlassian.jira.issue.status.category.StatusCategory

// Get the IssueManager instance
def issueManager = ComponentAccessor.getIssueManager()

// Initialize the counters
def totalTimeInStatus = [:]

// Iterate over all the issues in JIRA
for (issue in issueManager.getIssueObjects()) {
// Get the issue's current status
def currentStatus = issue.getStatusObject()

// Get the list of change items for this issue
def changeItems = issue.getChangeItems()

// Iterate over the change items
for (changeItem in changeItems) {
// Get the from and to status
def fromStatus = changeItem.getFromString()
def toStatus = changeItem.getToString()

// Check if the status has been changed
if (fromStatus != toStatus) {
// Get the time difference between the two statuses
def timeDiff = changeItem.getCreated().getTime() - issue.getCreated().getTime()

// Calculate the total time spent in the status
def totalTime = totalTimeInStatus.get(fromStatus, 0) + timeDiff

// Update the total time spent in the status
totalTimeInStatus.put(fromStatus, totalTime)
}
}

// Calculate the time spent in the current status
def timeDiff = System.currentTimeMillis() - issue.getCreated().getTime()
def totalTime = totalTimeInStatus.get(currentStatus, 0) + timeDiff
totalTimeInStatus.put(currentStatus, totalTime)
}

// Print out the results
totalTimeInStatus.each { status, totalTime ->
println "Total time spent in status '${status}': ${totalTime} ms"
}

Suggest an answer

Log in or Sign up to answer