From 280048cd6c99e4f95e7a3d49a0b085a8adee0c75 Mon Sep 17 00:00:00 2001 From: "Ben A. Morgan" Date: Sat, 9 Mar 2024 11:39:11 -0700 Subject: [PATCH] check if stock_items are loaded before doing a SUM() --- core/app/models/spree/product.rb | 2 ++ core/spec/models/spree/product_spec.rb | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/core/app/models/spree/product.rb b/core/app/models/spree/product.rb index 7ccc7d8b5ad..bd4f544bdac 100644 --- a/core/app/models/spree/product.rb +++ b/core/app/models/spree/product.rb @@ -289,6 +289,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 diff --git a/core/spec/models/spree/product_spec.rb b/core/spec/models/spree/product_spec.rb index 8075252106f..94c2d9acf7f 100644 --- a/core/spec/models/spree/product_spec.rb +++ b/core/spec/models/spree/product_spec.rb @@ -550,6 +550,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) @@ -561,17 +563,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