diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 2a88db9bfe..b874419ffa 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -194,7 +194,6 @@ Metrics/ClassLength: - 'app/controllers/admin/resource_controller.rb' - 'app/controllers/admin/schedules_controller.rb' - 'app/controllers/admin/subscriptions_controller.rb' - - 'app/controllers/api/v0/products_controller.rb' - 'app/controllers/application_controller.rb' - 'app/controllers/payment_gateways/paypal_controller.rb' - 'app/controllers/spree/admin/orders_controller.rb' diff --git a/app/controllers/api/v0/products_controller.rb b/app/controllers/api/v0/products_controller.rb index 6b6baa311a..e94a1e3832 100644 --- a/app/controllers/api/v0/products_controller.rb +++ b/app/controllers/api/v0/products_controller.rb @@ -13,7 +13,7 @@ module Api skip_authorization_check only: [:show, :bulk_products, :overridable] def show - @product = find_product(params[:id]) + @product = ProductScopeQuery.new(current_api_user, params).find_product render json: @product, serializer: Api::Admin::ProductSerializer end @@ -30,7 +30,7 @@ module Api def update authorize! :update, Spree::Product - @product = find_product(params[:id]) + @product = ProductScopeQuery.new(current_api_user, params).find_product if @product.update(product_params) render json: @product, serializer: Api::Admin::ProductSerializer, status: :ok else @@ -40,36 +40,20 @@ module Api def destroy authorize! :delete, Spree::Product - @product = find_product(params[:id]) + @product = ProductScopeQuery.new(current_api_user, params).find_product authorize! :delete, @product @product.destroy render json: @product, serializer: Api::Admin::ProductSerializer, status: :no_content end def bulk_products - product_query = OpenFoodNetwork::Permissions. - new(current_api_user). - editable_products. - merge(product_scope) - - if params[:import_date].present? - product_query = product_query. - imported_on(params[:import_date]). - group_by_products_id - end - - @products = product_query. - ransack(query_params_with_defaults). - result + @products = Spree::Product.bulk_products(current_api_user, params) render_paged_products @products end def overridable - producer_ids = OpenFoodNetwork::Permissions.new(current_api_user). - variant_override_producers.by_name.select('enterprises.id') - - @products = paged_products_for_producers producer_ids + @products = Spree::Product.paged_products_for_producers(current_api_user, params) render_paged_products @products, ::Api::Admin::ProductSimpleSerializer end @@ -78,7 +62,7 @@ module Api # def clone authorize! :create, Spree::Product - original_product = find_product(params[:product_id]) + original_product = ProductScopeQuery.new(current_api_user, params).find_product_to_be_cloned authorize! :update, original_product @product = original_product.duplicate @@ -88,39 +72,6 @@ module Api private - def find_product(id) - product_scope.find(id) - end - - def product_scope - if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present? - scope = Spree::Product - if params[:show_deleted] - scope = scope.with_deleted - end - else - scope = Spree::Product.active - end - - scope.includes(product_query_includes) - end - - def product_query_includes - [ - image: { attachment_attachment: :blob }, - variants: [:default_price, :stock_locations, :stock_items, :variant_overrides] - ] - end - - def paged_products_for_producers(producer_ids) - Spree::Product.where(nil). - merge(product_scope). - includes(variants: [:product, :default_price, :stock_items]). - where(supplier_id: producer_ids). - by_producer.by_name. - ransack(params[:q]).result - end - def render_paged_products(products, product_serializer = ::Api::Admin::ProductSerializer) @pagy, products = pagy(products, items: params[:per_page] || DEFAULT_PER_PAGE) @@ -135,10 +86,6 @@ module Api } end - def query_params_with_defaults - (params[:q] || {}).reverse_merge(s: 'created_at desc') - end - def product_params @product_params ||= params.permit(product: PermittedAttributes::Product.attributes)[:product].to_h diff --git a/app/models/spree/product.rb b/app/models/spree/product.rb index 0378df7322..76e3b8745c 100755 --- a/app/models/spree/product.rb +++ b/app/models/spree/product.rb @@ -189,6 +189,17 @@ module Spree scope :active, lambda { where("spree_products.deleted_at IS NULL") } + scope :bulk_products, lambda { |user, params| + ProductScopeQuery.new(user, params).bulk_products + } + + scope :paged_products_for_producers, + lambda { |user, params| ProductScopeQuery.new(user, params).paged_products_for_producers } + + scope :product_scope, lambda { |user, params| + ProductScopeQuery.new(user, params).product_scope + } + def self.group_by_products_id group(column_names.map { |col_name| "#{table_name}.#{col_name}" }) end diff --git a/app/queries/product_scope_query.rb b/app/queries/product_scope_query.rb new file mode 100644 index 0000000000..bc8b6953b2 --- /dev/null +++ b/app/queries/product_scope_query.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +class ProductScopeQuery + def initialize(user, params) + @user = user + @params = params + end + + def bulk_products + product_query = OpenFoodNetwork::Permissions. + new(@user). + editable_products. + merge(product_scope) + + if @params[:import_date].present? + product_query = product_query. + imported_on(@params[:import_date]). + group_by_products_id + end + + product_query. + ransack(query_params_with_defaults). + result + end + + def find_product + product_scope.find(@params[:id]) + end + + def find_product_to_be_cloned + product_scope.find(@params[:product_id]) + end + + def paged_products_for_producers + producer_ids = OpenFoodNetwork::Permissions.new(@user). + variant_override_producers.by_name.select('enterprises.id') + + Spree::Product.where(nil). + merge(product_scope). + includes(variants: [:product, :default_price, :stock_items]). + where(supplier_id: producer_ids). + by_producer.by_name. + ransack(@params[:q]).result + end + + def product_scope + if @user.has_spree_role?("admin") || @user.enterprises.present? + scope = Spree::Product + if @params[:show_deleted] + scope = scope.with_deleted + end + else + scope = Spree::Product.active + end + + scope.includes(product_query_includes) + end + + def product_query_includes + [ + image: { attachment_attachment: :blob }, + variants: [:default_price, :stock_locations, :stock_items, :variant_overrides] + ] + end + + def query_params_with_defaults + (@params[:q] || {}).reverse_merge(s: 'created_at desc') + end +end