mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Merge pull request #2615 from mkllnk/2575-variant-on-hand-api
2575 variant on hand api
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
require 'open_food_network/enterprise_fee_calculator'
|
||||
require 'open_food_network/variant_and_line_item_naming'
|
||||
require 'open_food_network/variant_stock'
|
||||
require 'open_food_network/products_cache'
|
||||
|
||||
Spree::Variant.class_eval do
|
||||
@@ -9,6 +10,7 @@ Spree::Variant.class_eval do
|
||||
# removing the Spree method to prevent error.
|
||||
remove_method :options_text if instance_methods(false).include? :options_text
|
||||
include OpenFoodNetwork::VariantAndLineItemNaming
|
||||
include OpenFoodNetwork::VariantStock
|
||||
|
||||
has_many :exchange_variants
|
||||
has_many :exchanges, through: :exchange_variants
|
||||
|
||||
80
lib/open_food_network/variant_stock.rb
Normal file
80
lib/open_food_network/variant_stock.rb
Normal file
@@ -0,0 +1,80 @@
|
||||
require 'active_support/concern'
|
||||
|
||||
# These methods were available in Spree 1, but were removed in Spree 2.
|
||||
# We would still like to use them. Therefore we use only a single stock location
|
||||
# (default stock location) and use it to track the `count_on_hand` value that
|
||||
# was previously a database column on variants.
|
||||
#
|
||||
# We may decide to deprecate these methods after we designed the Network feature.
|
||||
module OpenFoodNetwork
|
||||
module VariantStock
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
after_save :save_stock
|
||||
end
|
||||
|
||||
def on_hand
|
||||
if on_demand
|
||||
Float::INFINITY
|
||||
else
|
||||
total_on_hand
|
||||
end
|
||||
end
|
||||
|
||||
def count_on_hand
|
||||
total_on_hand
|
||||
end
|
||||
|
||||
def on_hand=(new_level)
|
||||
error = 'Cannot set on_hand value when Spree::Config[:track_inventory_levels] is false'
|
||||
raise error unless Spree::Config.track_inventory_levels
|
||||
|
||||
self.count_on_hand = new_level
|
||||
end
|
||||
|
||||
def count_on_hand=(new_level)
|
||||
raise_error_if_no_stock_item_available
|
||||
overwrite_stock_levels new_level
|
||||
end
|
||||
|
||||
def on_demand
|
||||
stock_items.any?(&:backorderable?)
|
||||
end
|
||||
|
||||
def on_demand=(new_value)
|
||||
raise_error_if_no_stock_item_available
|
||||
|
||||
# There should be only one at the default stock location.
|
||||
stock_items.each do |item|
|
||||
item.backorderable = new_value
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def save_stock
|
||||
stock_items.each(&:save)
|
||||
end
|
||||
|
||||
def raise_error_if_no_stock_item_available
|
||||
message = 'You need to save the variant to create a stock item before you can set stock levels.'
|
||||
raise message if stock_items.empty?
|
||||
end
|
||||
|
||||
# Backwards compatible setting of stock levels in Spree 2.0.
|
||||
# It would be better to use `Spree::StockItem.adjust_count_on_hand` which
|
||||
# takes a value to add to the current stock level and uses proper locking.
|
||||
# But this should work the same as in Spree 1.3.
|
||||
def overwrite_stock_levels(new_level)
|
||||
stock_items.first.send :count_on_hand=, new_level
|
||||
|
||||
# There shouldn't be any other stock items, because we should have only one
|
||||
# stock location. But in case there are, the total should be new_level,
|
||||
# so all others need to be zero.
|
||||
stock_items[1..-1].each do |item|
|
||||
item.send :count_on_hand=, 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -82,8 +82,8 @@ describe Spree::OrdersController, type: :controller do
|
||||
describe "generating stock levels" do
|
||||
let!(:order) { create(:order) }
|
||||
let!(:li) { create(:line_item, order: order, variant: v, quantity: 2, max_quantity: 3) }
|
||||
let!(:v) { create(:variant, count_on_hand: 4) }
|
||||
let!(:v2) { create(:variant, count_on_hand: 2) }
|
||||
let!(:v) { create(:variant, on_hand: 4) }
|
||||
let!(:v2) { create(:variant, on_hand: 2) }
|
||||
|
||||
before do
|
||||
order.reload
|
||||
@@ -107,7 +107,7 @@ describe Spree::OrdersController, type: :controller do
|
||||
end
|
||||
|
||||
describe "encoding Infinity" do
|
||||
let!(:v) { create(:variant, on_demand: true, count_on_hand: 0) }
|
||||
let!(:v) { create(:variant, on_demand: true, on_hand: 0) }
|
||||
|
||||
it "encodes Infinity as a large, finite integer" do
|
||||
controller.stock_levels(order, [v.id]).should ==
|
||||
|
||||
@@ -459,7 +459,17 @@ FactoryBot.define do
|
||||
end
|
||||
|
||||
factory :simple_product, parent: :base_product do
|
||||
on_hand 5
|
||||
transient do
|
||||
on_demand { false }
|
||||
on_hand { 5 }
|
||||
end
|
||||
after(:create) do |product, evaluator|
|
||||
product.variants.first.tap do |variant|
|
||||
variant.on_demand = evaluator.on_demand
|
||||
variant.count_on_hand = evaluator.on_hand
|
||||
variant.save
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -487,8 +497,19 @@ FactoryBot.modify do
|
||||
end
|
||||
|
||||
factory :variant do
|
||||
transient do
|
||||
on_demand { false }
|
||||
on_hand { 5 }
|
||||
end
|
||||
|
||||
unit_value 1
|
||||
unit_description ''
|
||||
|
||||
after(:create) do |variant, evaluator|
|
||||
variant.on_demand = evaluator.on_demand
|
||||
variant.count_on_hand = evaluator.on_hand
|
||||
variant.save
|
||||
end
|
||||
end
|
||||
|
||||
factory :shipping_method do
|
||||
|
||||
@@ -64,9 +64,9 @@ describe SubscriptionPlacementJob do
|
||||
let(:shop) { order_cycle.coordinator }
|
||||
let(:order) { create(:order, order_cycle: order_cycle, distributor: shop) }
|
||||
let(:ex) { create(:exchange, :order_cycle => order_cycle, :sender => shop, :receiver => shop, :incoming => false) }
|
||||
let(:variant1) { create(:variant, count_on_hand: 5) }
|
||||
let(:variant2) { create(:variant, count_on_hand: 5) }
|
||||
let(:variant3) { create(:variant, count_on_hand: 5) }
|
||||
let(:variant1) { create(:variant, on_hand: 5) }
|
||||
let(:variant2) { create(:variant, on_hand: 5) }
|
||||
let(:variant3) { create(:variant, on_hand: 5) }
|
||||
let!(:line_item1) { create(:line_item, order: order, variant: variant1, quantity: 3) }
|
||||
let!(:line_item2) { create(:line_item, order: order, variant: variant2, quantity: 3) }
|
||||
let!(:line_item3) { create(:line_item, order: order, variant: variant3, quantity: 3) }
|
||||
|
||||
@@ -36,7 +36,7 @@ module OpenFoodNetwork
|
||||
describe "lists" do
|
||||
let(:v2) { create(:variant) }
|
||||
let(:v3) { create(:variant) }
|
||||
let(:v4) { create(:variant, count_on_hand: 0, on_demand: true) }
|
||||
let(:v4) { create(:variant, on_hand: 0, on_demand: true) }
|
||||
let(:hub_address) { create(:address, :address1 => "distributor address", :city => 'The Shire', :zipcode => "1234") }
|
||||
let(:hub) { create(:distributor_enterprise, :address => hub_address) }
|
||||
let(:v2o) { create(:variant_override, hub: hub, variant: v2) }
|
||||
|
||||
@@ -3,7 +3,7 @@ require 'open_food_network/scope_variant_to_hub'
|
||||
module OpenFoodNetwork
|
||||
describe ScopeVariantToHub do
|
||||
let(:hub) { create(:distributor_enterprise) }
|
||||
let(:v) { create(:variant, price: 11.11, count_on_hand: 1, on_demand: true, sku: "VARIANTSKU") }
|
||||
let(:v) { create(:variant, price: 11.11, on_hand: 1, on_demand: true, sku: "VARIANTSKU") }
|
||||
let(:vo) { create(:variant_override, hub: hub, variant: v, price: 22.22, count_on_hand: 2, on_demand: false, sku: "VOSKU") }
|
||||
let(:vo_price_only) { create(:variant_override, hub: hub, variant: v, price: 22.22, count_on_hand: nil) }
|
||||
let(:scoper) { ScopeVariantToHub.new(hub) }
|
||||
|
||||
@@ -59,7 +59,7 @@ describe VariantOverride do
|
||||
|
||||
describe "looking up count on hand" do
|
||||
it "returns the numeric stock level when present" do
|
||||
VariantOverride.create!(variant: variant, hub: hub, count_on_hand: 12)
|
||||
VariantOverride.create!(variant: variant, hub: hub, on_hand: 12)
|
||||
VariantOverride.count_on_hand_for(hub, variant).should == 12
|
||||
end
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ describe SubscriptionForm do
|
||||
let!(:product3) { create(:product, supplier: shop) }
|
||||
let!(:variant1) { create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: []) }
|
||||
let!(:variant2) { create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: []) }
|
||||
let!(:variant3) { create(:variant, product: product2, unit_value: '1000', price: 2.50, option_values: [], count_on_hand: 1) }
|
||||
let!(:variant3) { create(:variant, product: product2, unit_value: '1000', price: 2.50, option_values: [], on_hand: 1) }
|
||||
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
|
||||
let!(:order_cycle1) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 9.days.ago, orders_close_at: 2.days.ago) }
|
||||
let!(:order_cycle2) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.days.ago, orders_close_at: 5.days.from_now) }
|
||||
|
||||
Reference in New Issue
Block a user