Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Next challenges

Recent achievements

  • Global
  • Personal

Recognition

  • Give kudos
  • Received
  • Given

Leaderboard

  • Global

Trophy case

Kudos (beta program)

Kudos logo

You've been invited into the Kudos (beta program) private group. Chat with others in the program, or give feedback to Atlassian.

View group

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Run JQL Search and Create Subtasks based on User Picker CF (PostFunction) Edited

HI Everyone

Scriptrunner version - 6.15.0

Jira Version - 8.11.0

Method - Post Function - Custom Script Function

Custom Field - Tempo Validator (User picker single)

JQL Query - project = TEMPO

Goal ->

I want to create a subtask on the issue which triggers the post-funtion based off the JQL query result. 

For example - Lets say the JQL query result has 5 tickets, each of these tickets has a custom field called Tempo Validator which is a single user picker type (Or I can use multi user)

So based on this example the postfunction will create 5 sub-task which will be assigned to the values of the Tempo Validators from the JQL query

 

I have below experimenting with below code but need some help to get this working 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser


def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

// The search query
def query = jqlQueryParser.parseQuery("project = TEMPO")

// Results from query
def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())

// Get the custom field that you want to update
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def customField = customFieldManager.getCustomFieldObjectByName("Tempo Validator")

Collection<ApplicationUser> users= (Collection) issue.getCustomFieldValue(customField);

if(users != null)
{
for(i in 0..users.size()-1)
{
Object AssigneeValue = users.get(i).getKey()
;

issueObject = ComponentAccessor.getIssueFactory().getIssue()
issueObject.setProjectObject(issue.getProjectObject())
issueObject.setIssueTypeId("10003") //id of subtask
issueObject.setParentId(issue.getId())
issueObject.setSummary(issue.getSummary() + ' ' + users.get(i).getDisplayName() + ' - Assessment')
issueObject.setFixVersions(issue.getFixVersions())
issueObject.setAssigneeId(AssigneeValue)
def subTask = issueManager.createIssueObject(ComponentAccessor.jiraAuthenticationContext.getLoggedInUser(), issueObject)
ComponentAccessor.subTaskManager.createSubTaskIssueLink(issue, subTask, ComponentAccessor.jiraAuthenticationContext.getLoggedInUser())
i++
}
}

Thanks in advance

Richard

2 answers

1 accepted

0 votes
Answer accepted

You mention PostFunction. This is normally something that happens on a single issue.

I don't understand what role your query results play in your script.

Can you elaborate on your goal a bit more?

Are we creating subtasks on the issue that triggered the postfunction? Or on all issues returned by the JQL?

Hi @Peter-Dave Sheehan 

I want to create a subtask on the issue which triggers the post-funtion based off the JQL query result. 

For example - Lets say the JQL query result has 5 tickets, each of these tickets has a custom field called Tempo Validator which is a single user picker type (Or I can use multi user)

So based on this example the postfunction will create 5 sub-task which will be assigned to the values of the Tempo Validators from the JQL query

Hope that makes more sense

Thanks

Richard

*updated summary to make it more clear

You could try something like the following that should work whether the custom field is a single or multi-user picker. If it's a multi, a subtask will be created for each user selected in the custom field.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.bc.issue.search.SearchService
//managers
def searchService = ComponentAccessor.getComponent(SearchService)
def issueManager = ComponentAccessor.issueManager
def customFieldManager = ComponentAccessor.customFieldManager

//some general variables
def tempoValidatorCf= customFieldManager.getCustomFieldObjectsByName('Tempo Validator')[0]
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser

//a closure to create the subtask for a given user
def createSubTaskForUser = {ApplicationUser user->
def subTask = ComponentAccessor.issueFactory.issue
subTask.projectObject = issue.projectObject
subTask.issueTypeId = "10003"
subTask.parentId =issue.id
subTask.summary = "$issue.summary $user.displayName - Assessment"
subTask.assignee = user
def subTaskIssue = issueManager.createIssueObject(currentUser, subTask)
ComponentAccessor.subTaskManager.createSubTaskIssueLink(issue, subTaskIssue, currentUser)
}

