Bring packer from spree_core

This commit is contained in:
Luis Ramos
2020-07-01 16:18:02 +01:00
parent ec50a788a6
commit e0f9894b7a
2 changed files with 150 additions and 0 deletions

View 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

View 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