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

Clone Issue in Workflow and set Request Type on clone using Groovy and Script Runner

Andrew Downs October 30, 2018

Hi guys,

 

I need some assistance please, I am trying to clone an issue in a workflow function using the below groovy script:

 

import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.CustomFieldManager
import org.apache.log4j.Category
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue

// Configure Logging
Category log = Category.getInstance("com.onresolve.jira.groovy")
log.setLevel(org.apache.log4j.Level.DEBUG)
log.debug "Clone Issue to Relevant Projects"

// Define required Components
customFieldManager = ComponentAccessor.getCustomFieldManager()
issueManager = ComponentAccessor.getIssueManager()
searchService = ComponentAccessor.getComponent(SearchService)
user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
issueFactory = ComponentAccessor.getIssueFactory()

// Insight Object Facade
Class objectFacadeClass = ComponentAccessor.getPluginAccessor().getClassLoader().findClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade");
objectFacade = ComponentAccessor.getOSGiComponentInstanceOfType(objectFacadeClass);

// Get Current Issue
//issueKey = issue.getKey()
//MutableIssue issue = issueManager.getIssueObject(issueKey)
Issue issue = issueManager.getIssueObject( "SSD-43282")

// Get custom fields
fullName = customFieldManager.getCustomFieldObjectByName("Full Name");
fullNameValue = issue.getCustomFieldValue(fullName);
firstName = customFieldManager.getCustomFieldObjectByName("Firstname");
firstNameValue = issue.getCustomFieldValue(firstName);
lastName = customFieldManager.getCustomFieldObjectByName("Surname");
lastNameValue = issue.getCustomFieldValue(lastName);
officeNumber = customFieldManager.getCustomFieldObjectByName("User Office Number");
officeNumberValue = issue.getCustomFieldValue(officeNumber);
lineManager = customFieldManager.getCustomFieldObjectByName("Line Manager");
lineManagerValue = issue.getCustomFieldValue(lineManager).toString();
mobileNumber = customFieldManager.getCustomFieldObjectByName("Cell Phone Number");
mobileNumberValue = issue.getCustomFieldValue(mobileNumber);
faxNumber = customFieldManager.getCustomFieldObjectByName("Office Number");
faxNumberValue = issue.getCustomFieldValue(faxNumber);
title = customFieldManager.getCustomFieldObjectByName("Job Title");
titleValue = issue.getCustomFieldValue(title);
department = customFieldManager.getCustomFieldObjectByName("Department");
departmentValue = issue.getCustomFieldValue(department);
siteName = customFieldManager.getCustomFieldObjectByName("Site Code");
siteNameValue = issue.getCustomFieldValue(siteName);
streetAddress = customFieldManager.getCustomFieldObjectByName("Street Address");
streetAddressValue = issue.getCustomFieldValue(streetAddress);
city = customFieldManager.getCustomFieldObjectByName("City");
cityValue = issue.getCustomFieldValue(city);
province = customFieldManager.getCustomFieldObjectByName("Province");
provinceValue = issue.getCustomFieldValue(province);
country = customFieldManager.getCustomFieldObjectByName("Country");
countryValue = issue.getCustomFieldValue(country);
BU1 = customFieldManager.getCustomFieldObjectByName("Business Unit 1");
BU1Value = issue.getCustomFieldValue(BU1)
BU2 = customFieldManager.getCustomFieldObjectByName("Business Unit 2");
BU2Value = issue.getCustomFieldValue(BU2)
BU3 = customFieldManager.getCustomFieldObjectByName("Business Unit 3");
BU3Value = issue.getCustomFieldValue(BU3)
emailRequired = customFieldManager.getCustomFieldObjectByName("Email Requirements");
emailRequiredValue = issue.getCustomFieldValue(emailRequired)
emailDomain = customFieldManager.getCustomFieldObjectByName("Email Domain Requirements");
emailDomainValue = issue.getCustomFieldValue(emailDomain)
logonNameOverride = customFieldManager.getCustomFieldObjectByName("Logon Name Override");
logonNameOverrideValue = issue.getCustomFieldValue(logonNameOverride);
requiredApplicationAccess = customFieldManager.getCustomFieldObjectByName("Required Application Access")
requiredApplicationAccessValue = issue.getCustomFieldValue(requiredApplicationAccess)
requiredApplicationPermissions = customFieldManager.getCustomFieldObjectByName("Required Application Permissions")
requiredApplicationPermissionValue = issue.getCustomFieldValue(requiredApplicationPermissions)
originalReference = customFieldManager.getCustomFieldObjectByName("Original Reference")

