From ea0067946d58fbde68cdeb92e80557199a68b048 Mon Sep 17 00:00:00 2001 From: David Cook Date: Wed, 21 Feb 2024 13:25:01 +1100 Subject: [PATCH] Generate variant unit options in Ruby This re-implements Angular JS function VariantUnitManager.variantUnitOptions() Well.. almost. See next commit. --- app/services/weights_and_measures.rb | 37 +++++++++++++--- spec/services/weights_and_measures_spec.rb | 51 +++++++++++++++++++++- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/app/services/weights_and_measures.rb b/app/services/weights_and_measures.rb index 7fd8528fe7..7d9aa19b3d 100644 --- a/app/services/weights_and_measures.rb +++ b/app/services/weights_and_measures.rb @@ -20,6 +20,37 @@ class WeightsAndMeasures scales[product_scale.to_f]['system'] end + # @returns enumerable with label and value for select + def self.variant_unit_options + available_units_sorted.flat_map do |measurement, measurement_info| + measurement_info.filter_map do |scale, unit_info| + scale_clean = + ActiveSupport::NumberHelper.number_to_rounded(scale, precision: nil, + strip_insignificant_zeros: true) + [ + "#{I18n.t(measurement)} (#{unit_info['name']})", # Label (eg "Weight (g)") + "#{measurement}_#{scale_clean}", # Scale ID (eg "weight_1") + ] + end + end << + [ + I18n.t('items'), + 'items' + ] + end + + def self.available_units + Spree::Config.available_units.split(",") + end + + def self.available_units_sorted + self::UNITS.transform_values do |measurement_info| + measurement_info.filter do |_scale, unit_info| + available_units.include?(unit_info['name']) + end.sort.to_h # sort by unit (hash key) + end + end + private UNITS = { @@ -49,7 +80,7 @@ class WeightsAndMeasures return @units[@variant.product.variant_unit] if ignore_available_units @units[@variant.product.variant_unit]&.reject { |_scale, unit_info| - available_units.exclude?(unit_info['name']) + self.class.available_units.exclude?(unit_info['name']) } end @@ -67,8 +98,4 @@ class WeightsAndMeasures largest_unit end - - def available_units - Spree::Config.available_units.split(",") - end end diff --git a/spec/services/weights_and_measures_spec.rb b/spec/services/weights_and_measures_spec.rb index d84c2c5b66..6748b3c034 100644 --- a/spec/services/weights_and_measures_spec.rb +++ b/spec/services/weights_and_measures_spec.rb @@ -55,7 +55,56 @@ describe WeightsAndMeasures do end end - describe "#scale_for_unit_value" do + describe "#variant_unit_options" do + let(:available_units) { "mg,g,kg,T,mL,cL,dL,L,kL,lb,oz,gal" } + subject { WeightsAndMeasures.variant_unit_options } + + before do + allow(Spree::Config).to receive(:available_units).and_return(available_units) + end + + it "returns options for each unit" do + expected_array = [ + ["Weight (mg)", "weight_0.001"], + ["Weight (g)", "weight_1"], + ["Weight (oz)", "weight_28.35"], + ["Weight (lb)", "weight_453.6"], + ["Weight (kg)", "weight_1000"], + ["Weight (T)", "weight_1000000"], + ["Volume (mL)", "volume_0.001"], + ["Volume (cL)", "volume_0.01"], + ["Volume (dL)", "volume_0.1"], + ["Volume (L)", "volume_1"], + ["Volume (gal)", "volume_4.54609"], + ["Volume (kL)", "volume_1000"], + ["Items", "items"], + ] + pending "imperial measurements are duplicated" + expect(subject).to match_array expected_array # diff each element + expect(subject).to eq expected_array # test ordering also + end + + describe "filtering available units" do + let(:available_units) { "g,kg,mL,L,lb,oz" } + + it "returns options for available units only" do + expected_array = [ + ["Weight (g)", "weight_1"], + ["Weight (oz)", "weight_28.35"], + ["Weight (lb)", "weight_453.6"], + ["Weight (kg)", "weight_1000"], + ["Volume (mL)", "volume_0.001"], + ["Volume (L)", "volume_1"], + ["Items", "items"], + ] + pending "imperial measurements are duplicated" + expect(subject).to match_array expected_array # diff each element + expect(subject).to eq expected_array # test ordering also + end + end + end + + describe "#scales_for_unit_value" do context "weight" do before do allow(product).to receive(:variant_unit) { "weight" }