Hi all,
I am writing a ScriptRunner listener in Jira to catch when a couple of issue fields are cleared by the user. I have the listener firing on an Issue Update event. If the value of the fields change to another valid value, the listener is being invoked. However, if the value of the field is cleared and is now null and the field gets deleted from the issue, the listener is not invoked. What event do I have to catch in order to be invoked when those fields are cleared and the attribute gets deleted from the issue? I am assuming that the CustomFieldDeletedEvent is looking strictly at custom fields, not at issues.
Also, for the two fields I am interested in (Epic Link and Portfolio's Parent Link), I don't seem to be getting invoked at all on some occassions, yet I do on others (without changing any additional fields on the issue - I only change Epic Link or Parent Link).
Thanks,
Greg
Hi Suzanne,
A scripted validator seems to be the solution here. But before you begin make sure that:
1) You have a screen attached to your "Resolve issue" transition.
2) That screen has your Start Time, End Time, and Root Cause Owner fields in it.
Next, create a scripted validator using the below code and add it to your "Resolve issue" transition. I'm going to assume that you know how to look up your custom field IDs because you'll need them for the code:
import com.atlassian.jira.component.ComponentAccessor
import com.opensymphony.workflow.InvalidInputException
def cfMgr = ComponentAccessor.getCustomFieldManager()
def projectKey = issue.getProjectObject().getKey()
def priority = issue.getPriority().getName()
def p2Alert = issue.getCustomFieldValue(cfMgr.getCustomFieldObject(11111 as Long)) as String //field id in parenthesis
def startTime = cfMgr.getCustomFieldObject(22222 as Long)
def endTime = cfMgr.getCustomFieldObject(33333 as Long)
def rootCauseOwner = cfMgr.getCustomFieldObject(44444 as Long)
def reqFieldsList = new ArrayList()
reqFieldsList.addAll(startTime, endTime, rootCauseOwner)
if ((projectKey == "ITIM" && (priority == "0 - (P1) Emergency" || priority == "1 - (P2) Critical")) || p2Alert == "Yes"){
for (int i = 0; i < reqFieldsList.size(); i++){
if (issue.getCustomFieldValue(reqFieldsList[i]) == null){
throw new InvalidInputException("'Start Time', 'End Time' and 'Root Cause Owner' are required!")
}
}
}
Hi Ivan, thank you! I do know how to look up the custom field IDs. I'll give it a shot and let you know how it works. Thanks!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I suppose a more flexible solution would be to run a JQL search inside your script and then check the current issue against the results.
Please note that if you want to use quotes ("") inside a String definition, make sure that you place a backslash (\) before them, like so:
String sampleString = "project = ITIM AND priority in (\"0 - (P1) Emergency\", \"1 - (P2) Critical\") OR \"P2 Alert\" = Yes"
import com.atlassian.jira.component.ComponentAccessor
import com.opensymphony.workflow.InvalidInputException
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def jqlQuery = jqlQueryParser.parseQuery("project = ITIM AND priority in (\"0 - (P1) Emergency\", \"1 - (P2) Critical\") OR \"P2 Alert\" = Yes")
def resultIssues = searchProvider.search(jqlQuery, currentUser, PagerFilter.getUnlimitedFilter()).getIssues()
for (int i; i < resultIssues.size(); i++){
if (issue.getKey() == resultIssues[i].getKey()){
def cfMgr = ComponentAccessor.getCustomFieldManager()
def startTime = cfMgr.getCustomFieldObject(22222 as Long)
def endTime = cfMgr.getCustomFieldObject(33333 as Long)
def rootCauseOwner = cfMgr.getCustomFieldObject(44444 as Long)
def reqFieldsList = new ArrayList()
reqFieldsList.addAll(startTime, endTime, rootCauseOwner)
for(int v; v < reqFieldsList.size(); v++){
if (issue.getCustomFieldValue(reqFieldsList[v]) == null){
throw new InvalidInputException("'Start Time', 'End Time' and 'Root Cause Owner' are required!")
}
}
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Ivan, I was finally able to try this today and I got the following error. Any ideas?
Script33.groovy:24 [Static type checking] - Cannot find matching method com.atlassian.jira.issue.Issue#getCustomFieldValue(E). Please check if the declared type is right and if the method exists. @ line 24, column 11.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
This is odd, it should work as is. But ok, let's change something.
Try this:
import com.atlassian.jira.component.ComponentAccessor
import com.opensymphony.workflow.InvalidInputException
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.fields.CustomField
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def jqlQuery = jqlQueryParser.parseQuery("project = ITIM AND priority in (\"0 - (P1) Emergency\", \"1 - (P2) Critical\") OR \"P2 Alert\" = Yes")
def resultIssues = searchProvider.search(jqlQuery, currentUser, PagerFilter.getUnlimitedFilter()).getIssues()
for (int i = 0; i < resultIssues.size(); i++){
if (issue.getKey() == resultIssues[i].getKey()){
def cfMgr = ComponentAccessor.getCustomFieldManager()
def startTime = cfMgr.getCustomFieldObject(22222 as Long)
def endTime = cfMgr.getCustomFieldObject(33333 as Long)
def rootCauseOwner = cfMgr.getCustomFieldObject(44444 as Long)
def reqFieldsList = new ArrayList()
reqFieldsList.addAll(startTime, endTime, rootCauseOwner)
for(int v = 0; v < reqFieldsList.size(); v++){
if (issue.getCustomFieldValue(reqFieldsList[v] as CustomField) == null){
throw new InvalidInputException("'Start Time', 'End Time' and 'Root Cause Owner' are required!")
}
}
}
}
Incidentally, what version of Jira are you using?
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.
Hi Suzanne,
Glad I could help.
A piece of advice if I may. For performance sake you might want to add a resolution check to your JQL to make the list of returned issues as short as possible so that the script doesn't go through a ton of issues while checking the current issue against them.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Ah, that makes perfect sense. Okay, I'll figure out how to do that on Monday. We are still just testing this in our testing instance. Thanks again!
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.