Scriptrunner: How to pull customfield value from issue into transition script (w/o being in trans)

Michael
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.
April 30, 2024

Hello everyone,

I'm trying to create a server side behavior script, that has a condition to happen within a specific workflow action. (IE: Transition screen)

I want to "pull" in the value of the single select customfield "Client" from within the current issue, and compare it to a list of clients within the script.

If the correct client value is present, a single select customfield named "request type" becomes visible and required. Otherwise I want the "request type" field to default to not required and hidden.

Here is the script I currently have, but since the client field isn't within the transition screen, the value always defaults to "null".

import com.onresolve.jira.groovy.user.FieldBehaviours
import com.onresolve.jira.groovy.user.FormField
import groovy.transform.BaseScript

@BaseScript FieldBehaviours fieldBehaviours

def clientField = getFieldById("customfield_13400")
def clientFieldValue = clientField.value.toString()
def requestTypeField = getFieldById("customfield_12001")

//Defines "required" fields. (If a field is Enabled it will be required)
def EnableField(FormField f) {
    f.setHidden(false)
    f.setRequired(true)

}

//Defines "hidden" fields. (If a field is Disabled it will be hidden & not required)
def DisableField(FormField f) {
    f.setHidden(true)
    f.setRequired(false)

}

//Defines which fields are "Enabled" / "Disabled" depending of option selected within 'Levels Of Effort' field.
switch (clientField.getValue()) {
    case "Client1":
        EnableField(requestTypeField)
        break;

    default:
        DisableField(requestTypeField)
        break;

}

Can someone please explain to me how I can grab the "clientField" value from within the issue without having it within the transition screen?

Thanks,

Mike

3 answers

1 accepted

0 votes
Answer accepted
Michael
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.
May 1, 2024

@Matt Parks Helped me resolve the issue with "underlyingIssue.getCustomFieldValue(13400)".

Please see below for working code, and follow his replies for full context.

import com.onresolve.jira.groovy.user.FieldBehaviours
import com.onresolve.jira.groovy.user.FormField
import groovy.transform.BaseScript

@BaseScript FieldBehaviours fieldBehaviours

def clientField = getFieldById("customfield_13400")
def clientFieldValue = underlyingIssue.getCustomFieldValue(13400)

//pushes value retrieved from clientFieldValue and pastes it to logs
log.warn(
"client value? ${clientFieldValue}")

def requestTypeField = getFieldById("customfield_12001")

//Defines "required" fields. (If a field is Enabled it will be required)
def EnableField(FormField f) {
    f.setHidden(false)
    f.setRequired(true)

}

//Defines "hidden" fields. (If a field is Disabled it will be hidden & not required)
def DisableField(FormField f) {
    f.setHidden(true)
    f.setRequired(false)

}

//Defines which fields are "Enabled" / "Disabled" depending of option selected within 'Client' field.
switch (clientFieldValue) {
    case "Client1":
        EnableField(requestTypeField)
        break;

    default:
        DisableField(requestTypeField)
        break;

}

 

0 votes
Michelle Sharp
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
April 30, 2024

Ah ok sorry so we use this to call the custom Filed once we Select it from the available list. Because we have already selected it from the dropdown list this basically sets the field value for it / no customid number needed 

 

def RequestgetFieldById(getFieldChanged())
def Selection = Request.getValue()
Michael
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.
April 30, 2024

Hi again @Michelle Sharp

The the "client" field is not changing and is not on the transition screen I'm trying to implement the script within.

So if I'm understanding the script above; it's grabbing the ID of the field that just changed correct? If so, I don't think it would ever be able to grab the correct field ID or value.

For some additional context:
The "client" field value was previously selected in the "create" screen, and this script only runs within a specific transition screen after creation. I hope that helps a bit...

Please let me know if I need to define this a bit more.

Thanks,

Mike

 

0 votes
Michelle Sharp April 30, 2024

Here is what use for behaviours to show hide custom fields - for the initialiser.

 

