Feature #22024 » support-localized-decimal-separator.patch
| app/helpers/application_helper.rb | ||
|---|---|---|
| 266 | 266 |
when 'Fixnum' |
| 267 | 267 |
object.to_s |
| 268 | 268 |
when 'Float' |
| 269 |
sprintf "%.2f", object |
|
| 269 |
number_with_delimiter(object, delimiter: ::I18n.t('number.format.delimiter'),
|
|
| 270 |
separator: ::I18n.t('number.format.separator'))
|
|
| 270 | 271 |
when 'User', 'Group' |
| 271 | 272 |
html ? link_to_principal(object) : object.to_s |
| 272 | 273 |
when 'Project' |
| lib/redmine/field_format.rb | ||
|---|---|---|
| 537 | 537 |
end |
| 538 | 538 | |
| 539 | 539 |
def validate_single_value(custom_field, value, customized=nil) |
| 540 |
value = normalize_float(value) |
|
| 540 | 541 |
errs = super |
| 541 |
errs << ::I18n.t('activerecord.errors.messages.invalid') unless (Kernel.Float(value) rescue nil)
|
|
| 542 |
errs << ::I18n.t('activerecord.errors.messages.invalid') unless Kernel.Float(value, exception: false)
|
|
| 542 | 543 |
errs |
| 543 | 544 |
end |
| 544 | 545 | |
| lib/redmine/i18n.rb | ||
|---|---|---|
| 99 | 99 |
end |
| 100 | 100 |
end |
| 101 | 101 | |
| 102 |
# Will consider language specific separator in user input |
|
| 103 |
# and normalize them to a unified format to be accepted by Kernel.Float(). |
|
| 104 |
# |
|
| 105 |
# @param value [String] A string represenation of a float value. |
|
| 106 |
# |
|
| 107 |
# @note The delimiter cannot be used here if it is a decimal point since it |
|
| 108 |
# will clash with the dot separator. |
|
| 109 |
def normalize_float(value) |
|
| 110 |
separator = ::I18n.t('number.format.separator')
|
|
| 111 |
value.gsub(/[#{separator}]/, separator => '.')
|
|
| 112 |
end |
|
| 113 | ||
| 102 | 114 |
def day_name(day) |
| 103 | 115 |
::I18n.t('date.day_names')[day % 7]
|
| 104 | 116 |
end |
| test/unit/lib/redmine/field_format/numeric_format_test.rb | ||
|---|---|---|
| 23 | 23 |
class Redmine::NumericFieldFormatTest < ActionView::TestCase |
| 24 | 24 |
include ApplicationHelper |
| 25 | 25 | |
| 26 |
fixtures :projects, :users, :issue_statuses, :enumerations, |
|
| 27 |
:trackers, :projects_trackers, :roles, :member_roles, |
|
| 28 |
:members, :enabled_modules |
|
| 29 | ||
| 26 | 30 |
def setup |
| 27 | 31 |
User.current = nil |
| 28 | 32 |
end |
| ... | ... | |
| 34 | 38 |
assert_equal 3, field.format.formatted_custom_value(self, custom_value, false) |
| 35 | 39 |
assert_equal '<a class="external" href="http://foo/3">3</a>', field.format.formatted_custom_value(self, custom_value, true) |
| 36 | 40 |
end |
| 41 | ||
| 42 |
def test_float_field_value_should_validate_when_given_with_various_separator |
|
| 43 |
field = IssueCustomField.generate!(field_format: 'float') |
|
| 44 |
issue = Issue.generate!(tracker: Tracker.find(1), status: IssueStatus.find(1), priority: IssuePriority.find(6)) |
|
| 45 |
::I18n.locale = :de |
|
| 46 |
assert field.format.validate_single_value(field, '3,33', issue) |
|
| 47 |
::I18n.locale = :en |
|
| 48 |
assert field.format.validate_single_value(field, '3.33', issue) |
|
| 49 |
end |
|
| 50 | ||
| 51 |
def test_float_field_should_format_with_various_locale_separator_and_delimiter |
|
| 52 |
field = IssueCustomField.generate!(field_format: 'float') |
|
| 53 |
issue = Issue.generate!(tracker: Tracker.find(1), status: IssueStatus.find(1), priority: IssuePriority.find(6)) |
|
| 54 |
::I18n.locale = :de |
|
| 55 |
issue.custom_field_values = { field.id => '3333.33' }
|
|
| 56 |
issue.save! |
|
| 57 |
assert_equal '3.333,33', format_object(issue.reload.custom_field_values.first, false) |
|
| 58 |
::I18n.locale = :en |
|
| 59 |
assert_equal '3333.33', format_object(issue.reload.custom_field_values.first, false) |
|
| 60 |
end |
|
| 37 | 61 |
end |