From 579f3bf90a9eb8d6b0919789c50aa93acc6d6f34 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 3 May 2017 16:11:39 +1000 Subject: [PATCH] Changing quantity and deleting line_items of completed orders works with inventory where present --- app/models/spree/line_item_decorator.rb | 33 ++++++++++++++++ spec/models/spree/line_item_spec.rb | 50 +++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 31d263761f..cdbae883fc 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -94,8 +94,41 @@ Spree::LineItem.class_eval do (final_weight_volume || 0) / quantity end + # MONKEYPATCH of Spree method + # Enables scoping of variant to hub/shop, stock drawn down from inventory + def update_inventory + return true unless order.completed? + + scoper.scope(variant) # this line added + + if new_record? + Spree::InventoryUnit.increase(order, variant, quantity) + elsif old_quantity = self.changed_attributes['quantity'] + if old_quantity < quantity + Spree::InventoryUnit.increase(order, variant, (quantity - old_quantity)) + elsif old_quantity > quantity + Spree::InventoryUnit.decrease(order, variant, (old_quantity - quantity)) + end + end + end + + # MONKEYPATCH of Spree method + # Enables scoping of variant to hub/shop, stock replaced to inventory + def remove_inventory + return true unless order.completed? + + scoper.scope(variant) # this line added + + Spree::InventoryUnit.decrease(order, variant, quantity) + end + private + def scoper + return @scoper unless @scoper.nil? + @scoper = OpenFoodNetwork::ScopeVariantToHub.new(order.distributor) + end + def calculate_final_weight_volume if final_weight_volume.present? && quantity_was > 0 self.final_weight_volume = final_weight_volume * quantity / quantity_was diff --git a/spec/models/spree/line_item_spec.rb b/spec/models/spree/line_item_spec.rb index 111108f7b4..d5ab83b59c 100644 --- a/spec/models/spree/line_item_spec.rb +++ b/spec/models/spree/line_item_spec.rb @@ -77,6 +77,56 @@ module Spree end end + describe "tracking stock when quantity is changed" do + context "when the order is already complete" do + let(:shop) { create(:distributor_enterprise)} + let(:order) { create(:completed_order_with_totals, distributor: shop) } + let!(:line_item) { order.reload.line_items.first } + let!(:variant) { line_item.variant } + + context "when a variant override applies" do + let!(:vo) { create(:variant_override, hub: shop, variant: variant, count_on_hand: 3 ) } + + it "draws stock from the variant override" do + expect(vo.reload.count_on_hand).to eq 3 + expect{line_item.increment!(:quantity)}.to_not change{Spree::Variant.find(variant.id).on_hand} + expect(vo.reload.count_on_hand).to eq 2 + end + end + + context "when a variant override does not apply" do + it "draws stock from the variant" do + expect{line_item.increment!(:quantity)}.to change{Spree::Variant.find(variant.id).on_hand}.by(-1) + end + end + end + end + + describe "tracking stock when a line item is destroyed" do + context "when the order is already complete" do + let(:shop) { create(:distributor_enterprise)} + let(:order) { create(:completed_order_with_totals, distributor: shop) } + let!(:line_item) { order.reload.line_items.first } + let!(:variant) { line_item.variant } + + context "when a variant override applies" do + let!(:vo) { create(:variant_override, hub: shop, variant: variant, count_on_hand: 3 ) } + + it "restores stock to the variant override" do + expect(vo.reload.count_on_hand).to eq 3 + expect{line_item.destroy}.to_not change{Spree::Variant.find(variant.id).on_hand} + expect(vo.reload.count_on_hand).to eq 4 + end + end + + context "when a variant override does not apply" do + it "restores stock to the variant" do + expect{line_item.destroy}.to change{Spree::Variant.find(variant.id).on_hand}.by(1) + end + end + end + end + describe "calculating price with adjustments" do it "does not return fractional cents" do li = LineItem.new