Script Runner Post Function fire Action

Hello!

I need some help about scripted post function. I want to fire an Action (ex: Sent to Review) as a Post Function another transition (ex: Integrate) if a complicated condition goes true.

I have some questions:

1, Is it possible to fire an Action (transition) as a post function of another transition.

I am writing you the whole situation and my expectation. If anybody has idea how to figure out the solution please answer me.

 

I want to fire automatic transitions on my parent issue depending on sub-task's status, different sub-task types and different statuses. All automatic transition has different condition concern to sub-task's types and statuses and the parent issue is must be in specified status.

Here is what is made:

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.user.util.UserManager
import java.util.logging.Logger;
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.IssueInputParameters

public void doTransition(String statusId, int transitionId) {
	try{
		Thread thread = Thread.start {
			sleep(1000);
	 
			IssueService issueService = ComponentAccessor.getIssueService()
			UserManager userManager = (UserManager)  ComponentAccessor.getUserManager()
			IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
			issueInputParameters.setStatusId(statusId);
			IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser(), issue.id, transitionId, issueInputParameters);
			
			if (transitionValidationResult.isValid()){
				IssueService.IssueResult transitionResult = issueService.transition(currentUser, transitionValidationResult);
				if (!transitionResult.isValid()) {
					transitionResult.errorCollection.errorMessages.each {log.error "Error Message: $it"}
					transitionResult.errorCollection.errors.each {log.error "Error: $it"}
					transitionResult.errorCollection.reasons.each {log.error "Reason: $it"}
				}
			} else {
				transitionValidationResult.errorCollection.errorMessages.each {log.error "Error Message: $it"}
				transitionValidationResult.errorCollection.errors.each {log.error "Error: $it"}
				transitionValidationResult.errorCollection.reasons.each {log.error "Reason: $it"}
			}
		}
	} catch (Exception e){
		log.error(e.getMessage());
	}
}
def subtasks = issue.getSubTaskObjects();
def cFieldValue = issue.getCustomFieldValue(ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_22200")) // status before trigger
def goToReproduction = false;
def goToProcessing = false;
def goToIntegrating = false;
def goToVerifying = false;
def goToConcluding = false;
for (int i=0; i < subtasks.size(); i++)
{
	def nextIssue = subtasks[i];
    
	if (cFieldValue == 'Categorizing')
	{
		if	(nextIssue.getIssueTypeId() == "13602" && nextIssue.getStatus()?.name != 'New') 
		{
			goToReproduction = true
			break;
		}
	} 
	else if (cFieldValue == 'Reproduction')
	{
		if ((nextIssue.getIssueTypeId() == "13603" || nextIssue.getIssueTypeId() == "13701") && nextIssue.getStatus()?.name != 'New') 
		{
			goToProcessing = true
			break;
		}
	} 
	else if (cFieldValue == 'Processing')
	{
		if ((nextIssue.getIssueTypeId() == "13603" || nextIssue.getIssueTypeId() == "13701") && nextIssue.getStatus()?.name == 'Closed') 
		{
			goToIntegrating = true
			break;
		
		}
	} 
	else if (cFieldValue == 'Integrating')
	{
		if ((nextIssue.getIssueTypeId() == "13507" && nextIssue.getStatus()?.name != 'New')) 
		{
		goToVerifying = true
		break;
		}
	}		
		else 
		{
		
		}
}

if (goToReproduction){
	doTransition("3", 21);
}
if (goToProcessing)
{
	doTransition("4", 31);
}
if (goToIntegrating)
{
	doTransition("5", 41);
}
if (goToVerifying)
{
	doTransition("6", 51);
}
if (goToConcluding)
{
	doTransition("7", 61);
}

Does anybody have better solution then mine, without hack?

 

 

1 answer

0 votes
Vasiliy Zverev Community Champion Oct 27, 2016

As I understand you have several transitions from single status of parent issue and you want automatically select correct one.

For this purpose I usually use respective conditions for transitions. When conditions are well organised user has the only button for transtion.

Bonus: I like to refactor code, here is refactored version of your code:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.user.util.UserManager
import java.util.logging.Logger;
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.IssueInputParameters

public void doTransition(String statusId, int transitionId) {
    try{
        Thread thread = Thread.start {
            sleep(1000);

            IssueService issueService = ComponentAccessor.getIssueService()
            UserManager userManager = (UserManager)  ComponentAccessor.getUserManager()
            IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
            issueInputParameters.setStatusId(statusId);
            IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser(), issue.id, transitionId, issueInputParameters);

            if (transitionValidationResult.isValid()){
                IssueService.IssueResult transitionResult = issueService.transition(currentUser, transitionValidationResult);
                if (!transitionResult.isValid()) {
                    transitionResult.errorCollection.errorMessages.each {log.error "Error Message: $it"}
                    transitionResult.errorCollection.errors.each {log.error "Error: $it"}
                    transitionResult.errorCollection.reasons.each {log.error "Reason: $it"}
                }
            } else {
                transitionValidationResult.errorCollection.errorMessages.each {log.error "Error Message: $it"}
                transitionValidationResult.errorCollection.errors.each {log.error "Error: $it"}
                transitionValidationResult.errorCollection.reasons.each {log.error "Reason: $it"}
            }
        }
    } catch (Exception e){
        log.error(e.getMessage());
    }
}

