<commit_before># rubocop:disable Metrics/ClassLength
module OpenFoodNetwork
  class OrdersAndFulfillmentsReport
    class CustomerTotalsReport
      REPORT_TYPE = "order_cycle_customer_totals".freeze

      attr_reader :context

      delegate :line_item_name, to: :context

      def initialize(context)
        @context = context
      end

      # rubocop:disable Metrics/AbcSize
      # rubocop:disable Metrics/MethodLength
      def header
        [I18n.t(:report_header_hub), I18n.t(:report_header_customer), I18n.t(:report_header_email),
         I18n.t(:report_header_phone), I18n.t(:report_header_producer),
         I18n.t(:report_header_product), I18n.t(:report_header_variant),
         I18n.t(:report_header_amount),
         I18n.t(:report_header_item_price, currency: currency_symbol),
         I18n.t(:report_header_item_fees_price, currency: currency_symbol),
         I18n.t(:report_header_admin_handling_fees, currency: currency_symbol),
         I18n.t(:report_header_ship_price, currency: currency_symbol),
         I18n.t(:report_header_pay_fee_price, currency: currency_symbol),
         I18n.t(:report_header_total_price, currency: currency_symbol),
         I18n.t(:report_header_paid), I18n.t(:report_header_shipping),
         I18n.t(:report_header_delivery), I18n.t(:report_header_ship_street),
         I18n.t(:report_header_ship_street_2), I18n.t(:report_header_ship_city),
         I18n.t(:report_header_ship_postcode), I18n.t(:report_header_ship_state),
         I18n.t(:report_header_comments), I18n.t(:report_header_sku),
         I18n.t(:report_header_order_cycle), I18n.t(:report_header_payment_method),
         I18n.t(:report_header_customer_code), I18n.t(:report_header_tags),
         I18n.t(:report_header_billing_street), I18n.t(:report_header_billing_street_2),
         I18n.t(:report_header_billing_city), I18n.t(:report_header_billing_postcode),
         I18n.t(:report_header_billing_state)]
      end
      # rubocop:enable Metrics/AbcSize
      # rubocop:enable Metrics/MethodLength

      # rubocop:disable Metrics/AbcSize
      # rubocop:disable Metrics/MethodLength
      def rules
        [
          {
            group_by: proc { |line_item| line_item.order.distributor },
            sort_by: proc { |distributor| distributor.name }
          },
          {
            group_by: proc { |line_item| line_item.order },
            sort_by: proc { |order| order.bill_address.full_name_reverse },
            summary_columns: [
              proc { |line_items| line_items.first.order.distributor.name },
              proc { |line_items| line_items.first.order.bill_address.full_name },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| I18n.t('admin.reports.total') },
              proc { |_line_items| "" },

              proc { |_line_items| "" },
              proc { |line_items| line_items.sum(&:amount) },
              proc { |line_items| line_items.sum(&:amount_with_adjustments) },
              proc { |line_items| line_items.first.order.admin_and_handling_total },
              proc { |line_items| line_items.first.order.ship_total },
              proc { |line_items| line_items.first.order.payment_fee },
              proc { |line_items| line_items.first.order.total },
              proc { |line_items| line_items.first.order.paid? ? I18n.t(:yes) : I18n.t(:no) },

              proc { |_line_items| "" },
              proc { |_line_items| "" },

              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },

              proc { |line_items| line_items.first.order.special_instructions },
              proc { |_line_items| "" },

              proc { |line_items| line_items.first.order.order_cycle.andand.name },
              proc { |line_items|
                line_items.first.order.payments.first.andand.payment_method.andand.name
              },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" }
            ]
          },
          {
            group_by: proc { |line_item| line_item.variant.product },
            sort_by: proc { |product| product.name }
          },
          {
            group_by: proc { |line_item| line_item.variant },
            sort_by: proc { |variant| variant.full_name }
          },
          {
            group_by: line_item_name,
            sort_by: proc { |full_name| full_name }
          }
        ]
      end
      # rubocop:enable Metrics/AbcSize
      # rubocop:enable Metrics/MethodLength

      # rubocop:disable Metrics/AbcSize
      # rubocop:disable Metrics/CyclomaticComplexity
      # rubocop:disable Metrics/MethodLength
      # rubocop:disable Metrics/PerceivedComplexity
      def columns
        rsa = proc { |line_items| line_items.first.order.shipping_method.andand.delivery? }
        [
          proc { |line_items| line_items.first.order.distributor.name },
          proc { |line_items|
            bill_address = line_items.first.order.bill_address
            bill_address.firstname + " " + bill_address.lastname
          },
          proc { |line_items| line_items.first.order.email },
          proc { |line_items| line_items.first.order.bill_address.phone },
          proc { |line_items| line_items.first.variant.product.supplier.name },
          proc { |line_items| line_items.first.variant.product.name },
          proc { |line_items| line_items.first.variant.full_name },

          proc { |line_items| line_items.sum(&:quantity) },
          proc { |line_items| line_items.sum(&:amount) },
          proc { |line_items| line_items.sum(&:amount_with_adjustments) },
          proc { |_line_items| "" },
          proc { |_line_items| "" },
          proc { |_line_items| "" },
          proc { |_line_items| "" },
          proc { |line_items|
            line_items.all? { |li| li.order.paid? } ? I18n.t(:yes) : I18n.t(:no)
          },

          proc { |line_items| line_items.first.order.shipping_method.andand.name },
          proc { |line_items| rsa.call(line_items) ? I18n.t(:yes) : I18n.t(:no) },

          proc { |line_items|
            line_items.first.order.ship_address.andand.address1 if rsa.call(line_items)
          },
          proc { |line_items|
            line_items.first.order.ship_address.andand.address2 if rsa.call(line_items)
          },
          proc { |line_items|
            line_items.first.order.ship_address.andand.city if rsa.call(line_items)
          },
          proc { |line_items|
            line_items.first.order.ship_address.andand.zipcode if rsa.call(line_items)
          },
          proc { |line_items|
            line_items.first.order.ship_address.andand.state if rsa.call(line_items)
          },

          proc { |_line_items| "" },
          proc { |line_items| line_items.first.variant.sku },

          proc { |line_items| line_items.first.order.order_cycle.andand.name },
          proc { |line_items|
            payment = line_items.first.order.payments.first
            payment.andand.payment_method.andand.name
          },
          proc { |line_items|
            distributor = line_items.first.order.distributor
            user = line_items.first.order.user
            user.andand.customer_of(distributor).andand.code
          },
          proc { |line_items|
            distributor = line_items.first.order.distributor
            user = line_items.first.order.user
            user.andand.customer_of(distributor).andand.tags.andand.join(', ')
          },

          proc { |line_items| line_items.first.order.bill_address.andand.address1 },
          proc { |line_items| line_items.first.order.bill_address.andand.address2 },
          proc { |line_items| line_items.first.order.bill_address.andand.city },
          proc { |line_items| line_items.first.order.bill_address.andand.zipcode },
          proc { |line_items| line_items.first.order.bill_address.andand.state }
        ]
      end
      # rubocop:enable Metrics/AbcSize
      # rubocop:enable Metrics/CyclomaticComplexity
      # rubocop:enable Metrics/MethodLength
      # rubocop:enable Metrics/PerceivedComplexity

      def line_item_includes
        [{ variant: :product, order: [:bill_address, :shipments] }]
      end
    end
  end
