Skip to content

Commit

Permalink
Merge pull request solidusio#4395 from jarednorman/jared/likes-config…
Browse files Browse the repository at this point in the history
…urable-classes

Make more stock classes configurable
  • Loading branch information
waiting-for-dev authored Jul 8, 2022
2 parents 64b6b6e + 244c5c0 commit df51df6
Show file tree
Hide file tree
Showing 7 changed files with 263 additions and 48 deletions.
21 changes: 16 additions & 5 deletions core/app/models/spree/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,8 @@ def create_proposed_shipments
end

def create_shipments_for_line_item(line_item)
units = Spree::Stock::InventoryUnitBuilder.new(self).missing_units_for_line_item(line_item)
units = Spree::Config.stock.inventory_unit_builder_class.new(self).missing_units_for_line_item(line_item)

Spree::Config.stock.coordinator_class.new(self, units).shipments.each do |shipment|
shipments << shipment
end
Expand Down Expand Up @@ -789,9 +790,12 @@ def require_email

def ensure_inventory_units
if has_checkout_step?("delivery")
inventory_validator = Spree::Stock::InventoryValidator.new
inventory_validator = Spree::Config.stock.inventory_validator_class.new

errors = line_items.map { |line_item|
inventory_validator.validate(line_item)
}.compact

errors = line_items.map { |line_item| inventory_validator.validate(line_item) }.compact
raise InsufficientStock if errors.any?
end
end
Expand All @@ -809,8 +813,15 @@ def ensure_promotions_eligible
end

def validate_line_item_availability
availability_validator = Spree::Stock::AvailabilityValidator.new
raise InsufficientStock unless line_items.all? { |line_item| availability_validator.validate(line_item) }
availability_validator = Spree::Config.stock.availability_validator_class.new

# NOTE: This code assumes that the availability validator will return
# true for success and false for failure. This is not normally the
# behaviour of validators, as the framework only cares about the
# population of the errors, not the return value of the validate method.
raise InsufficientStock unless line_items.all? { |line_item|
availability_validator.validate(line_item)
}
end

def ensure_line_items_present
Expand Down
3 changes: 2 additions & 1 deletion core/app/models/spree/stock/simple_coordinator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class SimpleCoordinator

def initialize(order, inventory_units = nil)
@order = order
@inventory_units = inventory_units || InventoryUnitBuilder.new(order).units
@inventory_units =
inventory_units || Spree::Config.stock.inventory_unit_builder_class.new(order).units
@splitters = Spree::Config.environment.stock_splitters

filtered_stock_locations = Spree::Config.stock.location_filter_class.new(Spree::StockLocation.all, @order).filter
Expand Down
18 changes: 18 additions & 0 deletions core/lib/spree/core/stock_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class StockConfiguration
attr_writer :location_filter_class
attr_writer :location_sorter_class
attr_writer :allocator_class
attr_writer :inventory_unit_builder_class
attr_writer :availability_validator_class
attr_writer :inventory_validator_class

def coordinator_class
@coordinator_class ||= '::Spree::Stock::SimpleCoordinator'
Expand All @@ -33,6 +36,21 @@ def allocator_class
@allocator_class ||= '::Spree::Stock::Allocator::OnHandFirst'
@allocator_class.constantize
end

def inventory_unit_builder_class
@inventory_unit_builder_class ||= '::Spree::Stock::InventoryUnitBuilder'
@inventory_unit_builder_class.constantize
end

def availability_validator_class
@availability_validator_class ||= '::Spree::Stock::AvailabilityValidator'
@availability_validator_class.constantize
end

def inventory_validator_class
@inventory_validator_class ||= '::Spree::Stock::InventoryValidator'
@inventory_validator_class.constantize
end
end
end
end
138 changes: 99 additions & 39 deletions core/spec/lib/spree/core/stock_configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,93 +3,153 @@
require 'rails_helper'

RSpec.describe Spree::Core::StockConfiguration do
let(:stock_configuration) { described_class.new }

describe '#coordinator_class' do
let(:stock_configuration) { described_class.new }
subject { stock_configuration.coordinator_class }

it "returns Spree::Stock::Coordinator" do
is_expected.to be ::Spree::Stock::SimpleCoordinator
it "returns Spree::Stock::Coordinator by default" do
expect(subject).to be ::Spree::Stock::SimpleCoordinator
end

context "with another constant name assiged" do
it "can be reassigned" do
MyCoordinator = Class.new
before { stock_configuration.coordinator_class = MyCoordinator.to_s }
stock_configuration.coordinator_class = MyCoordinator.to_s

expect(subject).to be MyCoordinator

it "returns the constant" do
is_expected.to be MyCoordinator
end
ensure
Object.send(:remove_const, :MyCoordinator)
end
end

