mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Report Refactor 3: Orders & Distributors
This commit is contained in:
committed by
Jean-Baptiste Bellet
parent
7a9ed7a73c
commit
22fe652e89
63
lib/reporting/reports/orders_and_distributors/base.rb
Normal file
63
lib/reporting/reports/orders_and_distributors/base.rb
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user