From d660c291406f7d50c42ddef6605bda25c2988bf8 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Wed, 15 Feb 2017 14:26:35 -0800 Subject: [PATCH 1/5] Implement Spree.formatMoney using accounting.js --- .../app/assets/javascripts/spree/backend.js | 1 + .../spree/backend/format_money.js.erb | 27 +++++++++++++++++++ .../spree/admin/shared/_translations.html.erb | 1 + .../admin/javascript_format_money_spec.rb | 20 ++++++++++++++ .../javascripts/solidus_admin/accounting.js | 4 +++ 5 files changed, 53 insertions(+) create mode 100644 backend/app/assets/javascripts/spree/backend/format_money.js.erb create mode 100644 backend/spec/features/admin/javascript_format_money_spec.rb create mode 100644 backend/vendor/assets/javascripts/solidus_admin/accounting.js diff --git a/backend/app/assets/javascripts/spree/backend.js b/backend/app/assets/javascripts/spree/backend.js index 5f29d353258..c4d3c1fd58e 100644 --- a/backend/app/assets/javascripts/spree/backend.js +++ b/backend/app/assets/javascripts/spree/backend.js @@ -15,6 +15,7 @@ //= require spree/backend/translation //= require spree/backend/backbone-overrides //= require spree/backend/spree-select2 +//= require spree/backend/format_money // //= require spree/backend/templates // diff --git a/backend/app/assets/javascripts/spree/backend/format_money.js.erb b/backend/app/assets/javascripts/spree/backend/format_money.js.erb new file mode 100644 index 00000000000..640e74fb232 --- /dev/null +++ b/backend/app/assets/javascripts/spree/backend/format_money.js.erb @@ -0,0 +1,27 @@ +//= require spree/backend/translation +//= require solidus_admin/accounting + +Spree.currencyInfo = <%= +Money::Currency.all.map { |c| + format = + if c.symbol == "" || c.symbol_first + "%s%v" + else + "%v %s" + end + [c.id.to_s.upcase, [ + c.symbol || "¤", + c.exponent, + format + ]] +}.to_h.to_json +%>; + +Spree.formatMoney = function(amount, currency) { + var currencyInfo = Spree.currencyInfo[currency]; + + var thousand = Spree.t('currency_delimiter'); + var decimal = Spree.t('currency_separator'); + + return accounting.formatMoney(amount, currencyInfo[0], currencyInfo[1], thousand, decimal, currencyInfo[2]); +} diff --git a/backend/app/views/spree/admin/shared/_translations.html.erb b/backend/app/views/spree/admin/shared/_translations.html.erb index a9ad2f63cf6..67bc4d71349 100644 --- a/backend/app/views/spree/admin/shared/_translations.html.erb +++ b/backend/app/views/spree/admin/shared/_translations.html.erb @@ -18,6 +18,7 @@ :item_stock_placeholder => Spree.t(:choose_location), :month_names => I18n.t(:month_names, scope: :date).reject(&:blank?), :currency_separator => I18n.t('number.currency.format.separator'), + :currency_delimiter => I18n.t('number.currency.format.delimiter'), :activerecord => I18n.t('activerecord') }).to_json %> diff --git a/backend/spec/features/admin/javascript_format_money_spec.rb b/backend/spec/features/admin/javascript_format_money_spec.rb new file mode 100644 index 00000000000..f7a7dcd35a0 --- /dev/null +++ b/backend/spec/features/admin/javascript_format_money_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +RSpec.describe 'JS Spree.formatMoney', js: true do + stub_authorization! + + # This is a slightly hacky spec to ensure that our JS will format money in + # the same was as our ruby code. + # This should probably replaced with a pure JS test in the future. + it 'should behave identically to Spree::Money#to_s' do + visit '/admin' + + Money::Currency.all.map(&:id).map(&:to_s).map(&:upcase).uniq.each do |currency| + money = Spree::Money.new(1234, currency: currency) + + js_result = page.evaluate_script("Spree.formatMoney(#{money.to_d}, '#{currency}')") + + expect(js_result).to eq money.to_s + end + end +end diff --git a/backend/vendor/assets/javascripts/solidus_admin/accounting.js b/backend/vendor/assets/javascripts/solidus_admin/accounting.js new file mode 100644 index 00000000000..8e09b868467 --- /dev/null +++ b/backend/vendor/assets/javascripts/solidus_admin/accounting.js @@ -0,0 +1,4 @@ +/*! + * accounting.js v0.4.2, copyright 2014 Open Exchange Rates, MIT license, http://openexchangerates.github.io/accounting.js + */ +(function(p,z){function q(a){return!!(""===a||a&&a.charCodeAt&&a.substr)}function m(a){return u?u(a):"[object Array]"===v.call(a)}function r(a){return"[object Object]"===v.call(a)}function s(a,b){var d,a=a||{},b=b||{};for(d in b)b.hasOwnProperty(d)&&null==a[d]&&(a[d]=b[d]);return a}function j(a,b,d){var c=[],e,h;if(!a)return c;if(w&&a.map===w)return a.map(b,d);for(e=0,h=a.length;ea?"-":"",g=parseInt(y(Math.abs(a||0),h),10)+"",l=3a?g.neg:g.zero).replace("%s",f.symbol).replace("%v",t(Math.abs(a),n(f.precision),f.thousand,f.decimal))};c.formatColumn=function(a,b,d,i,e,h){if(!a)return[];var f=s(r(b)?b:{symbol:b,precision:d,thousand:i,decimal:e,format:h},c.settings.currency),g=x(f.format),l=g.pos.indexOf("%s")a?g.neg:g.zero).replace("%s",f.symbol).replace("%v",t(Math.abs(a),n(f.precision),f.thousand,f.decimal));if(a.length>k)k=a.length;return a});return j(a,function(a){return q(a)&&a.length Date: Mon, 27 Feb 2017 10:47:17 -0800 Subject: [PATCH 2/5] Rename _translations partial to _js_locale_data This is going to include currency data as well. This makes the scope and purpose of the file more clear. --- backend/app/views/spree/admin/shared/_head.html.erb | 2 +- .../shared/{_translations.html.erb => _js_locale_data.html.erb} | 0 backend/app/views/spree/layouts/admin_style_guide.html.erb | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename backend/app/views/spree/admin/shared/{_translations.html.erb => _js_locale_data.html.erb} (100%) diff --git a/backend/app/views/spree/admin/shared/_head.html.erb b/backend/app/views/spree/admin/shared/_head.html.erb index 443358b602f..2eaef0ad500 100644 --- a/backend/app/views/spree/admin/shared/_head.html.erb +++ b/backend/app/views/spree/admin/shared/_head.html.erb @@ -32,7 +32,7 @@ <%= javascript_include_tag 'spree/backend/all' %> -<%= render "spree/admin/shared/translations" %> +<%= render "spree/admin/shared/js_locale_data" %> <%= javascript_tag do -%> Spree.api_key = "<%= try_spree_current_user.try(:spree_api_key) %>"; diff --git a/backend/app/views/spree/admin/shared/_translations.html.erb b/backend/app/views/spree/admin/shared/_js_locale_data.html.erb similarity index 100% rename from backend/app/views/spree/admin/shared/_translations.html.erb rename to backend/app/views/spree/admin/shared/_js_locale_data.html.erb diff --git a/backend/app/views/spree/layouts/admin_style_guide.html.erb b/backend/app/views/spree/layouts/admin_style_guide.html.erb index 2699597a800..26269d966a8 100644 --- a/backend/app/views/spree/layouts/admin_style_guide.html.erb +++ b/backend/app/views/spree/layouts/admin_style_guide.html.erb @@ -6,7 +6,7 @@ <%= stylesheet_link_tag "spree/backend/all" %> <%= javascript_include_tag "spree/backend/all" %> - <%= render "spree/admin/shared/translations" %> + <%= render "spree/admin/shared/js_locale_data" %> From ca482298c562f65dc6badf49764a617b734df2be Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Mon, 27 Feb 2017 10:47:24 -0800 Subject: [PATCH 3/5] Convert to 1.9 hash syntax --- .../admin/shared/_js_locale_data.html.erb | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/backend/app/views/spree/admin/shared/_js_locale_data.html.erb b/backend/app/views/spree/admin/shared/_js_locale_data.html.erb index 67bc4d71349..9a36b8e2cc3 100644 --- a/backend/app/views/spree/admin/shared/_js_locale_data.html.erb +++ b/backend/app/views/spree/admin/shared/_js_locale_data.html.erb @@ -4,22 +4,22 @@ } Spree.translations = <%== I18n.t("spree").merge({ - :date_picker => Spree.t(:js_format, - scope: 'date_picker', - default: 'yy/mm/dd'), - :abbr_day_names => I18n.t(:abbr_day_names, scope: :date), - :destroy => Spree.t(:destroy, scope: :actions), - :edit => Spree.t(:edit, scope: :actions), - :save => Spree.t(:save, scope: :actions), - :cancel => Spree.t(:cancel, scope: :actions), - :first_day => Spree.t(:first_day, - scope: 'date_picker', - default: 0).to_i, - :item_stock_placeholder => Spree.t(:choose_location), - :month_names => I18n.t(:month_names, scope: :date).reject(&:blank?), - :currency_separator => I18n.t('number.currency.format.separator'), - :currency_delimiter => I18n.t('number.currency.format.delimiter'), - :activerecord => I18n.t('activerecord') + date_picker: Spree.t(:js_format, + scope: 'date_picker', + default: 'yy/mm/dd'), + abbr_day_names: I18n.t(:abbr_day_names, scope: :date), + destroy: Spree.t(:destroy, scope: :actions), + edit: Spree.t(:edit, scope: :actions), + save: Spree.t(:save, scope: :actions), + cancel: Spree.t(:cancel, scope: :actions), + first_day: Spree.t(:first_day, + scope: 'date_picker', + default: 0).to_i, + item_stock_placeholder: Spree.t(:choose_location), + month_names: I18n.t(:month_names, scope: :date).reject(&:blank?), + currency_separator: I18n.t('number.currency.format.separator'), + currency_delimiter: I18n.t('number.currency.format.delimiter'), + activerecord: I18n.t('activerecord') }).to_json %> From 77f9760b35f1f1ce955a5ca84c0d439feb341f3d Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Mon, 27 Feb 2017 11:34:34 -0800 Subject: [PATCH 4/5] Move JS Spree.currencyInfo into erb view This allows us to pick up configuration changes the RubyMoney currencies. --- .../{format_money.js.erb => format_money.js} | 16 ---------------- .../admin/shared/_js_locale_data.html.erb | 18 +++++++++++++++++- 2 files changed, 17 insertions(+), 17 deletions(-) rename backend/app/assets/javascripts/spree/backend/{format_money.js.erb => format_money.js} (60%) diff --git a/backend/app/assets/javascripts/spree/backend/format_money.js.erb b/backend/app/assets/javascripts/spree/backend/format_money.js similarity index 60% rename from backend/app/assets/javascripts/spree/backend/format_money.js.erb rename to backend/app/assets/javascripts/spree/backend/format_money.js index 640e74fb232..6f327937053 100644 --- a/backend/app/assets/javascripts/spree/backend/format_money.js.erb +++ b/backend/app/assets/javascripts/spree/backend/format_money.js @@ -1,22 +1,6 @@ //= require spree/backend/translation //= require solidus_admin/accounting -Spree.currencyInfo = <%= -Money::Currency.all.map { |c| - format = - if c.symbol == "" || c.symbol_first - "%s%v" - else - "%v %s" - end - [c.id.to_s.upcase, [ - c.symbol || "¤", - c.exponent, - format - ]] -}.to_h.to_json -%>; - Spree.formatMoney = function(amount, currency) { var currencyInfo = Spree.currencyInfo[currency]; diff --git a/backend/app/views/spree/admin/shared/_js_locale_data.html.erb b/backend/app/views/spree/admin/shared/_js_locale_data.html.erb index 9a36b8e2cc3..e973981723c 100644 --- a/backend/app/views/spree/admin/shared/_js_locale_data.html.erb +++ b/backend/app/views/spree/admin/shared/_js_locale_data.html.erb @@ -21,7 +21,23 @@ currency_delimiter: I18n.t('number.currency.format.delimiter'), activerecord: I18n.t('activerecord') }).to_json -%> +%>; + + Spree.currencyInfo = <%== + Money::Currency.all.map { |c| + format = + if c.symbol == "" || c.symbol_first + "%s%v" + else + "%v %s" + end + [c.id.to_s.upcase, [ + c.symbol || "¤", + c.exponent, + format + ]] + }.to_h.to_json +%>; From b1e4990221f6520541810a5bd16ced48271cf800 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Tue, 28 Feb 2017 11:12:28 -0800 Subject: [PATCH 5/5] Add CHANGELOG entries for Spree.formatMoney --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 148552dd166..3d6b2230248 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,12 @@ * The `AvailabilityValidator` now correctly detects out of stock when there are multiple shipments from the same stock location. +* The spree/admin/shared/\_translations partial has moved to + spree/admin/shared/\_js\_locale\_data. + +* New method Spree.formatMoney(amount, currency) is available to javascript in + the admin. + * Deprecations * `cache_key_for_taxons` helper has been deprecated in favour of `cache [I18n.locale, @taxons]`