diff --git a/app/models/spree/shipping_method_decorator.rb b/app/models/spree/shipping_method_decorator.rb index a900f14936..6a512737bd 100644 --- a/app/models/spree/shipping_method_decorator.rb +++ b/app/models/spree/shipping_method_decorator.rb @@ -42,12 +42,6 @@ Spree::ShippingMethod.class_eval do ] end - def available_to_order_with_distributor_check?(order) - available_to_order_without_distributor_check?(order) && - self.distributors.include?(order.distributor) - end - alias_method_chain :available_to_order?, :distributor_check - def within_zone?(order) if order.ship_address zone && zone.include?(order.ship_address) diff --git a/app/models/stock/package.rb b/app/models/stock/package.rb new file mode 100644 index 0000000000..012e2265d4 --- /dev/null +++ b/app/models/stock/package.rb @@ -0,0 +1,33 @@ +# Extends Spree's Package implementation to skip shipping methods that are not +# valid for OFN. +# +# It requires the following configuration in config/initializers/spree.rb: +# +# Spree.config do |config| +# ... +# config.package_factory = Stock::Package +# end +# +module Stock + class Package < Spree::Stock::Package + # Skips the methods that are not used by the order's distributor + # + # @return [Array] + def shipping_methods + super.delete_if do |shipping_method| + !ships_with?(order.distributor, shipping_method) + end + end + + private + + # Checks whether the given distributor provides the specified shipping method + # + # @param distributor [Spree::Enterprise] + # @param shipping_method [Spree::ShippingMethod] + # @return [Boolean] + def ships_with?(distributor, shipping_method) + distributor.shipping_methods.include?(shipping_method) + end + end +end diff --git a/config/initializers/spree.rb b/config/initializers/spree.rb index 8495ec3824..77243c8ebb 100644 --- a/config/initializers/spree.rb +++ b/config/initializers/spree.rb @@ -20,6 +20,8 @@ Spree.config do |config| # Auto-capture payments. Without this option, payments must be manually captured in the paypal interface. config.auto_capture = true #config.override_actionmailer_config = false + + config.package_factory = Stock::Package end # TODO Work out why this is necessary diff --git a/spec/models/stock/package_spec.rb b/spec/models/stock/package_spec.rb new file mode 100644 index 0000000000..2c85b9b079 --- /dev/null +++ b/spec/models/stock/package_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +module Stock + describe Package do + describe '#shipping_methods' do + let(:stock_location) { double(:stock_location) } + let(:order) { build(:order) } + + subject(:package) { Package.new(stock_location, order, contents) } + + describe '#shipping_methods' do + let(:enterprise) { build(:enterprise) } + let(:other_enterprise) { build(:enterprise) } + + let(:order) { build(:order, distributor: enterprise) } + + let(:variant1) do + instance_double( + Spree::Variant, + shipping_category: shipping_method1.shipping_categories.first + ) + end + let(:variant2) do + instance_double( + Spree::Variant, + shipping_category: shipping_method2.shipping_categories.first + ) + end + let(:variant3) do + instance_double(Spree::Variant, shipping_category: nil) + end + + let(:contents) do + [ + Package::ContentItem.new(variant1, 1), + Package::ContentItem.new(variant1, 1), + Package::ContentItem.new(variant2, 1), + Package::ContentItem.new(variant3, 1) + ] + end + + let(:shipping_method1) { create(:shipping_method, distributors: [enterprise]) } + let(:shipping_method2) { create(:shipping_method, distributors: [other_enterprise]) } + + it 'does not return shipping methods not used by the package\'s order distributor' do + expect(package.shipping_methods).to eq [shipping_method1] + end + end + end + end +end