Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Validator: Check all other issues

Alexander Jancauskas February 12, 2019

Hi there,

I am wondering if there is any way to solve the following problem:

We are using Jira Software to manage the workload in our team. We're not working on actual software, but doing things like data analysis for our customers. We have a lot of different, very specific ticket types and workflows.

Certain analysis tasks require us to use a system residing at our customer's site. This system is built in a way that it uses 4 different "queues" to process our requests. If we now go ahead and put multiple requests in one queue, the system will mix up the results in this queue and we cannot separate the requests in the result set any more, which is necessary for us. Bottom line here is: We can only put one request in one queue at a time. It's a real drag, but we unfortunately can't change this system and its architecture.

Now because we're using Jira, we've added a custom field "Queue" to the issue type that is associated with this kind of task. It is used to track which issue / request is processed in which queue at the moment. The assignee has to choose a value Queue 1-4 and put the Jira-Ticket to status "Running in Queue". After that he starts the request in the customer system in the chosen queue.

What we wanna do now is inhibiting users of choosing a queue (in Jira) that someone else has already chosen to mitigate the risk of clashing requests. Right now we think of programming a Validator for the transition to Status "Running in Queue". We are thinking of a Groovy script via Adaptivist ScriptRunner that checks the value of "Queue" in all other issues in the status "Running in Queue" and inhibits the transition, if this value is already chosen in another ticket.

TL/DR
So our question is: Can we assess the value of the custom field "Queue" in all other issues, that are in status "Running in Queue" at the moment (should be max 4) and inhibit a transition, if the chosen value of "Queue" is already chosen in another issue?

 

I guess it's a rather unusual and complex problem, so thanks a lot for reading through this. Looking forward to your tips and tricks :)

2 answers

2 accepted

3 votes
Answer accepted
Max Foerster - K15t
Community Champion
February 13, 2019

Hi Alexander,

I got through your long post and survived! ;) But your use case is not that complex, so don't worry and let me try to help you with a possible solution. I'm not sure if you already use Scriptrunner or just plan to, because my solution uses our own app Jira Workflow Toolbox to achieve your goal. Shouldn't take you more than ten minutes to set this up.

  1. Add a Validation based on JQL query validator to your transition.
  2. Configure the following JQL query in the validator: status = "Running in Queue" AND Queue = "%{nnnnn}", where "nnnnn" is the field code/number of your custom field "Queue" so the selected value will be incorporated in the JQL search. In my case, it was the {11700}.
  3. Select the "Number of issues returned by the JQL query satisfies a boolean expression" option, so we can validate with "{00058} < 1" that there are no other issues already in that status and queue.
  4. Define a message to show to the user and translate it if necessary. You can integrate the selected value from the field here using field codes as well.

I attached a screenshot of the configuration:

 jwt_validator.png

 I hope this was helpful. If you're not just thinking of a groovy script solution but really want to write one, then I'm sorry for not providing the exact solution but the overall idea can be used in a script as well :)

Best, Max 

Alexander Jancauskas February 13, 2019

Hi Max,

thank you so much for your detailed answer! We're evaluating Add-Ons atm, so we will consider giving Jira Workflow Toolbox a try. We have several other use cases that we are solving with Scriptrunner at the moment, thus we were looking for a solution with a Groovy script. But of course it would be nicer to have everything in a configurable UI. We still have to check how much flexibility we really need in trade-off for easy usability.

I will try your solution tomorrow, thanks again!

Alex

Like Max Foerster - K15t likes this
Max Foerster - K15t
Community Champion
February 13, 2019

Sure thing Alex, if you need additional help, just let me know and have lots of fun evaluating! :)

0 votes
Answer accepted
Marc Minten (EVS)
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 13, 2019

Hi,

Here a solution only using scriptrunner. :-)

Just search the issues in the status "Running in Queue" (it returns a list of issues) : something like

JqlQueryParser jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
SearchProvider searchProvider = ComponentAccessor.getComponent(SearchProvider)
user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def query = jqlQueryParser.parseQuery('Status = "Running in Queue"')
def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())
List<Issue> issues = results.getIssues()

 Next loop over these issues , get their custom field and check if the value in your current issue is already used in one of these issues in the list

Alexander Jancauskas February 13, 2019

Hi Marc,

thanks a lot for your answer and for sharing your knowledge! Seems to be easier than I initially thought. I will give this a try tomorrow and let you know how it worked out.

Alex

Marc Minten (EVS)
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 13, 2019

I think you can still more simplify : if you change the query in something like

Status = "Running in Queue" AND Queue = <the value of the field in the current issue>

then you should only validate the list of returned issues is empty, in case the value was not used yet... :

if (issues.size() > 0) { -> validation goes wrong} 
Like Max Foerster - K15t likes this
Alexander Jancauskas March 1, 2019

Hi Marc,

sorry it took me so long to get back to this, but the flu took me out for some days ;)

But here I am telling you that your solution works fine, I even adapted it to a more advanced one with a ScriptRunner Behaviour, that shows the user only the available queues at every time he tries to edit the issue / make a transaction. We also had the added level of complexity that the user should be able to select multiple Queues at once for a single issue, so we are now working with a custom multi-select field. Here's the code:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.IssueManager

// User and issue manager
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def issueManager = ComponentAccessor.getIssueManager()

// Search pointers and variables
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
def query
def results

// Pointers to the custom field and options managers
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def optionsManager = ComponentAccessor.getOptionsManager()
def selectField = getFieldByName("Queue Test")
def customField = customFieldManager.getCustomFieldObject(selectField.getFieldId())
def config = customField.getRelevantConfig(getIssueContext())
def options = optionsManager.getOptions(config)

// Value list for multi-select field
def valueList = []

// Check use of Queue 1 without the current issue
query = jqlQueryParser.parseQuery('project = XXX AND Status = "Running in Queue" AND Queue IN ("Queue 1") AND key != ' + underlyingIssue.getKey())
results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())
if (results.total == 0) {valueList.add("Queue 1")}

// Check use of Queue 2 without the current issue
query = jqlQueryParser.parseQuery('project = XXX AND Status = "Running in Queue" AND Queue IN ("Queue 2") AND key != ' + underlyingIssue.getKey())
results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())
if (results.total == 0) {valueList.add("Queue 2")}

// Check use of Queue 3 without the current issue
query = jqlQueryParser.parseQuery('project = XXX AND Status = "Running in Queue" AND Queue IN ("Queue 3") AND key != ' + underlyingIssue.getKey())
results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())
if (results.total == 0) {valueList.add("Queue 3")}

// Check use of Queue 4 without the current issue
query = jqlQueryParser.parseQuery('project = XXX AND Status = "Running in Queue" AND Queue IN ("Queue 4") AND key != ' + underlyingIssue.getKey())
results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())
if (results.total == 0) {valueList.add("Queue 4")}


// Show the available Queue options
def optionsMap = options.findAll {it.value in valueList}.collectEntries {[(it.optionId.toString()): it.value]}
selectField.setFieldOptions(optionsMap)

This should make sure that the user is not presented a Queue that he may not be able to use. As a safety net I also double check the availability when saving, given the case that someone else might have chosen one of the available Queues right in that moment.

Thanks again for helping out!

Alex

Marc Minten (EVS)
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 4, 2019

Hi Alex,

Great! Happy it worked!

Marc

Suggest an answer

Log in or Sign up to answer