def Description = getFieldById("description")
def Summary = getFieldById("summary")
def customfield1 = getFieldById("customfield_32377")
def customfield2 = getFieldById("customfield_32380")
def customfield3 = getFieldById("customfield_32378")
def customfield4 = getFieldById("customfield_32379")

Description.setHidden(true)
Description.setRequired(false)
Summary.setHidden(true)
Summary.setRequired(false)
customfield1.setHidden(true)
customfield1.setRequired(false)
customfield2.setHidden(true)
customfield2.setRequired(false)
customfield3.setHidden(true)
customfield3.setRequired(false)
customfield4.setHidden(true)
customfield4.setRequired(false)
then scroll down and Add the custom field for the behaviour to work on as a field from dropdown:
in this initialiser 
def Request = getFieldById(getFieldChanged())
def Selection = Request.getValue()
*then copy and paste the details from the 1st initialiser*
def Description = getFieldById("description")
def Summary = getFieldById("summary")
def customfield1 = getFieldById("customfield_32377")
def customfield2 = getFieldById("customfield_32380")
def customfield3 = getFieldById("customfield_32378")
def customfield4 = getFieldById("customfield_32379")

Description.setHidden(true)
Description.setRequired(false)
Summary.setHidden(true)
Summary.setRequired(false)
customfield1.setHidden(true)
customfield1.setRequired(false)
customfield2.setHidden(true)
customfield2.setRequired(false)
customfield3.setHidden(true)
customfield3.setRequired(false)
customfield4.setHidden(true)
customfield4.setRequired(false)
*and set*
if Selection == ("dropdown item1 from above chosen field'){   
Description.setHidden(false)
Description.setRequired(true)
Summary.setHidden(false)
Summary.setRequired(true)
customfield1.setHidden(false)
customfield1.setRequired(true)
customfield2.setHidden(false)
customfield2.setRequired(true)
}
if Selection == ("Dropdown item 2 from above){
  
Description.setHidden(false)
Description.setRequired(true)
Summary.setHidden(false)
Summary.setRequired(true)
customfield3.setHidden(false)
customfield3.setRequired(true)
customfield4.setHidden(false)
customfield4.setRequired(true)
}
* the If statements in ("") must match the options on the custom field you need to use.
hope this helps.. also don't forget the {} at the beginning and end - this will also break it if missing :D
Michael
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.
April 30, 2024

Hi @Michelle Sharp

Thanks for your example; however, I already have showing / hiding of fields taken care of, and I can't find the code snippet which is pulling in the value of the "client" field from within the issue itself into the transition screen script.

I've already tried pulling in the values:

def clientField = getFieldById("customfield_13400")
def clientFieldValue = clientField.value.toString()

Which always pulls in "Null" as the value. I'm assuming there is another way to pull in the value from the "client" field within the issue into the transition screen, but for the life of me I can't figure it out.

Can you / anyone help with that aspect?

Thanks,

Mike

Matt Parks
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.
May 1, 2024

I created a behavior where fields on a transition screen were able to be made visible/hidden and required/optional based on the value of a field that was not on the transition screen and it worked as expected.

Did you try flipping the behavior in the switch statement so that, if Client1 is the value, the field is disabled and the default value is that the field is enabled?

The only thing that seems different about my behavior is that it is much simpler and only takes effect on a single transition screen:

 

import groovy.transform.BaseScript
import com.onresolve.jira.groovy.user.FieldBehaviours

@BaseScript FieldBehaviours fieldBehaviours

def dbImpactedField = getFieldByName("Databases Impacted")
def depSysField = getFieldByName("Deployed Systems")
def testSingleField = getFieldByName("Test single")
def testSingleValue = testSingleField.getValue()

if (fieldScreen.name == "Corporate Team DOD Transition Screen")
{
       if (testSingleValue == 1)
    {
        dbImpactedField.setHidden(false)
        dbImpactedField.setRequired(true)
        depSysField.setHidden(false)
        depSysField.setRequired(true)
    }

    else
    {
        dbImpactedField.setHidden(false)
        dbImpactedField.setRequired(true)
        depSysField.setHidden(true)
        depSysField.setRequired(false)
    }
}
Michael
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.
May 1, 2024

