Groovy listener - editing due date fields in linked tickets (using destinationObject)

James Fishwick September 19, 2016

Here is my inline Script Listner. Supposedly it isn't failing, but it isn't changing things as I would like either. Basically, it finds a certain type of linked issue of a subtask and tries to update the linked issue's Due Date against the subtask's Due Date (After adding an offset value.)

 

package com.onresolve.jira.groovy.test.scriptfields.scripts
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import java.sql.Timestamp
import java.io.*;
import java.util.concurrent.*;
def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def userUtil = ComponentAccessor.getUserUtil()

log.debug("Test data");
/**
* Set max DueDate of all subtasks to parent issue
*/
//Get parent issue
Issue issue = (Issue) event.issue;
//Check, that it is a subtask type issue
if(!issue.isSubTask())
return
MutableIssue parentIssue = issue.getParentObject();
Set issueLabels = parentIssue.getLabels();
boolean containsLabel = false;

for (String label : issueLabels) {
if (label.contains("complex")){
containsLabel = true;
}}
if(!containsLabel)
return
issueLinkManager.getOutwardLinks(issue.id).each {issueLink ->
if (issueLink.issueLinkType.name == "Sequence") {
def linkedIssue = issueLink.destinationObject
def offset = customFieldManager.getCustomFieldObject("customfield_27032")

log.info "got here"

def val = linkedIssue.getCustomFieldValue(offset)

log.debug "Issue type is : ${val}"

long number = (long) val;
Timestamp dueDate = issue.getDueDate();

Long duration = TimeUnit.DAYS.toMillis(number);
dueDate.setTime(dueDate.getTime() + duration);

if( ( linkedIssue.getDueDate() == null ) || (linkedIssue.getDueDate().before(dueDate)))
linkedIssue.setDueDate(dueDate)
}
}
//This line is not requred into postfunction also
ComponentAccessor.getIssueManager().updateIssue(ComponentAccessor.getJiraAuthenticationContext().getUser().getDirectoryUser(), parentIssue,EventDispatchOption.ISSUE_UPDATED, false)

 

The part I'm unsure about is `linkedIssue.setDueDate(dueDate)` – there seems not to be a matching method. Do I need to convert `issueLink.destinationObject` somehow before I try to change its Due Date fields?

1 answer

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

1 vote
Answer accepted
Vasiliy Zverev
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.
September 19, 2016

Hi James!

  1. I would recommend to define variable with it classname, not with def. name. issueLink.destinationObject returns an Issue object, but MutableIssue should be used for issue updates. Since you used def you can not understand how code really works.
  2. If you need to modify issues then update should be done into a loop

    Here is modified code:
package com.onresolve.jira.groovy.test.scriptfields.scripts

import com.atlassian.crowd.embedded.api.User
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.fields.CustomField

import java.sql.Timestamp
import java.io.*;
import java.util.concurrent.*;


log.debug("Test data");
/**
 * Set max DueDate of all subtasks to parent issue
 */
//Get parent issue
Issue issue = (Issue) event.issue;
//Check, that it is a subtask type issue
if(!issue.isSubTask())
    return

MutableIssue parentIssue = issue.getParentObject();
boolean containsLabel = false;

for (String label : parentIssue.getLabels()) {
    if (label.contains("complex")){
        containsLabel = true;
        break;
    }}
if(!containsLabel)
    return

//variables should not be defined into loops
MutableIssue linkedIssue;
def customFieldManager = ComponentAccessor.getCustomFieldManager()
CustomField offset = customFieldManager.getCustomFieldObject("customfield_27032")
long number = 0;
IssueManager issueManager = ComponentAccessor.getIssueManager();
User curUser = ComponentAccessor.getJiraAuthenticationContext().getUser().getDirectoryUser();

ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.id).each {issueLink ->
    if (issueLink.issueLinkType.name == "Sequence") {
        linkedIssue = issueLink.destinationObject

        log.info "got here"

        number = (long) linkedIssue.getCustomFieldValue(offset)

        log.debug "Issue type is : ${number}"

        Timestamp dueDate = issue.getDueDate();
        //I think that it is better to use Calendar to add only working days
        dueDate.setTime(dueDate.getTime() + TimeUnit.DAYS.toMillis(number));

        if( ( linkedIssue.getDueDate() == null ) || (linkedIssue.getDueDate().before(dueDate))) {
            linkedIssue.setDueDate(dueDate)

            //linked issue should be updated into a loop
            issueManager.updateIssue(
                    curUser
                    , linkedIssue
                    , EventDispatchOption.ISSUE_UPDATED
                    , false)
        }
    }
}
James Fishwick September 20, 2016

Fantastic, thanks for all your help, I am learning much. 

TAGS
AUG Leaders

Atlassian Community Events