Need to create a Scriptrunner listener to set a component

April July 21, 2016

Hi there,

I need to test the values of 3 custom fields, and based on those and the project name, set a component.

I'm trying to start out with the basics, and get a single custom field value + what project I'm in, and so I wrote:

package com.acme.scriptrunner.scripts
import com.atlassian.jira.bc.project.component.ProjectComponent
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.customfields.CustomFieldUtils
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.project.Project
import com.atlassian.jira.issue.Issue

Issue issue = issue
def project = issue.getProjectObject()
def projectComponentManager = ComponentAccessor.getProjectComponentManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def categoryCf = customFieldManager.getCustomFieldObjectByName("PMScategory")
def component = projectComponentManager.findByComponentName(project.getId(), "Core framework")
if (issue.getProjectObject() == "PMS Connectivity" && categoryCf.value == "Core Framework") 
issue.setComponentObjects([component])
else
component = ComponentAccessor.getProjectComponentManager().findByComponentName(project.getId(),"Unknown")
Issue.setComponentObjects([component])

 

This does not work.

Obviously, my knowledge of Groovy syntax would not even cover the head of a pin....

Can you tell what I'm missing?

 

Thanks!

2 answers

2 votes
Thanos Batagiannis _Adaptavist_
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.
July 23, 2016

Hi April,

For a jira7 instance you should try something like this

import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParametersImpl

def issue = event.issue as Issue
def project = issue.getProjectObject()
def projectComponentManager = ComponentAccessor.getProjectComponentManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def categoryCf = customFieldManager.getCustomFieldObjectByName("TextFieldA")

def component = (issue.getProjectObject().getName() == "JRA" && issue.getCustomFieldValue(categoryCf) == "testA") ?
projectComponentManager.findByComponentName(project.getId(), "Comp1") :
        projectComponentManager.findByComponentName(project.getId(),"Comp2")

def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def issueService = ComponentAccessor.getIssueService()

def issueInputParams = new IssueInputParametersImpl().setComponentIds(component?.getId())
IssueService.UpdateValidationResult updateValidationResult =  issueService.validateUpdate(user, issue.id, issueInputParams)
issueService.update(user, updateValidationResult, EventDispatchOption.DO_NOT_DISPATCH, false) // update the issue but do not dispatch any event or send notification

regards

Thanos

0 votes
April August 5, 2016

Hi Thanos!

That definitely fixes updating the issue.

However, I am trying to use a set of cases, and for some reason, that does not work.

For example, I see in the log I have:

/secure/AjaxIssueAction.jspa [c.o.scriptrunner.runner.ScriptRunnerImpl] SF value is [Accounting, Batch Processing, null] for issue PMS-12735

My code should set the component "Batch Processing," but it is setting "Unknown," which should only be a last resort. In addition, although I see the component on the ticket, it does not appear in search results.

After restarting Jira, I now get this error:

  2016-08-05 17:50:17,781 Caesium-1-2 ERROR anonymous     [c.o.scriptrunner.runner.AbstractScriptListener] Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: <inline script>

  java.lang.IllegalStateException: You can not update an issue with an invalid validation result.

      at com.atlassian.jira.bc.issue.DefaultIssueService.update(DefaultIssueService.java:304)

      at com.atlassian.jira.bc.issue.IssueService$update$0.call(Unknown Source)

      at com.acme.scriptrunner.scripts.Script5.run(Script5.groovy:78)

 

Do you see what I am doing wrong?

package com.acme.scriptrunner.scripts

import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParametersImpl

def issue = event.issue as Issue
def project = issue.getProjectObject()
def projectComponentManager = ComponentAccessor.getProjectComponentManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def casetypeCf = customFieldManager.getCustomFieldObjectByName("SFcasetype")
def subtypeCf = customFieldManager.getCustomFieldObjectByName("SFsubtype")
def categoryCf = customFieldManager.getCustomFieldObjectByName("SFcategory")
def component = issue.getComponents()
def casetypeCf1 = issue.getCustomFieldValue(casetypeCf)
def subtypeCf1 = issue.getCustomFieldValue(subtypeCf)
def categoryCf1 = issue.getCustomFieldValue(categoryCf)
def sf = [casetypeCf1,subtypeCf1,categoryCf1]

log.info "SF value is "+sf+" for issue "+issue

switch (sf) {
case "Accounting, Batch Processing, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Batch Processing")
case "Accounting, Corporate Actions, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Corporate Actions")
case "Accounting, Fees &amp; Financing Accruals, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Fees &amp; Financing Accruals")
case "Accounting, Financial Reporting, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Financial Reporting")
case "Accounting, Investor Management, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Investor Management")
case "Accounting, Pricing, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Pricing")
case "Accounting, Trade Import, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Trade Import")
case "Accounting, Trade Management, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Trade Management")
case "Compliance, Compliance, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Compliance")
case "Data Management &amp; Reporting, Reference Data, Security Master":
    component = projectComponentManager.findByComponentName(project.getId(), "Securities")
