mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-04 22:16:08 +00:00
When creating backoffice orders hide variants with no stock by default
But let people include out of stock variants by checking a checkbox if they want. Note, we only apply the variants in stock scope if a distributor is present. I think this is because this search method is also used when setting up subscriptions so I don't think we want to change the behaviour there. Co-authored-by: Maikel Linke <maikel@email.org.au>
This commit is contained in:
@@ -19,6 +19,7 @@ angular.module("admin.utils").directive "variantAutocomplete", ($timeout) ->
|
||||
distributor_id: scope.distributor_id
|
||||
order_cycle_id: scope.order_cycle_id
|
||||
eligible_for_subscriptions: scope.eligible_for_subscriptions
|
||||
include_out_of_stock: scope.include_out_of_stock
|
||||
results: (data, page) ->
|
||||
window.variants = data # this is how spree auto complete JS code picks up variants
|
||||
results: data
|
||||
@@ -27,3 +28,5 @@ angular.module("admin.utils").directive "variantAutocomplete", ($timeout) ->
|
||||
formatSelection: (variant) ->
|
||||
element.parent().children(".options_placeholder").html variant.options_text
|
||||
variant.name
|
||||
element.on "select2-opening", ->
|
||||
scope.include_out_of_stock = if $('#include_out_of_stock').is(':checked') then "1" else ""
|
||||
|
||||
@@ -114,7 +114,7 @@ module Spree
|
||||
|
||||
def variant_search_params
|
||||
params.permit(
|
||||
:q, :distributor_id, :order_cycle_id, :schedule_id, :eligible_for_subscriptions
|
||||
:q, :distributor_id, :order_cycle_id, :schedule_id, :eligible_for_subscriptions, :include_out_of_stock
|
||||
).to_h.with_indifferent_access
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,8 +7,13 @@
|
||||
- if @order.canceled?
|
||||
= t(".cannot_add_item_to_canceled_order")
|
||||
- else
|
||||
.field.twelve.columns.alpha{"data-hook" => "add_product_name"}
|
||||
.field.nine.columns.alpha{"data-hook" => "add_product_name"}
|
||||
= label_tag :add_variant_id, Spree.t(:name_or_sku)
|
||||
= hidden_field_tag :add_variant_id, "", :class => "variant_autocomplete fullwidth"
|
||||
.five.columns.omega
|
||||
.field
|
||||
= label_tag 'include_out_of_stock', t(".include_out_of_stock_variants")
|
||||
%br/
|
||||
= check_box_tag 'include_out_of_stock', '1'
|
||||
|
||||
#stock_details
|
||||
|
||||
@@ -3570,6 +3570,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
orders:
|
||||
add_product:
|
||||
cannot_add_item_to_canceled_order: "Cannot add item to canceled order"
|
||||
include_out_of_stock_variants: "Include variants with no available stock"
|
||||
index:
|
||||
listing_orders: "Listing Orders"
|
||||
new_order: "New Order"
|
||||
|
||||
@@ -16,6 +16,7 @@ module OpenFoodNetwork
|
||||
def search
|
||||
@variants = query_scope
|
||||
|
||||
scope_to_in_stock_only if params[:distributor_id] && params[:include_out_of_stock] != "1"
|
||||
scope_to_schedule if params[:schedule_id]
|
||||
scope_to_order_cycle if params[:order_cycle_id]
|
||||
scope_to_distributor if params[:distributor_id]
|
||||
@@ -68,6 +69,18 @@ module OpenFoodNetwork
|
||||
scope_variants_to_distributor(@variants, distributor)
|
||||
end
|
||||
|
||||
def scope_to_in_stock_only
|
||||
@variants = @variants.joins(
|
||||
"INNER JOIN spree_stock_items ON spree_stock_items.variant_id = spree_variants.id
|
||||
LEFT JOIN variant_overrides ON variant_overrides.variant_id = spree_variants.id"
|
||||
).where("
|
||||
variant_overrides.on_demand IS TRUE OR
|
||||
variant_overrides.count_on_hand > 0 OR
|
||||
(variant_overrides.on_demand IS NULL AND spree_stock_items.backorderable IS TRUE) OR
|
||||
(variant_overrides.count_on_hand IS NULL AND spree_stock_items.count_on_hand > 0)
|
||||
")
|
||||
end
|
||||
|
||||
def scope_variants_to_distributor(variants, distributor)
|
||||
scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor)
|
||||
# Perform scoping after all filtering is done.
|
||||
|
||||
@@ -37,8 +37,7 @@ describe OpenFoodNetwork::ScopeVariantsForSearch do
|
||||
let(:params) { { q: "product", schedule_id: s1.id } }
|
||||
|
||||
it "returns all products distributed through that schedule" do
|
||||
lala = result
|
||||
expect(lala).to include v1, v3
|
||||
expect(result).to include v1, v3
|
||||
expect(result).to_not include v2, v4
|
||||
end
|
||||
end
|
||||
@@ -59,6 +58,115 @@ describe OpenFoodNetwork::ScopeVariantsForSearch do
|
||||
expect(result).to include v4
|
||||
expect(result).to_not include v1, v2, v3
|
||||
end
|
||||
|
||||
context "filtering by stock availability" do
|
||||
let!(:distributor1_variant_on_hand_but_not_backorderable) do
|
||||
create_variant_with_stock_item_for(d1, backorderable: false, count_on_hand: 1)
|
||||
end
|
||||
let!(:distributor1_variant_backorderable_but_not_on_hand) do
|
||||
create_variant_with_stock_item_for(d1, backorderable: true, count_on_hand: 0)
|
||||
end
|
||||
let!(:distributor1_variant_not_backorderable_and_not_on_hand) do
|
||||
create_variant_with_stock_item_for(d1, backorderable: false, count_on_hand: 0)
|
||||
end
|
||||
let!(:distributor1_variant_with_override_on_hand_but_not_on_demand) do
|
||||
create_variant_with_variant_override_for(d1, on_demand: false, count_on_hand: 1)
|
||||
end
|
||||
let!(:distributor1_variant_with_override_on_demand_but_not_on_hand) do
|
||||
create_variant_with_variant_override_for(d1, on_demand: true, count_on_hand: nil)
|
||||
end
|
||||
let!(:distributor1_variant_with_override_not_on_demand_and_not_on_hand) do
|
||||
create_variant_with_variant_override_for(d1, on_demand: false, count_on_hand: 0)
|
||||
end
|
||||
let!(:distributor1_variant_with_override_not_in_stock_but_producer_in_stock) do
|
||||
variant = create(:simple_product).variants.first
|
||||
variant.stock_items.first.update!(backorderable: false, count_on_hand: 1)
|
||||
create(:simple_order_cycle, distributors: [d1], variants: [variant])
|
||||
create(:variant_override, variant: variant, hub: d1, on_demand: false, count_on_hand: 0)
|
||||
variant
|
||||
end
|
||||
let!(:distributor1_variant_with_override_without_stock_level_set_and_producer_not_in_stock) do
|
||||
variant = create(:simple_product).variants.first
|
||||
variant.stock_items.first.update!(backorderable: false, count_on_hand: 0)
|
||||
create(:simple_order_cycle, distributors: [d1], variants: [variant])
|
||||
create(:variant_override, variant: variant, hub: d1, on_demand: nil, count_on_hand: nil)
|
||||
variant
|
||||
end
|
||||
let!(:distributor1_variant_with_override_without_stock_level_set_but_producer_in_stock) do
|
||||
variant = create(:simple_product).variants.first
|
||||
variant.stock_items.first.update!(backorderable: false, count_on_hand: 1)
|
||||
create(:simple_order_cycle, distributors: [d1], variants: [variant])
|
||||
create(:variant_override, variant: variant, hub: d1, on_demand: nil, count_on_hand: nil)
|
||||
variant
|
||||
end
|
||||
let!(:distributor2_variant_with_override_in_stock) do
|
||||
create_variant_with_variant_override_for(d2, count_on_hand: 1)
|
||||
end
|
||||
|
||||
context "when :include_out_of_stock is not specified" do
|
||||
let(:params) { { distributor_id: d1.id } }
|
||||
|
||||
it "returns variants for the given distributor if they have a variant override which is
|
||||
in stock, or if they have a variant override with no stock level set but the producer
|
||||
has stock, or if they don't have a variant override and the producer has stock" do
|
||||
expect(result).to include(
|
||||
distributor1_variant_on_hand_but_not_backorderable,
|
||||
distributor1_variant_backorderable_but_not_on_hand,
|
||||
distributor1_variant_with_override_on_demand_but_not_on_hand,
|
||||
distributor1_variant_with_override_on_hand_but_not_on_demand,
|
||||
distributor1_variant_with_override_without_stock_level_set_but_producer_in_stock
|
||||
)
|
||||
expect(result).to_not include(
|
||||
distributor1_variant_not_backorderable_and_not_on_hand,
|
||||
distributor1_variant_with_override_not_on_demand_and_not_on_hand,
|
||||
distributor1_variant_with_override_not_in_stock_but_producer_in_stock,
|
||||
distributor1_variant_with_override_without_stock_level_set_and_producer_not_in_stock,
|
||||
distributor2_variant_with_override_in_stock
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when :include_out_of_stock is specified" do
|
||||
let(:params) { { distributor_id: d1.id, include_out_of_stock: "1" } }
|
||||
|
||||
it "returns all variants for the given distributor even if they are not in stock" do
|
||||
expect(result).to include(
|
||||
distributor1_variant_on_hand_but_not_backorderable,
|
||||
distributor1_variant_backorderable_but_not_on_hand,
|
||||
distributor1_variant_with_override_on_demand_but_not_on_hand,
|
||||
distributor1_variant_with_override_on_hand_but_not_on_demand,
|
||||
distributor1_variant_with_override_without_stock_level_set_but_producer_in_stock,
|
||||
distributor1_variant_with_override_without_stock_level_set_and_producer_not_in_stock,
|
||||
distributor1_variant_not_backorderable_and_not_on_hand,
|
||||
distributor1_variant_with_override_not_on_demand_and_not_on_hand,
|
||||
distributor1_variant_with_override_not_in_stock_but_producer_in_stock
|
||||
)
|
||||
expect(result).to_not include(
|
||||
distributor2_variant_with_override_in_stock
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_variant_with_stock_item_for(distributor, stock_item_attributes)
|
||||
variant = create(:simple_product).variants.first
|
||||
variant.stock_items.first.update!(stock_item_attributes)
|
||||
create(:simple_order_cycle, distributors: [distributor], variants: [variant])
|
||||
variant
|
||||
end
|
||||
|
||||
def create_variant_with_variant_override_for(distributor, variant_override_attributes)
|
||||
variant = create(:simple_product).variants.first
|
||||
variant.stock_items.first.update!(backorderable: false, count_on_hand: 0)
|
||||
create(:simple_order_cycle, distributors: [distributor], variants: [variant])
|
||||
create(:variant_override, {
|
||||
variant: variant,
|
||||
hub: distributor
|
||||
}.merge(variant_override_attributes))
|
||||
variant
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user