Hello @Matt Parks

Thanks for the reply and suggestion. Unfortunately we don't believe this would work for us because our instance is constantly evolving with field / value / workflow / transition name changes, so we want to try and keep everything as simple and as "revision proof" as possible.

We also already have several "Conditioned behaviors" setup for the "Client" field; and we'd prefer a way to pull issue related values into a transition screen conditioned script rather than re-doing several other scripts.

When I was looking all over, I did look at the Jira API and found something about the "Interface Issue" which allows for the "issue.getCustomFieldValue(customfield)" But for the life of me, I can't figure out what to import to allow for something like the following to retrieve that value from the request itself:

def clientFieldValue = issue.getCustomFieldValue(13400)

 I'm still trying to self teach my way through groovy / scriptrunner so any help here would be greatly appreciated.

Thanks,

Mike

Matt Parks
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.
May 1, 2024

If you're worried about field name changes, you can just change the getFieldByName in my script to getFieldByID the way you have it in yours.

 

I believe that, if you use underlyingIssue.getCustomFieldValue(13400), that might allow you to retrieve the value.

I guess I'm a little confused because I am able to get the value of of field even if that field isn't on the transition screen, so I'm not sure why you are getting null for that value.

Edit:  I don't know if you would need to import the issue class as below in order to run the getCustomFieldValue method

import com.atlassian.jira.issue.Issue

Michael
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.
May 1, 2024

Hi again @Matt Parks

We were also wondering why we can't just call the field by ID and pull in the value from the issue. (See script screenshot below) The only thing that we can think of is that it's due to use "conditioning" the script. Do you have your script conditioned to only happen on a specific workflow action?

conditioning example.jpg

When we check the log.warn for the value - it pulls in up logs as "null".

We've also tried importing the class "import com.atlassian.jira.issue.Issue" before; but after we add the import, and then try to add the "issue.getCustomFieldValue(13400)" it always stated: "variable [issue] is undeclared".

Luckily though, your "underlyingIssue.getCustomFieldValue(13400)" worked!

So just in-case anyone else is having the same issue with conditioned scripts and needs to pull a customfield within the underlying issue and compare it to a list of "approved" values to determine if it can be shown or not - here is the script that is working for us:

import com.onresolve.jira.groovy.user.FieldBehaviours
import com.onresolve.jira.groovy.user.FormField
import groovy.transform.BaseScript

@BaseScript FieldBehaviours fieldBehaviours

def clientField = getFieldById("customfield_13400")
def clientFieldValue = underlyingIssue.getCustomFieldValue(13400)

//pushes value retrieved from clientFieldValue and pastes it to logs
log.warn(
"client value? ${clientFieldValue}")

def requestTypeField = getFieldById("customfield_12001")

//Defines "required" fields. (If a field is Enabled it will be required)
def EnableField(FormField f) {
    f.setHidden(false)
    f.setRequired(true)

}

//Defines "hidden" fields. (If a field is Disabled it will be hidden & not required)
def DisableField(FormField f) {
    f.setHidden(true)
    f.setRequired(false)

}

//Defines which fields are "Enabled" / "Disabled" depending of option selected within 'Client' field.
switch (clientFieldValue) {
    case "Client1":
        EnableField(requestTypeField)
        break;

    default:
        DisableField(requestTypeField)
        break;

}

 

Matt Parks
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.
May 1, 2024

To close the loop, I typically don't use conditioning, mainly because we often have multiple workflows that exhibit similar functionality. In those instances, I try to make certain that all of the different workflows are using the same transition screen, so I then use the fieldScreen.name in the if statement. It basically does the same thing as specifying the workflow action (since the transition screen is only used on a particular transition), but allows for the same action from multiple workflows to be able to be used in a single behavior.

Suggest an answer

Log in or Sign up to answer