User input money value in grails - grails

I need to get a money value from the user, but the user can type the number in different formats:
1.234.234,78
1234566,26
123,123,132.12
I don't know how to treat the variable.
I have to transform that value in Double type but if the user give me a value with "," the program generate an exception, how can I handle this?

If you want to handle money then I recommend you a great grails plugin with many feature for currencies handling and conversions etc.
Have a look at Currency plugin.

In your domain static constraints use matches with the regular expression that handles currency format.
Then using java.text.NumberFormat allows you to format double regardless of having comma in the input.

Related

Different date format and one locale

I use I18n.t('date.formats.default') for date formatting.
The issue is that in different countries there are different date formats, but one english locale.
For example '%m.%d.%Y' fo US and '%d.%m.%Y' for Australia
I need the ideas how to handle with it.
While you might simply use something else for date formats, the easiest drop-in solution would be to store all possible variants in the same string and on retrieval do (assuming the country code is known):
'date.formats.default': 'US[%m.%d.%Y],AU[%d.%m.%Y]'
code = 'AU'
format = I18n.t('date.formats.default')
format[/(?<=#{code}\[).*?(?=\])/] || format
#⇒ "%d.%m.%Y"
The latter || format is needed to support normal format, without brackets.
If you don’t like regular expressions, store the JSON there, containing hash {CODE => FORMAT}, parse it and retrieve the value.
I think it is more convenient way to use different locales.
For example en-AU.yml, en-US.yml, en-CA.yml etc.? Especially i18n supports this.
Australia has different time format too.
Every time you have to take into account all these nuances for each country.
Using different locales simplifies this.

Bean Validation Min/Max wrong message

I'm using Min/Max Beanvalidation. Here is an example:
#Min(value = 100, message="too low")
#Max(value = 1000, message="too high")
private Integer example;
If i enter 99 i get the correct message "too low". If i enter 1001 i also get the correct message "too high". If i enter a very high number e.g. 10000000000 i get a generic message which i found out is this one: javax.faces.converter.BigIntegerConverter.BIGINTEGER={2}. So i suspect that if the user enters a number which is larger then the actual field type, he will get another message.
This is actually not what i want to achieve. I always want to show the user "too high". Is there a way to achieve this?
There are really two things going on, conversion and validation. In a first step JSF needs to take your string input and convert it to a number. This is where you get the error. Your value cannot be converted to an Integer. If conversions works, JSF populates your model and that's where validation kicks in. If validation then fails you get the defined Bean Validation messages. So what can you do:
Configure the JSF message for javax.faces.converter.BigIntegerConverter.BIGINTEGER={2} to be more descriptive
Change the datatype, for example use BigInteger. In this case the conversion from string to number will work
Use string in the bean and validate the string. You probably need then to convert to a number at a different point though, but that depends on you use case.
The maximum for Integer in java is 2^31 which is just over 2.1 billion. The input you used, 10 billion, is then beyond the maximum of an integer and would overflow the field, so it is not a valid given the field type, regardless of any validation you may have in place. you could switch the field type to be a BigInteger, then override the default validation messages to fit your needs, but that may be overkill given the purpose of your question. You can also have custom messages
Why not just limit the amount of characters in the inputfield in the frontend, for example
<h:inputText maxlength="4"/>
I'd guess it's possible to bypass if you really want, but I would'nt worry too much about the usability for someone hacking the site :-)

Properly formatting currency values based only on ISO4217 currency code?

I am using a web API that returns values like this:
{
"CNY": 42.0,
"DKK": 31337.00,
"EUR": 6789.01,
"GBP": 6502.00,
"USD": 12345.67,
...
}
I would like to format these values as proper currency values (e.g. for USD, "$12,345.67," for EUR, "6789.01€", for GBP, "£6502.00", for DKK, "31337.00 DKK", etc.) In other words, using the proper symbol ($, £, etc.), but also for some currencies, the symbol comes before the amount whereas for others, it comes after the amount, etc.
The catch is the API I am using only returns ISO4217 country codes ("USD," "EUR," "CNY," etc.) instead of locales. I know NSNumberFormatter has an NSNumberFormatterCurrencyStyle which looks like it does the proper formatting, but apparently the only way you can tell it what type of currency you're dealing with is by handing an NSLocale to its setLocale.
Is there any way to convert from ISO4217 currency codes to locales, other than hardcoding a ISO4217->locale conversion table in my code (which, granted, might work ok since ISO4217->locale mappings probably don't change very often??) Still, I would prefer a way of doing this programmatically if possible.
Of course you cannot map currency codes to locales - with the Euro this just must fail because there are probably 50 locales using Euro.
What you need to do is display the currency according to the locale of the user. Users in Germany, Britain, USA, can all display Euros, for example, and do it in different ways. Each locale can display all currencies.

floating point precision in ruby on rails model validations

I am trying to validate a dollar amount using a regex:
^[0-9]+\.[0-9]{2}$
This works fine, but whenever a user submits the form and the dollar amount ends in 0(zero), ruby(or rails?) chops the 0 off.
So 500.00 turns into 500.0 thus failing the regex validation.
Is there any way to make ruby/rails keep the format entered by the user, regardless of trailing zeros?
I presume your dollar amount is of decimal type. So, any value user enters in the field is being cast from string to appropriate type before saving to the database. Validation applies to the values already converted to numeric types, so regex is not really a suitable validation filter in your case.
You have couple of possibilities to solve this, though:
Use validates_numericality_of. That way you leave the conversion completely to Rails, and just check whether the amount is within a given range.
Use validate_each method and code your validation logic yourself (e.g. check whether the value has more than 2 decimal digits).
Validate the attribute before it's been typecasted:
This is especially useful in
validation situations where the user
might supply a string for an integer
field and you want to display the
original string back in an error
message. Accessing the attribute
normally would typecast the string to
0, which isn‘t what you want.
So, in your case, you should be able to use:
validates_format_of :amount_before_type_cast, :with => /^[0-9]+\.[0-9]{2}$/, :message => "must contain dollars and cents, seperated by a period"
Note, however, that users might find it tedious to follow your rigid entry rules (I would really prefer being able to type 500 instead 500.00, for example), and that in some locales period is not a decimal separator (if you ever plan to internationalize your app).
In general if you wish to “remember” the decimal precision of a floating point value, you should use a decimal type, not a binary float.
On the other hand, I'm not certain why you would wish to force the string representation in such a strict manner… How about accepting any number and formatting it with e.g. number_to_currency?
Usually with money it's best to store it as an integer in cents (500 cents is $5.00). I use the Money gem to handle this.

.NET Currency exponent ISO_4217

I'm developing something for international use. Wondering if anyone can shed any light on whether the CultureInfo class has support for finding currency exponents for particular countries, or whether I need to feed this data in at the database level.
I can't see any property that represents this at the minute, so if anyone knows definitively if it exists, before I look for it / buy it from ISO.
Currency Exponent is the minor units of the currency.
http://en.wikipedia.org/wiki/ISO_4217 - e.g. UK is "2"
Take a look at this blog post on getting CultureInfo for a region. Basically, Window and .NET know about the user's region but not their currency. A region implies a currency, but a country can have more than currency. For example, a person in Cambodia would more than likely want to enter and use USD than Riel. If possible, when capturing any currency amount in a multi-currency system you should capture the currency ISO code.
If you just want to make a quick guess, you can create a CultureInfo object and use it's NumberDecimalDigits property. The also creates a problem when countries switch currencies. For example, if Belarus joins the EU, then it's currency would change from BYR to EUR. It's currency symbol and exponent will be out of date.
I looked at this question and provided a solution which may or may not meet your needs here: http://www.codeproject.com/KB/recipes/MoneyTypeForCLR.aspx#CurrencyType
The short of it: I implemented the ISO spec as a custom type using the spec itself to generate the values. Obviously this would need to be regularly updated in production...

Resources