diff --git a/app/assets/javascripts/admin/products/services/variant_unit_manager.js.coffee b/app/assets/javascripts/admin/products/services/variant_unit_manager.js.coffee index fa3f1fbab2..6f6aefa336 100644 --- a/app/assets/javascripts/admin/products/services/variant_unit_manager.js.coffee +++ b/app/assets/javascripts/admin/products/services/variant_unit_manager.js.coffee @@ -2,6 +2,9 @@ angular.module("admin.products").factory "VariantUnitManager", (availableUnits) class VariantUnitManager @units: 'weight': + 0.001: + name: 'mg' + system: 'metric' 1.0: name: 'g' system: 'metric' @@ -21,12 +24,21 @@ angular.module("admin.products").factory "VariantUnitManager", (availableUnits) 0.001: name: 'mL' system: 'metric' + 0.01: + name: 'cL' + system: 'metric' + 0.1: + name: 'dL' + system: 'metric' 1.0: name: 'L' system: 'metric' 1000.0: name: 'kL' system: 'metric' + 4.54609: + name: 'gal' + system: 'metric' 'items': 1: name: 'items' @@ -60,8 +72,13 @@ angular.module("admin.products").factory "VariantUnitManager", (availableUnits) @compatibleUnitScales: (scale, unitType) -> scaleSystem = @units[unitType][scale]['system'] - (parseFloat(scale) for scale, scaleInfo of @units[unitType] when scaleInfo['system'] == scaleSystem).sort (a, b) -> - a - b + if availableUnits + available = availableUnits.split(",") + (parseFloat(scale) for scale, scaleInfo of @units[unitType] when scaleInfo['system'] == scaleSystem and available.includes(scaleInfo['name'])).sort (a, b) -> + a - b + else + (parseFloat(scale) for scale, scaleInfo of @units[unitType] when scaleInfo['system'] == scaleSystem).sort (a, b) -> + a - b @systemOfMeasurement: (scale, unitType) -> if @units[unitType][scale] diff --git a/app/helpers/spree/admin/general_settings_helper.rb b/app/helpers/spree/admin/general_settings_helper.rb index a370354c37..481658a3d0 100644 --- a/app/helpers/spree/admin/general_settings_helper.rb +++ b/app/helpers/spree/admin/general_settings_helper.rb @@ -4,7 +4,10 @@ module Spree module Admin module GeneralSettingsHelper def all_units - ["g", "oz", "lb", "kg", "T", "mL", "L", "kL"] + [ + WeightsAndMeasures::UNITS['weight'].values.pluck('name'), + WeightsAndMeasures::UNITS['volume'].values.pluck('name') + ].flatten.uniq end end end diff --git a/app/services/weights_and_measures.rb b/app/services/weights_and_measures.rb index ada5523e22..7fd8528fe7 100644 --- a/app/services/weights_and_measures.rb +++ b/app/services/weights_and_measures.rb @@ -14,7 +14,7 @@ class WeightsAndMeasures end def system - return "custom" unless scales = scales_for_variant_unit + return "custom" unless scales = scales_for_variant_unit(ignore_available_units: true) return "custom" unless product_scale = @variant.product.variant_unit_scale scales[product_scale.to_f]['system'] @@ -45,8 +45,12 @@ class WeightsAndMeasures } }.freeze - def scales_for_variant_unit - @units[@variant.product.variant_unit] + def scales_for_variant_unit(ignore_available_units: false) + 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']) + } end # Find the largest available and compatible unit where unit_value comes @@ -63,4 +67,8 @@ class WeightsAndMeasures largest_unit end + + def available_units + Spree::Config.available_units.split(",") + end end diff --git a/spec/controllers/api/v0/order_cycles_controller_spec.rb b/spec/controllers/api/v0/order_cycles_controller_spec.rb index 44a72be65a..dfc6010ec1 100644 --- a/spec/controllers/api/v0/order_cycles_controller_spec.rb +++ b/spec/controllers/api/v0/order_cycles_controller_spec.rb @@ -38,6 +38,18 @@ module Api expect(product_ids).to include product1.id, product2.id, product3.id end + context "when product's variant unit scale is not in the available units list" do + before do + allow(Spree::Config).to receive(:available_units).and_return("lb,oz,kg,T,mL,L,kL") + end + + it "loads products for distributed products in the order cycle" do + api_get :products, id: order_cycle.id, distributor: distributor.id + + expect(product_ids).to include product1.id, product2.id, product3.id + end + end + it "returns products that were searched for" do ransack_param = "name_or_meta_keywords_or_variants_display_as_or_" \ "variants_display_name_or_supplier_name_cont" diff --git a/spec/helpers/spree/admin/general_settings_helper_spec.rb b/spec/helpers/spree/admin/general_settings_helper_spec.rb new file mode 100644 index 0000000000..b63d7c8cdc --- /dev/null +++ b/spec/helpers/spree/admin/general_settings_helper_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Spree::Admin::GeneralSettingsHelper, type: :helper do + describe "#all_units" do + it "returns all units" do + expect(helper.all_units).to eq(["mg", "g", "kg", "T", "oz", "lb", "mL", "cL", "dL", "L", + "kL", "gal"]) + end + end +end diff --git a/spec/javascripts/unit/admin/services/variant_unit_manager_spec.js.coffee b/spec/javascripts/unit/admin/services/variant_unit_manager_spec.js.coffee index 9a635078d0..67753efef2 100644 --- a/spec/javascripts/unit/admin/services/variant_unit_manager_spec.js.coffee +++ b/spec/javascripts/unit/admin/services/variant_unit_manager_spec.js.coffee @@ -1,48 +1,63 @@ describe "VariantUnitManager", -> VariantUnitManager = null - beforeEach -> - module "admin.products" - module ($provide)-> - $provide.value "availableUnits", "g,kg,T,mL,L,kL,lb,oz" - null + describe "with default units", -> + beforeEach -> + module "admin.products" + module ($provide)-> + $provide.value "availableUnits", "g,kg,T,mL,L,kL,lb,oz" + null - beforeEach inject (_VariantUnitManager_) -> - VariantUnitManager = _VariantUnitManager_ + beforeEach inject (_VariantUnitManager_) -> + VariantUnitManager = _VariantUnitManager_ - describe "getUnitName", -> - it "returns the unit name based on the scale and unit type (weight/volume) provided", -> - expect(VariantUnitManager.getUnitName(1, "weight")).toEqual "g" - expect(VariantUnitManager.getUnitName(1000, "weight")).toEqual "kg" - expect(VariantUnitManager.getUnitName(1000000, "weight")).toEqual "T" - expect(VariantUnitManager.getUnitName(0.001, "volume")).toEqual "mL" - expect(VariantUnitManager.getUnitName(1, "volume")).toEqual "L" - expect(VariantUnitManager.getUnitName(1000, "volume")).toEqual "kL" - expect(VariantUnitManager.getUnitName(453.6, "weight")).toEqual "lb" - expect(VariantUnitManager.getUnitName(28.35, "weight")).toEqual "oz" + describe "getUnitName", -> + it "returns the unit name based on the scale and unit type (weight/volume) provided", -> + expect(VariantUnitManager.getUnitName(1, "weight")).toEqual "g" + expect(VariantUnitManager.getUnitName(1000, "weight")).toEqual "kg" + expect(VariantUnitManager.getUnitName(1000000, "weight")).toEqual "T" + expect(VariantUnitManager.getUnitName(0.001, "volume")).toEqual "mL" + expect(VariantUnitManager.getUnitName(1, "volume")).toEqual "L" + expect(VariantUnitManager.getUnitName(1000, "volume")).toEqual "kL" + expect(VariantUnitManager.getUnitName(453.6, "weight")).toEqual "lb" + expect(VariantUnitManager.getUnitName(28.35, "weight")).toEqual "oz" - describe "unitScales", -> - it "returns a sorted set of scales for unit type weight", -> - expect(VariantUnitManager.unitScales('weight')).toEqual [1.0, 28.35, 453.6, 1000.0, 1000000.0] + describe "unitScales", -> + it "returns a sorted set of scales for unit type weight", -> + expect(VariantUnitManager.unitScales('weight')).toEqual [0.001, 1.0, 28.35, 453.6, 1000.0, 1000000.0] - it "returns a sorted set of scales for unit type volume", -> - expect(VariantUnitManager.unitScales('volume')).toEqual [0.001, 1.0, 1000.0] + it "returns a sorted set of scales for unit type volume", -> + expect(VariantUnitManager.unitScales('volume')).toEqual [0.001, 0.01, 0.1, 1.0, 4.54609, 1000.0] - describe "compatibleUnitScales", -> - it "returns a sorted set of compatible scales based on the scale and unit type provided", -> - expect(VariantUnitManager.compatibleUnitScales(1, "weight")).toEqual [1.0, 1000.0, 1000000.0] - expect(VariantUnitManager.compatibleUnitScales(453.6, "weight")).toEqual [28.35, 453.6] + describe "compatibleUnitScales", -> + it "returns a sorted set of compatible scales based on the scale and unit type provided", -> + expect(VariantUnitManager.compatibleUnitScales(1, "weight")).toEqual [1.0, 1000.0, 1000000.0] + expect(VariantUnitManager.compatibleUnitScales(453.6, "weight")).toEqual [28.35, 453.6] - describe "variantUnitOptions", -> - it "returns an array of options", -> - expect(VariantUnitManager.variantUnitOptions()).toEqual [ - ["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 (L)", "volume_1"], - ["Volume (kL)", "volume_1000"], - ["Items", "items"] - ] + describe "variantUnitOptions", -> + it "returns an array of options", -> + expect(VariantUnitManager.variantUnitOptions()).toEqual [ + ["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 (L)", "volume_1"], + ["Volume (kL)", "volume_1000"], + ["Items", "items"] + ] + + describe "should only load available units", -> + beforeEach -> + module "admin.products" + module ($provide)-> + $provide.value "availableUnits", "g,T,mL,L,kL,lb" + null + beforeEach inject (_VariantUnitManager_) -> + VariantUnitManager = _VariantUnitManager_ + + describe "compatibleUnitScales", -> + it "returns a sorted set of compatible scales based on the scale and unit type provided", -> + expect(VariantUnitManager.compatibleUnitScales(1, "weight")).toEqual [1.0, 1000000.0] + expect(VariantUnitManager.compatibleUnitScales(453.6, "weight")).toEqual [453.6] diff --git a/spec/models/spree/line_item_spec.rb b/spec/models/spree/line_item_spec.rb index 527b86d551..2a1499a288 100644 --- a/spec/models/spree/line_item_spec.rb +++ b/spec/models/spree/line_item_spec.rb @@ -696,13 +696,17 @@ module Spree let(:v2) { create(:variant, product: p2, unit_value: 453.6) } let(:li2) { create(:line_item, order: o, product: p2, variant: v2) } + before do + allow(Spree::Config).to receive(:available_units).and_return("g,lb,oz,kg,T,mL,L,kL") + end + it "returns options_text" do li = build_stubbed(:line_item) allow(li).to receive(:options_text).and_return "ponies" expect(li.unit_to_display).to eq("ponies") end - it "returns options_text based on units" do + it "returns options_text based on configured units" do expect(li1.options_text).to eq("500g") expect(li2.options_text).to eq("1lb") end diff --git a/spec/services/unit_prices_spec.rb b/spec/services/unit_prices_spec.rb index eaec852e44..ef9aa86bee 100644 --- a/spec/services/unit_prices_spec.rb +++ b/spec/services/unit_prices_spec.rb @@ -9,6 +9,7 @@ describe UnitPrice do before do allow(variant).to receive(:product) { product } + allow(Spree::Config).to receive(:available_units).and_return("g,lb,oz,kg,T,mL,L,kL") end describe "#unit" do diff --git a/spec/services/variant_units/option_value_namer_spec.rb b/spec/services/variant_units/option_value_namer_spec.rb index cf9178c244..6d71ac3966 100644 --- a/spec/services/variant_units/option_value_namer_spec.rb +++ b/spec/services/variant_units/option_value_namer_spec.rb @@ -62,6 +62,10 @@ module VariantUnits let(:v) { Spree::Variant.new } let(:subject) { OptionValueNamer.new v } + before do + allow(Spree::Config).to receive(:available_units).and_return("g,lb,oz,kg,T,mL,L,kL") + end + it "generates simple values" do p = double(:product, variant_unit: 'weight', variant_unit_scale: 1.0) allow(v).to receive(:product) { p } diff --git a/spec/services/weights_and_measures_spec.rb b/spec/services/weights_and_measures_spec.rb index c6f98e6e5a..d84c2c5b66 100644 --- a/spec/services/weights_and_measures_spec.rb +++ b/spec/services/weights_and_measures_spec.rb @@ -6,9 +6,13 @@ describe WeightsAndMeasures do subject { WeightsAndMeasures.new(variant) } let(:variant) { Spree::Variant.new } let(:product) { instance_double(Spree::Product) } + let(:available_units) { + ["mg", "g", "kg", "T", "oz", "lb", "mL", "cL", "dL", "L", "kL", "gal"].join(",") + } before do allow(variant).to receive(:product) { product } + allow(Spree::Config).to receive(:available_units).and_return(available_units) end describe "#system" do @@ -69,16 +73,43 @@ describe WeightsAndMeasures do allow(variant).to receive(:unit_value) { 1500 } expect(subject.scale_for_unit_value).to eq([1000.0, "kg"]) end + + describe "should not display in kg if this unit is not selected" do + let(:available_units) { ["mg", "g", "T"].join(",") } + + it "should display in g" do + allow(product).to receive(:variant_unit_scale) { 1.0 } + allow(variant).to receive(:unit_value) { 1500 } + expect(subject.scale_for_unit_value).to eq([1.0, "g"]) + end + end end end context "volume" do - it "for a unit value that should display in L" do + it "for a unit value that should display in kL" do allow(product).to receive(:variant_unit) { "volume" } allow(product).to receive(:variant_unit_scale) { 1.0 } allow(variant).to receive(:unit_value) { 1500 } expect(subject.scale_for_unit_value).to eq([1000, "kL"]) end + + it "for a unit value that should display in dL" do + allow(product).to receive(:variant_unit) { "volume" } + allow(product).to receive(:variant_unit_scale) { 1.0 } + allow(variant).to receive(:unit_value) { 0.5 } + expect(subject.scale_for_unit_value).to eq([0.1, "dL"]) + end + + context "should not display in dL/cL if those units are not selected" do + let(:available_units){ ["mL", "L", "kL", "gal"].join(",") } + it "for a unit value that should display in mL" do + allow(product).to receive(:variant_unit) { "volume" } + allow(product).to receive(:variant_unit_scale) { 1.0 } + allow(variant).to receive(:unit_value) { 0.5 } + expect(subject.scale_for_unit_value).to eq([0.001, "mL"]) + end + end end context "items" do