/
Support for ScriptRunner script

Support for ScriptRunner script

Customer Requirement

I need of a method to get ApprovalMappings object and thenĀ  related approval users and approval groups to populate an User Picker(Multiple) Custom Field and a Group Picker(Multiple) Custom Field.

Solution

  • Create the Custom fields that will be populated when the workflow transition runs:

  • Navigate on Workflow associated to the Approval Mapping
  • Add aĀ Script Post-Function [ScriptRunner] and select Custom script post-function

  • Insert the Groovy Script code into the in-line editor, Save and Publish the workflow:
import com.atlassian.activeobjects.external.ActiveObjects
import com.atlassian.crowd.embedded.api.Group
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.issuetype.IssueType
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.project.Project
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.plugin.PluginAccessor

import com.opensymphony.workflow.loader.ActionDescriptor

import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.herzum.jira.plugin.approval.manager.impl.ApprovalServiceManagerImpl
import com.herzum.jira.plugin.approval.config.ao.Approval
import com.herzum.jira.plugin.approval.config.ao.ApprovalMapping

@WithPlugin("com.herzum.jira.plugin.approval.herzum-approval-plugin")

def workflow = ComponentAccessor.workflowManager.getWorkflow(issue.projectObject.id, issue.issueType.id)
def actions = workflow.getAllActions()
def cfApprovalGroups = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectsByName("Approval Groups").first()
def cfApprovalUsers = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectsByName("Approval Users").first()

List<ApprovalMapping> approvalMappings = getApprovalMapping(issue.projectObject.id, issue.issueType.id)

List<String> workflowStatusesIds = []
workflow.linkedStatusObjects.each {
    workflowStatusesIds.add(it.id)
}

List<ApprovalMapping> toRemove = []
approvalMappings.each {
	if (!workflowStatusesIds.contains(it.destinationStatusId) || it.isDelete) {
		toRemove.add(it)
	}
}
approvalMappings.removeAll(toRemove)

String strApprovalGroups = ""
String strApprovalUsers = ""

for (ApprovalMapping approvalMapping: approvalMappings) {
    Long mappedProjectId = approvalMapping.projectId
    Long mappedIssueTypeId = Long.valueOf(approvalMapping.issueTypeId)
    Long mappedTransitionId = Long.valueOf(approvalMapping.transitionId)
    ActionDescriptor mappedAction = getActionById(actions, mappedTransitionId)
    
    if (approvalMapping.sourceStatusId.equals(issue.status.id.toString())) {
        String mappedProjectName = ComponentAccessor.projectManager.getProjectObj(mappedProjectId).name
        String mappedIssueTypeName = getIssueTypeById(ComponentAccessor.projectManager.getProjectObj(mappedProjectId), mappedIssueTypeId).name
        Approval[] approvals = approvalMapping.approvals

        for (Approval approval : approvals) {
            if (!approval.groups.isEmpty()) {
                strApprovalGroups += ", " + approval.groups.replaceAll("&", ", ")
            }
            if (!approval.users.isEmpty()) {
                strApprovalUsers += ", " + approval.users.replaceAll("&", ", ")
            }
        }

        if (!strApprovalGroups.isEmpty() && strApprovalGroups.startsWith(", ")) {
            strApprovalGroups = strApprovalGroups.substring(2)
        }

        if (!strApprovalUsers.isEmpty() && strApprovalGroups.startsWith(", ")) {
            strApprovalUsers = strApprovalUsers.substring(2)
        }

        List<Group> approvalGroups = (List<Group>) issue.getCustomFieldValue(cfApprovalGroups)
        List<ApplicationUser> approvalUsers = (List<ApplicationUser>) issue.getCustomFieldValue(cfApprovalUsers)

        if (approvalGroups == null) {
            approvalGroups = []
        }
        
        if (approvalUsers == null) {
            approvalUsers = []
        }
        
        if (!strApprovalGroups.isEmpty()) {
            // removed space becouse it caused Custom field population failure
            strApprovalGroups.split(",").each {
                approvalGroups.add(ComponentAccessor.groupManager.getGroup(it.toString()))
            }
        }

        if (!strApprovalUsers.isEmpty()) {
            strApprovalUsers.split(", ").each {
                approvalUsers.add(ComponentAccessor.userManager.getUserByName(it.toString()))
            }
        }
        
        cfApprovalGroups.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(cfApprovalGroups), approvalGroups), new DefaultIssueChangeHolder())
        cfApprovalUsers.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(cfApprovalUsers), approvalUsers), new DefaultIssueChangeHolder())
    }
}

public List getApprovalMapping(Long projectId, String issueTypeId) {
    def approvalServiceManager = ComponentAccessor.getOSGiComponentInstanceOfType(ApprovalServiceManagerImpl.class);     
    ApprovalMapping[] approvals = (ApprovalMapping[])  approvalServiceManager.getApprovalMappings().findAll {
        it.projectId == projectId && it.issueTypeId.equals(issueTypeId)
    }.toArray()
    if (approvals.length > 0)
        return new ArrayList(Arrays.asList(approvals)); 
    return new LinkedList();
}

public IssueType getIssueTypeById(Project project, Long issueTypeId) {
    return project.issueTypes.find { it.id.toString().equals(issueTypeId.toString()) }
}

public IssueType getIssueTypeByName(Project project, String issueTypeName) {
    return project.issueTypes.find { it.name.equals(issueTypeName) }
}

public ActionDescriptor getActionById(Collection<ActionDescriptor> actions, Long id) {
    return actions.find { it.id.toString().equals(id.toString()) }
}

How it works

Assuming the following Requested Approvals:

On transitioning the issue, the Approval Groups and Approval Users Custom fields are populated automatically with the Users and the Groups configured as requested Approvals:

In this section

Related Documentation

Here you can find some links to our customer documentation relating to the configuration screens and other items described in this page:

Still need help?

We would love to help.

Related content