Files
openfoodnetwork/spec/models/spree/order_inventory_spec.rb
Maikel Linke 2197656606 Stop creating stock movements
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.
2025-05-13 14:56:29 +10:00

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