Auto-close subtasks when parent closed error

LaurieC May 26, 2021

Hello,

I'm new to groovy script and I'm not a developer. I'm looking to close subtasks when the parent is closed. I am trying to use the code from the Scriptrunner site: https://docs.adaptavist.com/sr4js/latest/features/workflows/post-functions/custom-post-functions/custom-post-function-examples/auto-close-sub-tasks

I've modified it a bit to say if the status of the subtask isn't closed, then close it. The workflow allows a transition from any status to the Closed status.  

import com.atlassian.jira.component.ComponentAccessor

import org.apache.log4j.Logger
import org.apache.log4j.Level

def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)

def issueService = ComponentAccessor.getIssueService()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def parentstatus = issue.getStatusObject().getName()
def parentResolution = issue.getResolutionObject().getName()

log.debug "status of parent is ${parentstatus}"
log.debug "resolution of parent is ${parentResolution}"

def subTasks = issue.getSubTaskObjects()
subTasks.each {
if (it.statusObject.name != "Closed") {
log.debug "status of subtask is $it.statusObject.name"

def issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.with {
setResolutionName("Done") // resolution to be set to Done
log.debug "resolution of subtask is $it.ResolutionObject.name"
setComment("Closing as a result of the parent issue being closed.")
setSkipScreenCheck(true)
}

// validate and transition subtask
def validationResult = issueService.validateTransition(user, it.id, 6, issueInputParameters)
if (validationResult.isValid()) {
def issueResult = issueService.transition(user, validationResult)
if (!issueResult.isValid()) {
log.warn("Failed to transition subtask ${it.key}, errors: ${issueResult.errorCollection}")
}
} else {
log.warn("Could not transition subtask ${it.key}, errors: ${validationResult.errorCollection}")
}
}
}

Here is the error log. I seem to be having a problem with the resolution. I've tried all sorts of things.
groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.setResolutionName() is applicable for argument types: (String) values: [Done]
	at Script183$_run_closure1$_closure2.doCall(Script183.groovy:24)
	at Script183$_run_closure1.doCall(Script183.groovy:23)
	at Script183.run(Script183.groovy:18)

 

I'd love some help. 

Thanks!
Laurie

2 answers

1 accepted

1 vote
Answer accepted
WW
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.
May 26, 2021

I think the error you're getting is because there is no issueInputParameter called "setResolutionName"

Untitled.png

on this line:

setResolutionName("Done") // resolution to be set to Done

That's what this part of the error translates to:

No signature of method: ...setResolutionName() is applicable for ...[Done]

I wish they'd leave out the extraneous stuff in the error messages and just tell you what exactly went wrong, but oh well.

You'd need to get the Resolution's Id and use it instead of the name.

That's probably why this method was used in the original example:

setResolutionId("1") // resolution of "Fixed"

To find the Resolution Id, what I'd do to cheat having to look it up through code, is go in to the Jira Admin area under Issues, then Resolutions.  Hover over the Edit link that's next to the Done resolution.  Then look at the URL that appears at the bottom (or wherever) of your browser:

Untitled2.png

That number at the end is the Id of the resolution.  In this case, mine would look like:

setResolutionId("10002") // resolution of "Done"

Your Id will probably be different.

LaurieC May 27, 2021

Can I just say, that you have earned the Wonder Woman title?!  Thank you so much for taking the time to explain all of that for me. That was super kind!

That makes a lot of sense.

So I updated it to 

setResolutionID("10000") 

and got the following error:

groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.setResolutionID() is applicable for argument types: (String) values: [10000]        at Script238$_run_closure1$_closure2.doCall(Script238.groovy:24)        at Script238$_run_closure1.doCall(Script238.groovy:23)        at Script238.run(Script238.groovy:18)

 

So I thought maybe the quotes around it were making it look like a string rather than an ID, so I changed it to

setResolutionID(10000)

and got the following error:

groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.setResolutionID() is applicable for argument types: (Integer) values: [10000]
        at Script243$_run_closure1$_closure2.doCall(Script243.groovy:24)
        at Script243$_run_closure1.doCall(Script243.groovy:23)
        at Script243.run(Script243.groovy:18)

Although I see in your documentation, that it is expecting a string. Obviously, I'm still missing something. I feel like it is rather simple, but I'm just not sure what it is...

Any additional thoughts on what I might try?

Thanks again WW!

Like WW likes this
LaurieC May 27, 2021

Also, do I need to have this in a particular order in the post-functions? I put it 3rd because it felt like the parent needed to be closed first. I had tried it at the end and it didn't work their either. Not sure if it matters in this instance?

2021-05-27_9-07-17.png

WW
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.
May 27, 2021

I am trying to reply to your comment, but it's saying I already posted the answer.  Maybe entering this comment will let the other one be added.

Finally!  I had to copy/paste to Notepad to remove any formatting, then re-add formatting before it allowed me to submit the reply.  They need to fix that issue, I've come up against it multiple times.

WW
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.
May 27, 2021

You are welcome. I like to explain in detail and in plain English, especially if the questioner says they're not a developer, but I suspect you know more than you say (or maybe think) you do. ;)