end
# rubocop:enable Metrics/ClassLength<commit_msg>Eager-load adjustments and calculate in place<commit_after># rubocop:disable Metrics/ClassLength
module OpenFoodNetwork
  class OrdersAndFulfillmentsReport
    class CustomerTotalsReport
      REPORT_TYPE = "order_cycle_customer_totals".freeze

      attr_reader :context

      delegate :line_item_name, to: :context

      def initialize(context)
        @context = context
      end

      # rubocop:disable Metrics/AbcSize
      # rubocop:disable Metrics/MethodLength
      def header
        [I18n.t(:report_header_hub), I18n.t(:report_header_customer), I18n.t(:report_header_email),
         I18n.t(:report_header_phone), I18n.t(:report_header_producer),
         I18n.t(:report_header_product), I18n.t(:report_header_variant),
         I18n.t(:report_header_amount),
         I18n.t(:report_header_item_price, currency: currency_symbol),
         I18n.t(:report_header_item_fees_price, currency: currency_symbol),
         I18n.t(:report_header_admin_handling_fees, currency: currency_symbol),
         I18n.t(:report_header_ship_price, currency: currency_symbol),
         I18n.t(:report_header_pay_fee_price, currency: currency_symbol),
         I18n.t(:report_header_total_price, currency: currency_symbol),
         I18n.t(:report_header_paid), I18n.t(:report_header_shipping),
         I18n.t(:report_header_delivery), I18n.t(:report_header_ship_street),
         I18n.t(:report_header_ship_street_2), I18n.t(:report_header_ship_city),
         I18n.t(:report_header_ship_postcode), I18n.t(:report_header_ship_state),
         I18n.t(:report_header_comments), I18n.t(:report_header_sku),
         I18n.t(:report_header_order_cycle), I18n.t(:report_header_payment_method),
         I18n.t(:report_header_customer_code), I18n.t(:report_header_tags),
         I18n.t(:report_header_billing_street), I18n.t(:report_header_billing_street_2),
         I18n.t(:report_header_billing_city), I18n.t(:report_header_billing_postcode),
         I18n.t(:report_header_billing_state)]
      end
      # rubocop:enable Metrics/AbcSize
      # rubocop:enable Metrics/MethodLength

      # rubocop:disable Metrics/AbcSize
      # rubocop:disable Metrics/MethodLength
      def rules
        [
          {
            group_by: proc { |line_item| line_item.order.distributor },
            sort_by: proc { |distributor| distributor.name }
          },
          {
            group_by: proc { |line_item| line_item.order },
            sort_by: proc { |order| order.bill_address.full_name_reverse },
            summary_columns: [
              proc { |line_items| line_items.first.order.distributor.name },
              proc { |line_items| line_items.first.order.bill_address.full_name },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| I18n.t('admin.reports.total') },
              proc { |_line_items| "" },

              proc { |_line_items| "" },
              proc { |line_items| line_items.sum(&:amount) },
              proc { |line_items| line_items.sum(&:amount_with_adjustments) },
              proc { |line_items| admin_and_handling_total(line_items.first.order) },
              proc { |line_items| ship_total(line_items.first.order) },
              proc { |line_items| payment_fee(line_items.first.order) },
              proc { |line_items| line_items.first.order.total },
              proc { |line_items| line_items.first.order.paid? ? I18n.t(:yes) : I18n.t(:no) },

              proc { |_line_items| "" },
              proc { |_line_items| "" },

              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },

              proc { |line_items| line_items.first.order.special_instructions },
              proc { |_line_items| "" },

              proc { |line_items| line_items.first.order.order_cycle.andand.name },
              proc { |line_items|
                line_items.first.order.payments.first.andand.payment_method.andand.name
              },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" },
              proc { |_line_items| "" }
            ]
          },
          {
            group_by: proc { |line_item| line_item.variant.product },
            sort_by: proc { |product| product.name }
          },
          {
            group_by: proc { |line_item| line_item.variant },
            sort_by: proc { |variant| variant.full_name }
          },
          {
            group_by: line_item_name,
            sort_by: proc { |full_name| full_name }
          }
        ]
      end
      # rubocop:enable Metrics/AbcSize
      # rubocop:enable Metrics/MethodLength

      # rubocop:disable Metrics/AbcSize
      # rubocop:disable Metrics/CyclomaticComplexity
      # rubocop:disable Metrics/MethodLength
      # rubocop:disable Metrics/PerceivedComplexity
      def columns
        rsa = proc { |line_items| line_items.first.order.shipping_method.andand.delivery? }
        [
          proc { |line_items| line_items.first.order.distributor.name },
          proc { |line_items|
            bill_address = line_items.first.order.bill_address
            bill_address.firstname + " " + bill_address.lastname
          },
          proc { |line_items| line_items.first.order.email },
          proc { |line_items| line_items.first.order.bill_address.phone },
          proc { |line_items| line_items.first.variant.product.supplier.name },
          proc { |line_items| line_items.first.variant.product.name },
          proc { |line_items| line_items.first.variant.full_name },

          proc { |line_items| line_items.sum(&:quantity) },
          proc { |line_items| line_items.sum(&:amount) },
          proc { |line_items| line_items.sum(&:amount_with_adjustments) },
          proc { |_line_items| "" },
          proc { |_line_items| "" },
          proc { |_line_items| "" },
          proc { |_line_items| "" },
          proc { |line_items|
            line_items.all? { |li| li.order.paid? } ? I18n.t(:yes) : I18n.t(:no)
          },

          proc { |line_items| line_items.first.order.shipping_method.andand.name },
          proc { |line_items| rsa.call(line_items) ? I18n.t(:yes) : I18n.t(:no) },

          proc { |line_items|
            line_items.first.order.ship_address.andand.address1 if rsa.call(line_items)
          },
          proc { |line_items|
            line_items.first.order.ship_address.andand.address2 if rsa.call(line_items)
          },
          proc { |line_items|
            line_items.first.order.ship_address.andand.city if rsa.call(line_items)
          },
          proc { |line_items|
            line_items.first.order.ship_address.andand.zipcode if rsa.call(line_items)
          },
          proc { |line_items|
            line_items.first.order.ship_address.andand.state if rsa.call(line_items)
          },

          proc { |_line_items| "" },
          proc { |line_items| line_items.first.variant.sku },

          proc { |line_items| line_items.first.order.order_cycle.andand.name },
          proc { |line_items|
            payment = line_items.first.order.payments.first
            payment.andand.payment_method.andand.name
          },
          proc { |line_items|
            distributor = line_items.first.order.distributor
            user = line_items.first.order.user
            user.andand.customer_of(distributor).andand.code
          },
          proc { |line_items|
            distributor = line_items.first.order.distributor
            user = line_items.first.order.user
            user.andand.customer_of(distributor).andand.tags.andand.join(', ')
          },

          proc { |line_items| line_items.first.order.bill_address.andand.address1 },
          proc { |line_items| line_items.first.order.bill_address.andand.address2 },
          proc { |line_items| line_items.first.order.bill_address.andand.city },
          proc { |line_items| line_items.first.order.bill_address.andand.zipcode },
          proc { |line_items| line_items.first.order.bill_address.andand.state }
        ]
      end
      # rubocop:enable Metrics/AbcSize
      # rubocop:enable Metrics/CyclomaticComplexity
      # rubocop:enable Metrics/MethodLength
      # rubocop:enable Metrics/PerceivedComplexity

      def line_item_includes
        [{ variant: :product, order: [:bill_address, :shipments, :order_cycle, :adjustments] }]
      end

      private

      def admin_and_handling_total(order)
        order.adjustments.select do |a|
          a.eligible && a.originator_type == 'EnterpriseFee' && a.source_type != 'Spree::LineItem'
        end.map(&:amount).sum.to_f
      end

      def ship_total(order)
        order.adjustments.select{ |a| a.originator_type == 'Spree::ShippingMethod' }.
          map(&:amount).sum.to_f
      end

      def payment_fee(order)
        order.adjustments.select{ |a| a.originator_type == 'Spree::PaymentMethod' }.
          map(&:amount).sum.to_f
      end
    end
  end
end
# rubocop:enable Metrics/ClassLength
{'fraction_non_alphanumeric': 0.11620012243307919, 'fraction_numerical': 0.00957204073682453, 'mean_word_length': 2.285792649478881, 'pattern_counts': {'":': 0, '<': 3, '<?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': '2373484', 'n_tokens_mistral': 5829, 'n_tokens_neox': 5635, 'n_words': 771}