Skip to content

Commit

Permalink
check if stock_items are loaded before doing a SUM()
Browse files Browse the repository at this point in the history
  • Loading branch information
BenMorganIO authored and tvdeyen committed Nov 4, 2024
1 parent d955ca4 commit 51df6ca
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
2 changes: 2 additions & 0 deletions core/app/models/spree/product.rb
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ def possible_promotions
def total_on_hand
if any_variants_not_track_inventory?
Float::INFINITY
elsif stock_items.loaded?
stock_items.sum(&:count_on_hand)
else
stock_items.sum(:count_on_hand)
end
Expand Down
19 changes: 17 additions & 2 deletions core/spec/models/spree/product_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,8 @@ class Extension < Spree::Base
end

context '#total_on_hand' do
let(:product) { create :product }

it 'should be infinite if track_inventory_levels is false' do
stub_spree_preferences(track_inventory_levels: false)
expect(build(:product, variants_including_master: [build(:master_variant)]).total_on_hand).to eql(Float::INFINITY)
Expand All @@ -547,17 +549,30 @@ class Extension < Spree::Base
end

it 'should return sum of stock items count_on_hand' do
product = create(:product)
product.stock_items.first.set_count_on_hand 5
product.variants_including_master.reload # force load association
expect(product.total_on_hand).to eql(5)
end

it 'should return sum of stock items count_on_hand when variants_including_master is not loaded' do
product = create(:product)
product.stock_items.first.set_count_on_hand 5
expect(product.reload.total_on_hand).to eql(5)
end

context 'when the stock items are loaded' do
it 'returns the loaded count_on_hand instead of doing SUM(count_on_hand)' do
product.stock_items.first.set_count_on_hand(5)

product = described_class.includes(:stock_items).find(product.id)

# Set the count on hand to a different number to highlight we loaded and
# must be done from the class level so that we don't update the instance
# product has loaded
Spree::StockItem.find(product.stock_items.first.id).set_count_on_hand(7)

expect(product.total_on_hand).to eql 5
end
end
end

# Regression spec for https://github.com/spree/spree/issues/5588
Expand Down

0 comments on commit 51df6ca

Please sign in to comment.