diff --git a/config/initializers/money.rb b/config/initializers/money.rb
new file mode 100644
index 0000000000..1dea6e473b
--- /dev/null
+++ b/config/initializers/money.rb
@@ -0,0 +1,2 @@
+Money.rounding_mode = BigDecimal::ROUND_HALF_EVEN
+Money.default_currency = Money::Currency.new(Spree::Config[:currency])
diff --git a/lib/spree/money.rb b/lib/spree/money.rb
index 8ff14ce203..994aceabb7 100644
--- a/lib/spree/money.rb
+++ b/lib/spree/money.rb
@@ -10,15 +10,12 @@ module Spree
def initialize(amount, options = {})
@money = ::Monetize.parse([amount, (options[:currency] || Spree::Config[:currency])].join)
- @options = {}
- @options[:with_currency] = Spree::Config[:display_currency]
- @options[:symbol_position] = Spree::Config[:currency_symbol_position].to_sym
- @options[:no_cents] = Spree::Config[:hide_cents]
- @options[:decimal_mark] = Spree::Config[:currency_decimal_mark]
- @options[:thousands_separator] = Spree::Config[:currency_thousands_separator]
- @options.merge!(options)
- # Must be a symbol because the Money gem doesn't do the conversion
- @options[:symbol_position] = @options[:symbol_position].to_sym
+
+ if options.key?(:symbol_position)
+ options[:format] = position_to_format(options.delete(:symbol_position))
+ end
+
+ @options = defaults.merge(options)
end
# Return the currency symbol (on its own) for the current default currency
@@ -30,14 +27,8 @@ module Spree
@money.format(@options)
end
- def to_html(options = { html: true })
- output = @money.format(@options.merge(options))
- if options[:html]
- # 1) prevent blank, breaking spaces
- # 2) prevent escaping of HTML character entities
- output = output.sub(" ", " ").html_safe
- end
- output
+ def to_html(options = { html_wrap: true })
+ @money.format(@options.merge(options)).html_safe
end
def format(options = {})
@@ -47,5 +38,30 @@ module Spree
def ==(other)
@money == other.money
end
+
+ private
+
+ def defaults
+ {
+ with_currency: Spree::Config[:display_currency],
+ no_cents: Spree::Config[:hide_cents],
+ decimal_mark: Spree::Config[:currency_decimal_mark],
+ thousands_separator: Spree::Config[:currency_thousands_separator],
+ format: position_to_format(Spree::Config[:currency_symbol_position])
+ }
+ end
+
+ def position_to_format(position)
+ return if position.nil?
+
+ case position.to_sym
+ when :before
+ '%u%n'
+ when :after
+ '%n %u'
+ else
+ raise 'Invalid symbol position'
+ end
+ end
end
end
diff --git a/spec/features/admin/configuration/general_settings_spec.rb b/spec/features/admin/configuration/general_settings_spec.rb
index 6c5b70a4ba..ecb6d61c91 100644
--- a/spec/features/admin/configuration/general_settings_spec.rb
+++ b/spec/features/admin/configuration/general_settings_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
describe "General Settings" do
include AuthenticationHelper
- before(:each) do
+ before do
login_as_admin_and_visit spree.admin_dashboard_path
click_link "Configuration"
click_link "General Settings"
@@ -24,16 +24,25 @@ describe "General Settings" do
fill_in "site_name", with: "OFN Demo Site99"
click_button "Update"
- assert_successful_update_message(:general_settings)
-
+ within("[class='flash success']") do
+ expect(page).to have_content(Spree.t(:successfully_updated, resource: Spree.t(:general_settings)))
+ end
expect(find("#site_name").value).to eq("OFN Demo Site99")
end
+ end
- def assert_successful_update_message(resource)
- flash = Spree.t(:successfully_updated, resource: Spree.t(resource))
- within("[class='flash success']") do
- expect(page).to have_content(flash)
+ context 'editing currency symbol position' do
+ it 'updates its position' do
+ expect(page).to have_content('Currency Settings')
+
+ within('.currency') do
+ find("[for='currency_symbol_position_after']").click
end
+
+ click_button 'Update'
+
+ expect(page).to have_content(Spree.t(:successfully_updated, resource: Spree.t(:general_settings)))
+ expect(page).to have_checked_field('10.00 $')
end
end
end
diff --git a/spec/lib/spree/money_spec.rb b/spec/lib/spree/money_spec.rb
index 12b1d975b8..676572eff6 100644
--- a/spec/lib/spree/money_spec.rb
+++ b/spec/lib/spree/money_spec.rb
@@ -25,13 +25,13 @@ describe Spree::Money do
context "with currency" do
it "passed in option" do
- money = Spree::Money.new(10, with_currency: true, html: false)
+ money = Spree::Money.new(10, with_currency: true, html_wrap: false)
expect(money.to_s).to eq("$10.00 USD")
end
it "config option" do
Spree::Config[:display_currency] = true
- money = Spree::Money.new(10, html: false)
+ money = Spree::Money.new(10, html_wrap: false)
expect(money.to_s).to eq("$10.00 USD")
end
end
@@ -53,14 +53,14 @@ describe Spree::Money do
context "currency parameter" do
context "when currency is specified in Canadian Dollars" do
it "uses the currency param over the global configuration" do
- money = Spree::Money.new(10, currency: 'CAD', with_currency: true, html: false)
+ money = Spree::Money.new(10, currency: 'CAD', with_currency: true, html_wrap: false)
expect(money.to_s).to eq("$10.00 CAD")
end
end
context "when currency is specified in Japanese Yen" do
it "uses the currency param over the global configuration" do
- money = Spree::Money.new(100, currency: 'JPY', html: false)
+ money = Spree::Money.new(100, currency: 'JPY', html_wrap: false)
expect(money.to_s).to eq("¥100")
end
end
@@ -68,34 +68,24 @@ describe Spree::Money do
context "symbol positioning" do
it "passed in option" do
- money = Spree::Money.new(10, symbol_position: :after, html: false)
+ money = Spree::Money.new(10, symbol_position: :after, html_wrap: false)
expect(money.to_s).to eq("10.00 $")
end
it "passed in option string" do
- money = Spree::Money.new(10, symbol_position: "after", html: false)
+ money = Spree::Money.new(10, symbol_position: "after", html_wrap: false)
expect(money.to_s).to eq("10.00 $")
end
it "config option" do
Spree::Config[:currency_symbol_position] = :after
- money = Spree::Money.new(10, html: false)
+ money = Spree::Money.new(10, html_wrap: false)
expect(money.to_s).to eq("10.00 $")
end
- end
- context "JPY" do
- before do
- configure_spree_preferences do |config|
- config.currency = "JPY"
- config.currency_symbol_position = :before
- config.display_currency = false
- end
- end
-
- it "formats correctly" do
- money = Spree::Money.new(1000, html: false)
- expect(money.to_s).to eq("¥1,000")
+ it 'raises with invalid position' do
+ expect { Spree::Money.new(10, symbol_position: 'invalid') }
+ .to raise_error('Invalid symbol position')
end
end
@@ -128,10 +118,14 @@ describe Spree::Money do
expect(money.to_s).to eq("1.000.00 €")
end
+ # rubocop:disable Layout/LineLength
it "formats as HTML if asked (nicely) to" do
money = Spree::Money.new(10)
# The HTMLified version of the euro sign
- expect(money.to_html).to eq("10.00 €")
+ expect(money.to_html).to eq(
+ "10.00 €"
+ )
end
+ # rubocop:enable Layout/LineLength
end
end