Report Refactor 3: Orders & Distributors

This commit is contained in:
Sebastian Castro
2022-04-02 17:29:18 +02:00
committed by Jean-Baptiste Bellet
parent 7a9ed7a73c
commit 22fe652e89
3 changed files with 67 additions and 115 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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