You're on your way to the next level! Join the Kudos program to earn points and save your progress.
Level 1: Seed
25 / 150 points
Next: Root
1 badge earned
Challenges come and go, but your rewards stay with you. Do more to earn more!
What goes around comes around! Share the love by gifting kudos to your peers.
Keep earning points to reach the top of the leaderboard. It resets every quarter so you always have a chance!
Join now to unlock these features and more
The Atlassian Community can help you and your team get more value out of Atlassian products and practices.
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)