mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
Spree added stock movements to track the movements between stock locations. But we got rid of stock locations and the only stock movements we have now are just records of stock level changes. These records were not created in all cases though and there were also not created for variant overrides (inventory items). And since these records aren't visible anywhere, I think it's best we remove them altogether. I do think that some kind of log would be useful but I don't think that AR records like this are the best solution for that. And the StockMovement model just added complexity to our already complex stock level storage. The actual adjustment of the count_on_hand attribute of the StockItem was performed in an after_create hook of the StockMovement. Now we call it explicitely.
158 lines
6.2 KiB
Ruby
158 lines
6.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe Spree::OrderInventory do
|
|
let(:order) { create :completed_order_with_totals }
|
|
let(:line_item) { order.line_items.first }
|
|
subject { described_class.new(order) }
|
|
|
|
it 'inventory_units_for should return array of units for a given variant' do
|
|
units = subject.inventory_units_for(line_item.variant)
|
|
expect(units.map(&:variant_id)).to eq [line_item.variant.id]
|
|
end
|
|
|
|
context "when order is missing inventory units" do
|
|
before do
|
|
line_item.update_column(:quantity, 2)
|
|
end
|
|
|
|
it 'should be a messed up order' do
|
|
expect(order.shipments.first.inventory_units_for(line_item.variant).size).to eq 1
|
|
expect(line_item.reload.quantity).to eq 2
|
|
end
|
|
|
|
it 'should increase the number of inventory units' do
|
|
subject.verify(line_item)
|
|
expect(order.reload.shipments.first.inventory_units_for(line_item.variant).size).to eq 2
|
|
end
|
|
end
|
|
|
|
context "#add_to_shipment" do
|
|
let(:shipment) { order.shipments.first }
|
|
let(:variant) { create :variant }
|
|
|
|
context "order is not completed" do
|
|
before { allow(order).to receive_messages completed?: false }
|
|
|
|
it "doesn't unstock items" do
|
|
expect(line_item.variant).not_to receive(:move)
|
|
expect(subject.__send__(:add_to_shipment, shipment, variant, 5)).to eq 5
|
|
end
|
|
end
|
|
|
|
it 'should create inventory_units in the necessary states' do
|
|
expect(variant).to receive(:fill_status).with(5).and_return([3, 2])
|
|
|
|
expect(subject.__send__(:add_to_shipment, shipment, variant, 5)).to eq 5
|
|
|
|
units = shipment.inventory_units.group_by(&:variant_id)
|
|
units = units[variant.id].group_by(&:state)
|
|
expect(units['backordered'].size).to eq 2
|
|
expect(units['on_hand'].size).to eq 3
|
|
end
|
|
end
|
|
|
|
context 'when order has too many inventory units' do
|
|
before do
|
|
line_item.quantity = 3
|
|
line_item.save!
|
|
|
|
line_item.update_column(:quantity, 2)
|
|
order.reload
|
|
end
|
|
|
|
it 'should be a messed up order' do
|
|
expect(order.shipments.first.inventory_units_for(line_item.variant).size).to eq 3
|
|
expect(line_item.quantity).to eq 2
|
|
end
|
|
|
|
it 'should decrease the number of inventory units' do
|
|
subject.verify(line_item)
|
|
expect(order.reload.shipments.first.inventory_units_for(line_item.variant).size).to eq 2
|
|
end
|
|
|
|
context '#remove_from_shipment' do
|
|
let(:shipment) { order.shipments.first }
|
|
let(:variant) { order.line_items.first.variant }
|
|
|
|
context "order is not completed" do
|
|
before { allow(order).to receive_messages completed?: false }
|
|
|
|
it "doesn't restock items" do
|
|
expect(variant).not_to receive(:move)
|
|
expect(subject.__send__(:remove_from_shipment, shipment, variant, 1, true)).to eq 1
|
|
end
|
|
end
|
|
|
|
context "order is completed" do
|
|
before { allow(order).to receive_messages completed?: true }
|
|
|
|
it "doesn't restock items" do
|
|
expect(variant).not_to receive(:move)
|
|
expect(subject.__send__(:remove_from_shipment, shipment, variant, 1, false)).to eq 1
|
|
end
|
|
end
|
|
|
|
it 'should destroy backordered units first' do
|
|
allow(shipment).to receive_messages(inventory_units_for: [
|
|
build(:inventory_unit,
|
|
variant_id: variant.id,
|
|
state: 'backordered'),
|
|
build(:inventory_unit,
|
|
variant_id: variant.id,
|
|
state: 'on_hand'),
|
|
build(:inventory_unit,
|
|
variant_id: variant.id,
|
|
state: 'backordered')
|
|
] )
|
|
|
|
expect(shipment.inventory_units_for[0]).to receive(:destroy)
|
|
expect(shipment.inventory_units_for[1]).not_to receive(:destroy)
|
|
expect(shipment.inventory_units_for[2]).to receive(:destroy)
|
|
|
|
expect(subject.__send__(:remove_from_shipment, shipment, variant, 2, true)).to eq 2
|
|
end
|
|
|
|
it 'should destroy unshipped units first' do
|
|
allow(shipment).to receive_messages(inventory_units_for: [
|
|
build(:inventory_unit,
|
|
variant_id: variant.id,
|
|
state: 'shipped'),
|
|
build(:inventory_unit,
|
|
variant_id: variant.id,
|
|
state: 'on_hand')
|
|
] )
|
|
|
|
expect(shipment.inventory_units_for[0]).not_to receive(:destroy)
|
|
expect(shipment.inventory_units_for[1]).to receive(:destroy)
|
|
|
|
expect(subject.__send__(:remove_from_shipment, shipment, variant, 1, true)).to eq 1
|
|
end
|
|
|
|
it 'only attempts to destroy as many units as are eligible, and return amount destroyed' do
|
|
allow(shipment).to receive_messages(inventory_units_for: [
|
|
build(:inventory_unit,
|
|
variant_id: variant.id,
|
|
state: 'shipped'),
|
|
build(:inventory_unit,
|
|
variant_id: variant.id,
|
|
state: 'on_hand')
|
|
] )
|
|
|
|
expect(shipment.inventory_units_for[0]).not_to receive(:destroy)
|
|
expect(shipment.inventory_units_for[1]).to receive(:destroy)
|
|
|
|
expect(subject.__send__(:remove_from_shipment, shipment, variant, 1, true)).to eq 1
|
|
end
|
|
|
|
it 'should destroy self if not inventory units remain' do
|
|
allow(shipment.inventory_units).to receive_messages(count: 0)
|
|
expect(shipment).to receive(:destroy)
|
|
|
|
expect(subject.__send__(:remove_from_shipment, shipment, variant, 1, true)).to eq 1
|
|
end
|
|
end
|
|
end
|
|
end
|