ScriptRunner: Prevent Edit Issue Screen from accepting the user input based on specified conditions

Deleted user August 11, 2017

Hey everyone

I currently have a behaviour which sets the assignee as required on the Create Issue Screen if a certain issue security has been selected. In addition to that, a workflow validator prevents the user from creating the issue if an assignee has not been set.

The behaviour works on the Edit Issue Screen as well. Since this action is not part of a workflow however, the user could set the appropriate issue security, leave the assignee on unassigned and it would be accepted like that. The problem now is, the team of assignable users is then unable to view the issue.

I then tried to create a custom listener for the Issue Updated event and display a error message if that would be the case. Since this listener gets activated AFTER the issue has been updated, it only displays the message but does not prevent the faulty input.

Any ideas on how I could achieve my desired behaviour?

Thanks and BR

Marius

1 answer

0 votes
Jenna Davis
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.
August 11, 2017

Hello, 

Just so I'm understanding the problem, you have a behaviour that makes the assignee field required if a certain security field is set. I'm not really seeing why you need a validator/listener if the field is getting set to required, the issue should not be allowed to be Created/Edited if you have a required field left blank.

If I'm understanding the problem incorrectly, please let me know. I think you might be able to find simple solution for this though. 

Could you please send me your behaviour's code and tell me how you're setting the behaviour up?

Regards,

Jenna

Deleted user August 14, 2017

Hi Jenna,

Here's my behaviour code.

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
 
@BaseScript FieldBehaviours fieldBehaviours
def childField = getFieldById("assignee")
def parentField = getFieldById(getFieldChanged())
def selectedOption = parentField.getValue()
 
/*import org.apache.log4j.Level
log.setLevel(Level.DEBUG)
log.debug("--------------------This is to test Behaviours Logging----------------")*/

def issueSecurityLevelManager = ComponentAccessor.getIssueSecurityLevelManager()
 
def level = issueSecurityLevelManager.getIssueSecurityLevelsByName("Autor, Bearbeiter & Beobachter")
 
if (selectedOption && level) {
    if(selectedOption == level[0].id?.toString())
    {
        childField.setRequired(true)
    }
    else
    {
        childField.setRequired(false)
    }
}

Yes, you understood it correctly. I think the problem is, that the assignee field is never truly empty. It's either set to a specific user, unassigned or automatic. This is why I needed a workflow validator. See below.

if (issue.getSecurityLevelId() == 10305 || issue.getSecurityLevelId() == 10308)
{
    return issue.assignee != null
}

else
{
    return true
}

grafik.png

The behaviour is set to all projects and all issue types.

grafik.png

Thanks for your help and best regards.

Marius

Jenna Davis
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.
August 14, 2017

You can check for an 'empty' or null assignee field using something like this in your behaviour:

if (!childField.value) {
childField.setError("You must set an assignee.")
}

Checking for automatic is a bit more complicated. Do you have your issues set to automatically assign to someone? Or do they remain unassigned upon creation?

Jenna Davis
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.
August 14, 2017

You could add a simple scripted validator that simply checks for a null assignee as such:

issue.assignee != null

If the issue is set to "unassigned" automatically. 

Like Benjamin Horst likes this
Deleted user August 17, 2017

Hey Jenna,

Your first solution almost works! However, even with an assignee set, I cannot update the issue anymore.

I've also just now noticed that the behaviour works with only one project even though the mapping is set to all projects and all issue types.

I've reassured and the security level is named the same in every project which is what I'm refering to in my behaviour: Autor, Bearbeiter & Beobachter

BR

Marius

Jenna Davis
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.
August 17, 2017

Did you have any success with the second solution I gave when used alongside a behaviour? I think that may be the trick. I will continue to work on this and see if I can find a better solution for you in the meantime.

The mapping problem is odd. Do you have any other behaviours acting on these fields that might be throwing something off? 

Jenna

Deleted user August 21, 2017

No, not yet. Would this have to be a workflow validator? Because editing an issue is not a workflow action in our instance.

We have one other behaviour active on the assignee field but it's only linked to one specific project and one issue type in that project.

I removed and re-created the behaviour and even restarted the server but no luck :(

Jenna Davis
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.
August 23, 2017

Sorry for my late reply on this!

Yes, it would need to be a workflow validator. The behaviour should catch any changes made while editing the issue. I 'think' the behaviour I added below should catch all of the problems without using a validator though, but if I'm missing something you may need to add that validator in

I've tested the out pretty thoroughly just to make sure it works properly and believe it should work for you. Please let me know if I missed something or you need more help on it. :)

def assignee = getFieldById("assignee")
def user = assignee.getValue()

assignee.setRequired(true)

if((user as String == '-1') || !user){
assignee.setError("You must add an assignee.")
}
else { assignee.clearError() }

 It should catch both Unassigned and Automatic assignments and make the field required. You'll need to add it on the 'Assignee' field. 

Please do let me know if this is still giving you trouble. :)

