I am trying to recalculate the average value whenever one of the numbers change. I believe this is possible using behaviors for each value, but there will be hundreds of such fields. As an example, I have attempted to put together this behavior in a Scriptrunner 6.20.0 custom scripted field:
-----
import com.atlassian.jira.component.ComponentAccessor
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def M1_nacc = customFieldManager.getCustomFieldObjectsByName("mon.M1.nacc")
def M1_conf = customFieldManager.getCustomFieldObjectsByName("mon.M1.conf")
def M2_nacc = customFieldManager.getCustomFieldObjectsByName("mon.M2.nacc")
def M2_conf = customFieldManager.getCustomFieldObjectsByName("mon.M2.conf")
def M3_nacc = customFieldManager.getCustomFieldObjectsByName("mon.M3.nacc")
def M3_conf = customFieldManager.getCustomFieldObjectsByName("mon.M3.conf")
static float metric_score (nacc, conf) {
if (nacc == "Unacceptable") { return 4.0 as float }
if (conf == "High") { return 1.0 as float }
if (conf == "Medium") { return 2.0 as float }
return 3.0 as float
}
def conf = 0
def acc = 0
if (M1_nacc != "N/A") { acc += 1; conf += metric_score (M1_nacc, M1_conf) }
if (M2_nacc != "N/A") { acc += 1; conf += metric_score (M2_nacc, M2_conf) }
if (M3_nacc != "N/A") { acc += 1; conf += metric_score (M3_nacc, M3_conf) }
if (acc == 0) return 0
return (conf / acc)
----
Here, the *_nacc field controls whether the *_conf field is calculated. if:
*_nacc = "N/A" --> ignore in calculation of average
*_nacc = "Unacceptable" --> value returned is 4
*_nacc = "Acceptable" --> use conf field value for average value calculation
The above script is simplistic, but it does calculate the appropriate value *the first time*. Any changes that occur later do not affect the returned value. What I would like to do is to capture each change to the nacc and conf values to modify the average value.
In the worst case scenario, this could be done on transition, but I would like to avoid that path.
Thanks!
To implement this as a behaviour, you would want to assign the same behaviour script to each field. That might be tedious, but by using a script file and pointing each field to the same file, at least you would have a central place to maintain the file.
Here is my attempt at reverse engineer your logic a best as I understood in a way that should be relatively easy to expand and adjust
def fieldPrefix = 'mon'
def fieldIdList = ['M1','M2','M3'] //add as many fields as you need
def confScoreMap = [High:1F, Medium: 2F]
def naccScoreMap = ['Unacceptable':4F, 'Acceptable':3F] //used for default values
def scores =[]
fieldIdList.each{
def naccField = getFieldByName("${fieldPrefix}.${it}.nacc")
def confField = getFieldByName("${fieldPrefix}.${it}.conf")
def nacc = naccField.value
def conf = confField.value
switch(nacc){
case 'Unacceptable':
scores << naccScoreMap[nacc]
break
case 'Acceptable':
scores << confScoreMap[conf] ?: naccScoreMap[nacc] //default to 3 if value not found in map
break
}
}
def total = scores.sum() as Float
def average = total/scores.size()
getFieldByName('average result field').setReadOnly(true).setFormValue(average)
This is a great reverse engineer! Though it may be slightly tedious to add the behavior to all .nacc and .conf fields, it us much less tedious than cluttering the behaviors in scriptrunner with > 150 specific behaviors.
Thanks!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.