Hi,
i am recently using the script runner plugin to autoclose suktasks when the parent issue is closed.
Can you tell me the lines to add to force the "Remaning Time" on subtasks to 0 at the same time ?
Thank you.
You can try this.
import com.atlassian.jira.bc.issue.IssueService import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.config.SubTaskManager import com.atlassian.jira.issue.IssueInputParameters import com.atlassian.jira.issue.MutableIssue import org.apache.log4j.Category import static org.apache.log4j.Level.DEBUG log = Category.getInstance("com.onresolve.jira.groovy.AutoCloseChildIssues") log.setLevel(DEBUG) log.debug "debug statements" IssueService issueService = ComponentAccessor.getIssueService() SubTaskManager subTaskManager = ComponentAccessor.getSubTaskManager(); if (subTaskManager.subTasksEnabled) { MutableIssue issue = issue // this is only for the IDE log.debug ("issue.statusObject.name: " + issue.statusObject.name) def currentUser = ComponentAccessor.getUserUtil().getUser("muleuser") issue.getSubTaskObjects().each { subtask -> IssueInputParameters issueInputParameters = issueService.newIssueInputParameters(); issueInputParameters.setRemainingEstimate(0L); issueInputParameters.setComment("*Réouverte*, car la demande mère a été réouverte.") IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(currentUser, subtask.id, 3, issueInputParameters); if (transitionValidationResult.isValid()){ IssueService.IssueResult transitionResult = issueService.transition(currentUser, transitionValidationResult); if (!transitionResult.isValid()) { transitionResult.errorCollection.errorMessages.each {log.error "Error Message: $it"} transitionResult.errorCollection.errors.each {log.error "Error: $it"} transitionResult.errorCollection.reasons.each {log.error "Reason: $it"} } } else { transitionValidationResult.errorCollection.errorMessages.each {log.error "Error Message: $it"} transitionValidationResult.errorCollection.errors.each {log.error "Error: $it"} transitionValidationResult.errorCollection.reasons.each {log.error "Reason: $it"} } } }
There is a nice documentation on how to use the issueService. If it doesn't work there could be a problem with the transition screen. Take a look here, especially setSkipScreenCheck().
You are really Good, it works fine.
Another question : if I want set the estimate to 2h for example ?
I wrote setRemainingEstimate(2h) but i doesnt work
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Try setRemainingEstimate('2h')
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You have to make sure you're using a String as parameter, than it should work like documented here. Could you enter 2h manually while entering an estimate?
If it doesn't work you could calculate a long of 2h in your timetracking default units ( APKeys.JIRA_TIMETRACKING_DEFAULT_UNIT
) and use this as parameter.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Yes, i can write 2h in the field "remaining estimate".
I also try issueInputParameters.setRemainingEstimate(1100L);
but no result
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Mmh. Setting to 0 works but not to any other value? What did you get if you call issueInputParameters.getRemainingEstimate() after setting the remaining estimate (before the transition)?
log.error "getRemainingEstimate(): ${issueInputParameters.getRemainingEstimate()}"
Are there any other errors in the log?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
i found this error :
2014-03-05 13:42:34,087 ajp-bio-8009-exec-31 ERROR leprince.t 821x55358x1 1v714k4 10.253.114.5 /secure/WorkflowUIDispatcher.jspa [atlassian.event.internal.AsynchronousAbleEventDispatcher] There was an exception thrown trying to dispatch event 'com.atlassian.jira.event.issue.IssueEvent@122580a1[issue=PROJWMS-16227,comment=<null>,worklog=<null>,changelog=[GenericEntity:ChangeGroup][id,3359167][author,leprince.t][created,2014-03-05 13:42:24.05][issue,420304],eventTypeId=5,sendMail=true,params={eventsource=workflow, baseurl=https://jira-app-rec-03.stef.com/jira},subtasksUpdated=false]' from the invoker 'SingleParameterMethodListenerInvoker{method=public void com.stef.jira.plugin.listener.JiraIssueListener.onIssueEvent(com.atlassian.jira.event.issue.IssueEvent), listener=com.stef.jira.plugin.listener.JiraIssueListener@2eedaaf4}'. java.lang.RuntimeException: java.lang.StackOverflowError
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Do you have any recursion in your code? Could you post the complete stack trace?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
(sample catalina.out.txt) contains all lines after the error line i sent before
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
There is a recursion in this code part:
at com.stef.jira.plugin.business.IssueEventFactory.buildCollectionIssueImpl(IssueEventFactory.java:276) at com.stef.jira.plugin.business.IssueEventFactory.buildIssueImpl(IssueEventFactory.java:79) at com.stef.jira.plugin.business.IssueEventFactory.buildIssueImpl(IssueEventFactory.java:78) at com.stef.jira.plugin.business.IssueEventFactory.buildCollectionIssueImpl(IssueEventFactory.java:276)
The numbers at the end are the line numbers in the source file. Maybe you should add some debug output to these lines to see why your code is calling itself over and over again. This leads to the stack overflow.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Any errors in the log?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
hi dude, i need your help, i want to changes status on every sub-task in a main issue. I make this code but it doen't work. Can you help me??
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.SubTaskManager
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.config.SubTaskManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.AttachmentManager
import com.atlassian.jira.issue.attachment.Attachment;
import com.atlassian.jira.issue.IssueFactory;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.MutableIssue;
Issue parentIssue = issue
IssueService issueService = ComponentAccessor.getIssueService()
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser();
if (issue.getIssueType().getName() != "Sub-task") {
if (parentIssue.getSubTaskObjects().size()>0) {
for(int o = 0; parentIssue.getSubTaskObjects().size() > o; o++) {
if(!parentIssue.getSubTaskObjects()[o].getStatus().equals("DONE")) {
//TransitionOptions traOpt = issue;
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
issueInputParameters.setRemainingEstimate(0L);
issueInputParameters.setComment("*Réouverte*, car la demande mère a été réouverte.")
// validateTransition(ApplicationUser user, Long issueId, int actionId, IssueInputParameters issueInputParameters, TransitionOptions transitionOptions)
IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(currentUser, parentIssue.getSubTaskObjects()[o].getId(), 3 as Integer, issueInputParameters);
//IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(currentUser, parentIssue.getSubTaskObjects()[o].getId(), 3,"10001", 5 as Integer, issueInputParameters, );
}
}
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Stefano,
you're only validating the transition, you have to do it if the validation result is valid.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
Issue parentIssue = issue
def issueService = ComponentAccessor.getIssueService()
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
if (!parentIssue.isSubTask()) {
parentIssue.subTaskObjects.each{ subtask ->
if (subtask.status.name != "DONE") {
def issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.setRemainingEstimate(0L)
issueInputParameters.setComment("*Réouverte*, car la demande mère a été réouverte.")
def transitionValidationResult = issueService.validateTransition(currentUser, subtask.id, 3 as Integer, issueInputParameters)
if (transitionValidationResult?.isValid()) {
issueService.transition(currentUser, transitionValidationResult)
} else {
def text = "Transition failed. "
transitionValidationResult?.errorCollection?.errorMessages?.each { text += "Error Message: $it\r\n" }
transitionValidationResult?.errorCollection?.errors?.each { text += "Error: $it\r\n" }
transitionValidationResult?.errorCollection?.reasons?.each { text += "Reason: $it\r\n" }
log?.error(text)
}
}
}
}
Best regards,
Henning
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
i copy and paste this scritp on my post function but it dosen't work
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Is the status name correct? Maybe it's "Done"?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
the condition is if the sub-task is not DONE run this code to set sub-task done
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Yes, that‘s correct. But it‘s a difference if the status name is DONE or Done. Case matters.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Take a look into the status list in administration to see the correct case.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
The problem is that script doesn't run
i don't know it doesn't run
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Did you changed
if (subtask.status.name != "DONE") {
to
if (subtask.status.name != "Done") {
?
But this doesn't explain why the postfunction has not run yet. Did you publish the workflow?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
ure dude look the code:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.onresolve.scriptrunner.runner.util.UserMessageUtil
UserMessageUtil.success("script is run");
Issue parentIssue = issue
def issueService = ComponentAccessor.getIssueService()
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
if (!parentIssue.isSubTask()) {
parentIssue.subTaskObjects.each{ subtask ->
UserMessageUtil.success("we are in the cicle");
if (subtask.status.name != "Done") {
UserMessageUtil.success("we are on the condition - if (subtask.status.name != Done)");
def issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.setRemainingEstimate(0L)
issueInputParameters.setComment("TESTETSTESTTESTET.")
def transitionValidationResult = issueService.validateTransition(currentUser, subtask.id, 3 as Integer, issueInputParameters)
if (transitionValidationResult?.isValid()) {
UserMessageUtil.success("insane - if (transitionValidationResult?.isValid())");
issueService.transition(currentUser, transitionValidationResult)
} else {
def text = "Transition failed. "
transitionValidationResult?.errorCollection?.errorMessages?.each { text += "Error Message: $it\r\n" }
transitionValidationResult?.errorCollection?.errors?.each { text += "Error: $it\r\n" }
transitionValidationResult?.errorCollection?.reasons?.each { text += "Reason: $it\r\n" }
log?.error(text)
}
}
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
And, do you see any of the messages?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
ok i fix that, now the script run, but it worked also if the sub-task is on some status where is connected with a transaction DONE, i need that status change always
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You have to take care that from every possible status of the subtask workflow (every status not "Done") there is the transition with ID 3 to status Done. If this is not the case add a global transition to Done and use the ID of this transition in your post function script.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
i dont know how to use issueService and issueInputParameters.setRemainingEstimate()
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Henning and Julian,
Many thanks for your asnwer.
Henning, here is my script, can you help me to apply what you said ?
import com.atlassian.jira.ComponentManager import com.atlassian.jira.issue.IssueService import com.atlassian.jira.issue.comments.CommentManager import com.opensymphony.workflow.WorkflowContext import org.apache.log4j.Category import com.atlassian.jira.config.SubTaskManager import com.atlassian.jira.workflow.WorkflowTransitionUtil; import com.atlassian.jira.workflow.WorkflowTransitionUtilImpl; import com.atlassian.jira.util.JiraUtils; import org.apache.log4j.Category def Category log = Category.getInstance("com.onresolve.jira.groovy.PostFunction") log.setLevel(org.apache.log4j.Level.DEBUG) log.debug "debug statements" log = Category.getInstance("com.onresolve.jira.groovy.AutoCloseChildIssues") String currentUser = ComponentManager.getInstance().getUserUtil().getUser("muleuser").getName() WorkflowTransitionUtil workflowTransitionUtil = ( WorkflowTransitionUtil ) JiraUtils.loadComponent( WorkflowTransitionUtilImpl.class ); SubTaskManager subTaskManager = ComponentManager.getInstance().getSubTaskManager(); Collection subTasks = issue.getSubTaskObjects() if (subTaskManager.subTasksEnabled && !subTasks.empty) { subTasks.each { log.debug ("issue.statusObject.name: " + issue.statusObject.name) workflowTransitionUtil.setIssue(it); workflowTransitionUtil.setUsername(currentUser); workflowTransitionUtil.setAction (3) // 3 == REOPEN ISSUE issueInputParameters.setRemainingEstimate(3) // Add a comment so people have a clue why the child has been closed CommentManager commentManager = (CommentManager) ComponentManager.getComponentInstanceOfType(CommentManager.class); String comment = "*Réouverte*, car la demande mère a été réouverte."; commentManager.create(it, currentUser, comment, true); // validate and transition issue workflowTransitionUtil.validate(); workflowTransitionUtil.progress(); } }
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I had created a simliar script for this a few months ago. Maybe this can help you.
Usage: Create a JQL-Query that matchs the subtasks, you want to edit. Copy that query
Replace ("INSERT HERE YOUR JQL QUERY") with the created Query.
Run the script
import com.atlassian.jira.issue.Issue; import com.atlassian.jira.issue.IssueManager; import com.atlassian.jira.issue.MutableIssue; import com.atlassian.jira.component.ComponentAccessor; import com.atlassian.jira.issue.fields.CustomField; import com.atlassian.jira.bc.JiraServiceContextImpl; import com.atlassian.jira.bc.filter.SearchRequestService; import com.atlassian.jira.bc.issue.search.SearchService; import com.atlassian.jira.component.ComponentAccessor; import com.atlassian.jira.issue.search.SearchRequest; import com.atlassian.jira.issue.search.SearchResults; import com.atlassian.jira.user.ApplicationUser; import com.atlassian.jira.web.bean.PagerFilter; import com.atlassian.query.Query; SearchResults getissuesByJQL(String jql) throws Exception { SearchService serchService = ComponentAccessor.getComponentOfType(SearchService.class); SearchService.ParseResult parseResult = serchService.parseQuery(ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser(), jql); if (!parseResult.isValid()) { throw new Exception("jql is not valid. jql was "+jql); } Query query = parseResult.getQuery(); SearchResults sr = serchService.search(ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser(), query, PagerFilter.getUnlimitedFilter()); return sr; } void setEstimateToNull(String key) { IssueManager im = ComponentAccessor.getIssueManager(); MutableIssue issue = im.getIssueObject(key); issue.setEstimate(0L); issue.store(); } for (Issue issue : getissuesByJQL("INSERT HERE YOUR JQL QUERY").getIssues()) { setEstimateToNull(issue.getKey()); }
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Use issueService and issueInputParameters.setRemainingEstimate()
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.