// Update Original Reference custom field
issue.setCustomFieldValue(originalReference,issue)

// Get originalReference Value

originalReferenceValue = issue.getCustomFieldValue(originalReference).toString()


if (logonNameOverrideValue == null){
   firstNameValue = firstNameValue.replaceAll('\\ ','').replaceAll('\\ ','').trim()
   fullNameValue = fullNameValue
}
else{
   firstNameValue = logonNameOverrideValue.replaceAll('\\ ','').replaceAll('\\ ','').trim()
   fullNameValue = logonNameOverrideValue + " " + lastNameValue
}

// Build Array of Required Applications

ArrayList requiredApplications = (ArrayList)issue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName("Required Application Access")).unique();

// Start loop on requiredApplications

for(i=0; i < requiredApplications.size();i++){
    
    // Get Object Bean
    // Uses value of i to get the index within the array
    
    log.debug ("Getting object for index ${i}")
    
    objectBean = requiredApplications[i]
    
    log.debug ("Object Bean is ${objectBean}")
        
    applicationAccessName = objectBean.name
    
      // Get Project ID, this is linked to Applications within Insight
        
    try{
        log.debug ("Attempting to get Project ID for ${objectBean}")
        projectIDs =  objectFacade.loadObjectAttributeBean(objectBean.getId(), 3320).getObjectAttributeValueBeans()[0].getValue()
        
    }
    catch(Exception ex){
        log.debug ("Application is not linked to a project, defaulting to Service Desk Project (10402)")
        projectIDs = 10402
    }

    log.debug ("Project ID is ${projectIDs}")
    
    // Get the project Key for associated Project ID returned in projectIDs
    
    projectKey = ComponentAccessor.getProjectManager().getAllProjectKeys(projectIDs).toString().replaceAll('\\[','').replaceAll('\\]','')
 
       PROJECT_KEY_TO = projectKey

    log.debug("Destination Project: $PROJECT_KEY_TO")

    
    // edit the JQL to return the issues you want to clone
    jqlSearch = """
    project = "SSD" AND Key = "$issue"
    """

     projectTo = ComponentAccessor.getProjectManager().getProjectByCurrentKey(PROJECT_KEY_TO)
    
     List<Issue> issuesFrom = []

    // Get all the issues returned from the JQL
   
    SearchService.ParseResult parseResult =  searchService.parseQuery(user, jqlSearch)
    if (parseResult.isValid()) {
        searchResult = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
        issuesFrom = searchResult.issues.collect { issueManager.getIssueObject(it.id) } as List <Issue>
        log.debug ("Issues From: $issuesFrom")
    }

    // Clone all the issues returned from the JQL to each project returned
   
    issuesFrom?.each { it ->
        newIssue = issueFactory.cloneIssue(it)

        log.debug ("New issue: $newIssue")

        // set the project and any field you want to have a different value
        newIssue.setProjectObject(projectTo)
        newIssue.setSummary("Please give user access to ${applicationAccessName}")
        newIssue.setAssignee(null)
        newIssue.setCustomFieldValue(fullName, fullNameValue)
        newIssue.setCustomFieldValue(firstName, firstNameValue)
        newIssue.setCustomFieldValue(lastName, lastNameValue)
        newIssue.setCustomFieldValue(title, titleValue)
        newIssue.setCustomFieldValue(department, departmentValue)
        newIssue.setCustomFieldValue(BU1, BU1Value)
        newIssue.setCustomFieldValue(BU2, BU2Value)
        newIssue.setCustomFieldValue(BU3, BU3Value)
        newIssue.setCustomFieldValue(siteName, siteNameValue)
        newIssue.setCustomFieldValue(streetAddress,streetAddressValue)
        newIssue.setCustomFieldValue(city,cityValue)
        newIssue.setCustomFieldValue(province,provinceValue)
        newIssue.setCustomFieldValue(country,countryValue)
        newIssue.setCustomFieldValue(mobileNumber, mobileNumberValue)
        newIssue.setCustomFieldValue(officeNumber, officeNumberValue)
        newIssue.setCustomFieldValue(requiredApplicationAccess, requiredApplicationAccessValue)
        newIssue.setCustomFieldValue(requiredApplicationPermissions, requiredApplicationPermissionValue)
        newIssue.setCustomFieldValue(originalReference, issue.toString())
        
           Map<String,Object> newIssueParams = ["issue":newIssue] as Map<String,Object>
        log.debug("Issue Params: ${newIssueParams}")
        log.debug ("Original Reference: ${originalReferenceValue}")
        issueManager.createIssueObject(user, newIssueParams)
        
        log.debug ("Issue Details ${newIssue?.issueType}")
        log.debug ("Issue ${newIssue?.key} cloned to project ${projectTo.key}")
        log.debug ("Successfully created linked issue in project ${PROJECT_KEY_TO}")
    }
}

 

