Script Runner help needed

Tim Patrick December 20, 2017

I need a basic thing from script runner, but i have no idea how to do it.

 

All i need is for a custom field in an issue to be updated with a value depending on the value of 2 other fields.

Example: If field A = X, and field B = Y, enter value 4 in custom field.

or, If field A = V, and field B = W, enter value 5 in custom field.

 

There will be quite a few entries and there are loads of values i have to be entered, but once ive got the general idea of how it works, i can do the rest.

 

Thanks

2 answers

1 accepted

Suggest an answer

Log in or Sign up to answer
0 votes
Answer accepted
Ivan Tovbin
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.
December 27, 2017

Ok. I am going to assume that you know how to look up the IDs of your custom fields and custom field options (for Field C).

The code for a post function on issue's 'Create' transition would look something like this. Please note, that this post function should be placed AFTER 'Re-index an issue to keep indexes in sync with the database' post-function.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.UpdateIssueRequest

def currentUser = ComponentAccessor().getJiraAuthenticationContext().getLoggedInUser()
def optsMgr = ComponentAccessor.getOptionsManager()
def cfMgr = ComponentAccessor.getCustomFieldManager()
def fieldB = cfMgr.getCustomFieldObject(11111) //field id in parenthesis
def fieldC = cfMgr.getCustomFieldObject(22222)

if(issue.getIssueType().getName() == "issue type 1" && issue.getCustomFieldValue(fieldB) as String == "Company 1"){
issue.setCustomFieldValue(fieldC,optsMgr.findByOptionId(33333)) //custom field option id in parenthesis
}
else if(issue.getIssueType().getName() == "issue type 2" && issue.getCustomFieldValue(fieldB) as String == "Company 1"){
issue.setCustomFieldValue(fieldC,optsMgr.findByOptionId(44444))
}
else if ..................

ComponentAccessor.getIssueManager().updateIssue(currentUser, issue, UpdateIssueRequest.builder().build())

Now as you can see, there are two 'if' statements in the above code, each of which covers ONE issue type for ONE Company.  So if you have, say 8 issue types and 20 compainies you'll have to write a total of 8*20 = 160 'if' statements to cover all possible variations. 

I realize that this is an awful solution not only to create but also to maintain. However, given you described field configurations, I don't see another way.

Now I can see a much more elegant solution but it will require changing you field configuration slightly. Let me know if you are interested and I will provide an in-depth explanation.

Tim Patrick January 2, 2018

Thanks for this Ivan. As I've not written anything in scriptrunner before, can you give me a little bit more information on your above script? 

I understand the process in place with with IF's and AND's, but just need to know which parts i need to customise to run the relevant details.

Say for instance the below is true:

Field A = Issue Type (field value 12345)

Field B = Company Name (field value 98765)

Field C = Tempo Account (field value 65432)

Tempo Account = Company A Chargeable (tempo value 240)

Would you be able to put this into your script just so i can fully understand it? Thanks

If you have better ideas on how this can be done, I'm always open to ideas and suggestions.

Tim Patrick January 4, 2018

so ive done the below but still not getting the expected response:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.UpdateIssueRequest
import com.atlassian.jira.component.ComponentAccessor

def currentUser = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser()
def optsMgr = ComponentAccessor.getOptionsManager()
def cfMgr = ComponentAccessor.getCustomFieldManager()
def fieldB = cfMgr.getCustomFieldObject(12303 as Long)
def fieldC = cfMgr.getCustomFieldObject(11302 as Long)

if(issue.getIssueType().getName() == "Incident" && issue.getCustomFieldValue(fieldB) as String == "1345"){
issue.setCustomFieldValue(fieldC,optsMgr.findByOptionId(242 as Long))
}
else if(issue.getIssueType().getName() == "Service Request" && issue.getCustomFieldValue(fieldB) as String == "1345"){
issue.setCustomFieldValue(fieldC,optsMgr.findByOptionId(240 as Long))
}

ComponentAccessor.getIssueManager().updateIssue(currentUser, issue, UpdateIssueRequest.builder().build())

 

