diff --git a/core/app/models/spree/stock/quantifier.rb b/core/app/models/spree/stock/quantifier.rb index 38a669c4bff..322c5a2ab5d 100644 --- a/core/app/models/spree/stock/quantifier.rb +++ b/core/app/models/spree/stock/quantifier.rb @@ -43,10 +43,23 @@ def can_supply?(required) total_on_hand >= required || backorderable? end + def positive_stock + return unless stock_location + + on_hand = stock_location.count_on_hand(variant) + on_hand.positive? ? on_hand : 0 + end + private attr_reader :variant, :stock_location_or_id + def stock_location + @stock_location ||= stock_location_or_id.is_a?(Spree::StockLocation) ? + stock_location_or_id : + Spree::StockLocation.find_by(id: stock_location_or_id) + end + def get_stock_items variant.stock_items.select do |stock_item| if stock_location_or_id diff --git a/core/spec/models/spree/stock/quantifier_spec.rb b/core/spec/models/spree/stock/quantifier_spec.rb index 4bc01f0d270..51d219f6ce7 100644 --- a/core/spec/models/spree/stock/quantifier_spec.rb +++ b/core/spec/models/spree/stock/quantifier_spec.rb @@ -12,6 +12,25 @@ module Stock expect(subject.can_supply?(100_001)).to eq true end end + + shared_examples_for "returns the positive stock on hand" do + context "when the stock location has no stock for the variant" do + it { is_expected.to be_zero } + end + + context "when the stock location has negative stock for the variant" do + before { stock_item.set_count_on_hand(-1) } + + it { is_expected.to be_zero } + end + + context "when the stock location has positive stock for the variant" do + before { stock_item.set_count_on_hand(10) } + + it { is_expected.to eq(10) } + end + end + let(:target_stock_location) { nil } let!(:stock_location) { create :stock_location_with_items } let!(:stock_item) { stock_location.stock_items.order(:id).first } @@ -107,6 +126,35 @@ module Stock expect(subject.can_supply?(6)).to eq false end end + + describe "#positive_stock" do + let(:variant) { create(:variant) } + let(:stock_location) { create(:stock_location) } + let(:stock_item) { stock_location.set_up_stock_item(variant) } + let(:instance) { described_class.new(variant, stock_location_or_id) } + + subject { instance.positive_stock } + + context "when stock location is not present" do + let(:stock_location_or_id) { nil } + + it { is_expected.to be_nil } + end + + context "when stock_location_id is present" do + context "when stock_location_id is a stock location" do + let(:stock_location_or_id) { stock_location } + + it_behaves_like "returns the positive stock on hand" + end + + context "when stock_location_id is a stock location id" do + let(:stock_location_or_id) { stock_location.id } + + it_behaves_like "returns the positive stock on hand" + end + end + end end end end