boolean goToConcluding = false;

for(Issue subtask: issue.getSubTaskObjects()) {

    switch (issue.getCustomFieldValue(ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_22200"))) {
        case "Categorizing":
            if (subtask.getIssueTypeId() == "13602" && subtask.getStatusObject()?.getName() != 'New') {
                doTransition("3", 21);
                break;
            }

        case 'Reproduction':
            if ((subtask.getIssueTypeId() == "13603" || subtask.getIssueTypeId() == "13701") && subtask.getStatusObject()?.getName() != 'New') {
                doTransition("4", 31);
                break;
            }

        case 'Processing':
            if ((subtask.getIssueTypeId() == "13603" || subtask.getIssueTypeId() == "13701") && subtask.getStatusObject()?.getName() == 'Closed') {
                doTransition("5", 41);
                break;
            }

        case 'Integrating':
            if ((subtask.getIssueTypeId() == "13507" && subtask.getStatusObject()?.getName() != 'New')) {
                doTransition("6", 51);
                break;
            }
    }
}

if (goToConcluding){
    doTransition("7", 61);
}

Hello Vasiliy!

Thank you very much for your answer and refactoring my code. I am quiet new at scriting, so this things always helps me a lot! smile

Yes, you understand well, I have several transitions from a single status and I want to fire the right one depending on sub-tasks type and status, but this transition I want to occur automatically.

More details about the situation.

I have a simple workflow for the parent ticket with one "hidden" status, named "Triggerd". I real process we don't use this status, this is just to help in automatize our complex workflow. In specified sub-task types, on the right transitions I added a post-function to call Trigger transition in parent ticket. (Trigger transition move to Triggered status). And I want my parent ticket to move toward to the right status is I fire this "triggering" transition in sub-task. I don't want to stay the parent ticket at "Triggered" status.

Easier, I want to automatize selecting and firing the right transition in parent ticket, launched with the specified sub-task transition.

Vasiliy Zverev Community Champion Oct 27, 2016

Your solution seems to difficalt for me.

I think that it could be easer to have respective postfunction on sub-task transitions. In this case there is no any need to check sub-task type and status.

Try to reorganise you processes and onle then start writing code. If information about your processes is not secret, I could help you to organase it.

I have never heard about respective post-functions. I will look for some information about it.

My process is not a secret but I think would be easier to contact each other on another platform not to disturb other users. Please contact me through my e-mail. mullnerbianka@gmail.com

Vasiliy Zverev Community Champion Oct 27, 2016

Respective is not some type of post-function. I mean appropriate or post-function which do what it should do

I see......

I need to monitor the sub-tasks because in my process it is possible to have more than one sub-task typed for ex. Reproducing and the parent ticket can't go toward to the next Status (ex:Fixing) until all the Reproducing tickets are not closed.

Vasiliy Zverev Community Champion Oct 27, 2016

I think that it is better to add a postfunction on close transition:

import com.atlassian.jira.issue.Issue

for(Issue subtask: issue.getParentObject().getSubTaskObjects()){
    if((subtask.getIssueTypeObject().getName().equals("Reproducing")) && (subtask.getResolutionObject()) == null){
        return; //we have at least 1 unresolved Reproducing issue 
    }
}

//Code to trasit parent issue

Suggest an answer

Log in or Sign up to answer
Community showcase
Published Nov 27, 2018 in Portfolio for Jira

Introducing a new planning experience in Portfolio for Jira (Server/DC)

In the past, Portfolio for Jira required a high degree of detail–foresight that was unrealistic for many businesses to   have–in   order to produce a reliable long-term roadmap. We're tur...

2,787 views 18 22
Read article

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