workflow post-function: creating subtask for each user of group

Hey,

i need a workflow post-function which creates a subtask for each user of a jira-group (given by a usergroup-customfield) and assign it to him/her. does anybody have a solution for this problem?

i was thinking about the groovyrunner-plugin, but obviously you need to create an own groovy-script for this purpose, which i am not capable of... :-/

thank you very much in advance!

cheers,
michael

3 answers

1 accepted

4 votes

Can't think of anything which you would not need to code. Here's a script that should work:

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.Issue
import com.opensymphony.user.Group
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.config.SubTaskManager
import org.ofbiz.core.entity.GenericValue

ComponentManager componentManager = ComponentManager.getInstance()
CustomFieldManager customFieldManager = componentManager.getCustomFieldManager()
def issueFactory = componentManager.getIssueFactory()
def issueManager = componentManager.getIssueManager()
def indexManager = componentManager.getIndexManager()

def groupCf = customFieldManager.getCustomFieldObjectByName("GroupPicker") // name of group CF

Group group = issue.getCustomFieldValue(groupCf) as Group

if (group) {
    group.getUsers().each {String user ->

        MutableIssue newIssue = issueFactory.getIssue()
        newIssue.summary = "Sub-task for $user"
        newIssue.issueTypeId = '5'
        newIssue.project = issue.project
        newIssue.affectedVersions = issue.affectedVersions
        newIssue.fixVersions = issue.fixVersions

        Map<String,Object> newIssueParams = ["issue":newIssue] as Map<String,Object>
        def currentUser = componentManager.getJiraAuthenticationContext().getUser()
        GenericValue newIssueGv = issueManager.createIssue(currentUser, newIssueParams)
        indexManager.reIndex(newIssueGv);

        SubTaskManager subTaskManager = componentManager.getSubTaskManager()
        subTaskManager.createSubTaskIssueLink(issue, newIssue, componentManager.getJiraAuthenticationContext().getUser())
    }
}

Thank you very much, Jamie!

Just one more question: To implement this code I have to create a groovy-script-file on the server and then refer to it in the post-function "script component", right? Is it sufficient to put just this code into the file or do i have to use a any class-construct like it is the case for the other groovy file examples?

Hi, no it's sufficent to just paste into a file exactly as is.