the insight value 240 is what needs to be written into fieldC (the field value is 11302.

the issue type is looked up, and the client account is fieldB (client is am using is also an insight value. this clients insight value is 1345).

is it the "as string" part causing the issue as the postfunction runs, but has no results?

Ivan Tovbin
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.
January 4, 2018

Hi Tim,

Let me try to clarify this.

First off, custom field declarations use custom field IDs to find relevand custom fields so make sure your are using IDs and NOT field values:

def fieldB = cfMgr.getCustomFieldObject(12303 as Long)
def fieldC = cfMgr.getCustomFieldObject(11302 as Long)

The above code stores your respective custom fields (not their values!) in 'fieldB' and 'fieldC' variables.

 

Next, we are checking the issue type of current issue the actual field value of Field B in this issue and based on that set the value for Field C:

if(issue.getIssueType().getName() == "Incident" && issue.getCustomFieldValue(fieldB) as String == "1345"){
issue.setCustomFieldValue(fieldC,optsMgr.findByOptionId(242 as Long))
}

The 'as String' method is called becuase we are comparing Field B value with a 'String' data type ("1345") and so we want to make sure that whatever is returned by 'issue.getCustomFieldValue(fieldB)' is converted to 'String' data type, so that we compare a 'String' with a 'String'. 

Now comes the interesting part, we have to set a value for Field C if the preceeding 'if' statement is true. Since Field C is a single select list, it already has hundreds of options pre-configured (as per your desciption) each of which already contains a value. That said, to set the value to this field, we need to call NOT the desired option value, but the option itself by using its ID, hence calling the 'findByOptionId' method. I think this is where you are making a mistake. You need to provide an option's ID, not its value here, since an option already contains a correct value inside.

Tim Patrick January 5, 2018

Hi Ivan,

We had a workshop today and found a completely different way around this and got everything working.

Thank you for all the time you put into this, it definitely helped us get to the end solution.

Thanks

0 votes
Ivan Tovbin
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.
December 23, 2017

Hi Tim,

Can you be more specific as to when you want this to trigger? Is it a workflow post-function or you want this to trigger whenever you edit the values for fields A and B? Also what is the field type of your custom field? Does it have predefined values (checkboxes, radio buttons, select list, etc.) or is it a just a free text field? What version of Jira are you using?

Cheers,

Ivan

Tim Patrick December 27, 2017

Hi Ivan,

This is to happen any time an issue is created, or if the issue type is changed so they are quite core fields.

For example, field A will be the issue type which is a core field of Jira. Field B is an insight object which is the client name. Each client has a unique reference number so that could potentially be used as a "contains" function.

The field to be filled in from this is a dropdown list of tempo accounts. Each client has 3 tempo accounts (one chargeable, one not chargeable, and the other to be used for budget hours).

The basis of this is for a script to be written that says, if issue type is Request and client is Company X, the tempo field should show account "Company X (Chargeable)". If the issue type is Incident, and client is Company X, the tempo field should show account "Company X (Non-Chargeable)".

Hopefully this makes a bit of sense. Let me know if you have any further questions.

Tim Patrick December 27, 2017

And the version we are using is 7.3.5

Ivan Tovbin
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.
December 27, 2017

Hi Tim,

Please correct me if I got this wrong:

Field A = Issue Type field

Field B = Company name custom field (I'm going to assume that it's a text field, as I don't know exactly how it's populated. Sadly, I'm not familiar with Insight for Jira)

Field C = tempo accounts custom field. Since (from your description) it's a select list, then it must have predefined values configured. Can you confirm that the list of available Field C options is universal for ALL your clients (companies)? i.e. regardless of company, you'll always have the same three options to choose from? In other words the value of Field B (company) is actually irrelevant to the when it comes to picking the value of Field C?

On the other hand if only your tempo account types (chargable, non-chargable, budget) are universal, but the value of each of these types differs for each company, then you need to change your custom field type from a select list to, i'd say text (single line).

Also, please advise if your issue types within this project must always equal a tempo account? i.e. issue type 1 = chargable, issue type 2 = non-chargable, issue type 3 = budget and there are no other issue types that might not have a corresponding tempo account?

Can you confirm the above? 

Tim Patrick December 27, 2017

Field A is the issue type.

Field B is an insight object. This field is completed when the client raises a call (mandatory field on issue creation). This insight object holds the client number which is the unique identifier we will need to use. Some clients have more than one client reference number.

Field C is the tempo account. Each client has 3 individual tempo accounts as each client may have separate pricing tables. Due to this, it is a drop down list of all the hundreds of tempo accounts we have already put into Jira. We need to know both A and B before this field can be populated.

Each tempo account actually has a value in the background. I have tested this. As an example, the value of the tempo account "Company A (Chargeable)" is 240. When i tell the system to write this value into the Account field, it then populates the field with "Company A (chargeable)". This is proven to work.

In total, we have 8 issue types. 1 is chargeable, 3 are non-chargeable, and 4 are against SLA budget hours.

TAGS
AUG Leaders

Atlassian Community Events