Set option type on product when variant unit changed

This commit is contained in:
Rohan Mitchell
2013-12-13 11:07:57 +11:00
parent 03aa5604e5
commit f2269654ff
2 changed files with 113 additions and 0 deletions

View File

@@ -17,6 +17,7 @@ Spree::Product.class_eval do
if: -> p { p.variant_unit == 'items' }
after_initialize :set_available_on_to_now, :if => :new_record?
after_save :update_units
# -- Joins
@@ -106,4 +107,25 @@ Spree::Product.class_eval do
def set_available_on_to_now
self.available_on ||= Time.now
end
def update_units
if variant_unit_changed?
option_types.delete self.class.all_variant_unit_option_types
option_types << option_type_for_variant_unit if variant_unit.present?
end
end
def option_type_for_variant_unit
option_type_name = "unit_#{variant_unit}"
option_type_presentation = variant_unit.capitalize
Spree::OptionType.find_by_name(option_type_name) ||
Spree::OptionType.create!(name: option_type_name, presentation: option_type_presentation)
end
def self.all_variant_unit_option_types
Spree::OptionType.where('name LIKE ?', 'unit_%%')
end
end

View File

@@ -302,5 +302,96 @@ module Spree
p1.should_not be_in_order_cycle oc2
end
end
describe "variant units" do
context "when the product initially has no variant unit" do
let!(:p) { create(:simple_product,
variant_unit: nil,
variant_unit_scale: nil,
variant_unit_name: nil) }
context "when the required option type does not exist" do
it "creates the option type and assigns it to the product" do
expect {
p.update_attributes!(variant_unit: 'weight', variant_unit_scale: 1000)
}.to change(Spree::OptionType, :count).by(1)
ot = Spree::OptionType.last
ot.name.should == 'unit_weight'
ot.presentation.should == 'Weight'
p.option_types.should == [ot]
end
it "does the same with volume" do
expect {
p.update_attributes!(variant_unit: 'volume', variant_unit_scale: 1000)
}.to change(Spree::OptionType, :count).by(1)
ot = Spree::OptionType.last
ot.name.should == 'unit_volume'
ot.presentation.should == 'Volume'
p.option_types.should == [ot]
end
it "does the same with items" do
expect {
p.update_attributes!(variant_unit: 'items', variant_unit_name: 'packet')
}.to change(Spree::OptionType, :count).by(1)
ot = Spree::OptionType.last
ot.name.should == 'unit_items'
ot.presentation.should == 'Items'
p.option_types.should == [ot]
end
end
context "when the required option type already exists" do
let!(:ot) { create(:option_type, name: 'unit_weight', presentation: 'Weight') }
it "looks up the option type and assigns it to the product" do
expect {
p.update_attributes!(variant_unit: 'weight', variant_unit_scale: 1000)
}.to change(Spree::OptionType, :count).by(0)
p.option_types.should == [ot]
end
end
end
context "when the product already has a variant unit set (and all required option types exist)" do
let!(:p) { create(:simple_product,
variant_unit: 'weight',
variant_unit_scale: 1,
variant_unit_name: nil) }
let!(:ot_volume) { create(:option_type, name: 'unit_volume', presentation: 'Volume') }
it "removes the old option type and assigns the new one" do
p.update_attributes!(variant_unit: 'volume', variant_unit_scale: 0.001)
p.option_types.should == [ot_volume]
end
it "removes the related option values from all its variants"
it "leaves option type unassigned if none is provided"
it "does not remove and re-add the option type if it is not changed" do
p.option_types.should_receive(:delete).never
p.update_attributes!(name: 'foo')
end
end
it "finds all variant unit option types" do
ot1 = create(:option_type, name: 'unit_weight', presentation: 'Weight')
ot2 = create(:option_type, name: 'unit_volume', presentation: 'Volume')
ot3 = create(:option_type, name: 'unit_items', presentation: 'Items')
ot4 = create(:option_type, name: 'foo_unit_bar', presentation: 'Foo')
Spree::Product.all_variant_unit_option_types.sort.should == [ot1, ot2, ot3].sort
end
end
end
end