Hello, you script don`t work in JIRA 5.0.7. Help me, please.

Error:

javax.script.ScriptException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script30.groovy: 4: unable to resolve class com.opensymphony.user.Group
 @ line 4, column 1.
   import com.opensymphony.user.Group
   ^

1 error

Dear @Jamie Echlin [Adaptavist] , how to do the same with checkbox custom field.

Hi Jamie,

just one more question: Why doesn't the subtask appear in the "assign to me" gadget?
How can I assure that?

Thanks again!

Cheers,
Michael

I seem to have missed a critical line from the script I wrote for you:

newIssue.assigneeId = user
Put that line along with the other setters...

Hi Jamie,

thanks for your fast respone. Unfortunately this doesnt work. Maybe it is because if have modified your script simply. it does look like this now:

do i miss something here?

Can you put the whole script on gist.github.com? I can't see your script...

the code is too long for a comment. please take a look here: http://pastebin.com/XgdAwtXw

This stuff with UserList you've added seems bogus.. what's the point of it? You can't have duplicate usernames in a group. Also use userList for a variable name.

You only need one of

newIssue.assignee = UserUtils.getUser(user)
newIssue.assigneeId = user

Are the subtasks created? Any errors in the log? Do all the users you're trying to assign have ASSIGNABLE permission?

meanwhile the requirements have changed. our users wanted to have a list of checkboxes instead of the group-list customfield. thus i have created a checkbox-list with the names of the groups as options. since a user can be in multiple of these groups i used the userlist to avoid creating multiple subtasks for one user.

previously i used only the assigne-line. after i've recognized that the issue doesnt appear in the "assigned to me"-gadget i also added the assigneId-line like you have suggested it.

all subtasks will be created. there are no errors in the log. and yes, the users do have the assignable permission. after making some modifications on a subtask, it also appears in the "assigned to me"-gadget.

i was thinking that it is an indexing-problem and therefore added some reIndex-lines which unfortunately didnt work out... :-(

do you have any other ideas?

Sounds like an indexing problem yes. So if you ran the post-function, the do a Admin -> Reindex, everything works properly?

Try replacing with this section. Also I don't see any point in reindexing the parent issue.

boolean wasIndexing = ImportUtils.isIndexIssues();
ImportUtils.setIndexIssues(true);

indexManager.reIndex(newIssueGv);

SubTaskManager subTaskManager = componentManager.getSubTaskManager()
subTaskManager.createSubTaskIssueLink(issue, newIssue, componentManager.getJiraAuthenticationContext().getUser())

indexManager.reIndex(newIssueGv);
indexManager.reIndex(issue);

ImportUtils.setIndexIssues(wasIndexing);

seems to work.. thank you very much!

No worries. How about an upvote or two for the comment and answer... ;-)

SO does this this look like a correct transition using the above script?

Add a new post function to the unconditional result of the transition.

Set issue status to the linked status of the destination workflow step.
— THEN
Add a comment to an issue if one is entered during a transition.
— THEN
Script /opt/atlassian/jira/myscripts/CreateSubtaskForEachGroupMember.groovy will be run.
Edit | Move Up | Move Down | Delete
— THEN
Update change history for an issue and store the issue in the database.
— THEN
Re-index an issue to keep indexes in sync with the database.
— THEN
Fire a Issue Assigned event that can be processed by the listeners.
Edit
Also, I'm not sure I understand the addition/modification.
This is what I have for the complete script. Is it correct because if I try to execute it in the groovy script plugin manager, I get a very long stack trace. The short version is
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: Script3.groovy: 8: unable to resolve class com.opensymphony.user.User @ line 8, column 1. import com.opensymphony.user.User ^ Script3.groovy: 9: unable to resolve class com.atlassian.core.user.UserUtils @ line 9, column 1. import com.atlassian.core.user.UserUtils ^ Script3.groovy: 4: unable to resolve class com.opensymphony.user.Group @ line 4, column 1. import com.opensymphony.user.Group ^ 3 error
I haven't finished my workflow yet so I don't know if it will work in it.
BTW - I'm a new Jira user and I'm designing my first workflow.
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.Issue
import com.opensymphony.user.Group
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.config.SubTaskManager
import org.ofbiz.core.entity.GenericValue
import com.opensymphony.user.User
import com.atlassian.core.user.UserUtils
import com.atlassian.jira.user.util.UserManager
import com.opensymphony.workflow.WorkflowContext
import com.atlassian.jira.security.util.GroupSelectorUtils

ComponentManager componentManager = ComponentManager.getInstance()
CustomFieldManager customFieldManager = componentManager.getCustomFieldManager()
def issueFactory = componentManager.getIssueFactory()
def issueManager = componentManager.getIssueManager()
def indexManager = componentManager.getIndexManager()
def groupCf = customFieldManager.getCustomFieldObjectByName("Kompetenzcluster") // name of group CF
def UserList = []
String currentUser = ((WorkflowContext) transientVars.get("context")).getCaller()
User currentUserObj = UserUtils.getUser(currentUser)
GroupSelectorUtils util = (GroupSelectorUtils) ComponentManager.getInstance().getContainer().getComponentInstanceOfType(GroupSelectorUtils.class)

//Group group = issue.getCustomFieldValue(groupCf) as Group
issue.getCustomFieldValue(groupCf).each {Object group ->
if (group) {
Group groupObj = util.getGroups((String) group)
groupObj.getUsers().each {String user ->
if(!UserList.contains(user) && user != currentUser) {
MutableIssue newIssue = issueFactory.getIssue()
newIssue.summary = "$user: " + issue.summary
newIssue.issueTypeId = '71'
newIssue.project = issue.project
newIssue.reporter = UserUtils.getUser(user)
newIssue.assignee = UserUtils.getUser(user)
newIssue.assigneeId = user
newIssue.priority = issue.priority
Map<String,Object> newIssueParams = ["issue":newIssue] as Map<String,Object>
//User currentUser = componentManager.getJiraAuthenticationContext().getUser()
GenericValue newIssueGv = issueManager.createIssue(currentUserObj, newIssueParams)
ImportUtils.setIndexIssues(true);
indexManager.reIndex(newIssueGv);
SubTaskManager subTaskManager = componentManager.getSubTaskManager()
subTaskManager.createSubTaskIssueLink(issue, newIssue, componentManager.getJiraAuthenticationContext().getUser())
indexManager.reIndex(newIssueGv);
indexManager.reIndex(issue);
ImportUtils.setIndexIssues(wasIndexing);
UserList.add(user)
}
}
}
}

this does not work in JIRA 7.3 ? 

Suggest an answer

Log in or Join to answer
Community showcase
Sarah Schuster
Posted Jan 29, 2018 in Jira

What are common themes you've seen across successful & failed Jira Software implementations?

Hey everyone! My name is Sarah Schuster, and I'm a Customer Success Manager in Atlassian specializing in Jira Software Cloud. Over the next few weeks I will be posting discussion topics (8 total) to ...

2,799 views 11 18
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you
Atlassian Team Tour

Join us on the Team Tour

We're bringing product updates and pro tips on teamwork to ten cities around the world.

Save your spot