From d13bd86e4c374590fc8191ecee5ac6323cdf4267 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 6 Aug 2020 10:16:54 +0100 Subject: [PATCH 1/9] Bring stocck movement and stock location from spree --- app/models/spree/stock_location.rb | 79 +++++++++ app/models/spree/stock_movement.rb | 25 +++ spec/models/spree/stock_location_spec.rb | 205 +++++++++++++++++++++++ spec/models/spree/stock_movement_spec.rb | 48 ++++++ 4 files changed, 357 insertions(+) create mode 100644 app/models/spree/stock_location.rb create mode 100644 app/models/spree/stock_movement.rb create mode 100644 spec/models/spree/stock_location_spec.rb create mode 100644 spec/models/spree/stock_movement_spec.rb diff --git a/app/models/spree/stock_location.rb b/app/models/spree/stock_location.rb new file mode 100644 index 0000000000..57cfd3f2b1 --- /dev/null +++ b/app/models/spree/stock_location.rb @@ -0,0 +1,79 @@ +module Spree + class StockLocation < ActiveRecord::Base + has_many :stock_items, dependent: :delete_all + has_many :stock_movements, through: :stock_items + + belongs_to :state, class_name: 'Spree::State' + belongs_to :country, class_name: 'Spree::Country' + + validates_presence_of :name + + scope :active, -> { where(active: true) } + + after_create :create_stock_items, :if => "self.propagate_all_variants?" + + # Wrapper for creating a new stock item respecting the backorderable config + def propagate_variant(variant) + self.stock_items.create!(variant: variant, backorderable: self.backorderable_default) + end + + # Return either an existing stock item or create a new one. Useful in + # scenarios where the user might not know whether there is already a stock + # item for a given variant + def set_up_stock_item(variant) + self.stock_item(variant) || propagate_variant(variant) + end + + def stock_item(variant) + stock_items.where(variant_id: variant).order(:id).first + end + + def stock_item_or_create(variant) + stock_item(variant) || stock_items.create(variant: variant) + end + + def count_on_hand(variant) + stock_item(variant).try(:count_on_hand) + end + + def backorderable?(variant) + stock_item(variant).try(:backorderable?) + end + + def restock(variant, quantity, originator = nil) + move(variant, quantity, originator) + end + + def unstock(variant, quantity, originator = nil) + move(variant, -quantity, originator) + end + + def move(variant, quantity, originator = nil) + stock_item_or_create(variant).stock_movements.create!(quantity: quantity, + originator: originator) + end + + def fill_status(variant, quantity) + if item = stock_item(variant) + + if item.count_on_hand >= quantity + on_hand = quantity + backordered = 0 + else + on_hand = item.count_on_hand + on_hand = 0 if on_hand < 0 + backordered = item.backorderable? ? (quantity - on_hand) : 0 + end + + [on_hand, backordered] + else + [0, 0] + end + end + + private + def create_stock_items + Variant.find_each { |variant| self.propagate_variant(variant) } + end + end +end diff --git a/app/models/spree/stock_movement.rb b/app/models/spree/stock_movement.rb new file mode 100644 index 0000000000..33281653c0 --- /dev/null +++ b/app/models/spree/stock_movement.rb @@ -0,0 +1,25 @@ +module Spree + class StockMovement < ActiveRecord::Base + belongs_to :stock_item, class_name: 'Spree::StockItem' + belongs_to :originator, polymorphic: true + + + after_create :update_stock_item_quantity + + validates :stock_item, presence: true + validates :quantity, presence: true + + scope :recent, -> { order('created_at DESC') } + + def readonly? + !new_record? + end + + private + def update_stock_item_quantity + return unless Spree::Config[:track_inventory_levels] + stock_item.adjust_count_on_hand quantity + end + end +end + diff --git a/spec/models/spree/stock_location_spec.rb b/spec/models/spree/stock_location_spec.rb new file mode 100644 index 0000000000..02a55ac877 --- /dev/null +++ b/spec/models/spree/stock_location_spec.rb @@ -0,0 +1,205 @@ +require 'spec_helper' + +module Spree + describe StockLocation do + subject { create(:stock_location_with_items, backorderable_default: true) } + let(:stock_item) { subject.stock_items.order(:id).first } + let(:variant) { stock_item.variant } + + it 'creates stock_items for all variants' do + subject.stock_items.count.should eq Variant.count + end + + context "handling stock items" do + let!(:variant) { create(:variant) } + + context "given a variant" do + subject { StockLocation.create(name: "testing", propagate_all_variants: false) } + + context "set up" do + it "creates stock item" do + subject.should_receive(:propagate_variant) + subject.set_up_stock_item(variant) + end + + context "stock item exists" do + let!(:stock_item) { subject.propagate_variant(variant) } + + it "returns existing stock item" do + subject.set_up_stock_item(variant).should == stock_item + end + end + end + + context "propagate variants" do + let(:stock_item) { subject.propagate_variant(variant) } + + it "creates a new stock item" do + expect { + subject.propagate_variant(variant) + }.to change{ StockItem.count }.by(1) + end + + context "passes backorderable default config" do + context "true" do + before { subject.backorderable_default = true } + it { stock_item.backorderable.should be_true } + end + + context "false" do + before { subject.backorderable_default = false } + it { stock_item.backorderable.should be_false } + end + end + end + + context "propagate all variants" do + subject { StockLocation.new(name: "testing") } + + context "true" do + before { subject.propagate_all_variants = true } + + specify do + subject.should_receive(:propagate_variant).at_least(:once) + subject.save! + end + end + + context "false" do + before { subject.propagate_all_variants = false } + + specify do + subject.should_not_receive(:propagate_variant) + subject.save! + end + end + end + end + end + + it 'finds a stock_item for a variant' do + stock_item = subject.stock_item(variant) + stock_item.count_on_hand.should eq 10 + end + + it 'finds a stock_item for a variant by id' do + stock_item = subject.stock_item(variant.id) + stock_item.variant.should eq variant + end + + it 'returns nil when stock_item is not found for variant' do + stock_item = subject.stock_item(100) + stock_item.should be_nil + end + + it 'creates a stock_item if not found for a variant' do + variant = create(:variant) + variant.stock_items.destroy_all + variant.save + + stock_item = subject.stock_item_or_create(variant) + stock_item.variant.should eq variant + end + + it 'finds a count_on_hand for a variant' do + subject.count_on_hand(variant).should eq 10 + end + + it 'finds determines if you a variant is backorderable' do + subject.backorderable?(variant).should be_true + end + + it 'restocks a variant with a positive stock movement' do + originator = double + subject.should_receive(:move).with(variant, 5, originator) + subject.restock(variant, 5, originator) + end + + it 'unstocks a variant with a negative stock movement' do + originator = double + subject.should_receive(:move).with(variant, -5, originator) + subject.unstock(variant, 5, originator) + end + + it 'it creates a stock_movement' do + expect { + subject.move variant, 5 + }.to change { subject.stock_movements.where(stock_item_id: stock_item).count }.by(1) + end + + it 'can be deactivated' do + create(:stock_location, :active => true) + create(:stock_location, :active => false) + Spree::StockLocation.active.count.should eq 1 + end + + context 'fill_status' do + it 'all on_hand with no backordered' do + on_hand, backordered = subject.fill_status(variant, 5) + on_hand.should eq 5 + backordered.should eq 0 + end + + it 'some on_hand with some backordered' do + on_hand, backordered = subject.fill_status(variant, 20) + on_hand.should eq 10 + backordered.should eq 10 + end + + it 'zero on_hand with all backordered' do + zero_stock_item = mock_model(StockItem, + count_on_hand: 0, + backorderable?: true) + subject.should_receive(:stock_item).with(variant).and_return(zero_stock_item) + + on_hand, backordered = subject.fill_status(variant, 20) + on_hand.should eq 0 + backordered.should eq 20 + end + + context 'when backordering is not allowed' do + before do + @stock_item = mock_model(StockItem, backorderable?: false) + subject.should_receive(:stock_item).with(variant).and_return(@stock_item) + end + + it 'all on_hand' do + @stock_item.stub(count_on_hand: 10) + + on_hand, backordered = subject.fill_status(variant, 5) + on_hand.should eq 5 + backordered.should eq 0 + end + + it 'some on_hand' do + @stock_item.stub(count_on_hand: 10) + + on_hand, backordered = subject.fill_status(variant, 20) + on_hand.should eq 10 + backordered.should eq 0 + end + + it 'zero on_hand' do + @stock_item.stub(count_on_hand: 0) + + on_hand, backordered = subject.fill_status(variant, 20) + on_hand.should eq 0 + backordered.should eq 0 + end + end + + context 'without stock_items' do + subject { create(:stock_location) } + let(:variant) { create(:base_variant) } + + it 'zero on_hand and backordered', focus: true do + subject + variant.stock_items.destroy_all + on_hand, backordered = subject.fill_status(variant, 1) + on_hand.should eq 0 + backordered.should eq 0 + end + end + end + end +end diff --git a/spec/models/spree/stock_movement_spec.rb b/spec/models/spree/stock_movement_spec.rb new file mode 100644 index 0000000000..fcc387c460 --- /dev/null +++ b/spec/models/spree/stock_movement_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' + +describe Spree::StockMovement do + let(:stock_location) { create(:stock_location_with_items) } + let(:stock_item) { stock_location.stock_items.order(:id).first } + subject { build(:stock_movement, stock_item: stock_item) } + + it 'should belong to a stock item' do + subject.should respond_to(:stock_item) + end + + it 'is readonly unless new' do + subject.save + expect { + subject.save + }.to raise_error(ActiveRecord::ReadOnlyRecord) + end + + it 'does not update count on hand when track inventory levels is false' do + Spree::Config[:track_inventory_levels] = false + subject.quantity = 1 + subject.save + stock_item.reload + stock_item.count_on_hand.should == 10 + end + + context "when quantity is negative" do + context "after save" do + it "should decrement the stock item count on hand" do + subject.quantity = -1 + subject.save + stock_item.reload + stock_item.count_on_hand.should == 9 + end + end + end + + context "when quantity is positive" do + context "after save" do + it "should increment the stock item count on hand" do + subject.quantity = 1 + subject.save + stock_item.reload + stock_item.count_on_hand.should == 11 + end + end + end +end From 0b053c18af41ecffc8f498059136e421d37c1857 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 6 Aug 2020 10:17:50 +0100 Subject: [PATCH 2/9] Merge decoorator with original file from spree --- app/models/spree/stock_location.rb | 19 ++----------------- app/models/spree/stock_location_decorator.rb | 9 --------- 2 files changed, 2 insertions(+), 26 deletions(-) delete mode 100644 app/models/spree/stock_location_decorator.rb diff --git a/app/models/spree/stock_location.rb b/app/models/spree/stock_location.rb index 57cfd3f2b1..a1e19233c0 100644 --- a/app/models/spree/stock_location.rb +++ b/app/models/spree/stock_location.rb @@ -49,26 +49,11 @@ module Spree end def move(variant, quantity, originator = nil) - stock_item_or_create(variant).stock_movements.create!(quantity: quantity, - originator: originator) + variant.move(quantity, originator) end def fill_status(variant, quantity) - if item = stock_item(variant) - - if item.count_on_hand >= quantity - on_hand = quantity - backordered = 0 - else - on_hand = item.count_on_hand - on_hand = 0 if on_hand < 0 - backordered = item.backorderable? ? (quantity - on_hand) : 0 - end - - [on_hand, backordered] - else - [0, 0] - end + variant.fill_status(quantity) end private diff --git a/app/models/spree/stock_location_decorator.rb b/app/models/spree/stock_location_decorator.rb deleted file mode 100644 index 87702616c7..0000000000 --- a/app/models/spree/stock_location_decorator.rb +++ /dev/null @@ -1,9 +0,0 @@ -Spree::StockLocation.class_eval do - def move(variant, quantity, originator = nil) - variant.move(quantity, originator) - end - - def fill_status(variant, quantity) - variant.fill_status(quantity) - end -end From e89eb8f76c1144c3dd44cbaaa46b341b08c9f732 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 6 Aug 2020 10:23:08 +0100 Subject: [PATCH 3/9] Fix simepl rubocop issues --- app/models/spree/stock_location.rb | 17 ++++++++++------- app/models/spree/stock_movement.rb | 6 ++++-- spec/models/spree/stock_location_spec.rb | 8 +++++--- spec/models/spree/stock_movement_spec.rb | 2 ++ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/app/models/spree/stock_location.rb b/app/models/spree/stock_location.rb index a1e19233c0..e46461d27a 100644 --- a/app/models/spree/stock_location.rb +++ b/app/models/spree/stock_location.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Spree class StockLocation < ActiveRecord::Base has_many :stock_items, dependent: :delete_all @@ -6,22 +8,22 @@ module Spree belongs_to :state, class_name: 'Spree::State' belongs_to :country, class_name: 'Spree::Country' - validates_presence_of :name + validates :name, presence: true scope :active, -> { where(active: true) } - after_create :create_stock_items, :if => "self.propagate_all_variants?" + after_create :create_stock_items, if: "self.propagate_all_variants?" # Wrapper for creating a new stock item respecting the backorderable config def propagate_variant(variant) - self.stock_items.create!(variant: variant, backorderable: self.backorderable_default) + stock_items.create!(variant: variant, backorderable: backorderable_default) end # Return either an existing stock item or create a new one. Useful in # scenarios where the user might not know whether there is already a stock # item for a given variant def set_up_stock_item(variant) - self.stock_item(variant) || propagate_variant(variant) + stock_item(variant) || propagate_variant(variant) end def stock_item(variant) @@ -57,8 +59,9 @@ module Spree end private - def create_stock_items - Variant.find_each { |variant| self.propagate_variant(variant) } - end + + def create_stock_items + Variant.find_each { |variant| propagate_variant(variant) } + end end end diff --git a/app/models/spree/stock_movement.rb b/app/models/spree/stock_movement.rb index 33281653c0..1b799754d9 100644 --- a/app/models/spree/stock_movement.rb +++ b/app/models/spree/stock_movement.rb @@ -1,9 +1,10 @@ +# frozen_string_literal: true + module Spree class StockMovement < ActiveRecord::Base belongs_to :stock_item, class_name: 'Spree::StockItem' belongs_to :originator, polymorphic: true - after_create :update_stock_item_quantity validates :stock_item, presence: true @@ -16,10 +17,11 @@ module Spree end private + def update_stock_item_quantity return unless Spree::Config[:track_inventory_levels] + stock_item.adjust_count_on_hand quantity end end end - diff --git a/spec/models/spree/stock_location_spec.rb b/spec/models/spree/stock_location_spec.rb index 02a55ac877..261a5b175d 100644 --- a/spec/models/spree/stock_location_spec.rb +++ b/spec/models/spree/stock_location_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' module Spree @@ -102,7 +104,7 @@ module Spree end it 'finds a count_on_hand for a variant' do - subject.count_on_hand(variant).should eq 10 + subject.count_on_hand(variant).should eq 10 end it 'finds determines if you a variant is backorderable' do @@ -128,8 +130,8 @@ module Spree end it 'can be deactivated' do - create(:stock_location, :active => true) - create(:stock_location, :active => false) + create(:stock_location, active: true) + create(:stock_location, active: false) Spree::StockLocation.active.count.should eq 1 end diff --git a/spec/models/spree/stock_movement_spec.rb b/spec/models/spree/stock_movement_spec.rb index fcc387c460..54a10620e4 100644 --- a/spec/models/spree/stock_movement_spec.rb +++ b/spec/models/spree/stock_movement_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Spree::StockMovement do From 8f19ad06461df9fa1ad5070d4ce0597e0666ebd1 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 6 Aug 2020 10:23:53 +0100 Subject: [PATCH 4/9] Delete dead code --- app/models/spree/stock_location.rb | 7 ------- spec/models/spree/stock_location_spec.rb | 15 --------------- 2 files changed, 22 deletions(-) diff --git a/app/models/spree/stock_location.rb b/app/models/spree/stock_location.rb index e46461d27a..a90c94f240 100644 --- a/app/models/spree/stock_location.rb +++ b/app/models/spree/stock_location.rb @@ -19,13 +19,6 @@ module Spree stock_items.create!(variant: variant, backorderable: backorderable_default) end - # Return either an existing stock item or create a new one. Useful in - # scenarios where the user might not know whether there is already a stock - # item for a given variant - def set_up_stock_item(variant) - stock_item(variant) || propagate_variant(variant) - end - def stock_item(variant) stock_items.where(variant_id: variant).order(:id).first end diff --git a/spec/models/spree/stock_location_spec.rb b/spec/models/spree/stock_location_spec.rb index 261a5b175d..6fe9ce9388 100644 --- a/spec/models/spree/stock_location_spec.rb +++ b/spec/models/spree/stock_location_spec.rb @@ -18,21 +18,6 @@ module Spree context "given a variant" do subject { StockLocation.create(name: "testing", propagate_all_variants: false) } - context "set up" do - it "creates stock item" do - subject.should_receive(:propagate_variant) - subject.set_up_stock_item(variant) - end - - context "stock item exists" do - let!(:stock_item) { subject.propagate_variant(variant) } - - it "returns existing stock item" do - subject.set_up_stock_item(variant).should == stock_item - end - end - end - context "propagate variants" do let(:stock_item) { subject.propagate_variant(variant) } From e0ea25b7a3dc35aca4714bb614d4e05efae8e480 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 6 Aug 2020 10:25:09 +0100 Subject: [PATCH 5/9] track_inventory_levels is always true in OFN --- app/models/spree/stock_movement.rb | 2 -- spec/models/spree/stock_movement_spec.rb | 8 -------- 2 files changed, 10 deletions(-) diff --git a/app/models/spree/stock_movement.rb b/app/models/spree/stock_movement.rb index 1b799754d9..f435ed1f50 100644 --- a/app/models/spree/stock_movement.rb +++ b/app/models/spree/stock_movement.rb @@ -19,8 +19,6 @@ module Spree private def update_stock_item_quantity - return unless Spree::Config[:track_inventory_levels] - stock_item.adjust_count_on_hand quantity end end diff --git a/spec/models/spree/stock_movement_spec.rb b/spec/models/spree/stock_movement_spec.rb index 54a10620e4..de48d90459 100644 --- a/spec/models/spree/stock_movement_spec.rb +++ b/spec/models/spree/stock_movement_spec.rb @@ -18,14 +18,6 @@ describe Spree::StockMovement do }.to raise_error(ActiveRecord::ReadOnlyRecord) end - it 'does not update count on hand when track inventory levels is false' do - Spree::Config[:track_inventory_levels] = false - subject.quantity = 1 - subject.save - stock_item.reload - stock_item.count_on_hand.should == 10 - end - context "when quantity is negative" do context "after save" do it "should decrement the stock item count on hand" do From d87d5d3537945a84097a53b5e91734c376ee739d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 6 Aug 2020 10:51:24 +0100 Subject: [PATCH 6/9] Fix stock_movement and stock_location specs brought from spree_core propagate_all_variants is always true in OFN --- app/models/spree/stock_location.rb | 2 +- spec/models/spree/stock_location_spec.rb | 152 +++++------------------ spec/models/spree/stock_movement_spec.rb | 6 +- 3 files changed, 37 insertions(+), 123 deletions(-) diff --git a/app/models/spree/stock_location.rb b/app/models/spree/stock_location.rb index a90c94f240..cb017cfe68 100644 --- a/app/models/spree/stock_location.rb +++ b/app/models/spree/stock_location.rb @@ -12,7 +12,7 @@ module Spree scope :active, -> { where(active: true) } - after_create :create_stock_items, if: "self.propagate_all_variants?" + after_create :create_stock_items # Wrapper for creating a new stock item respecting the backorderable config def propagate_variant(variant) diff --git a/spec/models/spree/stock_location_spec.rb b/spec/models/spree/stock_location_spec.rb index 6fe9ce9388..22c7e43361 100644 --- a/spec/models/spree/stock_location_spec.rb +++ b/spec/models/spree/stock_location_spec.rb @@ -9,56 +9,21 @@ module Spree let(:variant) { stock_item.variant } it 'creates stock_items for all variants' do - subject.stock_items.count.should eq Variant.count + expect(subject.stock_items.count).to eq Variant.count end context "handling stock items" do let!(:variant) { create(:variant) } context "given a variant" do - subject { StockLocation.create(name: "testing", propagate_all_variants: false) } - - context "propagate variants" do - let(:stock_item) { subject.propagate_variant(variant) } - - it "creates a new stock item" do - expect { - subject.propagate_variant(variant) - }.to change{ StockItem.count }.by(1) - end - - context "passes backorderable default config" do - context "true" do - before { subject.backorderable_default = true } - it { stock_item.backorderable.should be_true } - end - - context "false" do - before { subject.backorderable_default = false } - it { stock_item.backorderable.should be_false } - end - end - end - context "propagate all variants" do subject { StockLocation.new(name: "testing") } - context "true" do - before { subject.propagate_all_variants = true } + before { subject.propagate_all_variants = true } - specify do - subject.should_receive(:propagate_variant).at_least(:once) - subject.save! - end - end - - context "false" do - before { subject.propagate_all_variants = false } - - specify do - subject.should_not_receive(:propagate_variant) - subject.save! - end + specify do + expect(subject).to receive(:propagate_variant).at_least(:once) + subject.save! end end end @@ -66,126 +31,75 @@ module Spree it 'finds a stock_item for a variant' do stock_item = subject.stock_item(variant) - stock_item.count_on_hand.should eq 10 + expect(stock_item.count_on_hand).to eq 15 end it 'finds a stock_item for a variant by id' do stock_item = subject.stock_item(variant.id) - stock_item.variant.should eq variant + expect(stock_item.variant).to eq variant end it 'returns nil when stock_item is not found for variant' do stock_item = subject.stock_item(100) - stock_item.should be_nil - end - - it 'creates a stock_item if not found for a variant' do - variant = create(:variant) - variant.stock_items.destroy_all - variant.save - - stock_item = subject.stock_item_or_create(variant) - stock_item.variant.should eq variant + expect(stock_item).to be_nil end it 'finds a count_on_hand for a variant' do - subject.count_on_hand(variant).should eq 10 + expect(subject.count_on_hand(variant)).to eq 15 end it 'finds determines if you a variant is backorderable' do - subject.backorderable?(variant).should be_true + expect(subject.backorderable?(variant)).to be_truthy end it 'restocks a variant with a positive stock movement' do originator = double - subject.should_receive(:move).with(variant, 5, originator) + expect(subject).to receive(:move).with(variant, 5, originator) subject.restock(variant, 5, originator) end it 'unstocks a variant with a negative stock movement' do originator = double - subject.should_receive(:move).with(variant, -5, originator) + expect(subject).to receive(:move).with(variant, -5, originator) subject.unstock(variant, 5, originator) end it 'it creates a stock_movement' do + variant.on_demand = false expect { subject.move variant, 5 }.to change { subject.stock_movements.where(stock_item_id: stock_item).count }.by(1) end - it 'can be deactivated' do - create(:stock_location, active: true) - create(:stock_location, active: false) - Spree::StockLocation.active.count.should eq 1 - end - context 'fill_status' do - it 'all on_hand with no backordered' do + before { variant.on_demand = false } + + it 'is all on_hand if variant is on_demand' do + variant.on_demand = true + + on_hand, backordered = subject.fill_status(variant, 25) + expect(on_hand).to eq 25 + expect(backordered).to eq 0 + end + + it 'is all on_hand if on_hand is enough' do on_hand, backordered = subject.fill_status(variant, 5) - on_hand.should eq 5 - backordered.should eq 0 + expect(on_hand).to eq 5 + expect(backordered).to eq 0 end - it 'some on_hand with some backordered' do + it 'is some on_hand if not all available' do on_hand, backordered = subject.fill_status(variant, 20) - on_hand.should eq 10 - backordered.should eq 10 + expect(on_hand).to eq 15 + expect(backordered).to eq 0 end - it 'zero on_hand with all backordered' do - zero_stock_item = mock_model(StockItem, - count_on_hand: 0, - backorderable?: true) - subject.should_receive(:stock_item).with(variant).and_return(zero_stock_item) + it 'is zero on_hand if none available' do + variant.on_hand = 0 on_hand, backordered = subject.fill_status(variant, 20) - on_hand.should eq 0 - backordered.should eq 20 - end - - context 'when backordering is not allowed' do - before do - @stock_item = mock_model(StockItem, backorderable?: false) - subject.should_receive(:stock_item).with(variant).and_return(@stock_item) - end - - it 'all on_hand' do - @stock_item.stub(count_on_hand: 10) - - on_hand, backordered = subject.fill_status(variant, 5) - on_hand.should eq 5 - backordered.should eq 0 - end - - it 'some on_hand' do - @stock_item.stub(count_on_hand: 10) - - on_hand, backordered = subject.fill_status(variant, 20) - on_hand.should eq 10 - backordered.should eq 0 - end - - it 'zero on_hand' do - @stock_item.stub(count_on_hand: 0) - - on_hand, backordered = subject.fill_status(variant, 20) - on_hand.should eq 0 - backordered.should eq 0 - end - end - - context 'without stock_items' do - subject { create(:stock_location) } - let(:variant) { create(:base_variant) } - - it 'zero on_hand and backordered', focus: true do - subject - variant.stock_items.destroy_all - on_hand, backordered = subject.fill_status(variant, 1) - on_hand.should eq 0 - backordered.should eq 0 - end + expect(on_hand).to eq 0 + expect(backordered).to eq 0 end end end diff --git a/spec/models/spree/stock_movement_spec.rb b/spec/models/spree/stock_movement_spec.rb index de48d90459..2da7976c57 100644 --- a/spec/models/spree/stock_movement_spec.rb +++ b/spec/models/spree/stock_movement_spec.rb @@ -8,7 +8,7 @@ describe Spree::StockMovement do subject { build(:stock_movement, stock_item: stock_item) } it 'should belong to a stock item' do - subject.should respond_to(:stock_item) + expect(subject).to respond_to(:stock_item) end it 'is readonly unless new' do @@ -24,7 +24,7 @@ describe Spree::StockMovement do subject.quantity = -1 subject.save stock_item.reload - stock_item.count_on_hand.should == 9 + expect(stock_item.count_on_hand).to eq 14 end end end @@ -35,7 +35,7 @@ describe Spree::StockMovement do subject.quantity = 1 subject.save stock_item.reload - stock_item.count_on_hand.should == 11 + expect(stock_item.count_on_hand).to eq 16 end end end From bf81b5a3053e0a3b3c5fa6a8d5b8004b6d7b68be Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 7 Aug 2020 08:53:09 +0100 Subject: [PATCH 7/9] Remove unnecessary setup code in spec, propagate_all_variants is always true in OFN --- spec/models/spree/stock_location_spec.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/models/spree/stock_location_spec.rb b/spec/models/spree/stock_location_spec.rb index 22c7e43361..86996b40b4 100644 --- a/spec/models/spree/stock_location_spec.rb +++ b/spec/models/spree/stock_location_spec.rb @@ -19,8 +19,6 @@ module Spree context "propagate all variants" do subject { StockLocation.new(name: "testing") } - before { subject.propagate_all_variants = true } - specify do expect(subject).to receive(:propagate_variant).at_least(:once) subject.save! From 3198bbd3cb5f235d3f08ab967d9a513cdd0fb3c5 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 1 Sep 2020 10:17:45 +0100 Subject: [PATCH 8/9] Bring required factory from spree_core --- spec/factories/stock_location_factory.rb | 12 ++++++++++++ spec/models/spree/stock_item_spec.rb | 10 +--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/spec/factories/stock_location_factory.rb b/spec/factories/stock_location_factory.rb index 48fc14d772..f348788700 100644 --- a/spec/factories/stock_location_factory.rb +++ b/spec/factories/stock_location_factory.rb @@ -18,5 +18,17 @@ FactoryBot.define do state do |stock_location| stock_location.country.states.first || stock_location.association(:state, country: stock_location.country) end + + factory :stock_location_with_items do + after(:create) do |stock_location, evaluator| + # variant will add itself to all stock_locations in an after_create + # creating a product will automatically create a master variant + product_1 = create(:product) + product_2 = create(:product) + + stock_location.stock_items.where(:variant_id => product_1.master.id).first.adjust_count_on_hand(10) + stock_location.stock_items.where(:variant_id => product_2.master.id).first.adjust_count_on_hand(20) + end + end end end diff --git a/spec/models/spree/stock_item_spec.rb b/spec/models/spree/stock_item_spec.rb index 6dccf13665..9c9b233986 100644 --- a/spec/models/spree/stock_item_spec.rb +++ b/spec/models/spree/stock_item_spec.rb @@ -3,15 +3,7 @@ require 'spec_helper' RSpec.describe Spree::StockItem do - let(:stock_location) { create(:stock_location) } - - before do - product_1 = create(:product) - product_2 = create(:product) - - stock_location.stock_items.where(variant_id: product_1.master.id).first.adjust_count_on_hand(10) - stock_location.stock_items.where(variant_id: product_2.master.id).first.adjust_count_on_hand(20) - end + let(:stock_location) { create(:stock_location_with_items) } subject { stock_location.stock_items.order(:id).first } From b35d579f64e3c930719ad6c10b257d765b13fe8d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 1 Sep 2020 10:20:51 +0100 Subject: [PATCH 9/9] Bring stock_movement factory from spree_core --- spec/factories/stock_movement_factory.rb | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 spec/factories/stock_movement_factory.rb diff --git a/spec/factories/stock_movement_factory.rb b/spec/factories/stock_movement_factory.rb new file mode 100644 index 0000000000..b2eb1cd65e --- /dev/null +++ b/spec/factories/stock_movement_factory.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :stock_movement, class: Spree::StockMovement do + quantity 1 + action 'sold' + end +end