// The search query
def jql ="project = TEMPO"

def jqlParseResult = searchService.parseQuery(currentUser,jql)
if(jqlParseResult.isValid()){
// Results from query
def results = searchService.search(currentUser, jqlParseResult.query,PagerFilter.getUnlimitedFilter())
//look through each result, load the issue, get the cf value, create sub-tasks
results.results.each{indexIssue->
def filterIssue = issueManager.getIssueObject(indexIssue.id)
def tempoValidatorValue = filterIssue.getCustomFieldValue(tempoValidatorCf)
if(tempoValidatorValue instanceof ApplicationUser){
//this is the case when the customfield is a single-user-picker
createSubTaskForUser(tempoValidatorValue)
} else {
//for multi-user, we'll create a subtask for each selected users
tempoValidatorValue.each{ApplicationUser user-> createSubTaskForUser(user)}
}
}
}

Hi @Peter-Dave Sheehan 

Thank you so much this works very well!

One requirement I forgot was to have the subtask names have the same summary as the JQL tickets + Assignee + Text

So lets say the JQL has 1 ticket with summary "Project Connect" and Assignee "Bill"

The subtask summary would be something like ->

Project Connect - Bill - Validation Task

 

 

Thanks

Richard

Hi @Peter-Dave Sheehan 

I haven't been able too get the summary part working, can you help?

Thanks

Richard 

You could try it like this:


import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.bc.issue.search.SearchService
//managers
def searchService = ComponentAccessor.getComponent(SearchService)
def issueManager = ComponentAccessor.issueManager
def customFieldManager = ComponentAccessor.customFieldManager

//some general variables
def tempoValidatorCf= customFieldManager.getCustomFieldObjectsByName('Tempo Validator')[0]
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser

//a closure to create the subtask for a given user using an issue (sourceIssue) from the JQL search below
def createSubTaskForUser = {Issue sourceIssue, ApplicationUser user->
   def subTask = ComponentAccessor.issueFactory.issue
   subTask.projectObject = issue.projectObject //this issue is the one where the postfunction is running on
   subTask.issueTypeId = "10003"
   subTask.parentId =issue.id
   subTask.summary = "$sourceIssue.summary $user.displayName - Assessment"
   subTask.assignee = user
   def subTaskIssue = issueManager.createIssueObject(currentUser, subTask)
   ComponentAccessor.subTaskManager.createSubTaskIssueLink(issue, subTaskIssue, currentUser)
}

// The search query
def jql ="project = TEMPO"

def jqlParseResult = searchService.parseQuery(currentUser,jql)
if(jqlParseResult.isValid()){
   // Results from query
   def results = searchService.search(currentUser, jqlParseResult.query,PagerFilter.getUnlimitedFilter())
   //look through each result, load the issue, get the cf value, create sub-tasks
   results.results.each{indexIssue->
      def filterIssue = issueManager.getIssueObject(indexIssue.id)
    def tempoValidatorValue = filterIssue.getCustomFieldValue(tempoValidatorCf)
if(tempoValidatorValue instanceof ApplicationUser){
//this is the case when the customfield is a single-user-picker
createSubTaskForUser(filterIssue, tempoValidatorValue)
} else {
//for multi-user, we'll create a subtask for each selected users
tempoValidatorValue.each{ApplicationUser user-> createSubTaskForUser(filterIssue,user)}
}
}
}

I added a parameter to the closure that created the sub-task to be able to pass the issue from the JQL currently being processed and then use that issue's summary as part of the new sub-task summary. 

Awesome thanks so much @Peter-Dave Sheehan ! It works well.

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Jira

Announcing the waitlist for Jira Work Management

Hey there Cloud Community members! We’re excited to give you the first glimpse of the new home for business teams on Jira — Jira Work Management. Jira Work Management is the next generation of J...

149 views 3 7
Read article

Community Events

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

Find an event

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

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you