describe '#estimator_class' do
let(:stock_configuration) { described_class.new }
subject { stock_configuration.estimator_class }

it "returns Spree::Stock::Estimator" do
is_expected.to be ::Spree::Stock::Estimator
expect(subject).to be ::Spree::Stock::Estimator
end

context "with another constant name assiged" do
it "can be reassigned" do
MyEstimator = Class.new
before { stock_configuration.estimator_class = MyEstimator.to_s }
stock_configuration.estimator_class = MyEstimator.to_s

expect(subject).to be MyEstimator

it "returns the constant" do
is_expected.to be MyEstimator
end
ensure
Object.send(:remove_const, :MyEstimator)
end
end

describe '#location_filter_class' do
let(:stock_configuration) { described_class.new }
subject { stock_configuration.location_filter_class }

it "returns Spree::Stock::LocationFilter::Active" do
is_expected.to be ::Spree::Stock::LocationFilter::Active
it "returns Spree::Stock::LocationFilter::Active by default" do
expect(subject).to be ::Spree::Stock::LocationFilter::Active
end

context "with another constant name assiged" do
it "can be reassigned" do
MyFilter = Class.new
before { stock_configuration.location_filter_class = MyFilter.to_s }
stock_configuration.location_filter_class = MyFilter.to_s

expect(subject).to be MyFilter

it "returns the constant" do
is_expected.to be MyFilter
end
ensure
Object.send(:remove_const, :MyFilter)
end
end

describe '#location_sorter_class' do
let(:stock_configuration) { described_class.new }
subject { stock_configuration.location_sorter_class }

it "returns Spree::Stock::LocationSorter::Unsorted" do
is_expected.to be ::Spree::Stock::LocationSorter::Unsorted
it "returns Spree::Stock::LocationSorter::Unsorted by default" do
expect(subject).to be ::Spree::Stock::LocationSorter::Unsorted
end

context "with another constant name assiged" do
it "can be reassigned" do
MySorter = Class.new
before { stock_configuration.location_sorter_class = MySorter.to_s }
stock_configuration.location_sorter_class = MySorter.to_s

it "returns the constant" do
is_expected.to be MySorter
end
expect(subject).to be MySorter

ensure
Object.send(:remove_const, :MySorter)
end
end

describe '#allocator_class' do
let(:stock_configuration) { described_class.new }
subject { stock_configuration.allocator_class }

it "returns Spree::Stock::Allocator::OnHandFirst" do
is_expected.to be ::Spree::Stock::Allocator::OnHandFirst
it "returns Spree::Stock::Allocator::OnHandFirst by default" do
expect(subject).to be ::Spree::Stock::Allocator::OnHandFirst
end

context "with another constant name assiged" do
it "can be reassigned" do
MyAllocator = Class.new
before { stock_configuration.allocator_class = MyAllocator.to_s }
stock_configuration.allocator_class = MyAllocator.to_s

expect(subject).to be MyAllocator

ensure
Object.send(:remove_const, :MyAllocator)
end
end

describe '#inventory_unit_builder_class' do
subject { stock_configuration.inventory_unit_builder_class }

it "returns Spree::Stock::InventoryUnitBuilder by default" do
expect(subject).to be ::Spree::Stock::InventoryUnitBuilder
end

it "can be reassigned" do
MyInventoryUnitBuilder = Class.new
stock_configuration.inventory_unit_builder_class = MyInventoryUnitBuilder.to_s

expect(subject).to be MyInventoryUnitBuilder

ensure
Object.send(:remove_const, :MyInventoryUnitBuilder)
end
end

describe '#availability_validator_class' do
subject { stock_configuration.availability_validator_class }

let(:stock_configuration) { described_class.new }

it "returns Spree::Stock::AvailabilityValidator" do
is_expected.to be ::Spree::Stock::AvailabilityValidator
end

it "can be reassigned" do
MyAvailabilityValidator = Class.new
stock_configuration.availability_validator_class = MyAvailabilityValidator.to_s

expect(subject).to be MyAvailabilityValidator

ensure
Object.send(:remove_const, :MyAvailabilityValidator)
end
end

describe '#inventory_validator_class' do
subject { stock_configuration.inventory_validator_class }

let(:stock_configuration) { described_class.new }

it "returns Spree::Stock::InventoryValidator" do
is_expected.to be ::Spree::Stock::InventoryValidator
end

it "can be reassigned" do
MyInventoryValidator = Class.new
stock_configuration.inventory_validator_class = MyInventoryValidator.to_s

expect(subject).to be MyInventoryValidator

it "returns the constant" do
is_expected.to be MyAllocator
end
ensure
Object.send(:remove_const, :MyInventoryValidator)
end
end
end
Loading

0 comments on commit df51df6

Please sign in to comment.