Hey there!
I just wanted to share my solution for clearing the Resolution on a status transition (if moved from Done to To-Do or In-Progress) and wanted to ask for some feedback - perhaps I've missed something, or I'm doing something very silly.
The reason I haven't used Post Functions to clear the resolution is to have 1 script that covers all cases and avoid having to setup and maintain multiple post-functions (e.g. if a new status is added, it's covered automatically).
Using ScriptRunner I've created a Listener that listens to All Issue Events for my particular project (there didn't seem to be one for just listening to status transitions).
Here's the script:
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.status.category.StatusCategory
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
/*
A status Transition listener that clears the Resolution status if an issue is
moved from a "Complete" status category any of the to the other categories ("To-Do" / "In Progress").
*/
// The issue provided to us in the binding
MutableIssue issue = event.issue as MutableIssue
// Not an epic? We only care about those. Early exit.
if (issue.getIssueType().getName() != "Epic") {
return
}
// No changelog (e.g. an edit with only a comment)? Early exit.
if (event.getChangeLog() == null) {
return
}
def statusChangeItems = ComponentAccessor.getChangeHistoryManager().getChangeItemsForField(issue, 'status')
// No status changes? It's a new issue. Early exit.
if (statusChangeItems.isEmpty()) {
return
}
def lastTransitionChangeItem = statusChangeItems?.last()
def fromStatus = lastTransitionChangeItem.fromString
def toStatus = lastTransitionChangeItem.toString
// No status change? Early exit.
if (fromStatus == toStatus) {
return
}
def eventFiredTimestamp = event.getChangeLog().created
def changeItemTimestamp = lastTransitionChangeItem.created
// If the last status change was at the exact same time as the event we can (somewhat?)
// safely deduce that this event was fired because of a status transition
if(changeItemTimestamp != eventFiredTimestamp) {
return
}
StatusCategory fromStatusCategory = null
StatusCategory toStatusCategory = null
def workflow = ComponentAccessor.getWorkflowManager().getWorkflow(issue)
// Find category of status by name
workflow.getLinkedStatusObjects().each {
if ("${it.name}" == fromStatus) {
fromStatusCategory = it.statusCategory
}
if ("${it.name}" == toStatus) {
toStatusCategory = it.statusCategory
}
}
// Couldn't find status categories from status name? (Shouldn't happen..)
if (fromStatusCategory == null || toStatusCategory == null) {
log.warn ("Could not find category for from- (${fromStatus}), or to-, status (${toStatus}).")
return
}
// Not a transition from a "Complete" (green) status? Not interested. Early exit.
if (fromStatusCategory.getKey() != StatusCategory.COMPLETE) {
return
}
// Transition to "Complete" status? Don't want to clear resolution. Early exit.
if (toStatusCategory.getKey() == StatusCategory.COMPLETE) {
return
}
// Let's clear that resolution!
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
issue.setResolution(null)
issueManager.updateIssue(user, issue, EventDispatchOption.DO_NOT_DISPATCH, false)
Recommended Learning For You
Level up your skills with Atlassian learning
Learning Path
Get the most out of Jira
Explore the interface and basic Jira terms, then discover how to effectively manage your work.
Learning Path
Atlassian tools and practices for developers
Focus on your development work by using Jira software features and functions efficiently.
Atlassian Certified Associate
Jira Software Essentials certification
Demonstrate proficiency in utilizing essential Jira features and working efficiently with Agile frameworks like Kanban and Scrum.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.