<commit_before># frozen_string_literal: true

# This controller lists products that can be added to an exchange
#
# Pagination is optional and can be required by using param[:page]
module Api
  module V0
    class ExchangeProductsController < Api::V0::BaseController
      include PaginationData
      DEFAULT_PER_PAGE = 100

      skip_authorization_check only: [:index]

      # If exchange_id is present in the URL:
      #   Lists Products that can be added to that Exchange
      #
      # If exchange_id is not present in the URL:
      #   Lists Products of the Enterprise given that can be added to the given Order Cycle
      #   In this case parameters are: enterprise_id, order_cycle_id and incoming
      #     (order_cycle_id is not necessary for incoming exchanges)
      def index
        if exchange_params[:exchange_id].present?
          load_data_from_exchange
        else
          load_data_from_other_params
        end

        render_variant_count && return if params[:action_name] == "variant_count"

        render_paginated_products paginated_products
      end

      private

      def render_variant_count
        render plain: {
          count: variants.count
        }.to_json
      end

      def variants
        renderer.exchange_variants(@incoming, @enterprise)
      end

      def products
        renderer.exchange_products(@incoming, @enterprise)
      end

      def renderer
        @renderer ||= ExchangeProductsRenderer.
          new(@order_cycle, spree_current_user)
      end

      def paginated_products
        return products unless pagination_required?

        products.
          page(params[:page]).
          per(params[:per_page] || DEFAULT_PER_PAGE)
      end

      def load_data_from_exchange
        exchange = Exchange.find_by(id: exchange_params[:exchange_id])

        @order_cycle = exchange.order_cycle
        @incoming = exchange.incoming
        @enterprise = exchange.sender
      end

      def load_data_from_other_params
        @enterprise = Enterprise.find_by(id: exchange_params[:enterprise_id])

        # This will be a string (eg "true") when it arrives via params, but we want a boolean
        @incoming = ActiveModel::Type::Boolean.new.cast exchange_params[:incoming]

        if exchange_params[:order_cycle_id]
          @order_cycle = OrderCycle.find_by(id: exchange_params[:order_cycle_id])
        elsif !@incoming
          raise "order_cycle_id is required to list products for new outgoing exchange"
        end
      end

      def render_paginated_products(paginated_products)
        serialized_products = ActiveModel::ArraySerializer.new(
          paginated_products,
          each_serializer: Api::Admin::ForOrderCycle::SuppliedProductSerializer,
          order_cycle: @order_cycle
        )

        render json: {
          products: serialized_products,
          pagination: pagination_data(paginated_products)
        }
      end

      def exchange_params
        params.permit(:enterprise_id, :exchange_id, :order_cycle_id, :incoming).
          to_h.with_indifferent_access
      end
    end
  end
end<commit_msg>Update pagination in Api::ExchangeProductsController<commit_after># frozen_string_literal: true

# This controller lists products that can be added to an exchange
#
# Pagination is optional and can be required by using param[:page]
module Api
  module V0
    class ExchangeProductsController < Api::V0::BaseController
      include PaginationData
      DEFAULT_PER_PAGE = 100

      skip_authorization_check only: [:index]

      # If exchange_id is present in the URL:
      #   Lists Products that can be added to that Exchange
      #
      # If exchange_id is not present in the URL:
      #   Lists Products of the Enterprise given that can be added to the given Order Cycle
      #   In this case parameters are: enterprise_id, order_cycle_id and incoming
      #     (order_cycle_id is not necessary for incoming exchanges)
      def index
        if exchange_params[:exchange_id].present?
          load_data_from_exchange
        else
          load_data_from_other_params
        end

        render_variant_count && return if params[:action_name] == "variant_count"

        render_paginated_products
      end

      private

      def render_variant_count
        render plain: {
          count: variants.count
        }.to_json
      end

      def variants
        renderer.exchange_variants(@incoming, @enterprise)
      end

      def products
        renderer.exchange_products(@incoming, @enterprise)
      end

      def renderer
        @renderer ||= ExchangeProductsRenderer.
          new(@order_cycle, spree_current_user)
      end

      def load_data_from_exchange
        exchange = Exchange.find_by(id: exchange_params[:exchange_id])

        @order_cycle = exchange.order_cycle
        @incoming = exchange.incoming
        @enterprise = exchange.sender
      end

      def load_data_from_other_params
        @enterprise = Enterprise.find_by(id: exchange_params[:enterprise_id])

        # This will be a string (eg "true") when it arrives via params, but we want a boolean
        @incoming = ActiveModel::Type::Boolean.new.cast exchange_params[:incoming]

        if exchange_params[:order_cycle_id]
          @order_cycle = OrderCycle.find_by(id: exchange_params[:order_cycle_id])
        elsif !@incoming
          raise "order_cycle_id is required to list products for new outgoing exchange"
        end
      end

      def render_paginated_products
        pagy, results = nil, products
        pagy, results = pagy(results, items: params[:per_page] || DEFAULT_PER_PAGE) if pagination_required?

        serialized_products = ActiveModel::ArraySerializer.new(
          results,
          each_serializer: Api::Admin::ForOrderCycle::SuppliedProductSerializer,
          order_cycle: @order_cycle
        )

        render json: {
          products: serialized_products,
          pagination: pagination_data(pagy)
        }
      end

      def exchange_params
        params.permit(:enterprise_id, :exchange_id, :order_cycle_id, :incoming).
          to_h.with_indifferent_access
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.060949910844545305, 'fraction_numerical': 0.0016210082671421625, 'mean_word_length': 2.640117994100295, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6715940', 'n_tokens_mistral': 1715, 'n_tokens_neox': 1642, 'n_words': 462}