Calculated Fields

Purpose

Hosting

Compatible Tools

Purpose

Hosting

Compatible Tools

Calculated Fields

Use this script to sum the values of number fields on the form and place the result in a destination field.

Server or Data Center

Any scripting tool, such as JMWE, Power Scripts or Scriptrunner, that uses Groovy.

Script

import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.IssueManager import com.atlassian.jira.issue.Issue import com.atlassian.jira.issue.MutableIssue import com.atlassian.jira.bc.issue.properties.IssuePropertyService import com.atlassian.jira.event.type.EventDispatchOption import com.atlassian.jira.user.ApplicationUser import com.atlassian.jira.entity.property.EntityPropertyService import org.apache.commons.lang3.StringUtils ////If used in a transition, comment next line: Issue issue = ComponentAccessor.getIssueManager().getIssueObject("ISSUE-1") String formName = "Form Name" def fieldNames = ["Field One", "Field Two"] def fieldDestination = "Destination Field" ApplicationUser loggedInUser = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser() IssuePropertyService issuePropertyService = ComponentAccessor.getComponentOfType(IssuePropertyService.class) IssueManager issueManager = ComponentAccessor.getIssueManager() Closure getFormIds = { def property, String name -> def slurper = new groovy.json.JsonSlurper() def parsedJson = slurper.parseText(property.value) def ids = [] parsedJson.forms.each(){ form -> String id if(form.name.equals(name)){ id = form.id.toString() } if(id){ ids.add(Long.valueOf(id)) } } return ids } Closure<String> getFieldId = { def property, String fieldName -> def slurper = new groovy.json.JsonSlurper() def parsedJson = slurper.parseText(property.value) for (def question : parsedJson.design.questions){ if(fieldName.equals(question.value.label)){ return question.key.toString() } } } Closure<String> getFieldValue = { def property, String fieldName -> def slurper = new groovy.json.JsonSlurper() def parsedJson = slurper.parseText(property.value) for (def answer : parsedJson.state.answers){ String fieldId = getFieldId(property, fieldName) if(fieldId.equals(answer.key)){ return answer.value.text.toString() } } } def allProperties = issuePropertyService.getProperties(loggedInUser, issue.id) def forms = [] for(def property : allProperties){ if(property.key.equals("proforma.forms")){ forms = getFormIds(property, formName) } } for (def formId : forms){ Double result = 0 for(def property : allProperties){ if(property.key.equals("proforma.forms" + ".i" + formId) && property.value.contains("\"schemaVersion\":8")){ for(def fieldName : fieldNames) { if(getFieldValue(property, fieldName)){ result = result + getFieldValue(property, fieldName).toDouble() } } } } for(def property : allProperties){ if(property.key.equals("proforma.forms" + ".i" + formId) && property.value.contains("\"schemaVersion\":8")){ String toReplace = "\"" + getFieldId(property, fieldDestination) + "\":{\"text\":\"" + getFieldValue(property, fieldDestination) + "\"}" String replacement = "\"" + getFieldId(property, fieldDestination) + "\":{\"text\":\"" + result.toString() + "\"}" if(!toReplace.contains("null")){ EntityPropertyService.SetPropertyValidationResult validationResult = issuePropertyService.validateSetProperty( loggedInUser, issue.id, new EntityPropertyService.PropertyInput(property.value.replace(toReplace, replacement), property.key)) if(validationResult.isValid()){ issuePropertyService.setProperty(loggedInUser, validationResult) } } else { EntityPropertyService.SetPropertyValidationResult validationResult = issuePropertyService.validateSetProperty( loggedInUser, issue.id, new EntityPropertyService.PropertyInput(property.value.replace("\"answers\":{", "\"answers\":{" + replacement + ", "), property.key)) if(validationResult.isValid()){ issuePropertyService.setProperty(loggedInUser, validationResult) } } } } }

Installation instructions

  • If used in a transition:

    • Comment line 12

    • Change formName in line 13 to the name of the form that has all fields used in the script.

    • Change/Add in fieldNames in line 14 the name/label of all number fields you want to use in the calculation; in quotation marks and separated by commas.

    • Change fieldDestination in line 15 to the name/label of the destination field that will receive the final sum of all values.

  • If used in the script console:

    • Change the issue key in line 12 to the key of the issue you want to sum the field values in a form.

    • Change formName in line 13 to the name of the form that has all fields used in the script.

    • Change/Add in fieldNames in line 14 the name/label of all number fields you want to use in the calculation; in quotation marks and separated by commas.

    • Change fieldDestination in line 15 to the name/label of the destination field that will receive the final sum of all values.

Possible use cases

Calculations can be particularly useful when used with financial forms such as purchase orders and expense claims.

Limitations

  • Will override the value in the destination field with the of the calculation of all fields set in the fieldNames variable.

  • All fields used in the calculation must be number fields and must be on the same form, of the same issue.

  • If there is more than one copy of the same form on the issue, the script will execute on each copy of the form.

  • You may need to refresh the issue after running the script.

  • This script will not work if the form is over 32 KB. You can limit the size of your forms by using multiple smaller forms, and by including character/word limits on your text fields.