Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

ScriptRunner - Issue Picker JQL / Condition / Validator

Ricky Wang Lin July 6, 2021

I looked through this KB (https://scriptrunner.adaptavist.com/5.6.8/jira/script-fields/issue-picker.html) but could not find the answer.  I was wondering if there's a way to run checks against ScriptRunner's Issue Picker field to see if the issue is in a certain status. 

For example, I have an Issue Picker filled called "Related Issue" and only want a transition to show up / be transitionable IF that issue has been transitioned to the "Done" status.

This is very much similar to Linked/Related Issues Status Condition provided by JMWE, but using ScriptRunner's field.

Any thoughts would be appreciated.  Thank you!

2 answers

1 accepted

Suggest an answer

Log in or Sign up to answer
2 votes
Answer accepted
David Fischer
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 6, 2021

@Ricky Wang Lin ,

if you have JMWE, you could create a Scripted (Groovy) Condition/Validator with a script like:

issue.get("RelatedIssue")?.get("status")?.name == "Done"
Ricky Wang Lin July 6, 2021

Hi David.  Great hearing from ya!  I just tried out what you proposed and it worked like a charm... 

Switched up my gig, but I had to scoop JMWE and JMCF with me for how flexible it is and how helpful you are.  Thank you!

Ricky Wang Lin July 9, 2021

Hi David.  A quick expansion on this as I understand the request a bit more (I'm unsure how to combine multiple fields/checks together, but below is what I'm seeing looking at the Groovy Script Help information)

:

  • How would I be able to use Scripted (Groovy) Condition / Validator to check the following:
    • If RelatedIssue Issue Picker Field has a Cascading Field with Child Value = Omaha with the Status = Done
      • Would it look like:
        issue.get("RelatedIssue")?.get("CascadingField")?.name == "Omaha"
        issue.get("RelatedIssue")?.get("status")?.name == "Done"
    • If a Linked Issue with Link Type = Blocked By in Project ABC has Cascading Field with Child Value = Omaha and Status = Done

      • issue.get("issuelinks")?.first()?.issueLinkType.name == "Blocked By"

        issue.get("project")?.key == "ABC"

        issue.get("CascadingField")?.name == "Omaha"

Appreciate any further insight.  Thank you!

David Fischer
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 12, 2021

Hi @Ricky Wang Lin 

Case #1:

issue.get("RelatedIssue")?.get("CascadingField")?.get("1")?.value == "Omaha" && issue.get("RelatedIssue")?.get("status")?.name == "Done"

Note that you can find out how to test issue fields using the "Issue Fields" help tab at the bottom of the editor.

Case #2:

issue.getLinkedIssues("is blocked by").findAll { it.get("project").key == "ABC" }.any { it.get("CascadingField")?.get("1")?.value == "Omaha" && it.get("status")?.name == "Done" }
3 votes
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 6, 2021

If you want to stick within the world of scriptrunner, this is easy to accomplish with the scriptrunner simple-scripted condition (very similar to the  jmwe)

 

cfValues['Related Issue']?.status?.name == "Done"

If your related issues allow multiple, then you would do it like this

cfValues['Related Issue'].every{it?.status?.name == "Done"}
Ricky Wang Lin July 7, 2021

Hi Peter.  Appreciate your answer here.  Looks like ScriptRunner also has a simple-scripted validator that can be utilized depending on how we'd like this to be enforced.

If I were to go with ScriptRunner simple validator, Is it possible to mix in a cascading field check into this and display different error messages or should I configure 2 validators?  Example would be:

  • IF the RelatedIssue is not in Done status, prevent transition and display an error ""Key - Summary" must be completed first"
  • IF the RelatedIssue does not have "CascadingField Child value" = X, prevent transition and display an error "Key - Summary does not have "Child value"
  • IF the RelatedIssue field is empty, prevent transition and display an error "RelatedIssue field cannot be empty"

I know I'm mixing in more logic now, but wonder if this is something that ScriptRunner can also achieve.

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 7, 2021

Yeah, the simple scripted condition will hide the button completely.

If you're looking to validate the input, then the simple scripted validator or the custom validator will give you what you're looking for.

The simple scripted validator will only allow you to display a single message against a single field (or at the top of the form).

So, either you configure 2 separate simple scripted validators or a single custom validator.

The downside of a custom scripted validator is that you don't get access to the cfValues shortcut... you need to get your customfield values from the api.

A custom validator would look like this:

import  com.atlassian.jira.component.ComponentAccessor
def cfm = ComponentAccessor.customFieldManager
def relatedIssueCf= cfm.getCustomFieldObjectsByName('Related Issue')[0]
def cascadingCf = cfm.getCustomFieldObjectsByName('Cascading Field Name')[0]

def relatedIssue = issue.getCustomFieldValue(relatedIssueCf)
if(!relatedIssue){
throw new InvalidInputException(relatedIssueCf.id, "Related Issue must not be empty")
}

def errorPrefix = "'$relatedIssue.key - $relatedIssue.summary'"
if(relatedIssue?.status?.name != "Done"){
throw new InvalidInputException(relatedIssueCf.id, "$errorPrefix must be completed first")
}

//get the cascading value for the relatedIssue
def cascadingValues = relatedIssue.getCustomFieldValue(cascadingCf)
if(cascadingValues.size() == 0){
//the cascading field is empty
throw new InvalidInputException(relatedIssueCf.id, "$errorPrefix $cascadingCf.name must not be empty")
}
if(cascadingValues.size() == 1){
//only the parent was selected
throw new InvalidInputException(relatedIssueCf.id, "$errorPrefix does not have a child value in $cascadingCf.name")
}
if(cascadingValues[1] != "X"){
throw new InvalidInputException(relatedIssueCf.id, "$errorPrefix does not have a child value == X in $cascadingCf.name")
}

Some notes about cascading field values ... this will be an array of either 0, 1 or 2 items. If the field is empty, the array size is 0, if only the top-level is selected, the size is 1 and if both parent and child values are selected the size is 2.

Then you can access either the parent value or child value by getting the index (base 0) the first or second value in the array. Attempting to access the child value when only the parent is selected will result in an error.

TAGS
AUG Leaders

Atlassian Community Events