From 255935da744678bfcefb7814b269c810005c0923 Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Sat, 2 Mar 2024 12:11:14 +0100 Subject: [PATCH 01/10] Add a promotion finder class for the classic promotion system This is intended to be used by the API Promotions Controller. --- core/app/models/spree/promotion_finder.rb | 9 ++++++++ .../models/spree/promotion_finder_spec.rb | 23 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 core/app/models/spree/promotion_finder.rb create mode 100644 core/spec/models/spree/promotion_finder_spec.rb diff --git a/core/app/models/spree/promotion_finder.rb b/core/app/models/spree/promotion_finder.rb new file mode 100644 index 00000000000..65517df622b --- /dev/null +++ b/core/app/models/spree/promotion_finder.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Spree + class PromotionFinder + def self.by_code_or_id(coupon_code) + Spree::Promotion.with_coupon_code(coupon_code.to_s) || Spree::Promotion.find(coupon_code) + end + end +end diff --git a/core/spec/models/spree/promotion_finder_spec.rb b/core/spec/models/spree/promotion_finder_spec.rb new file mode 100644 index 00000000000..d4a0ccbe61e --- /dev/null +++ b/core/spec/models/spree/promotion_finder_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe Spree::PromotionFinder do + describe ".by_code_or_id" do + let!(:promotion) { create(:promotion, code: "promo") } + + it "finds a promotion by its code" do + expect(described_class.by_code_or_id("promo")).to eq promotion + end + + it "finds a promotion by its ID" do + expect(described_class.by_code_or_id(promotion.id)).to eq promotion + end + + context "when the promotion does not exist" do + it "raises an error" do + expect { described_class.by_code_or_id("nonexistent") }.to raise_error(ActiveRecord::RecordNotFound) + end + end + end +end From 1e1c0f89b70ecf136c8bcb736422dcf9a783ca1e Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Sat, 2 Mar 2024 12:00:58 +0100 Subject: [PATCH 02/10] Add a Null Promotion Finder This configurable class finds a promotion by its code. --- core/app/models/spree/null_promotion_finder.rb | 9 +++++++++ core/spec/models/spree/null_promotion_finder_spec.rb | 11 +++++++++++ 2 files changed, 20 insertions(+) create mode 100644 core/app/models/spree/null_promotion_finder.rb create mode 100644 core/spec/models/spree/null_promotion_finder_spec.rb diff --git a/core/app/models/spree/null_promotion_finder.rb b/core/app/models/spree/null_promotion_finder.rb new file mode 100644 index 00000000000..6a2fc96123c --- /dev/null +++ b/core/app/models/spree/null_promotion_finder.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Spree + module NullPromotionFinder + def self.by_code_or_id(*) + raise ActiveRecord::RecordNotFound, "No promotion system configured." + end + end +end diff --git a/core/spec/models/spree/null_promotion_finder_spec.rb b/core/spec/models/spree/null_promotion_finder_spec.rb new file mode 100644 index 00000000000..f9ae0044b23 --- /dev/null +++ b/core/spec/models/spree/null_promotion_finder_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe Spree::NullPromotionFinder do + describe ".by_code_or_id" do + it "raises ActiveRecord::RecordNotFound" do + expect { described_class.by_code_or_id("promo") }.to raise_error(ActiveRecord::RecordNotFound) + end + end +end From d5039de6b3209b32662764ba0fe8041fda17eca9 Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Sat, 2 Mar 2024 12:02:20 +0100 Subject: [PATCH 03/10] Make the promotion finder class configurable The default has to be the Null promotion finder. --- core/lib/spree/core/null_promotion_configuration.rb | 8 ++++++++ .../lib/spree/core/null_promotion_configuration_spec.rb | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/core/lib/spree/core/null_promotion_configuration.rb b/core/lib/spree/core/null_promotion_configuration.rb index 8e73dbf5317..e3b5a821a31 100644 --- a/core/lib/spree/core/null_promotion_configuration.rb +++ b/core/lib/spree/core/null_promotion_configuration.rb @@ -13,6 +13,14 @@ class NullPromotionConfiguration < Spree::Preferences::Configuration # the standard coupon code handler class # Spree::NullPromotionHandler. class_name_attribute :coupon_code_handler_class, default: 'Spree::NullPromotionHandler' + + # Allows providing a different promotion finder. + # @!attribute [rw] promotion_finder_class + # @see Spree::NullPromotionFinder + # @return [Class] an object that conforms to the API of + # the standard promotion finder class + # Spree::NullPromotionFinder. + class_name_attribute :promotion_finder_class, default: 'Spree::NullPromotionFinder' end end end diff --git a/core/spec/lib/spree/core/null_promotion_configuration_spec.rb b/core/spec/lib/spree/core/null_promotion_configuration_spec.rb index b82401ecaf9..70bdd54496c 100644 --- a/core/spec/lib/spree/core/null_promotion_configuration_spec.rb +++ b/core/spec/lib/spree/core/null_promotion_configuration_spec.rb @@ -12,4 +12,8 @@ it "uses the null coupon code handler class by default" do expect(config.coupon_code_handler_class).to eq Spree::NullPromotionHandler end + + it "uses the null promotion finder class by default" do + expect(config.promotion_finder_class).to eq Spree::NullPromotionFinder + end end From 9b495012e19e8672ef527c7d670617430d1a62c3 Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Sat, 2 Mar 2024 12:15:14 +0100 Subject: [PATCH 04/10] Add promotion_finder_class attribute to classic PromotionConfiguration --- core/lib/spree/core/promotion_configuration.rb | 3 +++ core/spec/lib/spree/core/promotion_configuration_spec.rb | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/core/lib/spree/core/promotion_configuration.rb b/core/lib/spree/core/promotion_configuration.rb index 5e3aa3b04e7..b4c7ba7f208 100644 --- a/core/lib/spree/core/promotion_configuration.rb +++ b/core/lib/spree/core/promotion_configuration.rb @@ -15,6 +15,9 @@ class PromotionConfiguration < Spree::Preferences::Configuration # promotion_adjuster_class allows extensions to provide their own Promotion Adjuster class_name_attribute :promotion_adjuster_class, default: 'Spree::Promotion::OrderAdjustmentsRecalculator' + # promotion_finder_class allows extensions to provide their own Promotion Finder + class_name_attribute :promotion_finder_class, default: 'Spree::PromotionFinder' + # Allows providing a different shipping promotion handler. # @!attribute [rw] shipping_promotion_handler_class # @see Spree::PromotionHandler::Shipping diff --git a/core/spec/lib/spree/core/promotion_configuration_spec.rb b/core/spec/lib/spree/core/promotion_configuration_spec.rb index a91c9e98d9b..37cef1e8290 100644 --- a/core/spec/lib/spree/core/promotion_configuration_spec.rb +++ b/core/spec/lib/spree/core/promotion_configuration_spec.rb @@ -21,6 +21,10 @@ expect(config.shipping_promotion_handler_class).to eq Spree::PromotionHandler::Shipping end + it "uses promotion finder class by default" do + expect(config.promotion_finder_class).to eq Spree::PromotionFinder + end + describe "#calculators" do subject { config.calculators[promotion_action] } From eb76aae9399c57c81603959d376b3943013f5ad1 Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Sat, 2 Mar 2024 12:16:49 +0100 Subject: [PATCH 05/10] Use promotion finder in API promotions controller The API promotions controller is pretty straightforward, and the only touch point here is finding a promotion. With that added to the promotion configuration, we can now use it with no changes to our specs. --- api/app/controllers/spree/api/promotions_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/app/controllers/spree/api/promotions_controller.rb b/api/app/controllers/spree/api/promotions_controller.rb index 3af2a62d212..1c628388f07 100644 --- a/api/app/controllers/spree/api/promotions_controller.rb +++ b/api/app/controllers/spree/api/promotions_controller.rb @@ -13,7 +13,7 @@ def show private def load_promotion - @promotion = Spree::Promotion.with_coupon_code(params[:id]) || Spree::Promotion.find(params[:id]) + @promotion = Spree::Config.promotions.promotion_finder_class.by_code_or_id(params[:id]) end end end From 2f29de00e8b91f4c6c73c8e4fcda9dff271f742c Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Sat, 2 Mar 2024 12:31:14 +0100 Subject: [PATCH 06/10] Promotions Request Spec: Stub Finder This allows us to change the promotion system with factories, because we stop using factories in this spec. --- .../requests/spree/api/promotions_spec.rb | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/api/spec/requests/spree/api/promotions_spec.rb b/api/spec/requests/spree/api/promotions_spec.rb index e896efb748f..7ab350e779e 100644 --- a/api/spec/requests/spree/api/promotions_spec.rb +++ b/api/spec/requests/spree/api/promotions_spec.rb @@ -24,28 +24,38 @@ module Spree::Api stub_authentication! end - let(:promotion) { create :promotion, code: '10off' } + let(:found_promotion) do + OpenStruct.new( + id: 1, + name: 'Test Promotion', + description: 'Promotion for testing purposes', + path: '/api/promotions/test-promo', + starts_at: 1.day.ago, + expires_at: 1.day.from_now, + type: "something", + usage_limit: 100, + advertise: false, + ) + end describe 'GET #show' do - subject { get spree.api_promotion_path(id) } + subject { get spree.api_promotion_path("1") } context 'when admin' do sign_in_as_admin! - context 'when finding by id' do - let(:id) { promotion.id } - - it_behaves_like "a JSON response" - end - - context 'when finding by code' do - let(:id) { promotion.codes.first.value } + context 'when finding by a promotion' do + before do + allow(Spree::Config.promotions.promotion_finder_class).to receive(:by_code_or_id).and_return(found_promotion) + end it_behaves_like "a JSON response" end context 'when id does not exist' do - let(:id) { 'argh' } + before do + allow(Spree::Config.promotions.promotion_finder_class).to receive(:by_code_or_id).and_raise(ActiveRecord::RecordNotFound) + end it 'should be 404' do subject @@ -55,7 +65,9 @@ module Spree::Api end context 'when non admin' do - let(:id) { promotion.id } + before do + allow(Spree::Config.promotions.promotion_finder_class).to receive(:by_code_or_id).and_return(found_promotion) + end it 'should be unauthorized' do subject From 5b136abadb2259354c853454d49e9da8a4abbc88 Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Fri, 26 Jan 2024 15:36:02 +0100 Subject: [PATCH 07/10] Scaffold for solidus_legacy_promotions extension We want to extract the legacy promotion system from Solidus into its own gem to facilitate moving towards solidus_promotions. --- bin/rspec | 1 + legacy_promotions/Rakefile | 42 +++++++++++++++ legacy_promotions/bin/rails | 13 +++++ .../lib/solidus_legacy_promotions.rb | 10 ++++ .../lib/solidus_legacy_promotions/engine.rb | 7 +++ .../solidus_legacy_promotions.gemspec | 28 ++++++++++ .../lib/solidus_legacy_promotions_spec.rb | 9 ++++ legacy_promotions/spec/rails_helper.rb | 51 +++++++++++++++++++ legacy_promotions/spec/spec_helper.rb | 44 ++++++++++++++++ solidus.gemspec | 1 + 10 files changed, 206 insertions(+) create mode 100644 legacy_promotions/Rakefile create mode 100755 legacy_promotions/bin/rails create mode 100644 legacy_promotions/lib/solidus_legacy_promotions.rb create mode 100644 legacy_promotions/lib/solidus_legacy_promotions/engine.rb create mode 100644 legacy_promotions/solidus_legacy_promotions.gemspec create mode 100644 legacy_promotions/spec/lib/solidus_legacy_promotions_spec.rb create mode 100644 legacy_promotions/spec/rails_helper.rb create mode 100644 legacy_promotions/spec/spec_helper.rb diff --git a/bin/rspec b/bin/rspec index e573a4a625d..d9b88dab572 100755 --- a/bin/rspec +++ b/bin/rspec @@ -8,6 +8,7 @@ LIBS = %w[ backend core sample + legacy_promotions ] # Ignore line info, e.g. foo/bar.rb:123 would become foo/bar.rb diff --git a/legacy_promotions/Rakefile b/legacy_promotions/Rakefile new file mode 100644 index 00000000000..c4633164579 --- /dev/null +++ b/legacy_promotions/Rakefile @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'rubygems' +require 'rake' +require 'rake/testtask' +require 'rspec/core/rake_task' +require 'spree/testing_support/dummy_app/rake_tasks' +require 'bundler/gem_tasks' + +RSpec::Core::RakeTask.new +task default: :spec + +DummyApp::RakeTasks.new( + gem_root: File.dirname(__FILE__), + lib_name: 'solidus_legacy_promotions' +) + +require 'yard/rake/yardoc_task' +YARD::Rake::YardocTask.new(:yard) +# The following workaround can be removed +# once https://github.com/lsegal/yard/pull/1457 is merged. +task('yard:require') { require 'yard' } +task yard: 'yard:require' + +namespace :spec do + task :isolated do + spec_files = Dir['spec/**/*_spec.rb'] + failed_specs = + spec_files.reject do |file| + puts "rspec #{file}" + system('rspec', file) + end + + if !failed_specs.empty? + puts "Failed specs:" + puts failed_specs + exit 1 + end + end +end + +task test_app: 'db:reset' diff --git a/legacy_promotions/bin/rails b/legacy_promotions/bin/rails new file mode 100755 index 00000000000..35347a1f6a8 --- /dev/null +++ b/legacy_promotions/bin/rails @@ -0,0 +1,13 @@ +#!/usr/bin/env ruby +# This command will automatically be run when you run "rails" with Rails gems +# installed from the root of your application. + +ENGINE_ROOT = File.expand_path('..', __dir__) +ENGINE_PATH = File.expand_path('../lib/spree/core/engine', __dir__) + +# Set up gems listed in the Gemfile. +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __dir__) +require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"]) + +require "rails/all" +require "rails/engine/commands" diff --git a/legacy_promotions/lib/solidus_legacy_promotions.rb b/legacy_promotions/lib/solidus_legacy_promotions.rb new file mode 100644 index 00000000000..3f5857cad20 --- /dev/null +++ b/legacy_promotions/lib/solidus_legacy_promotions.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require "solidus_core" +require "solidus_support" + +module SolidusLegacyPromotions + VERSION = Spree.solidus_version +end + +require "solidus_legacy_promotions/engine" diff --git a/legacy_promotions/lib/solidus_legacy_promotions/engine.rb b/legacy_promotions/lib/solidus_legacy_promotions/engine.rb new file mode 100644 index 00000000000..7ebf4f2288a --- /dev/null +++ b/legacy_promotions/lib/solidus_legacy_promotions/engine.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module SolidusLegacyPromotions + class Engine < ::Rails::Engine + include SolidusSupport::EngineExtensions + end +end diff --git a/legacy_promotions/solidus_legacy_promotions.gemspec b/legacy_promotions/solidus_legacy_promotions.gemspec new file mode 100644 index 00000000000..778d9fc367f --- /dev/null +++ b/legacy_promotions/solidus_legacy_promotions.gemspec @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require_relative '../core/lib/spree/core/version' + +Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = 'solidus_legacy_promotions' + s.version = Spree.solidus_version + s.summary = 'Legacy Solidus promotion system' + s.description = s.summary + + s.author = 'Solidus Team' + s.email = 'contact@solidus.io' + s.homepage = 'http://solidus.io' + s.license = 'BSD-3-Clause' + + s.metadata['rubygems_mfa_required'] = 'true' + + s.files = `git ls-files -z`.split("\x0").reject do |f| + f.match(%r{^(spec|script)/}) + end + + s.required_ruby_version = '>= 3.0.0' + s.required_rubygems_version = '>= 1.8.23' + + s.add_dependency 'solidus_core', s.version + s.add_dependency 'solidus_support' +end diff --git a/legacy_promotions/spec/lib/solidus_legacy_promotions_spec.rb b/legacy_promotions/spec/lib/solidus_legacy_promotions_spec.rb new file mode 100644 index 00000000000..1e2b5254d91 --- /dev/null +++ b/legacy_promotions/spec/lib/solidus_legacy_promotions_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe SolidusLegacyPromotions do + it "has a version number" do + expect(SolidusLegacyPromotions::VERSION).not_to be nil + end +end diff --git a/legacy_promotions/spec/rails_helper.rb b/legacy_promotions/spec/rails_helper.rb new file mode 100644 index 00000000000..c86a7eba5e9 --- /dev/null +++ b/legacy_promotions/spec/rails_helper.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'spec_helper' + +ENV["RAILS_ENV"] ||= 'test' + +require 'spree/testing_support/dummy_app' +DummyApp.setup( + gem_root: File.expand_path('..', __dir__), + lib_name: 'solidus_legacy_promotions' +) + +require 'rspec/rails' +require 'rspec-activemodel-mocks' +require 'database_cleaner' + +Dir["./spec/support/**/*.rb"].sort.each { |f| require f } + +require 'spree/testing_support/factory_bot' +require 'spree/testing_support/preferences' +require 'spree/testing_support/rake' +require 'spree/testing_support/job_helpers' +require 'cancan/matchers' + +ActiveJob::Base.queue_adapter = :test + +Spree::TestingSupport::FactoryBot.add_paths_and_load! + +RSpec.configure do |config| + config.fixture_path = File.join(__dir__, "fixtures") + + config.infer_spec_type_from_file_location! + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, comment the following line or assign false + # instead of true. + config.use_transactional_fixtures = true + + config.before :suite do + FileUtils.rm_rf(Rails.configuration.active_storage.service_configurations[:test][:root]) unless ENV['DISABLE_ACTIVE_STORAGE'] == 'true' + DatabaseCleaner.clean_with :truncation + end + + config.before :each do + Rails.cache.clear + end + + config.include Spree::TestingSupport::JobHelpers + + config.include FactoryBot::Syntax::Methods +end diff --git a/legacy_promotions/spec/spec_helper.rb b/legacy_promotions/spec/spec_helper.rb new file mode 100644 index 00000000000..d2ba4e945dd --- /dev/null +++ b/legacy_promotions/spec/spec_helper.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +if ENV["COVERAGE"] + require 'simplecov' + if ENV["COVERAGE_DIR"] + SimpleCov.coverage_dir(ENV["COVERAGE_DIR"]) + end + SimpleCov.command_name('solidus:core') + SimpleCov.merge_timeout(3600) + SimpleCov.start('rails') +end + +require 'rspec/core' + +require 'spree/testing_support/flaky' +require 'spree/testing_support/partial_double_verification' +require 'spree/testing_support/silence_deprecations' +require 'spree/testing_support/preferences' +require 'spree/deprecator' +require 'spree/config' + +require "solidus_legacy_promotions" + +RSpec.configure do |config| + config.disable_monkey_patching! + config.color = true + config.expect_with :rspec do |c| + c.syntax = :expect + end + config.mock_with :rspec do |c| + c.syntax = :expect + end + + config.include Spree::TestingSupport::Preferences + + config.filter_run focus: true + config.run_all_when_everything_filtered = true + + config.example_status_persistence_file_path = "./spec/examples.txt" + + config.order = :random + + Kernel.srand config.seed +end diff --git a/solidus.gemspec b/solidus.gemspec index 4a040ee6acb..92d782ec448 100644 --- a/solidus.gemspec +++ b/solidus.gemspec @@ -25,4 +25,5 @@ Gem::Specification.new do |s| s.add_dependency 'solidus_backend', s.version s.add_dependency 'solidus_core', s.version s.add_dependency 'solidus_sample', s.version + s.add_dependency 'solidus_legacy_promotions', s.version end From 3222e60121224d9f6b7454828a3d5570663c1de9 Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Sat, 27 Jan 2024 15:58:19 +0100 Subject: [PATCH 08/10] Run legacy promotions on CI The new weights for the individual sub-projects are their duration in seconds. --- .circleci/config.yml | 3 +++ bin/build-ci | 13 +++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 82880900eec..f9cee07c97a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -117,6 +117,9 @@ commands: - run: name: "Run Sample Tests" command: ./bin/build-ci sample + - run: + name: "Run Legacy Promotion Tests" + command: ./bin/build-ci legacy_promotions - store_artifacts: path: /tmp/test-artifacts diff --git a/bin/build-ci b/bin/build-ci index 650113d8611..0569fac0418 100755 --- a/bin/build-ci +++ b/bin/build-ci @@ -21,12 +21,13 @@ class Project def self.all [ - new('admin', weight: 215), - new('api', weight: 50), - new('backend', weight: 215), - new('backend', test_type: :teaspoon, title: "backend JS", weight: 15), - new('core', weight: 220), - new('sample', weight: 22) + new('admin', weight: 102), + new('api', weight: 69), + new('backend', weight: 282), + new('backend', test_type: :teaspoon, title: "backend JS", weight: 18), + new('core', weight: 266), + new('sample', weight: 28), + new('legacy_promotions', weight: 63) ] end From 991a179b4edfd401f33622d8ad14206c8f47e5a0 Mon Sep 17 00:00:00 2001 From: andrea longhi Date: Tue, 5 Mar 2024 13:49:38 +0100 Subject: [PATCH 09/10] Fix flash messages coloring Previously, all flash messages were showing with the same (black) background. Internally, the flash object converts and stores keys as strings [1]. [1] https://github.com/rails/rails/blob/main/actionpack/lib/action_dispatch/middleware/flash.rb#L163 --- admin/app/views/layouts/solidus_admin/application.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/app/views/layouts/solidus_admin/application.html.erb b/admin/app/views/layouts/solidus_admin/application.html.erb index 4fa30ebdfd8..b65504bfc82 100644 --- a/admin/app/views/layouts/solidus_admin/application.html.erb +++ b/admin/app/views/layouts/solidus_admin/application.html.erb @@ -29,7 +29,7 @@ From f19e6fcab59db4887ba46c36ee6e2616c06d3a46 Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Wed, 6 Mar 2024 22:56:11 +0100 Subject: [PATCH 10/10] Fix JS locale data for release of Money 6.19 The money gem in its latest iteration added a space between value and unit of the Swiss Franc. Our heuristic in `_js_locale_data.html.erb` can't deal with that, so we add a third branch to it: If the money gem has a format wish, we'll respect it, but replace its abbreviations with the one the `accounting.js` library prefers. --- backend/app/assets/javascripts/spree/backend/format_money.js | 2 +- .../app/views/spree/admin/shared/_js_locale_data.html.erb | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/app/assets/javascripts/spree/backend/format_money.js b/backend/app/assets/javascripts/spree/backend/format_money.js index 6f327937053..535693cbd9a 100644 --- a/backend/app/assets/javascripts/spree/backend/format_money.js +++ b/backend/app/assets/javascripts/spree/backend/format_money.js @@ -7,5 +7,5 @@ Spree.formatMoney = function(amount, 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]); + return accounting.formatMoney(amount, currencyInfo[0], currencyInfo[1], thousand, decimal, currencyInfo[2]).trim(); } 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 785175eb772..6d66721035e 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 @@ -17,11 +17,14 @@ JSON.dump( Spree::Config.available_currencies.map { |c| format = - if c.symbol == "" || c.symbol_first + if c.format.present? + c.format.gsub("%u", "%s").gsub("%n", "%v") + elsif c.symbol == "" || c.symbol_first "%s%v" else "%v %s" end + [c.id.to_s.upcase, [ c.symbol || "ยค", c.exponent,