creating custom JQL functions

Hi all, 

Im trying to pal up with jql functions and write a function to catch the issues with inactive users in some single user picker field. In the internet I've found this code, but cannot figure it out how to use it in my case (not reporter / assignee, but any other field. For example, issueFunction in HasInactiveUser('Manager')

Could you please help with this? 

Thank you!

class HasInactiveAssignee extends AbstractScriptedJqlFunction implements JqlQueryFunction{
    @Override
    String getDescription() {
        "Function to show only the inactive users"
    }
 
    @Override
    List<Map> getArguments() {
        [
            [
                "description": "Subquery",
                "optional": false,
            ]
        ]
    }
 
    @Override
    String getFunctionName() {
        "hasInactiveAssignee"
    }
 
    def String subquery
    //@Override
    MessageSet validate(User user, FunctionOperand operand, TerminalClause terminalClause) {
         def messageSet = new MessageSetImpl()
         return messageSet
    }
 
    @Override
    Query getQuery(QueryCreationContext queryCreationContext, FunctionOperand operand, TerminalClause terminalClause) {
         //User user=ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser();
         JiraAuthenticationContext context = ComponentAccessor.getJiraAuthenticationContext();
         ApplicationUser applicationUser = context.getUser();
         def booleanQuery = new BooleanQuery()
         issues = getIssues(operand.args[0], applicationUser)
         issues.each {Issue issue ->
                        try{
                                def active = issue.assignee.isActive()
                                if ( !active )
                                booleanQuery.add(new TermQuery(new Term("issue_id", issue.id as String)), BooleanClause.Occur.SHOULD)
                        }catch(NullPointerException NPE){
                            
                        }
                    }                                 
          
        return booleanQuery
    }
}

1 answer

1 accepted

1 vote
Accepted answer

So, first things first: can you use the built-in InactiveUsers function in ScriptRunner? https://scriptrunner.adaptavist.com/4.3.16/jira/jql-functions.html#_inactiveusers 

If you really want to roll your own JQL function, you'll want to review the documentation on Custom JQL Functions. In short, you'll need to create the directory path com/onresolve/jira/groovy/jql under one of your script roots on your JIRA server's filesystem (of course, your path will use backslashes if your JIRA server is a Windows machine). Take that code and put it in a HasInactiveAssignee.groovy file.

Also, it looks like your code is missing some imports and a package declaration ( package com.onresolve.jira.groovy.jql ) at the top. Make sure to include those, or the script won't work.

Once that's in place, you'll need to rescan for the new JQL function and you should be able to use it, assuming that code is good and you got all the imports added.

Hi Jonny, 

Thank you for your help! We are on an older version now, so I havent seen this function. Need to try smile 

And about custom functions, I have tested this one, it works, but to be honest I'm not a professional in groovy, so cannot find which part of this code can get a custom field, for example as it is in your function 

user in InactiveUsers()

or IssueFunction in inactiveUser(customfield)

maybe there is some "create a function" tutorial for very-very new groovy developers? With explaining 'who is who'

Thanks again! 

package com.onresolve.jira.groovy.jql
 
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.operand.QueryLiteral
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.jql.query.RangeQueryFactory
import com.atlassian.jira.util.MessageSetImpl
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.query.operand.FunctionOperand
import com.atlassian.query.operator.Operator
import org.apache.log4j.Category
import com.atlassian.jira.util.MessageSet
import com.atlassian.crowd.embedded.api.User
import com.atlassian.query.clause.TerminalClause
import com.atlassian.jira.jql.query.QueryCreationContext
import org.apache.lucene.document.NumberTools
import org.apache.lucene.index.Term
import org.apache.lucene.search.Query
import org.apache.lucene.search.TermQuery
import com.onresolve.jira.groovy.jql.AbstractScriptedJqlFunction
import org.apache.lucene.search.BooleanClause
import org.apache.lucene.search.BooleanQuery
import org.apache.lucene.search.Query
import org.apache.lucene.search.TermQuery
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.security.JiraAuthenticationContext;
 
 
 
class HasInactiveAssignee extends AbstractScriptedJqlFunction implements JqlQueryFunction{
    @Override
    String getDescription() {
        "Function to show only the inactive users"
    }
 
    @Override
    List<Map> getArguments() {
        [
            [
                "description": "Subquery",
                "optional": false,
            ]
        ]
    }
 
    @Override
    String getFunctionName() {
        "hasInactiveAssignee"
    }
 
    def String subquery
    //@Override
    MessageSet validate(User user, FunctionOperand operand, TerminalClause terminalClause) {
         def messageSet = new MessageSetImpl()
         return messageSet
    }
 
    @Override
    Query getQuery(QueryCreationContext queryCreationContext, FunctionOperand operand, TerminalClause terminalClause) {
         //User user=ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser();
         JiraAuthenticationContext context = ComponentAccessor.getJiraAuthenticationContext();
         ApplicationUser applicationUser = context.getUser();
         def booleanQuery = new BooleanQuery()
         issues = getIssues(operand.args[0], applicationUser)
         issues.each {Issue issue ->
                        try{
                                def active = issue.assignee.isActive()
                                if ( !active )
                                booleanQuery.add(new TermQuery(new Term("issue_id", issue.id as String)), BooleanClause.Occur.SHOULD)
                        }catch(NullPointerException NPE){
                            
                        }
                    }                                 
          
        return booleanQuery
    }
}

Suggest an answer

Log in or Sign up to answer
Community showcase
Published Nov 29, 2018 in Marketplace Apps

How to set up an incident workflow from the VP of Engineering at Sentry

Hey Atlassian community, I help lead engineering at Sentry, an open-source error-tracking and monitoring tool that integrates with Jira. We started using Jira Software Cloud internally last year, a...

1,443 views 0 8
Read article

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