diff --git a/app/controllers/api/v0/order_cycles_controller.rb b/app/controllers/api/v0/order_cycles_controller.rb index 0b864f55ea..df96577339 100644 --- a/app/controllers/api/v0/order_cycles_controller.rb +++ b/app/controllers/api/v0/order_cycles_controller.rb @@ -22,7 +22,8 @@ module Api distributor, order_cycle, customer, - search_params + search_params, + inventory_enabled: ).products_json render plain: products @@ -95,9 +96,13 @@ module Api def distributed_products OrderCycles::DistributedProductsService.new( - distributor, order_cycle, customer + distributor, order_cycle, customer, inventory_enabled: ).products_relation.pluck(:id) end + + def inventory_enabled + OpenFoodNetwork::FeatureToggle.enabled?(:inventory, distributor) + end end end end diff --git a/app/models/spree/ability.rb b/app/models/spree/ability.rb index e0214eea66..ea1c67f827 100644 --- a/app/models/spree/ability.rb +++ b/app/models/spree/ability.rb @@ -213,18 +213,20 @@ module Spree managed_product_enterprises.include? variant.supplier end - can [:admin, :index, :read, :update, :bulk_update, :bulk_reset], VariantOverride do |vo| - next false unless vo.hub.present? && vo.variant&.supplier.present? + if OpenFoodNetwork::FeatureToggle.enabled?(:inventory, user.enterprises) + can [:admin, :index, :read, :update, :bulk_update, :bulk_reset], VariantOverride do |vo| + next false unless vo.hub.present? && vo.variant&.supplier.present? - hub_auth = OpenFoodNetwork::Permissions.new(user). - variant_override_hubs. - include? vo.hub + hub_auth = OpenFoodNetwork::Permissions.new(user). + variant_override_hubs. + include? vo.hub - producer_auth = OpenFoodNetwork::Permissions.new(user). - variant_override_producers. - include? vo.variant.supplier + producer_auth = OpenFoodNetwork::Permissions.new(user). + variant_override_producers. + include? vo.variant.supplier - hub_auth && producer_auth + hub_auth && producer_auth + end end can [:admin, :create, :update], InventoryItem do |ii| diff --git a/app/services/order_cycles/distributed_products_service.rb b/app/services/order_cycles/distributed_products_service.rb index 0b109253eb..71b0574d1e 100644 --- a/app/services/order_cycles/distributed_products_service.rb +++ b/app/services/order_cycles/distributed_products_service.rb @@ -5,10 +5,11 @@ module OrderCycles class DistributedProductsService # rubocop:disable Metrics/ClassLength - def initialize(distributor, order_cycle, customer) + def initialize(distributor, order_cycle, customer, **options) @distributor = distributor @order_cycle = order_cycle @customer = customer + @options = options end def products_relation @@ -26,13 +27,13 @@ module OrderCycles def variants_relation order_cycle. variants_distributed_by(distributor). - merge(stocked_variants_and_overrides). + merge(variants). select("DISTINCT spree_variants.*") end private - attr_reader :distributor, :order_cycle, :customer + attr_reader :distributor, :order_cycle, :customer, :options def relation_by_sorting query = Spree::Product.where(id: stocked_products) @@ -112,10 +113,18 @@ module OrderCycles def stocked_products order_cycle. variants_distributed_by(distributor). - merge(stocked_variants_and_overrides). + merge(variants). select("DISTINCT spree_variants.product_id") end + def variants + options[:inventory_enabled] ? stocked_variants_and_overrides : stocked_variants + end + + def stocked_variants + Spree::Variant.joins(:stock_items).where(query_stock) + end + def stocked_variants_and_overrides stocked_variants = Spree::Variant. joins("LEFT OUTER JOIN variant_overrides ON variant_overrides.variant_id = spree_variants.id @@ -126,6 +135,10 @@ module OrderCycles ProductTagRulesFilterer.new(distributor, customer, stocked_variants).call end + def query_stock + "( #{variant_on_demand} OR #{variant_in_stock} )" + end + def query_stock_with_overrides "( #{variant_not_overriden} AND ( #{variant_on_demand} OR #{variant_in_stock} ) ) OR ( #{variant_overriden} AND ( #{override_on_demand} OR #{override_in_stock} ) ) diff --git a/app/services/products_renderer.rb b/app/services/products_renderer.rb index d12d92ffde..634663790d 100644 --- a/app/services/products_renderer.rb +++ b/app/services/products_renderer.rb @@ -8,11 +8,12 @@ class ProductsRenderer class NoProducts < RuntimeError; end DEFAULT_PER_PAGE = 10 - def initialize(distributor, order_cycle, customer, args = {}) + def initialize(distributor, order_cycle, customer, args = {}, **options) @distributor = distributor @order_cycle = order_cycle @customer = customer @args = args + @options = options end def products_json @@ -28,7 +29,7 @@ class ProductsRenderer private - attr_reader :order_cycle, :distributor, :customer, :args + attr_reader :order_cycle, :distributor, :customer, :args, :options def products return unless order_cycle @@ -106,19 +107,21 @@ class ProductsRenderer end def distributed_products - OrderCycles::DistributedProductsService.new(distributor, order_cycle, customer) + OrderCycles::DistributedProductsService.new(distributor, order_cycle, customer, **options) end def variants_for_shop @variants_for_shop ||= begin - scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor) - - # rubocop:disable Rails/FindEach # .each returns an array, .find_each returns nil - distributed_products.variants_relation. + variants = distributed_products.variants_relation. includes(:default_price, :product). - where(product_id: products). - each { |v| scoper.scope(v) } # Scope results with variant_overrides - # rubocop:enable Rails/FindEach + where(product_id: products) + + if options[:inventory_enabled] + scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor) + variants = variants.each { |v| scoper.scope(v) } # Scope results with variant_overrides + end + + variants end end diff --git a/app/views/spree/admin/shared/_product_sub_menu.html.haml b/app/views/spree/admin/shared/_product_sub_menu.html.haml index 6c222d49e7..91fc3e6bc5 100644 --- a/app/views/spree/admin/shared/_product_sub_menu.html.haml +++ b/app/views/spree/admin/shared/_product_sub_menu.html.haml @@ -2,5 +2,5 @@ %ul#sub_nav.inline-menu = tab :products, :products_v3 = tab :properties - = tab :variant_overrides, url: main_app.admin_inventory_path, match_path: '/inventory' + = tab :variant_overrides, url: main_app.admin_inventory_path, match_path: '/inventory' if feature?(:inventory, spree_current_user.enterprises) = tab :import, url: main_app.admin_product_import_path, match_path: '/product_import' diff --git a/lib/open_food_network/feature_toggle.rb b/lib/open_food_network/feature_toggle.rb index 524a273f0b..604f949084 100644 --- a/lib/open_food_network/feature_toggle.rb +++ b/lib/open_food_network/feature_toggle.rb @@ -64,6 +64,9 @@ module OpenFoodNetwork "variant_tag" => <<~DESC, Variant Tag are available on the Bulk Edit Products page. DESC + "inventory" => <<~DESC, + Enable the inventory. + DESC }.merge(conditional_features).freeze; # Features you would like to be enabled to start with. diff --git a/spec/controllers/api/v0/order_cycles_controller_spec.rb b/spec/controllers/api/v0/order_cycles_controller_spec.rb index 4082232282..0a55c57c61 100644 --- a/spec/controllers/api/v0/order_cycles_controller_spec.rb +++ b/spec/controllers/api/v0/order_cycles_controller_spec.rb @@ -59,7 +59,7 @@ RSpec.describe Api::V0::OrderCyclesController do expect(product_ids).not_to include product2.id end - context "with variant overrides" do + context "with variant overrides", feature: :inventory do let!(:vo1) { create(:variant_override, hub: distributor, @@ -91,7 +91,6 @@ RSpec.describe Api::V0::OrderCyclesController do before do product1.update!(properties: [property1, property2]) end - it "filters by product property" do api_get :products, id: order_cycle.id, distributor: distributor.id, q: { with_properties: [property1.id, property2.id] } @@ -133,7 +132,7 @@ RSpec.describe Api::V0::OrderCyclesController do end end - context "when tag rules apply" do + context "when tag rules apply", feature: :inventory do let!(:vo1) { create(:variant_override, hub: distributor, diff --git a/spec/models/spree/ability_spec.rb b/spec/models/spree/ability_spec.rb index 5756b9795f..42e0300b36 100644 --- a/spec/models/spree/ability_spec.rb +++ b/spec/models/spree/ability_spec.rb @@ -549,7 +549,7 @@ RSpec.describe Spree::Ability do end end - describe "variant overrides" do + describe "variant overrides", feature: :inventory do let(:vo1) { create(:variant_override, hub: d1, variant: p1.variants.first) } let(:vo2) { create(:variant_override, hub: d1, variant: p2.variants.first) } let(:vo3) { create(:variant_override, hub: d2, variant: p1.variants.first) } @@ -788,7 +788,7 @@ RSpec.describe Spree::Ability do end end - describe "permissions for variant overrides" do + describe "permissions for variant overrides", feature: :inventory do let!(:distributor) { create(:distributor_enterprise) } let!(:producer) { create(:supplier_enterprise) } let!(:variant) { create(:variant, supplier: producer) } diff --git a/spec/services/order_cycles/distributed_products_service_spec.rb b/spec/services/order_cycles/distributed_products_service_spec.rb index 0ba85468a2..ff6b9a55a4 100644 --- a/spec/services/order_cycles/distributed_products_service_spec.rb +++ b/spec/services/order_cycles/distributed_products_service_spec.rb @@ -71,6 +71,12 @@ RSpec.describe OrderCycles::DistributedProductsService do end context "with variant overrides" do + subject(:products_relation) { + described_class.new( + distributor, order_cycle, customer, inventory_enabled: true + ).products_relation + } + let!(:override) { create(:variant_override, hub: distributor, variant:, count_on_hand: 0) } @@ -161,7 +167,9 @@ RSpec.describe OrderCycles::DistributedProductsService do let!(:v2) { create(:variant, product:) } let!(:v3) { create(:variant, product:) } let!(:vo) { create(:variant_override, hub: distributor, variant_id: v3.id, count_on_hand: 0) } - let(:variants) { described_class.new(distributor, oc, customer).variants_relation } + let(:variants) { + described_class.new(distributor, oc, customer, inventory_enabled: true).variants_relation + } it "returns variants in the oc" do expect(variants).to include v1 diff --git a/spec/services/products_renderer_spec.rb b/spec/services/products_renderer_spec.rb index a0266d3d16..90fbb31347 100644 --- a/spec/services/products_renderer_spec.rb +++ b/spec/services/products_renderer_spec.rb @@ -206,6 +206,8 @@ RSpec.describe ProductsRenderer do end it "loads tag_list for variants" do + products_renderer = ProductsRenderer.new(distributor, order_cycle, customer, {}, + inventory_enabled: true) VariantOverride.create(variant:, hub: distributor, tag_list: 'lalala') expect(products_renderer.products_json).to include "[\"lalala\"]" end