mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Adding packing reports as required by the UK contingent
This commit is contained in:
committed by
Rohan Mitchell
parent
197c99349d
commit
c168dec14b
@@ -75,6 +75,40 @@ Spree::Admin::ReportsController.class_eval do
|
||||
render_report(@report.header, @report.table, params[:csv], "order_cycle_management_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
def packing
|
||||
# -- Prepare parameters
|
||||
params[:q] ||= {}
|
||||
if params[:q][:completed_at_gt].blank?
|
||||
params[:q][:completed_at_gt] = Time.zone.now.beginning_of_month
|
||||
else
|
||||
params[:q][:completed_at_gt] = Time.zone.parse(params[:q][:completed_at_gt]) rescue Time.zone.now.beginning_of_month
|
||||
end
|
||||
if params[:q] && !params[:q][:completed_at_lt].blank?
|
||||
params[:q][:completed_at_lt] = Time.zone.parse(params[:q][:completed_at_lt]) rescue ""
|
||||
end
|
||||
params[:q][:meta_sort] ||= "completed_at.desc"
|
||||
|
||||
# -- Prepare form options
|
||||
my_distributors = Enterprise.is_distributor.managed_by(spree_current_user)
|
||||
my_suppliers = Enterprise.is_primary_producer.managed_by(spree_current_user)
|
||||
|
||||
# My distributors and any distributors distributing products I supply
|
||||
@distributors = my_distributors | Enterprise.with_distributed_products_outer.merge(Spree::Product.in_any_supplier(my_suppliers))
|
||||
# My suppliers and any suppliers supplying products I distribute
|
||||
@suppliers = my_suppliers | my_distributors.map { |d| Spree::Product.in_distributor(d) }.flatten.map(&:supplier).uniq
|
||||
@order_cycles = OrderCycle.active_or_complete.accessible_by(spree_current_user).order('orders_close_at DESC')
|
||||
@report_types = REPORT_TYPES[:packing]
|
||||
@report_type = params[:report_type]
|
||||
|
||||
# -- Build Report with Order Grouper
|
||||
@report = OpenFoodNetwork::PackingReport.new spree_current_user, params
|
||||
order_grouper = OpenFoodNetwork::OrderGrouper.new @report.rules, @report.columns
|
||||
@table = order_grouper.table(@report.table_items)
|
||||
csv_file_name = "#{params[:report_type]}_#{timestamp}.csv"
|
||||
|
||||
render_report(@report.header, @table, params[:csv], "packing_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
def orders_and_distributors
|
||||
params[:q] ||= {}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
%ul{style: "margin-left: 12pt"}
|
||||
- report_types.each do |report_type|
|
||||
%li
|
||||
= link_to report_type[0], "#{packing_admin_reports_url}?report_type=#{report_type[1]}"
|
||||
42
app/views/spree/admin/reports/packing.html.haml
Normal file
42
app/views/spree/admin/reports/packing.html.haml
Normal file
@@ -0,0 +1,42 @@
|
||||
= form_for @report.search, :url => spree.packing_admin_reports_path do |f|
|
||||
= render 'date_range_form', f: f
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "Hubs: "
|
||||
.omega.fourteen.columns= f.collection_select(:distributor_id_in, @distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "Producers: "
|
||||
.omega.fourteen.columns= select_tag(:supplier_id_in, options_from_collection_for_select(@suppliers, :id, :name, params[:supplier_id_in]), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "Order Cycles: "
|
||||
.omega.fourteen.columns
|
||||
= f.select(:order_cycle_id_in, report_order_cycle_options(@order_cycles), {selected: params[:q][:order_cycle_id_in]}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "Report Type: "
|
||||
.omega.fourteen.columns= select_tag(:report_type, options_for_select(@report_types, @report_type))
|
||||
|
||||
.row
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, "Download as csv"
|
||||
|
||||
.row
|
||||
= button t(:search)
|
||||
|
||||
%br
|
||||
%br
|
||||
%table#listing_orders.index
|
||||
%thead
|
||||
%tr{'data-hook' => "orders_header"}
|
||||
- @report.header.each do |heading|
|
||||
%th=heading
|
||||
%tbody
|
||||
- @table.each do |row|
|
||||
%tr
|
||||
- row.each do |column|
|
||||
%td= column
|
||||
- if @table.empty?
|
||||
%tr
|
||||
%td{:colspan => "2"}= t(:none)
|
||||
121
lib/open_food_network/packing_report.rb
Normal file
121
lib/open_food_network/packing_report.rb
Normal file
@@ -0,0 +1,121 @@
|
||||
module OpenFoodNetwork
|
||||
class PackingReport
|
||||
attr_reader :params
|
||||
def initialize(user, params = {})
|
||||
@params = params
|
||||
@user = user
|
||||
end
|
||||
|
||||
def header
|
||||
if is_by_customer?
|
||||
["Hub", "Code", "First Name", "Last Name", "Supplier", "Product", "Variant", "Quantity", "TempControlled?"]
|
||||
else
|
||||
["Hub", "Supplier", "Code", "First Name", "Last Name", "Product", "Variant", "Quantity", "TempControlled?"]
|
||||
end
|
||||
end
|
||||
|
||||
def search
|
||||
Spree::Order.complete.not_state(:canceled).managed_by(@user).search(params[:q])
|
||||
end
|
||||
|
||||
def table_items
|
||||
orders = search.result
|
||||
@line_items = orders.map do |o|
|
||||
lis = o.line_items.managed_by(@user)
|
||||
lis = lis.supplied_by_any(params[:supplier_id_in]) if params[:supplier_id_in].present?
|
||||
lis
|
||||
end.flatten
|
||||
end
|
||||
|
||||
def rules
|
||||
if is_by_customer?
|
||||
# customer_rows orders
|
||||
# table_items = @line_items
|
||||
|
||||
[
|
||||
{ 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.lastname },
|
||||
summary_columns: [ proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "TOTAL ITEMS" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| line_items.sum { |li| li.quantity } },
|
||||
proc { |line_items| "" } ] },
|
||||
{ group_by: proc { |line_item| line_item.variant.product.supplier },
|
||||
sort_by: proc { |supplier| supplier.name } },
|
||||
{ group_by: proc { |line_item| line_item.variant },
|
||||
sort_by: proc { |variant| variant.product.name } } ]
|
||||
else
|
||||
# supplier_rows orders
|
||||
# table_items = supplier_rows orders
|
||||
#
|
||||
[ { group_by: proc { |line_item| line_item.order.distributor },
|
||||
sort_by: proc { |distributor| distributor.name } },
|
||||
{ group_by: proc { |line_item| line_item.variant.product.supplier },
|
||||
sort_by: proc { |supplier| supplier.name },
|
||||
summary_columns: [ proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "TOTAL ITEMS" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| line_items.sum { |li| li.quantity } },
|
||||
proc { |line_items| "" } ] },
|
||||
{ group_by: proc { |line_item| line_item.variant },
|
||||
sort_by: proc { |variant| variant.product.name } } ]
|
||||
end
|
||||
end
|
||||
|
||||
def columns
|
||||
if is_by_customer?
|
||||
[ proc { |line_items| line_items.first.order.distributor.name },
|
||||
proc { |line_items| customer_code(line_items.first.order.email) },
|
||||
proc { |line_items| line_items.first.order.bill_address.firstname },
|
||||
proc { |line_items| line_items.first.order.bill_address.lastname },
|
||||
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 { |li| li.quantity } },
|
||||
proc { |line_items| is_temperature_controlled?(line_items.first) }
|
||||
]
|
||||
else
|
||||
[
|
||||
proc { |line_items| line_items.first.order.distributor.name },
|
||||
proc { |line_items| line_items.first.variant.product.supplier.name },
|
||||
proc { |line_items| customer_code(line_items.first.order.email) },
|
||||
proc { |line_items| line_items.first.order.bill_address.firstname },
|
||||
proc { |line_items| line_items.first.order.bill_address.lastname },
|
||||
proc { |line_items| line_items.first.variant.product.name },
|
||||
proc { |line_items| line_items.first.variant.full_name },
|
||||
proc { |line_items| line_items.sum { |li| li.quantity } },
|
||||
proc { |line_items| is_temperature_controlled?(line_items.first) }
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def is_temperature_controlled?(line_item)
|
||||
if line_item.product.shipping_category.andand.temperature_controlled
|
||||
"Yes"
|
||||
else
|
||||
"No"
|
||||
end
|
||||
end
|
||||
|
||||
def is_by_customer?
|
||||
params[:report_type] == "pack_by_customer"
|
||||
end
|
||||
|
||||
def customer_code(email)
|
||||
customer = Customer.where(email: email).first
|
||||
customer.nil? ? "" : customer.code
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -84,6 +84,66 @@ feature %q{
|
||||
end
|
||||
end
|
||||
|
||||
describe "Packing reports" do
|
||||
before do
|
||||
login_to_admin_section
|
||||
click_link "Reports"
|
||||
end
|
||||
|
||||
let(:bill_address1) { create(:address, lastname: "Aman") }
|
||||
let(:bill_address2) { create(:address, lastname: "Bman") }
|
||||
let(:distributor_address) { create(:address, :address1 => "distributor address", :city => 'The Shire', :zipcode => "1234") }
|
||||
let(:distributor) { create(:distributor_enterprise, :address => distributor_address) }
|
||||
let(:order1) { create(:order, distributor: distributor, bill_address: bill_address1) }
|
||||
let(:order2) { create(:order, distributor: distributor, bill_address: bill_address2) }
|
||||
let(:supplier) { create(:supplier_enterprise, name: "Supplier") }
|
||||
let(:product_1) { create(:simple_product, name: "Product 1", supplier: supplier ) }
|
||||
let(:variant_1) { create(:variant, product: product_1, unit_description: "Big") }
|
||||
let(:variant_2) { create(:variant, product: product_1, unit_description: "Small") }
|
||||
let(:product_2) { create(:simple_product, name: "Product 2", supplier: supplier) }
|
||||
|
||||
before do
|
||||
Timecop.travel(Time.zone.local(2013, 4, 25, 14, 0, 0)) { order1.finalize! }
|
||||
Timecop.travel(Time.zone.local(2013, 4, 25, 15, 0, 0)) { order2.finalize! }
|
||||
|
||||
create(:line_item, variant: variant_1, quantity: 1, order: order1)
|
||||
create(:line_item, variant: variant_2, quantity: 3, order: order1)
|
||||
create(:line_item, variant: product_2.master, quantity: 3, order: order2)
|
||||
|
||||
end
|
||||
|
||||
scenario "Pack By Customer" do
|
||||
click_link "Pack By Customer"
|
||||
fill_in 'q_completed_at_gt', with: '2013-04-25 13:00:00'
|
||||
fill_in 'q_completed_at_lt', with: '2013-04-25 16:00:00'
|
||||
#select 'Pack By Customer', from: 'report_type'
|
||||
click_button 'Search'
|
||||
|
||||
rows = find("table#listing_orders.index").all("thead tr")
|
||||
table = rows.map { |r| r.all("th").map { |c| c.text.strip } }
|
||||
table.sort.should == [
|
||||
["Hub", "Code", "First Name", "Last Name", "Supplier", "Product", "Variant", "Quantity", "TempControlled?"]
|
||||
].sort
|
||||
all('table#listing_orders tbody tr').count.should == 5 # Totals row per order
|
||||
end
|
||||
|
||||
scenario "Pack By Supplier" do
|
||||
click_link "Pack By Supplier"
|
||||
fill_in 'q_completed_at_gt', with: '2013-04-25 13:00:00'
|
||||
fill_in 'q_completed_at_lt', with: '2013-04-25 16:00:00'
|
||||
#select 'Pack By Customer', from: 'report_type'
|
||||
click_button 'Search'
|
||||
|
||||
rows = find("table#listing_orders").all("thead tr")
|
||||
table = rows.map { |r| r.all("th").map { |c| c.text.strip } }
|
||||
table.sort.should == [
|
||||
["Hub", "Supplier", "Code", "First Name", "Last Name", "Product", "Variant", "Quantity", "TempControlled?"]
|
||||
].sort
|
||||
all('table#listing_orders tbody tr').count.should == 4 # Totals row per supplier
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
scenario "orders and distributors report" do
|
||||
login_to_admin_section
|
||||
click_link 'Reports'
|
||||
|
||||
Reference in New Issue
Block a user