Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

I need to track expenses in a custom field. I would use Jira's native number-type field, but that allows for more than 2 decimal places, which would not be proper formatting for currency/expense values. I want to ensure the values entered in this field are consistent so I can run some math operations (like summing across a collection of issues) on them using automation. I'm hoping to find a way to use a text custom field and a Behaviour to enforce regex to allow only digits, no commas, and only two decimal places.

I've seen some examples of using regex with a scripted validator on the workflow, but none of them relating exactly to a currency format, plus I want to enforce it even on the Edit screen when there is no transition occurring, so for that reason a workflow validator won't suffice.

I've searched quite a bit for an answer to this assuming that someone else would have tried this exact thing before, but have not found a solution, so I apologize if this is an easy one and I just missed it in my searching :)

I'm not sure why I couldn't find a quick answer on this, but for anyone else who may struggle to figure it out in the future, it is actually simple (once you get the regex syntax correct for the matches() method):

def field = getFieldById(getFieldChanged())

def val = field.getValue() as String

if (!val.matches("[0-9]*|([0-9]*.[0-9]{2})")) {

field.setError("Enter either a whole number or up to 2 decimal places.")

} else {

field.clearError()

}

In my case the custom field is a text type, but I would guess this would work or could be adapted easily for a number-type field.

Hi Jordan.

Thank you so much for posting the answer. I have tried using your script on a number field so it will only accepts integer numbers.

I thought I could modify it like the following but couldn't get it work. Would you have any idea why it won't work?

def field = getFieldById(getFieldChanged())

def val = field.getValue() as String

if (!val.matches("[0-9]*")) {

field.setError("Please enter integer values (i.e. can not be 4.1 etc.) only for Model Version")

} else {

field.clearError()

}

If you try logging the field value after converting to a String you'll quickly discover the problem with this. Jira number fields are stored as Double, and when casting a Double to String, it is represented with a decimal. That is just one problem. If you get a large number (which you may not with something like model version), the converted string will be the scientific notation of the number. I believe I ran into that with numbers in the tens of millions. Basically, you're opening a whole can of worms when you try to regex a number value; what began as a very short script becomes a lot larger.

I did end up implementing this to use a number field for currency and ensure no one enters a number with more than 2 decimal places. You might very well get away with a shortened version of this script if you can reasonably expect users to keep their numbers short. See my finished script below:

def field = getFieldById(getFieldChanged())

def val = field.getValue() as String

// Only run input validation if user enters a value

if (val != null) {

// If user enters a whole number, casting the Double to a String will include a trailing ".O". Remove this before checking.

if (val.matches("[0-9]*.0")) {

def index = val.indexOf(".")

val = val.substring(0,index)

}

// If user enters a large number, the value is represented in scientific notation. Convert this to a String representation of the non-scientific number before checking.

if (val.matches(/[0-9]{1}\.[0-9]*E[0-9]{1,2}/)) {

def index = val.indexOf("E") + 1 // Where is the E?

def exp = val.substring(index, val.length()).asType(int) // Get the trailing exponent value from scientific format

def num = val.substring(0,index - 1) // Get the numerical value preceding the E, example "1.23456789"

def decIndex = num.indexOf(".") // Where is the decimal?

num = num.substring(0, decIndex) + num.substring(decIndex + 1, num.length())

if (exp + 1 >= num.length()) { // Catch large whole numbers ending in one or more 0s

for (def i = 0; i < exp + 1 - num.length(); i++) {

num += "0"

}

val = num

} else { // Value includes a decimal. Put it back in the right place for non-scientific format.

StringBuffer newString = new StringBuffer(num) // Convert to StringBuffer class to make use of insert() method

val = newString.insert(exp + 1, ".").toString() // Put the decimal where it belongs in non-scientific format, based on the exponent.

decIndex = val.indexOf(".") + 1 // Where is the decimal now?

def places = val.length() - decIndex // How many decimal places are represented?

if (places < 2) { // If true, the last non-zero character the user entered was in the tenths place. Add trailing 0s before passing val to the final regex check.

while (places > 0) {

val += "0"

places--

}

}

}

}

// Check if the formatted "val" string is a whole number or no more than 2 decimal places

if (!val.matches("[0-9]*|([0-9]*.[0-9]{1,2})")) {

field.setError("Enter either a whole number or up to 2 decimal places.")

} else {

field.clearError()

}

}

Hope this helps you.

Thank you so much for the answer. I have tried using the script contain digit and one decimal and two decimal only. example 50, 50.5, 50.55 acceptable

but 50.555 not acceptable.

It giving XSRF Security token error while updating the issue.

Could you please help me?

def field = getFieldById(getFieldChanged())

def val = field.getValue() as String

if (!val.matches("[0-9]*(|[0-9]*.[0-9]{2})") && !val.matches("[0-9]*(|[0-9]*.[0-9]{1})") && !val.matches("[0-9]*")) {

field.setError("Enter either a whole number and 1 decimal or up to 2 decimal places.")

} else {

field.clearError()

}

@Jordan Nimlos how to prefix $ in regrex -----

if (!val.matches("[0-9]*(|[0-9]*.[0-9]{2})"))

any help is appreciated

Thanks

I don't see any error and still behavior won't work

This is what am using

def field = getFieldById(getFieldChanged())

def val = field.getValue() as String

if (!val.matches("\$[0-9].[0-9]{2})")) {

field.setError("Amount must be in dollar format.")

} else {

field.clearError()

}

You'll have to be more specific about how it doesn't work. Is your customfield a text field? Is it allowing you to enter strings that don't include the $ dollar sign? Some other problem?

From what you posted it looks like you're only allowing values that begin with a $, include a single digit before the decimal, and two decimal places, i.e. "$9.99" is an acceptable value but "$10.00" is not, nor is "9.99" or "$9".

You also might want to escape the "." because technically an unescaped period matches pretty much any character, so you'd want this instead:

\$[0-9]\.[0-9]{2}

@Jordan Nimlos cant get it to work too.

Text field. Behaviour on field. Mapping applied. What else could be wrong?

- FAQ
- Community Guidelines
- About
- Privacy policy
- Notice at Collection
- Terms of use
- © 2024 Atlassian

You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.