Hi folks,
I have a tough issue here and need some assistance coming up with a solution.
Background
Jira Software 8.2.0
Adaptavist ScriptRunner 5.5.8.1-jira8
I have an inherited Jira Software instance that I have been slowly working on cleaning up, as it outgrew its original purpose long ago.
One of my projects has a Single Select List custom field named TTS Approver. It contains a text list users that can approve issues in the TTS project. I'm trying to get rid of this Single Select List in favor of a new Single User Picker custom field, which will be much easier to manage. Let's call it newApprover for now.
Creating the newApprover field is easy enough, and I've added it to the relevant screens in my test environment. The problem I face now is replacing the old TTS Approver information in existing issues (both resolved and unresolved) with this new field. I will then remove the old field from the screens and rename newApprover as TTS Approver. I'm looking at about 35,000 issues in this project alone.
Problem
I thought I could use ScriptRunner's built-in script Copy custom field values to simply copy the value from TTS Approver to newApprover, but this does not work with User Picker custom fields.
Does anyone know a way to script this such that the text value in TTS Approver = the name property of the newApprover user field, and thus the correct user will be populated in the field?
I built a code to solve your problem, you can run it trough the "Script Console" page.
It only works if your TTS Approvers contains an "username" instead o the "Full Name"
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.query.Query
CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()
ApplicationUser currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
CustomField cfTTSapprover = customFieldManager.getCustomFieldObject(67890L) //Change with the ID of your "TTS Approver" CustomField
CustomField cfNewApprover = customFieldManager.getCustomFieldObject(12345L) //Change with the ID of your "New Aprrover" CustomField
String filter = "\"cf[${cfTTSapprover.getId().toString()}]\" is not EMPTY"
Query query = ComponentAccessor.getComponent(JqlQueryParser).parseQuery(filter)
SearchResults<Issue> search = ComponentAccessor.getComponent(SearchService).search(currentUser, query, new PagerFilter())
String currentUserName
search?.getResults()?.each {
currentUserName ? ComponentAccessor.getUserManager().getUserByName(it.getCustomFieldValue(cfTTSapprover).toString()) : null
cfNewApprover.updateValue(null, it, new ModifiedValue(it.getCustomFieldValue(cfNewApprover), currentUserName), new DefaultIssueChangeHolder())
ComponentAccessor.getComponent(IssueIndexingService).reIndex(it)
}
PS. If you have the "Full Names" instead the "user names" in the options of your TTS Select List, if you give me the match values I can solve it for you. Example:
TTS Approver Option 1: Michael Thompson (username: mthompson)
Options 2: Second Name(username: sname)
...
...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I'm looking at 43 people with full names listed, but as you listed in your Option 1 item, the username format is first letter/last name (Michael Thompson becomes mthompson). this is true for all entries.
You are awesome Alejandro, thank you for your help!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Here you go, it will pick that pattern and set it in the user picker field. Hope it helps :)
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.query.Query
CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()
ApplicationUser currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
CustomField cfTTSapprover = customFieldManager.getCustomFieldObject(67890L) //Change with the ID of your "TTS Approver" CustomField
CustomField cfNewApprover = customFieldManager.getCustomFieldObject(12345L) //Change with the ID of your "New Aprrover" CustomField
String filter = "\"cf[${cfTTSapprover.getId()}]\" is not EMPTY"
Query query = ComponentAccessor.getComponent(JqlQueryParser).parseQuery(filter)
SearchResults<Issue> search = ComponentAccessor.getComponent(SearchService).search(currentUser, query, new PagerFilter())
Option TTSapprover
String[] split
String userName
String firstNameLetter
String lastName
search?.getResults()?.each {
TTSapprover = it.getCustomFieldValue(cfTTSapprover) as Option
split = TTSapprover.getValue().split(" ")
firstNameLetter = split[0].charAt(0).toLowerCase()
lastName = split[1].toLowerCase()
userName ? ComponentAccessor.getUserManager().getUserByName(firstNameLetter + lastName) : null
cfNewApprover.updateValue(null, it, new ModifiedValue(it.getCustomFieldValue(cfNewApprover), userName), new DefaultIssueChangeHolder())
ComponentAccessor.getComponent(IssueIndexingService).reIndex(it)
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You are amazing Alejandro, thank you so much!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey Michael,
You might could export as CSV, update the values to match user names and then reimport.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks John. I had thought of that, but exporting and importing over 35,000 records will likely kill my server, if I can even get Jira to handle that high a number.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Yeah, you would probably have to do that 1,000 at a time. So, I guess it becomes, which one is faster - or less painful :-(
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.