diff --git a/app/services/orders/check_stock_service.rb b/app/services/orders/check_stock_service.rb index d4a4aa0273..8cde5c46fa 100644 --- a/app/services/orders/check_stock_service.rb +++ b/app/services/orders/check_stock_service.rb @@ -4,12 +4,24 @@ module Orders class CheckStockService attr_reader :order - def initialize(order: ) + def initialize(order:) @order = order end def sufficient_stock? @sufficient_stock ||= order.insufficient_stock_lines.blank? end + + def update_line_items + return [] if sufficient_stock? + + variants = [] + order.insufficient_stock_lines.each do |line_item| + order.contents.update_item(line_item, { quantity: line_item.variant.on_hand }) + variants.push line_item.variant + end + + variants + end end end diff --git a/spec/services/orders/check_stock_service_spec.rb b/spec/services/orders/check_stock_service_spec.rb index 0a2453abd3..4a3f6e26d0 100644 --- a/spec/services/orders/check_stock_service_spec.rb +++ b/spec/services/orders/check_stock_service_spec.rb @@ -21,4 +21,85 @@ RSpec.describe Orders::CheckStockService do end end end + + describe "#update_line_items" do + context "with no variant out of stock" do + it "returns an empty array" do + expect(subject.update_line_items).to be_empty + end + end + + context "with no variant with reduced stock" do + it "returns an empty array" do + expect(subject.update_line_items).to be_empty + end + end + + context "with a variant out of stock" do + let(:variant) { order.line_items.first.variant } + + before do + variant.update!(on_demand: false, on_hand: 0) + end + + it "removes the machting line item" do + subject.update_line_items + + expect(order.line_items.reload.select { |li| li.variant == variant }).to be_empty + end + + it "returns an array including the out of stock variant" do + expect(subject.update_line_items).to eq([variant]) + end + end + + context "with a variant with reduced stock" do + let(:line_item) { order.line_items.last } + let(:variant) { line_item.variant } + + before do + order.contents.add(variant, 2) + variant.update!(on_demand: false, on_hand: 1) + end + + it "updates the machting line item quantity" do + subject.update_line_items + + expect(line_item.reload.quantity).to be(1) + end + + it "returns an array including the reduced stock variant" do + expect(subject.update_line_items).to eq([variant]) + end + end + + context "with a variant with reduced stock and a variant out of stock" do + let(:line_item_out_of_stock) { order.line_items.last } + let(:variant_out_of_stock) { line_item_out_of_stock.variant } + let(:line_item_reduced_stock) { order.line_items.first } + let(:variant_reduced_stock) { line_item_reduced_stock.variant } + + before do + variant_out_of_stock.update!(on_demand: false, on_hand: 0) + order.contents.add(variant_reduced_stock, 3) + variant_reduced_stock.update!(on_demand: false, on_hand: 2) + end + + it "removes the line item matching the out of stock variant" do + subject.update_line_items + + expect(order.line_items).not_to include(line_item_out_of_stock) + end + + it "updates the line item quantity matching the reduced stock variant" do + subject.update_line_items + + expect(line_item_reduced_stock.reload.quantity).to eq(2) + end + + it "returns an array including the out of stock variant and thereduced stock variant" do + expect(subject.update_line_items).to include(variant_out_of_stock, variant_reduced_stock) + end + end + end end