diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 5b2744d718..970c09a7ee 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -1,5 +1,6 @@ require 'open_food_network/referer_parser' require 'open_food_network/permissions' +require 'open_food_network/order_cycle_permissions' module Admin class EnterprisesController < ResourceController diff --git a/app/controllers/api/exchange_products_controller.rb b/app/controllers/api/exchange_products_controller.rb index e9e3ec537b..3c20c7c764 100644 --- a/app/controllers/api/exchange_products_controller.rb +++ b/app/controllers/api/exchange_products_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # This controller lists products that can be added to an exchange module Api class ExchangeProductsController < Api::BaseController @@ -29,17 +31,21 @@ module Api def render_variant_count render text: { - count: Spree::Variant. - not_master. - where(product_id: products). - count + count: variants.count }.to_json end + def variants + renderer.exchange_variants(@incoming, @enterprise) + end + def products - ExchangeProductsRenderer. - new(@order_cycle, spree_current_user). - exchange_products(@incoming, @enterprise) + renderer.exchange_products(@incoming, @enterprise) + end + + def renderer + @renderer ||= ExchangeProductsRenderer. + new(@order_cycle, spree_current_user) end def paginated_products diff --git a/app/services/exchange_products_renderer.rb b/app/services/exchange_products_renderer.rb index faadba34f1..d1a0b0a225 100644 --- a/app/services/exchange_products_renderer.rb +++ b/app/services/exchange_products_renderer.rb @@ -1,3 +1,7 @@ +# frozen_string_literal: true + +require 'open_food_network/order_cycle_permissions' + class ExchangeProductsRenderer def initialize(order_cycle, user) @order_cycle = order_cycle @@ -12,6 +16,14 @@ class ExchangeProductsRenderer end end + def exchange_variants(incoming, enterprise) + variants_relation = Spree::Variant. + not_master. + where(product_id: exchange_products(incoming, enterprise).select(&:id)) + + filter_visible(variants_relation) + end + private def products_for_incoming_exchange(enterprise) @@ -21,12 +33,16 @@ class ExchangeProductsRenderer def supplied_products(enterprises_query_matcher) products_relation = Spree::Product.where(supplier_id: enterprises_query_matcher) + filter_visible(products_relation) + end + + def filter_visible(relation) if @order_cycle.present? && @order_cycle.prefers_product_selection_from_coordinator_inventory_only? - products_relation = products_relation.visible_for(@order_cycle.coordinator) + relation = relation.visible_for(@order_cycle.coordinator) end - products_relation + relation end def products_for_outgoing_exchange diff --git a/spec/services/exchange_products_renderer_spec.rb b/spec/services/exchange_products_renderer_spec.rb index 2af3636e3d..3293d27709 100644 --- a/spec/services/exchange_products_renderer_spec.rb +++ b/spec/services/exchange_products_renderer_spec.rb @@ -26,4 +26,38 @@ describe ExchangeProductsRenderer do end end end + + describe "#exchange_variants" do + describe "for an incoming exchange" do + it "loads variants" do + exchange = order_cycle.exchanges.incoming.first + variants = renderer.exchange_variants(true, exchange.sender) + + expect(variants.first.product.supplier.name).to eq exchange.variants.first.product.supplier.name + end + + describe "when OC is showing only the coordinators inventory" do + let(:exchange_with_visible_variant) { order_cycle.exchanges.incoming.second } + let(:exchange_with_hidden_variant) { order_cycle.exchanges.incoming.first } + let!(:visible_inventory_item) { create(:inventory_item, enterprise: order_cycle.coordinator, variant: exchange_with_visible_variant.variants.first, visible: true) } + let!(:hidden_inventory_item) { create(:inventory_item, enterprise: order_cycle.coordinator, variant: exchange_with_hidden_variant.variants.first, visible: false) } + + before do + order_cycle.prefers_product_selection_from_coordinator_inventory_only = true + end + + it "renders visible inventory variants" do + variants = renderer.exchange_variants(true, exchange_with_visible_variant.sender) + + expect(variants.size).to eq 1 + end + + it "does not render hidden inventory variants" do + variants = renderer.exchange_variants(true, exchange_with_hidden_variant.sender) + + expect(variants.size).to eq 0 + end + end + end + end end