diff --git a/lib/reporting/reports/orders_and_distributors/base.rb b/lib/reporting/reports/orders_and_distributors/base.rb new file mode 100644 index 0000000000..92e2b3b06e --- /dev/null +++ b/lib/reporting/reports/orders_and_distributors/base.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module OrdersAndDistributors + class Base < ReportObjectTemplate + def initialize(user, params = {}) + super(user, params) + end + + # rubocop:disable Metrics/AbcSize + def columns + { + order_date: proc { |line_item| line_item.order.completed_at.strftime("%F %T") }, + order_id: proc { |line_item| line_item.order.id }, + customer_name: proc { |line_item| line_item.order.bill_address.full_name }, + customer_email: proc { |line_item| line_item.order.email }, + customer_phone: proc { |line_item| line_item.order.bill_address.phone }, + customer_city: proc { |line_item| line_item.order.bill_address.city }, + sku: proc { |line_item| line_item.product.sku }, + item_name: proc { |line_item| line_item.product.name }, + variant: proc { |line_item| line_item.options_text }, + quantity: proc { |line_item| line_item.quantity }, + max_quantity: proc { |line_item| line_item.max_quantity }, + cost: proc { |line_item| line_item.price * line_item.quantity }, + shipping_cost: proc { |line_item| line_item.distribution_fee }, + payment_method: proc { |li| li.order.payments.first&.payment_method&.name }, + distributor: proc { |line_item| line_item.order.distributor&.name }, + distributor_address: proc { |line_item| line_item.order.distributor.address.address1 }, + distributor_city: proc { |line_item| line_item.order.distributor.address.city }, + distributor_postcode: proc { |line_item| line_item.order.distributor.address.zipcode }, + shipping_method: proc { |line_item| line_item.order.shipping_method&.name }, + shipping_instructions: proc { |line_item| line_item.order.special_instructions } + } + end + # rubocop:enable Metrics/AbcSize + + def search + permissions.visible_orders.select("DISTINCT spree_orders.*"). + complete.not_state(:canceled). + ransack(@params[:q]) + end + + def query_result + orders = search.result + # Mask non editable order details + editable_orders_ids = permissions.editable_orders.select(&:id).map(&:id) + orders + .filter { |order| order.in?(editable_orders_ids) } + .each { |order| OrderDataMasker.new(order).call } + # Get Line Items + orders.map(&:line_items).flatten + end + + private + + def permissions + @permissions ||= ::Permissions::Order.new(user, params[:q]) + end + end + end + end +end diff --git a/lib/reporting/reports/orders_and_distributors/orders_and_distributors_report.rb b/lib/reporting/reports/orders_and_distributors/orders_and_distributors_report.rb deleted file mode 100644 index afd1120412..0000000000 --- a/lib/reporting/reports/orders_and_distributors/orders_and_distributors_report.rb +++ /dev/null @@ -1,111 +0,0 @@ -# frozen_string_literal: true - -module Reporting - module Reports - module OrdersAndDistributors - class OrdersAndDistributorsReport < ReportObjectTemplate - def initialize(user, params = {}) - super(user, params) - @permissions = ::Permissions::Order.new(user, @params[:q]) - end - - def table_headers - [ - I18n.t(:report_header_order_date), - I18n.t(:report_header_order_id), - I18n.t(:report_header_customer_name), - I18n.t(:report_header_customer_email), - I18n.t(:report_header_customer_phone), - I18n.t(:report_header_customer_city), - I18n.t(:report_header_sku), - I18n.t(:report_header_item_name), - I18n.t(:report_header_variant), - I18n.t(:report_header_quantity), - I18n.t(:report_header_max_quantity), - I18n.t(:report_header_cost), - I18n.t(:report_header_shipping_cost), - I18n.t(:report_header_payment_method), - I18n.t(:report_header_distributor), - I18n.t(:report_header_distributor_address), - I18n.t(:report_header_distributor_city), - I18n.t(:report_header_distributor_postcode), - I18n.t(:report_header_shipping_method), - I18n.t(:report_header_shipping_instructions) - ] - end - - def search - @permissions.visible_orders.select("DISTINCT spree_orders.*"). - complete.not_state(:canceled). - ransack(@params[:q]) - end - - def table_rows - orders = search.result - - orders.select{ |order| orders_with_hidden_details(orders).include? order }.each do |order| - OrderDataMasker.new(order).call - end - - line_item_details orders - end - - private - - def orders_with_hidden_details(orders) - # If empty array is passed in, the where clause will return all line_items, which is bad - if @permissions.editable_orders.empty? - orders - else - orders. - where('spree_orders.id NOT IN (?)', - @permissions.editable_orders.select(&:id)) - end - end - - def line_item_details(orders) - order_and_distributor_details = [] - - orders.each do |order| - order.line_items.each do |line_item| - order_and_distributor_details << row_for(line_item, order) - end - end - - order_and_distributor_details - end - - # Returns a row with the data to display for the specified line_item and - # its order - # - # @param line_item [Spree::LineItem] - # @param order [Spree::Order] - # @return [Array] - def row_for(line_item, order) - [ - order.completed_at.strftime("%F %T"), - order.id, - order.bill_address.full_name, - order.email, - order.bill_address.phone, - order.bill_address.city, - line_item.product.sku, - line_item.product.name, - line_item.options_text, - line_item.quantity, - line_item.max_quantity, - line_item.price * line_item.quantity, - line_item.distribution_fee, - order.payments.first&.payment_method&.name, - order.distributor&.name, - order.distributor.address.address1, - order.distributor.address.city, - order.distributor.address.zipcode, - order.shipping_method&.name, - order.special_instructions - ] - end - end - end - end -end diff --git a/spec/lib/reports/orders_and_distributors_report_spec.rb b/spec/lib/reports/orders_and_distributors_report_spec.rb index a1a6eb196a..85a84ab788 100644 --- a/spec/lib/reports/orders_and_distributors_report_spec.rb +++ b/spec/lib/reports/orders_and_distributors_report_spec.rb @@ -5,10 +5,10 @@ require 'spec_helper' module Reporting module Reports module OrdersAndDistributors - describe OrdersAndDistributorsReport do + describe Base do describe 'orders and distributors report' do it 'should return a header row describing the report' do - subject = OrdersAndDistributorsReport.new nil + subject = Base.new nil expect(subject.table_headers).to eq( [ @@ -45,7 +45,7 @@ module Reporting end it 'should denormalise order and distributor details for display as csv' do - subject = OrdersAndDistributorsReport.new create(:admin_user), {} + subject = Base.new create(:admin_user), {} table = subject.table_rows @@ -77,7 +77,7 @@ module Reporting it "prints one row per line item" do create(:line_item_with_shipment, order: order) - subject = OrdersAndDistributorsReport.new(create(:admin_user)) + subject = Base.new(create(:admin_user)) table = subject.table_rows expect(table.size).to eq 2