Hi Guys,
Hoping you can help me on this one. I am looking for a way to basically meet the following
Users try's to create ticket and fills duplicate data into a custom field which already exists in a separate ticket. Jira denies this ticket creation due to the duplicate field info
The existing ticket with that info transitions automatically to a new status.
Hopefully have explained that clearly, have Scriptrunner and JSU as plugins so can probably be achieved using that although im still sharpening my groovy skills
Regards
So it sounds like you are attempting the have the values in that custom field unique across all issues in the project. Is that correct?
What type of field if the custom field?
I see several aspects to this requirement
1) Behaviour
When the user fills in the custom field, create a JQL to search for other tickets matching the input. If nothing is found. All is good. If an issue is retrieved, set an error on the field with a link to the existing issue for the user to click on.
From there, the user might need to manually re-open that ticket.
2) Workflow Validator
Like behaviour, but will report the error only after the user attempts to submit. This will never happen from the UI if the behaviour is also setup, but it will catch anyone trying to use the rest api of some other non-standard ui.
What I would not recommend, is to have either the behaviour or the validator trigger a change in the existing issue. Validations should never trigger transactions elsewhere in the system.
Maybe the user just made a typo or other mistake. They may not really want that other issue to be re-opened.
I can help suggest some groovy script for the behaviour and validator if I'm on the right direction and you confirm the type of field (and searcher) that the custom field is.
Hi Peter,
Yes that’s correct . The field in question is type text field (single line) . From above I think you have the requirements spot on. The link wouldn’t be necessary as these tickets are coming in through an RPA bot. As long as the custom field having duplicate data and a ticket being created is stopped that is sufficient. The only thing I might reiterate is the 2nd point where if that happens the original ticket with the data is then moved to a status in workflow ( this is to highlight it needs to be looked at again hence why another ticket is trying to be logged with the same custom field id. It seems tricky to me but hopefully you could help. Really appreciate this
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Oh and the custom field search template is free text searcher
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
As I said, I think triggering the re-open on the original issue seems like a bad idea. Perhaps the user only made a typo in the custom field and I don't think you should automatically re-open the ticket that matched the typo.
A script like this in a behaviour configuration for your project against the unique field's server-side script should get you close:
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.web.bean.PagerFilter
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
@BaseScript FieldBehaviours fieldBehaviours
def uniqueFieldName = 'Unique Text Field'
def field = getFieldByName(uniqueFieldName)
field.clearError() //remove any prior errors
def inputValue = field.value as String // the value the user just typed
def jql = """project = $issueContext.projectObject.key and "$uniqueFieldName" like "$inputValue" """
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def searchService = ComponentAccessor.getComponent(SearchService)
def parseResult = searchService.parseQuery(currentUser, jql)
assert parseResult.valid , "The JQL ($jql) could not be parsed: $parseResult.errors"
if(searchService.searchCount(currentUser, parseResult.query)){
def issue = searchService.search(currentUser, parseResult.query, PagerFilter.unlimitedFilter).results.first()
def issueUrl = "$baseUrl/browse/$issue.key"
field.setError("""$inputValue has already been used on issue <a href="$issueUrl">$issue.key</a> if more work is needed, access that issue and re-open it.""")
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for that Peter I will give it a try and let you know how it goes . Just on the second part about triggering the transition . The issues in question I would want to transition wouldn’t actually be in a closed status, it would just be transitioning from one open status to another within the workflow . If the issue was indeed closed then it wouldn’t trigger a reopen . I was thinking if the logic was included to only transition if it’s on that open status else don’t run. Would this logic make more sense? I think this doesn’t affect anything then in terms of if some mistakes were made . Hopefully I’m making my point clear if not I can further explain . Really appreciate your help
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I would recommend we simply just adjust the error message based on the status of the found issue:
if(searchService.searchCount(currentUser, parseResult.query)){
def issue = searchService.search(currentUser, parseResult.query, PagerFilter.unlimitedFilter).results.first()
if(issue.resolution){
field.setError("""$inputValue has already been used on a closed issue: <a href="$issueUrl">$issue.key</a> """)
} else {
def issueUrl = "$baseUrl/browse/$issue.key"
field.setError("""$inputValue has already been used on issue <a href="$issueUrl">$issue.key</a>. Open this issue to apply transition X.""")
}
}
Basically, you want to have a clear intention from the users to trigger a transition, any transition. Normally, that's done by clicking a button, either a "submit" button on a form or a transition button on an issue view screen.
Triggering a transition based on typed text in a field is a bad idea.
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.
For the text in a field is its actually a 6 figure ID so for example '235443' so it would be very unlikely a typo would occur there if that makes sense? Would you still advise against that as its really a key requirement for me
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@PD Sheehan If the above isn’t feasible could you add the code to do this which you outlined in your first response ?
“If an issue is retrieved, set an error on the field with a link to the existing issue for the user to click on.”
Thanks
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
That is exactly what the code I provided in my previous comment does.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Peter,
I have placed the first code you gave in the behaviour and added the custom field against it but it is still allowing me to enter duplicate data when creating issue for that field, any possible reason ?
Thanks again
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Can you share a screenshot of the behaviour configuration page?
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Can you review the atlassian-jira.log file for errors at the time that you attempted to update the Claim ID field?
Let's try to output some messages on the field to make it easier.
Replace the script with:
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.web.bean.PagerFilter
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
@BaseScript FieldBehaviours fieldBehaviours
def showDebugMessage = true
def uniqueFieldName = 'Claim Id'
def field = getFieldByName(uniqueFieldName)
field.clearError() //remove any prior errors
def inputValue = field.value as String // the value the user just typed
def jql = """project = $issueContext.projectObject.key and "$uniqueFieldName" like "$inputValue" """
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def searchService = ComponentAccessor.getComponent(SearchService)
def parseResult = searchService.parseQuery(currentUser, jql)
if(!parseResult.valid){
field.setError("The JQL ($jql) could not be parsed: $parseResult.errors")
return
}
if(searchService.searchCount(currentUser, parseResult.query)){
def issue = searchService.search(currentUser, parseResult.query, PagerFilter.unlimitedFilter).results.first()
def issueUrl = "$baseUrl/browse/$issue.key"
if(issue.resolution){
field.setError("""$inputValue has already been used on a closed issue: <a href="$issueUrl">$issue.key</a> """)
} else {
field.setError("""$inputValue has already been used on issue <a href="$issueUrl">$issue.key</a>. Open this issue to apply transition X.""")
}
} else {
showDebugMessage && field.setHelpText("DEBUG: The search using JQL ($jql) returned no results when exececuted as $currentUser.name")
}
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.
Ah!
Sorry, that was my mistake. I've been working with Assets AQL too much lately.
Let's try this:
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.web.bean.PagerFilter
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
@BaseScript FieldBehaviours fieldBehaviours
def showDebugMessage = true
def uniqueFieldName = 'Claim Id'
def field = getFieldByName(uniqueFieldName)
field.clearError() //remove any prior errors
def inputValue = field.value as String // the value the user just typed
def jql = """project = $issueContext.projectObject.key and "$uniqueFieldName" ~ "$inputValue" """
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def searchService = ComponentAccessor.getComponent(SearchService)
def parseResult = searchService.parseQuery(currentUser, jql)
if(!parseResult.valid){
field.setError("The JQL ($jql) could not be parsed: $parseResult.errors")
return
}
if(searchService.searchCount(currentUser, parseResult.query)){
def issue = searchService.search(currentUser, parseResult.query, PagerFilter.unlimitedFilter).results.first()
def issueUrl = "$baseUrl/browse/$issue.key"
if(issue.resolution){
field.setError("""$inputValue has already been used on a closed issue: <a href="$issueUrl">$issue.key</a> """)
} else {
field.setError("""$inputValue has already been used on issue <a href="$issueUrl">$issue.key</a>. Open this issue to apply transition X.""")
}
} else {
showDebugMessage && field.setHelpText("DEBUG: The search using JQL ($jql) returned no results when exececuted as $currentUser.name")
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Amazing ! That’s working , final question , any good resources/websites to share to get to this level of groovy scripting ? Really impressive , thanks again Peter !
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I'm completely self-thought.
But the main resources I use are
1) This site. There are many great examples in various posts.
2) The groovy documentation
3) The jira javadocs (almost everything starts with the component accessor)
4) The scriptrunner documentation
5) The adaptavist library
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
If you only need to run a script during issue creation, you can do that easily by checking to see if there is an "underlyingIssue".
When we are creating an issue, that variable is empty.
So add, near the top:
//if the is an underlying issue, we're not in in a create screen. Nothing to do
if(underlyingIssue) return null
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Peter,
I found one issue with this , when you click edit on an issue with this now it shows this message and gives the link to the same ticket so there is no way to actually edit and close an issue now . Is there anyway to only have this behaviour happen on the create screen ?
Thanks
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.
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.