Basically, this clone occurs based on a selection of applications, I have successfully managed to get the issue cloned to the relevant project based on application selection, but I am struggling to set the Type on the clone. Current issue type is Account Request New Employee, what I want it to be is Account Request New Employee  - Application Access, I have created the type and made sure it is present it each project that requires it. But when I try set it by using newIssue.setIssueType("Account Request New Employee  - Application Access") I get the following error:

 

No signature of method: com.atlassian.jira.issue.IssueImpl.setIssueType() is applicable for argument types: (java.lang.String) values: [Account Request New Employee - Application Access] Possible solutions: setIssueType(com.atlassian.jira.issue.issuetype.IssueType), getIssueType(), setIssueTypeId(java.lang.String), getIssueTypeId()

I am fairly sure it is something small that I am missing. I would love to use the built in function for cloning issues supplied by Script runner, but unfortunately I don't see a way to override the project. The applications can be one or multiple and currently we have about 70 Applications, so to do 70 odd Clone issue and links from Script runner is going to be a nightmare to manage and maintain.

Any help is greatly appreciated.

I am using the latest version of script runner.

 

1 answer

Suggest an answer

Log in or Sign up to answer
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.
November 1, 2018

Hi Andrew, 

Indeed, you are passing the wrong data type to setIssueType() method. You are passing a String, when in fact you need to pass it IssueType object. To make this work you need something like this:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.IssueTypeManager
import com.atlassian.jira.issue.issuetype.IssueType

IssueTypeManager issueTypeManager = ComponentAccessor.getComponent(IssueTypeManager.class)
IssueType issueType = issueTypeManager.getIssueType("issue type name")
issue.setIssueType(issueType)
Andrew Downs November 1, 2018

Hi Ivan,

 

Will give it a try. Thank you, on another note how I would I link the issues that have been created to the main issue?

 

I am populating a custom field with the key of the original issue?

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.
November 1, 2018

You need to use createIssueLink() method from IssueLinkManager interface. Make sure you that you are getting the id of you new issue correctly. You need to call getId() from the object which is returned by your createIssueObject() method.

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.
November 1, 2018

On a side note, if you are cloning an issue, you might wanna use cloneIssueWithAllFields() method in your IssueFactory.  This will dispense you from having to set all field values manually.

Andrew Downs November 1, 2018

I have looked at that method, but there are some fields that I don't need on the new issues. I may have to move to it though as I see the cloneIssue is deprecated. But for now it works. I am not familiar enough with the permissions on Jira either, so don't know really if I can hide a field from view based on access.

TAGS
AUG Leaders

Atlassian Community Events