diff --git a/app/assets/javascripts/darkswarm/services/cart.js.coffee b/app/assets/javascripts/darkswarm/services/cart.js.coffee index b0311cb402..bdd0aa3676 100644 --- a/app/assets/javascripts/darkswarm/services/cart.js.coffee +++ b/app/assets/javascripts/darkswarm/services/cart.js.coffee @@ -57,18 +57,20 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo scope = $rootScope.$new(true) scope.variants = [] - # TODO: These changes to quantity/max_quantity trigger another cart update, which - # is unnecessary. - + # TODO: These changes to quantity/max_quantity trigger another cart update, which is unnecessary. for li in @line_items when li.quantity > 0 - if stockLevels[li.variant.id]? - li.variant.on_hand = stockLevels[li.variant.id].on_hand - if li.quantity > li.variant.on_hand - li.quantity = li.variant.on_hand - scope.variants.push li.variant - if li.variant.on_hand == 0 && li.max_quantity > li.variant.on_hand - li.max_quantity = li.variant.on_hand - scope.variants.push(li.variant) unless li.variant in scope.variants + continue unless stockLevels[li.variant.id]? + + li.variant.on_hand = stockLevels[li.variant.id].on_hand + li.variant.on_demand = stockLevels[li.variant.id].on_demand + continue if li.variant.on_demand + + if li.quantity > li.variant.on_hand + li.quantity = li.variant.on_hand + scope.variants.push li.variant + if li.variant.on_hand == 0 && li.max_quantity > li.variant.on_hand + li.max_quantity = li.variant.on_hand + scope.variants.push(li.variant) unless li.variant in scope.variants if scope.variants.length > 0 $modal.open(templateUrl: "out_of_stock.html", scope: scope, windowClass: 'out-of-stock-modal') diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 31b4945c51..d64c02155d 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -64,6 +64,7 @@ Spree::LineItem.class_eval do def cap_quantity_at_stock! scoper.scope(variant) + return if variant.on_demand update_attributes!(quantity: variant.on_hand) if quantity > variant.on_hand end diff --git a/app/services/variants_stock_levels.rb b/app/services/variants_stock_levels.rb index 43d9190800..69dbc49dee 100644 --- a/app/services/variants_stock_levels.rb +++ b/app/services/variants_stock_levels.rb @@ -10,8 +10,8 @@ class VariantsStockLevels order_variant_ids = variant_stock_levels.keys missing_variant_ids = requested_variant_ids - order_variant_ids missing_variant_ids.each do |variant_id| - variant_on_hand = Spree::Variant.find(variant_id).on_hand - variant_stock_levels[variant_id] = { quantity: 0, max_quantity: 0, on_hand: variant_on_hand } + variant = Spree::Variant.find(variant_id) + variant_stock_levels[variant_id] = { quantity: 0, max_quantity: 0, on_hand: variant.on_hand, on_demand: variant.on_demand } end # The code above is most probably dead code, this bugsnag notification will confirm it @@ -37,14 +37,9 @@ class VariantsStockLevels [line_item.variant.id, { quantity: line_item.quantity, max_quantity: line_item.max_quantity, - on_hand: wrap_json_infinity(line_item.variant.on_hand) }] + on_hand: line_item.variant.on_hand, + on_demand: line_item.variant.on_demand }] end ] end - - # Rails to_json encodes Float::INFINITY as Infinity, which is not valid JSON - # Return it as a large integer (max 32 bit signed int) - def wrap_json_infinity(number) - number == Float::INFINITY ? 2_147_483_647 : number - end end diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index 4b18a62434..abf1cc7d51 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -302,6 +302,15 @@ feature "As a consumer I want to shop with a distributor", js: true do Spree::LineItem.where(id: li).should be_empty end + it "lets us add a quantity greater than on_hand value if product is on_demand" do + variant.update_attributes on_hand: 5, on_demand: true + visit shop_path + + fill_in "variants[#{variant.id}]", with: '10' + + page.should have_field "variants[#{variant.id}]", with: '10' + end + it "alerts us when we enter a quantity greater than the stock available" do variant.update_attributes on_hand: 5 visit shop_path @@ -341,6 +350,18 @@ feature "As a consumer I want to shop with a distributor", js: true do page.should have_selector "#variants_#{variant.id}[disabled='disabled']" end + it 'does not show out of stock modal if product is on_demand' do + expect(page).to have_content "Product" + + variant.update_attributes! on_hand: 0, on_demand: true + + expect(page).to have_input "variants[#{variant.id}]" + fill_in "variants[#{variant.id}]", with: '1' + wait_until { !cart_dirty } + + expect(page).to_not have_selector '.out-of-stock-modal' + end + context "group buy products" do let(:product) { create(:simple_product, group_buy: true) } diff --git a/spec/services/variants_stock_levels_spec.rb b/spec/services/variants_stock_levels_spec.rb index 48088a6fce..f4a77d7018 100644 --- a/spec/services/variants_stock_levels_spec.rb +++ b/spec/services/variants_stock_levels_spec.rb @@ -17,34 +17,34 @@ describe VariantsStockLevels do order.reload end - it "returns a hash with variant id, quantity, max_quantity and stock on hand" do + it "returns a hash with variant id, quantity, max_quantity, on hand and on demand" do expect(variant_stock_levels.call(order, [variant_in_the_order.id])).to eq( - variant_in_the_order.id => { quantity: 2, max_quantity: 3, on_hand: 4 } + variant_in_the_order.id => { quantity: 2, max_quantity: 3, on_hand: 4, on_demand: false } ) end it "includes all line items, even when the variant_id is not specified" do expect(variant_stock_levels.call(order, [])).to eq( - variant_in_the_order.id => { quantity: 2, max_quantity: 3, on_hand: 4 } + variant_in_the_order.id => { quantity: 2, max_quantity: 3, on_hand: 4, on_demand: false } ) end it "includes an empty quantity entry for variants that aren't in the order" do variant_ids = [variant_in_the_order.id, variant_not_in_the_order.id] expect(variant_stock_levels.call(order, variant_ids)).to eq( - variant_in_the_order.id => { quantity: 2, max_quantity: 3, on_hand: 4 }, - variant_not_in_the_order.id => { quantity: 0, max_quantity: 0, on_hand: 2 } + variant_in_the_order.id => { quantity: 2, max_quantity: 3, on_hand: 4, on_demand: false }, + variant_not_in_the_order.id => { quantity: 0, max_quantity: 0, on_hand: 2, on_demand: false } ) end - describe "encoding Infinity" do + describe "when variant is on_demand" do let!(:variant_in_the_order) { create(:variant, on_demand: true) } before { variant_in_the_order.on_hand = 0 } - it "encodes Infinity as a large, finite integer" do + it "includes the actual on_hand value and on_demand: true" do expect(variant_stock_levels.call(order, [variant_in_the_order.id])).to eq( - variant_in_the_order.id => { quantity: 2, max_quantity: 3, on_hand: 2147483647 } + variant_in_the_order.id => { quantity: 2, max_quantity: 3, on_hand: 0, on_demand: true } ) end end