From: Go MAEDA Date: Thu, 4 Jan 2024 06:55:14 +0000 (+0000) Subject: Support localized decimal separators for float values (#22024). X-Git-Tag: 6.0.0~524 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1ab44859feac685719b1f8f4023fec6f89b78e08;p=redmine.git Support localized decimal separators for float values (#22024). Patch by Liane Hampe (@liane_hampe). git-svn-id: https://svn.redmine.org/redmine/trunk@22592 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index ac7cc3c50..dcf1da35b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -266,7 +266,7 @@ module ApplicationHelper when Integer object.to_s when Float - sprintf "%.2f", object + number_with_delimiter(sprintf('%.2f', object), delimiter: nil) when User, Group html ? link_to_principal(object) : object.to_s when Project diff --git a/lib/redmine/field_format.rb b/lib/redmine/field_format.rb index a27311141..5e81055f1 100644 --- a/lib/redmine/field_format.rb +++ b/lib/redmine/field_format.rb @@ -539,8 +539,9 @@ module Redmine end def validate_single_value(custom_field, value, customized=nil) + value = normalize_float(value) errs = super - errs << ::I18n.t('activerecord.errors.messages.invalid') unless (Kernel.Float(value) rescue nil) + errs << ::I18n.t('activerecord.errors.messages.invalid') unless Kernel.Float(value, exception: false) errs end diff --git a/lib/redmine/i18n.rb b/lib/redmine/i18n.rb index 8434cd9be..dab486893 100644 --- a/lib/redmine/i18n.rb +++ b/lib/redmine/i18n.rb @@ -99,6 +99,18 @@ module Redmine end end + # Will consider language specific separator in user input + # and normalize them to a unified format to be accepted by Kernel.Float(). + # + # @param value [String] A string represenation of a float value. + # + # @note The delimiter cannot be used here if it is a decimal point since it + # will clash with the dot separator. + def normalize_float(value) + separator = ::I18n.t('number.format.separator') + value.gsub(/[#{separator}]/, separator => '.') + end + def day_name(day) ::I18n.t('date.day_names')[day % 7] end diff --git a/test/unit/lib/redmine/field_format/numeric_format_test.rb b/test/unit/lib/redmine/field_format/numeric_format_test.rb index 9ced022fb..c1914d2e8 100644 --- a/test/unit/lib/redmine/field_format/numeric_format_test.rb +++ b/test/unit/lib/redmine/field_format/numeric_format_test.rb @@ -23,6 +23,10 @@ require 'redmine/field_format' class Redmine::NumericFieldFormatTest < ActionView::TestCase include ApplicationHelper + fixtures :projects, :users, :issue_statuses, :enumerations, + :trackers, :projects_trackers, :roles, :member_roles, + :members, :enabled_modules + def setup User.current = nil end @@ -34,4 +38,28 @@ class Redmine::NumericFieldFormatTest < ActionView::TestCase assert_equal 3, field.format.formatted_custom_value(self, custom_value, false) assert_equal '3', field.format.formatted_custom_value(self, custom_value, true) end + + def test_float_field_value_should_validate_when_given_with_various_separator + field = IssueCustomField.generate!(field_format: 'float') + issue = Issue.generate!(tracker: Tracker.find(1), status: IssueStatus.find(1), priority: IssuePriority.find(6)) + to_test = {'en' => '3.33', 'de' => '3,33'} + to_test.each do |locale, expected| + with_locale locale do + assert field.format.validate_single_value(field, expected, issue) + end + end + end + + def test_float_field_should_format_with_various_locale_separator + field = IssueCustomField.generate!(field_format: 'float') + issue = Issue.generate!(tracker: Tracker.find(1), status: IssueStatus.find(1), priority: IssuePriority.find(6)) + issue.custom_field_values = { field.id => '1234.56' } + issue.save! + to_test = {'en' => '1234.56', 'de' => '1234,56'} + to_test.each do |locale, expected| + with_locale locale do + assert_equal expected, format_object(issue.reload.custom_field_values.last, false) + end + end + end end