You're definitely right to question the order of the Post Functions. It can make a difference, but in your case, I think it's in the right spot.

The line with validateTransition does have a different number for actionId in the example than in yours.

validateTransition(ApplicationUser user, Long issueId, int actionId, IssueInputParameters issueInputParameters)

This method will validate parameters and check the transition conditions and if all checks pass it will construct a new instance of the Issue and will update it with the new parameters.

The error might be happening on that line, since it checks to see if the issueInputParameters are valid. Sometimes an error message can appear to be for one part of the code, but really end up being for another part of the code that influenced the code shown in the error. Who knows?

Your actionId=6, the example's actionId=5.

You are in luck, though, because this particular method is actually documented fairly decently, which is rare. :) It says:

actionId - is the id of the workflow action that you would like to transition the issue through.

So, I'm not sure if your actionId is 6 because that's your workflow's action. I'm guessing that's the same as the transition Id, but I'm not sure. I'd experiment here with hovering over links in the workflow edit screen to find the right actionId, if it's not 6.

Or maybe there's some other ResolutionId that I'm unaware of. So you could try to use "1" like in the example, just to see if it does anything.

Beyond that, I can't see any other differences between yours and the example.

PS: Instead of having to write the 4 lines of code for the logger, you can just use this line (if you're not using it in a class or something more complicated than a simple script):

log.setLevel(org.apache.log4j.Level.DEBUG)
LaurieC May 27, 2021

Thanks again @WW

I've tried everything for the actionID - resolution ID, transition ID, workflow step ID - with and without quotes. 

I'm still getting the same error on the log, no matter what I do.

Is there something potentially related to the issueInputParameters.with? it really isn't getting past the setResolutionID(). 

Is there a way to do the transition prior to setting the resolution? Although the validate step seems to rely on that resolution.

Ugh.. feeling like it is right in front of my eyes somewhere, I'm just missing it...

WW
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.
May 27, 2021

I know the feeling, @LaurieC :)

I just saw it!

Your error message says:

setResolutionID() 

The example code and documentation say:

setResolutionId()

Do you see it now?

I HATE these kinds of errors.  Why can't the language be smarter than that?

LaurieC May 28, 2021

Woohoo @WW ! That was it! Amazing!

Wow, it took me three times looking at what you wrote to find the problem. Thank you! Thank you! Thank you!!

 

Now... on to getting the resolution reason from the parent and using it for the subtasks.

If you've got energy for that one, I can tell you what I've got. If not, you've gotten me over the big hurdle and I'm grateful!

WW
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.
May 28, 2021

Yes, I've learned that they never capitalize the "d" in Id anywhere in Jira.  (At least I hope they don't or that will get confusing!)

I don't have the time to write the code for your next step, but if you get stuck, put out another question, and I'll see if I can help answer it. :)

If you do post to another question, let me know on here or @mention me (if it's possible) in a comment on the other question so that I get a notification.

LaurieC May 28, 2021

Thanks again @WW .

 

I got it working! (with a little help) Here's my final code that also carries down the parent resolution.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.ResolutionManager

log.setLevel(org.apache.log4j.Level.DEBUG)

def issueService = ComponentAccessor.getIssueService()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def parentstatus = issue.getStatusObject().getName()
def resolutionManager = ComponentAccessor.getComponent(ResolutionManager)
def parentResolution = issue.getResolutionObject()?.getId()

log.debug "status of parent is ${parentstatus}"
log.debug "resolution of parent is ${parentResolution}"

def subTasks = issue.getSubTaskObjects()
subTasks.each {
if (it.statusObject.name != "Closed") {
log.debug "status of subtask is $it.statusObject.name"

def issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.with {
setResolutionId(parentResolution) // resolution to be set to same as parent resolution
setComment("Closing with as a result of the parent issue being closed.")
setSkipScreenCheck(true)
}

// validate and transition subtask
def validationResult = issueService.validateTransition(user, it.id, 161, issueInputParameters)
if (validationResult.isValid()) {
def issueResult = issueService.transition(user, validationResult)
if (!issueResult.isValid()) {
log.warn("Failed to transition subtask ${it.key}, errors: ${issueResult.errorCollection}")
}
} else {
log.warn("Could not transition subtask ${it.key}, errors: ${validationResult.errorCollection}")
}
}
}

 Have a great weekend!

Like WW likes this
WW
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.
May 28, 2021

Good job! :)

Like LaurieC likes this
0 votes
Amirul May 28, 2021

Hi Laurie,

Thank you for the script, I believe I found why you are running into such errors. There are several problems with the current script:
1) In variable *parentResolution* you were getting a Resolution Name.

def parentResolution issue.getResolutionObject().getName()


2) The setResolutionID() is not correct the correct method setResolutionId()

setResolutionID(parentResolution)

Solution

1) You would need to replace the *parentResolution* to be as below:

def parentResolution = issue.getResolutionObject()?.getId()

2) Then you need to change the setResolutionID() to be:

setResolutionId(parentResolution)


If you can see from this setResolutionId()|method, it was expecting a resolutionId instead of a name which what we get from Step 1.

Kind regards,
Amirul

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events