Hello,
I've found some helpful code in the Community that allows for a specific sub-task to be open and still allow for a transition to complete, and am trying to modify it to check if other sub-tasks have either a null resolution or not a Status "Done" or "Canceled," and if so, block the transition.
The code works fine if I only include the status check for "Done," but if I try to check for "Canceled" too, it's not working. I thought it would be correct to put the status check in an OR contained in parenthesis, but I think this is causing the issue, and I'm not very good at coding, so I'm unsure on how to proceed.
Any assistance would be greatly appreciated!
(it.getStatus().name != "Done" || it.getStatus().name != "Canceled")
import com.opensymphony.workflow.InvalidInputException
def passesCondition = true
def subTasks = issue.getSubTaskObjects()
def subBoolean = issue.subTask
//If the issue is not a subtask and contains subtasks
if(!subBoolean && subTasks){
subTasks.each { //Loop each subtask of parent issue
//If the subtask is "System Build"
if (it.summary == "System Build") {
passesCondition = true
}else{ //Else if the subtask is not "System Build"
//If the subtask has null resolution or not a Status "Done" or "Canceled"
if(!it.getResolution() || (it.getStatus().name != "Done" || it.getStatus().name != "Canceled")){
passesCondition = false
//Block the transition
throw new InvalidInputException("subTask","Not all substasks ($it) are closed as 'Done'!")
}else{
passesCondition = true
}
}
}
}else{
return true
}
First off... it's not clear if you are using a Simple Scripted Validator or a Custom Validator. Your script has components of both.
The Simple Scripted Validator requires a true/false return value.
The Customer Validator does not use the return value. Instead, the validation fails if an exception is raised (it will pass by default).
To compare against multiple statuses, I like to group those in a list variable then use the 'contains' operator.
But the following 2 lines are equivalent:
def doneStatusList = ['Done', 'Canceled']
if(!doneStasusList.contains(subTask.status.name)) //do something if the list does not contain the status
if(!(subTask.status.name in doneStatusList)) //do something if the status is not in the list
//notice the extra parens in the second option. Groovy does not have a !in operator
//if you forget the parens, the ! will convert the satus name to a boolean (true by default) and negate that (false) and then chekc if false is in the list
For a custom scripted validated, you could use this:
import com.opensymphony.workflow.InvalidInputException
def doneStasusList = ['Done', 'Canceled']
if(issue.subTask) return //no validation needed for subtask issues
if(!issue.subTaskObjects) return //no validation needed is the issues doesn't contain any subtasks
issue.subTaskObjects.each{subTask->
if(subTask.summary == 'System Build') return //no validation needed on System Build subtasks, continue with next subtasks
if(!subTask.resolution || !doneStasusList.contains(subTask.status.name) ){
throw new InvalidInputException("subTask","At least one subTask ($subTask.key) is not closed as 'Done'!")
}
}
For a simple scripted validator, you could use this:
def doneStasusList = ['Done', 'Canceled']
if(issue.subTask) return true//no validation needed for subtask issues
if(!issue.subTaskObjects) return true //no validation needed is the issues doesn't contain any subtasks
return issue.subTaskObjects.every{subTask->
if(subTask.summary == 'System Build') return true//no validation needed on System Build subtasks, continue with next subtasks
if(!subTask.resolution || !doneStasusList.contains(subTask.status.name) ){
return false
}
}
In the case of the simple scripted, the "every" iterator will stop processing at the first instance of a false returned within the closure and the overall return value will be false.
Otherwise, if every iteration returns true, the overall return will be true.
Thanks very much, @Peter-Dave Sheehan - the custom scripted validator code works for the goal. I just have a question about the comment in this line.
if(issue.subTask) return //no validation needed for subtask issues
Should the comment actually be "validation needed for subtask issues," or am I misunderstanding the code?
Thanks again!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
This was my interpretation of your "if(!subBoolean ...) statement.
Basically, if the current issue IS a subtask, we don't need to validate ITS subtasks, because it won't have any.
So we "return" or exit the script immediately.
You could change the comment to
//no validation needed if the current issue is a subtask type
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.