mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Bring packer from spree_core
This commit is contained in:
48
app/models/spree/stock/packer.rb
Normal file
48
app/models/spree/stock/packer.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
module Spree
|
||||
module Stock
|
||||
class Packer
|
||||
attr_reader :stock_location, :order, :splitters, :package_factory
|
||||
|
||||
def initialize(stock_location, order, splitters=[Splitter::Base])
|
||||
@stock_location = stock_location
|
||||
@order = order
|
||||
@splitters = splitters
|
||||
@package_factory = Spree::Config.package_factory
|
||||
end
|
||||
|
||||
def packages
|
||||
if splitters.empty?
|
||||
[default_package]
|
||||
else
|
||||
build_splitter.split [default_package]
|
||||
end
|
||||
end
|
||||
|
||||
def default_package
|
||||
package = package_factory.new(stock_location, order)
|
||||
order.line_items.each do |line_item|
|
||||
if Config.track_inventory_levels
|
||||
next unless stock_location.stock_item(line_item.variant)
|
||||
|
||||
on_hand, backordered = stock_location.fill_status(line_item.variant, line_item.quantity)
|
||||
package.add line_item.variant, on_hand, :on_hand if on_hand > 0
|
||||
package.add line_item.variant, backordered, :backordered if backordered > 0
|
||||
else
|
||||
package.add line_item.variant, line_item.quantity, :on_hand
|
||||
end
|
||||
end
|
||||
package
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_splitter
|
||||
splitter = nil
|
||||
splitters.reverse.each do |klass|
|
||||
splitter = klass.new(self, splitter)
|
||||
end
|
||||
splitter
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
102
spec/models/spree/stock/packer_spec.rb
Normal file
102
spec/models/spree/stock/packer_spec.rb
Normal file
@@ -0,0 +1,102 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Spree
|
||||
module Stock
|
||||
describe Packer do
|
||||
let(:order) { create(:order_with_line_items, line_items_count: 5) }
|
||||
let(:stock_location) { create(:stock_location) }
|
||||
|
||||
subject { Packer.new(stock_location, order) }
|
||||
|
||||
before do
|
||||
Spree::Config.stub(:package_factory) { Package }
|
||||
end
|
||||
|
||||
context 'packages' do
|
||||
it 'builds an array of packages' do
|
||||
packages = subject.packages
|
||||
packages.size.should eq 1
|
||||
packages.first.contents.size.should eq 5
|
||||
end
|
||||
|
||||
it 'allows users to set splitters to an empty array' do
|
||||
packages = Packer.new(stock_location, order, []).packages
|
||||
packages.size.should eq 1
|
||||
end
|
||||
end
|
||||
|
||||
context 'default_package' do
|
||||
it 'contains all the items' do
|
||||
package = subject.default_package
|
||||
package.contents.size.should eq 5
|
||||
package.weight.should > 0
|
||||
end
|
||||
|
||||
it 'variants are added as backordered without enough on_hand' do
|
||||
stock_location.should_receive(:fill_status).exactly(5).times.and_return([2,3])
|
||||
|
||||
package = subject.default_package
|
||||
package.on_hand.size.should eq 5
|
||||
package.backordered.size.should eq 5
|
||||
end
|
||||
|
||||
context 'when a packer factory is not specified' do
|
||||
let(:package) { double(:package, add: true) }
|
||||
|
||||
it 'calls Spree::Stock::Package' do
|
||||
Package
|
||||
.should_receive(:new)
|
||||
.with(stock_location, order)
|
||||
.and_return(package)
|
||||
|
||||
subject.default_package
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a packer factory is specified' do
|
||||
before do
|
||||
Spree::Config.stub(:package_factory) { TestPackageFactory }
|
||||
end
|
||||
|
||||
class TestPackageFactory; end
|
||||
|
||||
let(:package) { double(:package, add: true) }
|
||||
|
||||
it 'calls the specified factory' do
|
||||
TestPackageFactory
|
||||
.should_receive(:new)
|
||||
.with(stock_location, order)
|
||||
.and_return(package)
|
||||
|
||||
subject.default_package
|
||||
end
|
||||
end
|
||||
|
||||
context "location doesn't have order items in stock" do
|
||||
let(:stock_location) { create(:stock_location, propagate_all_variants: false) }
|
||||
let(:packer) { Packer.new(stock_location, order) }
|
||||
|
||||
it "builds an empty package" do
|
||||
packer.default_package.contents.should be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context "doesn't track inventory levels" do
|
||||
let(:order) { Order.create }
|
||||
let!(:line_item) { order.contents.add(create(:variant), 30) }
|
||||
|
||||
before { Config.track_inventory_levels = false }
|
||||
|
||||
it "doesn't bother stock items status in stock location" do
|
||||
expect(subject.stock_location).not_to receive(:fill_status)
|
||||
subject.default_package
|
||||
end
|
||||
|
||||
it "still creates package with proper quantity" do
|
||||
expect(subject.default_package.quantity).to eql 30
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user