case "Data Management &amp; Reporting, Reference Data, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Standing Data")
case "Data Management &amp; Reporting, Reporting, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Reporting")
case "Data Management &amp; Reporting, Reporting, Performance Analysis":
    component = projectComponentManager.findByComponentName(project.getId(), "Performance Analysis")
case "Framework, Alert Monitor/Server, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Alert Monitor/Server")
case "Framework, Installers, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Installers")
case "Framework, Scheduler/Workflow Server, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Scheduler/Workflow Server")
case "Framework, System Configuration, null":
    component = projectComponentManager.findByComponentName(project.getId(), "System Configuration")
case "Modeling, Analytics, &amp; Risk, Risk, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Risk Analysis")
case "Operations, Reconcilliations, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Reconcilliation")
case "Order Execution (FIX), Routing &amp; Execution (FIX), ETM":
    component = projectComponentManager.findByComponentName(project.getId(), "ETM")
case "Order Management, null, null":
    component = projectComponentManager.findByComponentName(project.getId(), "Order Management")

default: component = projectComponentManager.findByComponentName(project.getId(), "Unknown")
}

def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def issueService = ComponentAccessor.getIssueService()

def issueInputParams = new IssueInputParametersImpl().setComponentIds(component?.getId())
IssueService.UpdateValidationResult updateValidationResult =  issueService.validateUpdate(user, issue.id, issueInputParams)
// update the issue but do not dispatch any event or send notification
issueService.update(user, updateValidationResult, EventDispatchOption.DO_NOT_DISPATCH, false)

 

Thanks,

April

Thanos Batagiannis _Adaptavist_
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.
August 8, 2016

Hi April,

So I wrote a couple of comments in your code, hope that helps

import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParametersImpl

def issue = event.issue as Issue
def project = issue.getProjectObject()
def projectComponentManager = ComponentAccessor.getProjectComponentManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def casetypeCf = customFieldManager.getCustomFieldObjectByName("SFcasetype")
def subtypeCf = customFieldManager.getCustomFieldObjectByName("SFsubtype")

//def listOfComponents = issue.getComponents() - you do not this - just returns a list of the components
def casetypeCf1 = issue.getCustomFieldValue(casetypeCf)
def subtypeCf1 = issue.getCustomFieldValue(subtypeCf)

//in this part you are adding the values in an array, probably not what you want
def sfArray = [casetypeCf1,subtypeCf1] 
log.info "SF value is "+sfArray+" for issue "+issue

//this will create a string (by concat) with the values of the custom fields (supposing are single fields), probably this is what you want
def sfToString = "${casetypeCf1}, ${subtypeCf1}"
log.debug ("To string: ${sfToString}")

//this will create a string by iterating the sfArray and "joining" it's elements with a comma separator - if you want to use the array above (sfArray) then this is the string you have to use in your switch case comparisons 
def toStringJoin = sf.join(", ")
log.debug ("To string joined: ${toStringJoin}")

// use a string for the comparisons in your switch. Do not forget the break after each case :)
def component
switch (sfToString) {
    case "Accounting, Batch Processing":
        component = projectComponentManager.findByComponentName(project.getId(), "Batch Processing")
        break
    case "Accounting, Corporate Actions":
        component = projectComponentManager.findByComponentName(project.getId(), "Corporate Actions")
        break
    default:
        component = projectComponentManager.findByComponentName(project.getId(), "Unknown")
        break
}

def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def issueService = ComponentAccessor.getIssueService()

def issueInputParams = new IssueInputParametersImpl().setComponentIds(component?.getId() as Long)
IssueService.UpdateValidationResult updateValidationResult =  issueService.validateUpdate(user, issue.id, issueInputParams)
assert !updateValidationResult.getErrorCollection().hasAnyErrors()
// update the issue but do not dispatch any event or send notification
def updatedIssue = issueService.update(user, updateValidationResult, EventDispatchOption.DO_NOT_DISPATCH, false)

regards

Thanos

April August 8, 2016

Hi Thanos,

You are awesome!

I did forget the breaks; noticed that after I hit save on the comment. I also had some other missing punctuation smile

The component is being set now, so just a little more tweaking..

Had to check if yet another custom field is null, and only perform all these operations if it has data. After 'def customFieldManager,' I just added:

def customer = customFieldManager.getCustomFieldObjectByName("CRM_CaseNo")

if (customer) { ...do the rest of the stuff }

else if (!customer)

break

Seems to be OK.

So I'm wondering, why is the array bad? Is that a performance thing? I had it in mind that if they added any more fields to this, I could evaluate by index number for some cases, but maybe that sucks?

Also, is there any way to remove a component?

If the users come  back and update their Salesforce case, I'd like to get rid of "Unknown" when I set the correct component.

Oddly, I see I can delete a whole issue, but not a way to get rid of the darned component.

Thanks,

April

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events