Calculated field on transition screen using Behaviours plugin

mark richardson July 10, 2013

Hi,

I wonder if I could get some help with this problem.

(I'm a C++ developer by trade so apologies in advance if my script code isn't the best.)

I've used the script runner plugin to create a custom scripted field to calculate a 'Fix urgency' field from three other fields as follows:

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.MutableIssue
import org.apache.log4j.Category

ComponentManager compManager = ComponentManager.getInstance()
CustomFieldManager cfm = compManager.getCustomfieldManager()

CustomField cfFreq = cfm.getCustomfieldObjects(issue).find{ it.name == "Frequency" }
CustomField cfPrev = cfm.getCustomfieldObjects(issue).find{ it.name == "Prevalance" }
CustomField cfSev = cfm.getCustomfieldObjects(issue).find{ it.name == "Severity" }

frqVal =  issue.getCustomeFieldValue(cfFreq).toString()
prevVal = issue.getCustomeFieldValue(cfPrev).toString() 
sevVal =  issue.getCustomeFieldValue(cfSev).toString()

def urgencyResult = GetUrgency(frqVal, prevVal, sevVal)

def GetUrgency(fre, prev, sev)
{
	def urgency = [ 3:"Urgent(Hotfix)", 2:"Medium(Service Pack)", 1:"Low(Next Release)" ]
        def frequency = [ Rare:1, Occasional:2, Often:3 ]
        def prevalence = [ Few:1, Some:2, Most:3 ]
        def severity = [ Cosmetic:1, Inconvenience:2, LossOfFunction:3, Catastrophic:4 ]
        def calcVal = frequency[fre] * prevalance[prev] * severity[sev]
        def lookup = 1
        if (calcVal < 6) { lookup = 1 }
        else if (calcVal > 22) { lookup = 3 }
        else { lookup = 2 }
        return urgency[ lookup ]
}

return urgencyResult == null ? "Undefined or Legacy issue" : urgencyResult

This works great in a normal screen (ie after a transition) but the original idea is that in a transition screen the 3 source fields (Frequency, Prevalance and Severity) are set which causes the 'Urgency' field to be calculated. This field then provides information (still in the transition screen) to enable the user to select a target release for the fix.

From what I could discover using google the behaviours plugin should do the job as I want it, but I don't know how to modify the above script so that it references fields on the same transition screen. Is this even possible?

It would also be great if the calculated 'Urgency' was persisted so it could be viewed in the issue afterwards.

I'd be really, really grateful for any assistance with this.

Thanks in advance.

Mark

1 answer

1 accepted

1 vote
Answer accepted
JamieA
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.
July 10, 2013

It sounds like you want one or the other of script runner or behaviours plugin, not both.

If you want to see the field in the form as it's being edited, with real time updates, use behaviours, or write your own javascript. But the code above needs to be rewritten. Eg:

def cfFreq = getFieldByName("Frequency")

// cfFreq.getValue()... has the value

You should also set the fix urgency read-only in your behaviours script.

If you do this it's persisted. But I don't really understand why you want it persisted, you can query on a calculated field. By persisting you just unnecessarily use a row in the db.

You might want to try this script here: https://jamieechlin.atlassian.net/wiki/display/GRV/Scripted+Fields#ScriptedFields-DisplayingScriptedFieldsinTransitionScreens - which allows a calcalated field to be put on a transition screen. To make it update in real time you would need to adjust it somewhat.

mark richardson July 10, 2013

Hi,

Thanks for your helpful response (and for a great couple of plugins).

So I have my three fields (Frequency, Prevalance and Severity) and an urgency field on a transition screen. Ive set up a validation script on the Frequency as follows (which may be a bit long winded at the moment):

FormField formFreq = getFieldById(getFieldChanged())
FormField formPrev = getFieldByName("Prevalance")
FormField formSev = getFieldByName("Severity")
FormField formUrg = getFieldByName("Urgency2")

String strFreq = formFreq.getValue()
String strPrev = formPrev.getValue()
String strSev = formSev.getValue()

def urgencyResult = GetUrgency(strFreq, strPrev, strSev)

def GetUrgency(fre, prev, sev)
{
  def urgency = [ 4:"Undefined or Legacy issue", 3:"Urgent(Hotfix)", 2:"Medium(Service Pack)", 1:"Low(Next Release)" ]
        def frequency = [ Rare:1, Occasional:2, Often:3 ]
        def prevalance = [ Few:1, Some:2, Most:3 ]
        def severity = [ Cosmetic:1, Inconvenience:2, LossOfFunction:3, Catastrophic:4 ]
        def calcVal = (fre && prev && sev) ? frequency[fre] * prevalance[prev] * severity[sev] : 0
        def lookup = 1
        if (calcVal < 1) { lookup = 4 }
        else if (calcVal < 6) { lookup = 1 }
        else if (calcVal > 22) { lookup = 3 }
        else { lookup = 2 }
        return calcVal + urgency[ lookup ]
}

formUrg.setFormValue(urgencyResult)

This works fine when I change the 'Frequency' field but I now want to add the behaviour to 'Prevalance' and 'Severity' so should I be adding the validation script to all three fields inside the same behaviour or a separate behaviour for each field with the same script(with different getFieldByName calls)?

I've tried both and I must be doing something wrong because only my 'Frequency' field selection seems to make any difference.

Thanks again for your help.

JamieA
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.
July 10, 2013

Hi...

Remove the getFieldChanged(), and get the field by name as with the other ones.

Put the script in a file.

Attach the same validator (all using the same file) to all three fields whose value is considered when creating your calculated value.

mark richardson July 11, 2013

Hi,

Thanks again for your help. I'm feeling pretty stupid here because I still have a problem.

I keep getting this error : Compilation failure: startup failed: /opt/atlassian/jira/atlassian-jira/WEB-INF/classes/urgencyscript.groovy: 2: unable to resolve class FormField @ line 2, column 12. FormField formFreq = getFieldByName("Frequency") ^ /opt/atlassian/jira/atlassian-jira/WEB-INF/classes/urgencyscript.groovy:

I imagine I need to import a library or have the script in some specific location so the required library can be found?

JamieA
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.
July 11, 2013

It might be easiest to change your package to: com.onresolve.jira.groovy.user

Otherwise, try importing:

import com.onresolve.jira.groovy.user.FormField

I don't think you will need any other imports.

IIRC when you use a script it defaults to that package... can't check the code right at this minute.

Suggest an answer

Log in or Sign up to answer