Script Runner Post Function fire Action

Bianka Müllner October 27, 2016

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
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 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);
}
Bianka Müllner October 27, 2016

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
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 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.

Bianka Müllner October 27, 2016

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
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 27, 2016

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

Bianka Müllner October 27, 2016

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
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 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