When adding an item to cart with not enough stock, add as much as we can without erroring

This commit is contained in:
Rohan Mitchell
2016-03-24 14:48:13 +11:00
parent a1bcdc616f
commit 292d027498
2 changed files with 76 additions and 9 deletions

View File

@@ -49,17 +49,32 @@ Spree::OrderPopulator.class_eval do
def attempt_cart_add(variant_id, quantity, max_quantity = nil)
quantity = quantity.to_i
max_quantity = max_quantity.to_i if max_quantity
variant = Spree::Variant.find(variant_id)
OpenFoodNetwork::ScopeVariantToHub.new(@distributor).scope(variant)
if quantity > 0
if check_stock_levels(variant, quantity) &&
check_order_cycle_provided_for(variant) &&
check_variant_available_under_distribution(variant)
@order.add_variant(variant, quantity, max_quantity, currency)
if quantity > 0 &&
check_order_cycle_provided_for(variant) &&
check_variant_available_under_distribution(variant)
quantity_to_add, max_quantity_to_add = quantities_to_add(variant, quantity, max_quantity)
if quantity_to_add > 0
@order.add_variant(variant, quantity_to_add, max_quantity_to_add, currency)
end
end
end
def quantities_to_add(variant, quantity, max_quantity)
# If not enough stock is available, add as much as we can to the cart
on_hand = variant.on_hand
on_hand = [quantity, max_quantity].compact.max if Spree::Config.allow_backorders
quantity_to_add = [quantity, on_hand].min
max_quantity_to_add = [max_quantity, on_hand].min if max_quantity
[quantity_to_add, max_quantity_to_add]
end
def cart_remove(variant_id)
variant = Spree::Variant.find(variant_id)
@order.remove_variant(variant)

View File

@@ -149,13 +149,15 @@ module Spree
end
describe "attempt_cart_add" do
it "performs additional validations" do
variant = double(:variant)
quantity = 123
let(:variant) { double(:variant, on_hand: 250) }
let(:quantity) { 123 }
before do
Spree::Variant.stub(:find).and_return(variant)
VariantOverride.stub(:for).and_return(nil)
end
op.should_receive(:check_stock_levels).with(variant, quantity).and_return(true)
it "performs additional validations" do
op.should_receive(:check_order_cycle_provided_for).with(variant).and_return(true)
op.should_receive(:check_variant_available_under_distribution).with(variant).
and_return(true)
@@ -163,8 +165,58 @@ module Spree
op.attempt_cart_add(333, quantity.to_s)
end
it "filters quantities through #quantities_to_add" do
op.should_receive(:quantities_to_add).with(variant, 123, 123).
and_return([5, 5])
op.stub(:check_order_cycle_provided_for) { true }
op.stub(:check_variant_available_under_distribution) { true }
order.should_receive(:add_variant).with(variant, 5, 5, currency)
op.attempt_cart_add(333, quantity.to_s, quantity.to_s)
end
end
describe "quantities_to_add" do
let(:v) { double(:variant, on_hand: 10) }
context "when max_quantity is not provided" do
it "returns full amount when available" do
op.quantities_to_add(v, 5, nil).should == [5, nil]
end
it "returns a limited amount when not entirely available" do
op.quantities_to_add(v, 15, nil).should == [10, nil]
end
end
context "when max_quantity is provided" do
it "returns full amount when available" do
op.quantities_to_add(v, 5, 6).should == [5, 6]
end
it "returns a limited amount when not entirely available" do
op.quantities_to_add(v, 15, 16).should == [10, 10]
end
end
context "when backorders are allowed" do
around do |example|
Spree::Config.allow_backorders = true
example.run
Spree::Config.allow_backorders = false
end
it "does not limit quantity" do
op.quantities_to_add(v, 15, nil).should == [15, nil]
end
it "does not limit max_quantity" do
op.quantities_to_add(v, 15, 16).should == [15, 16]
end
end
end
describe "validations" do
describe "determining if distributor can supply products in cart" do