Jenna

Deleted user August 24, 2017

No problem :) It works now! Just for the record, I had to use two behaviours. One mapped to the field security level and one mapped to the assignee field.

Security Field:

import com.atlassian.jira.component.ComponentAccessor

def assignee = getFieldById("assignee")
def user = assignee.getValue()
def issueSecurity = getFieldById(getFieldChanged())
def selectedLevel = issueSecurity.getValue()
 
/*import org.apache.log4j.Level
log.setLevel(Level.DEBUG)
log.debug("--------------------This is to test Behaviours Logging----------------")*/

def issueSecurityLevelManager = ComponentAccessor.getIssueSecurityLevelManager()
 
def level = issueSecurityLevelManager.getIssueSecurityLevelsByName("Autor, Bearbeiter & Beobachter")
 
if (selectedLevel && level)
{
    if(selectedLevel == level[0].id?.toString())
    {
        assignee.setRequired(true)

        if((user as String == '-1') || !user)
        {
            assignee.setError("Für diese Sicherheitsstufe müssen Sie zwingend einen Bearbeiter angeben.")
        }
        
        else
        {
            assignee.clearError()
        }
    }

    else
    {
        assignee.setRequired(false)

        assignee.clearError()
    }
}

Assignee Field

import com.atlassian.jira.component.ComponentAccessor

def assignee = getFieldById(getFieldChanged())
def user = assignee.getValue()
def issueSecurity = getFieldById("security")
def selectedLevel = issueSecurity.getValue()
 
/*import org.apache.log4j.Level
log.setLevel(Level.DEBUG)
log.debug("--------------------This is to test Behaviours Logging----------------")*/

def issueSecurityLevelManager = ComponentAccessor.getIssueSecurityLevelManager()
 
def level = issueSecurityLevelManager.getIssueSecurityLevelsByName("Autor, Bearbeiter & Beobachter")
 
if((user as String == '-1') || !user)
{
    if(selectedLevel && level)
    {
        if(selectedLevel == level[0].id?.toString())
        {
            assignee.setRequired(true)
            
            assignee.setError("Für diese Sicherheitsstufe müssen Sie zwingend einen Bearbeiter angeben.")
        }
        
        else
        {
            assignee.setRequired(false)
            
            assignee.clearError()
        }
    }

    else
    {
        assignee.setRequired(false)

        assignee.clearError()
    }
}

Reason:

I created an issue with our restricted security level that requires an assignee. I assigned the issue to me on creation. After that, I was able to successfully edit the issue and set the assignee to unassigned. Since I did not change the security level, the behaviour did not get triggered and thus did not prevent the update action. This is why a second behaviour on the assignee field is necessary.

Now it should be impossible to bypass this requirement :) Thanks for your help!

The only issue that remains now is that it only works for one project :/ Even with explicit mapping to another project and issue type, it does not get executed when creating such an issue..

grafik.png

Working Project:

grafik.png

Not working project:

grafik.png

I know that even with the same name, these security levels have different IDs. But since I'm using "getIssueSecurityLevelsByName", I thought that wouldn't matter.

I debugged the script and noticed that this line

def level = issueSecurityLevelManager.getIssueSecurityLevelsByName("Autor, Bearbeiter & Beobachter")

gets the security level ID of the working project instead of the project in which the issue is about to be created.

Log:

[c.o.j.groovy.user.FieldBehaviours] --------------------This is to test Behaviours Logging----------------
[c.o.j.groovy.user.FieldBehaviours] 10801 -> Form initialized / ID of default security level
[c.o.j.groovy.user.FieldBehaviours] 10305 -> Form initialized / ID of the restricted security level from the wrong project
[c.o.j.groovy.user.FieldBehaviours] --------------------This is to test Behaviours Logging----------------
[c.o.j.groovy.user.FieldBehaviours] 10504 -> Security level changed to "Autor, Bearbeiter & Beobachter"
[c.o.j.groovy.user.FieldBehaviours] 10305 -> ID of the restricted security level from the wrong project

Any ideas why it's not getting the ID of the project in context?

Jenna Davis
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.
August 28, 2017

Hmm, I'm not sure why that's happening. Do you think you could submit a support request for that over on the support site? It's possible that it's a bug or another issue occuring in your instance.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events