Force Update with ScriptRunner for Jira DC

On this post we will have a Script that uses ScriptRunner tool

We will have a custom Listener. that when an automation is done thru SR, it will force an UPDATE EVENT, that will send all the modifications.

This force helps on having all the information at the same time, because sometimes, automations happen so fast, that are unable to create an event

On this case is based on a Cascading select list, but It can be modify for any field

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.user.UserUtils
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.event.type.EventType

// Get the issue manager
def issueManager = ComponentAccessor.getIssueManager()
IssueEvent issueEvent = event as IssueEvent
MutableIssue mutableIssue = issueEvent.getIssue() as MutableIssue

// Define the custom field and assignee mapping
def customFieldName = "CascadingListName"
def cascadeListAssigneeMapping = [
    "ZZZZZ-XXXXX" : "sxxxxxxxx",
    "YYYY-ZZZZ"   : "mxxxxxxxx",
    "XXXX-ZZZZ"   : "sxxxxxxxx",
    "XXXX-ZZZZ"   : "cxxxxxxxx",
    "XXXX-ZZZZ"   : "mxxxxxxxx",
    "XXXX-ZZZZ"   : "xxxxxxxx"
]

// Get the custom field object for the customFieldName
def customField = ComponentAccessor.customFieldManager.getCustomFieldObjects(mutableIssue).find { it.name == customFieldName }

// Check if the custom field exists
if (customField) {
log.debug("Cascade List field found: " + customFieldName)

// Retrieve the cascading select value (parent and child)
def cascadingSelectValue = mutableIssue.getCustomFieldValue(customField) as Map<String, Object>

if (cascadingSelectValue) {
    def value1 = cascadingSelectValue?.get(null)?.toString()  // Parent value
    def value2 = cascadingSelectValue?.get('1')?.toString()  // Child value

    // Log the parent and child values
    log.debug("Parent value: " + value1)
    log.debug("Child value: " + value2)

    // Combine the values into a single string to match the mapping
    def cascadeFieldValue = "${value1}-${value2}"

    // Log the combined cascade field value for debugging
    log.debug("Combined cascade field value: " + cascadeFieldValue)

    // Check if a mapping exists for the combined cascade value
    def assigneeEmail = cascadeListAssigneeMapping[cascadeFieldValue]
    
    if (assigneeEmail) {
        log.debug("Assignee email found for cascade value: " + assigneeEmail)
        ApplicationUser assignee = UserUtils.getUserByEmail(assigneeEmail)
        if (assignee) {
            def currentAssignee = mutableIssue.getAssignee()
            // Only update if the assignee is different
            if (assignee != currentAssignee) {
                mutableIssue.setAssignee(assignee)
                log.debug("Assignee updated to: " + assignee.getDisplayName())

                // Get the actor to trigger the event changemeforyourUserName
                ApplicationUser actor = ComponentAccessor.getUserManager().getUserByName("changemeforyourUserName")

                // Use the correct method to update the issue and trigger the event
                def eventId = EventType.ISSUE_UPDATED_ID.intValue()  // Event for issue updated
                def eventDispatchOption = EventDispatchOption.ISSUE_UPDATED  // Force event dispatch

                try {
                    // Correct method signature for updateIssue
                    issueManager.updateIssue(actor, mutableIssue, eventDispatchOption, false)
                    log.debug("Issue updated and event triggered for actor: " + actor.getDisplayName())
                } catch (Exception e) {
                    log.error("Error while triggering issue update: " + e.message)
                }
            } else {
                log.debug("No assignee change required. Current assignee is: " + currentAssignee?.getDisplayName())
            }
        } else {
            log.warn("User not found for email: " + assigneeEmail)
        }
    } else {
        log.warn("No assignee mapping found for cascade value: " + cascadeFieldValue)
        // If no assignee is found, assign to project lead
        ApplicationUser projectLead = mutableIssue.getProjectObject()?.getProjectLead()
        if (projectLead) {
            mutableIssue.setAssignee(projectLead)
            log.debug("Assignee set to project lead: " + projectLead.getDisplayName())

            // Trigger the issue update event for project lead assignment
            def eventDispatchOption = EventDispatchOption.ISSUE_UPDATED  // Force event dispatch
            ApplicationUser actor = ComponentAccessor.getUserManager().getUserByName("changemeforyourUserName")
            try {
                // Correct method signature for updateIssue
                issueManager.updateIssue(actor, mutableIssue, eventDispatchOption, false)
                log.debug("Issue updated and event triggered for project lead.")
            } catch (Exception e) {
                log.error("Error while triggering issue update for project lead: " + e.message)
            }
        } else {
            log.warn("No project lead found. Cannot assign issue.")
        }
    }
} else {
    log.warn("No cascading select value found for custom field: " + customFieldName)
}
} else {
    log.warn("Custom field not found: " + customFieldName)
}

Hope this helps to achieve the needed modifications

1 Like