diff --git a/lib/open_food_network/bulk_coop_report.rb b/lib/open_food_network/bulk_coop_report.rb index 1dc3be5a0e..2c1c4bce9e 100644 --- a/lib/open_food_network/bulk_coop_report.rb +++ b/lib/open_food_network/bulk_coop_report.rb @@ -1,15 +1,19 @@ +require 'open_food_network/reports/bulk_coop_supplier_report' + module OpenFoodNetwork class BulkCoopReport attr_reader :params def initialize(user, params = {}) @params = params @user = user + + @supplier_report = OpenFoodNetwork::Reports::BulkCoopSupplierReport.new end def header case params[:report_type] when "bulk_coop_supplier_report" - ["Supplier", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total", "Units Required", "Remainder"] + @supplier_report.header when "bulk_coop_allocation" ["Customer", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total", "Total Allocated", "Remainder"] when "bulk_coop_packing_sheets" @@ -33,21 +37,8 @@ module OpenFoodNetwork def rules case params[:report_type] when "bulk_coop_supplier_report" - [ { group_by: proc { |li| li.variant.product.supplier }, - sort_by: proc { |supplier| supplier.name } }, - { group_by: proc { |li| li.variant.product }, - sort_by: proc { |product| product.name }, - summary_columns: [ proc { |lis| lis.first.variant.product.supplier.name }, - proc { |lis| lis.first.variant.product.name }, - proc { |lis| lis.first.variant.product.group_buy ? (lis.first.variant.product.group_buy_unit_size || 0.0) : "" }, - proc { |lis| "" }, - proc { |lis| "" }, - proc { |lis| lis.sum { |li| (li.quantity || 0) * (li.variant.weight || 0) } }, - proc { |lis| lis.sum { |li| (li.max_quantity || 0) * (li.variant.weight || 0) } }, - proc { |lis| ( (lis.first.variant.product.group_buy_unit_size || 0).zero? ? 0 : ( lis.sum { |li| ( [li.max_quantity || 0, li.quantity || 0].max ) * (li.variant.weight || 0) } / lis.first.variant.product.group_buy_unit_size ) ).floor }, - proc { |lis| lis.sum { |li| ( [li.max_quantity || 0, li.quantity || 0].max) * (li.variant.weight || 0) } - ( ( (lis.first.variant.product.group_buy_unit_size || 0).zero? ? 0 : ( lis.sum { |li| ( [li.max_quantity || 0, li.quantity || 0].max) * (li.variant.weight || 0) } / lis.first.variant.product.group_buy_unit_size ) ).floor * (lis.first.variant.product.group_buy_unit_size || 0) ) } ] }, - { group_by: proc { |li| li.variant }, - sort_by: proc { |variant| variant.full_name } } ] + @supplier_report.rules + when "bulk_coop_allocation" [ { group_by: proc { |li| li.variant.product }, sort_by: proc { |product| product.name }, @@ -96,15 +87,7 @@ module OpenFoodNetwork def columns case params[:report_type] when "bulk_coop_supplier_report" - [ proc { |lis| lis.first.variant.product.supplier.name }, - proc { |lis| lis.first.variant.product.name }, - proc { |lis| lis.first.variant.product.group_buy ? (lis.first.variant.product.group_buy_unit_size || 0.0) : "" }, - proc { |lis| lis.first.variant.full_name }, - proc { |lis| lis.first.variant.weight || 0 }, - proc { |lis| lis.sum { |li| li.quantity } }, - proc { |lis| lis.sum { |li| li.max_quantity || 0 } }, - proc { |lis| "" }, - proc { |lis| "" } ] + @supplier_report.columns when "bulk_coop_allocation" [ proc { |lis| lis.first.order.bill_address.firstname + " " + lis.first.order.bill_address.lastname }, proc { |lis| lis.first.variant.product.name }, diff --git a/lib/open_food_network/reports/bulk_coop_supplier_report.rb b/lib/open_food_network/reports/bulk_coop_supplier_report.rb new file mode 100644 index 0000000000..078037e4b7 --- /dev/null +++ b/lib/open_food_network/reports/bulk_coop_supplier_report.rb @@ -0,0 +1,98 @@ +require 'open_food_network/reports/report' + +module OpenFoodNetwork::Reports + class BulkCoopSupplierReport < Report + header "Supplier", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total", "Units Required", "Remainder" + + organise do + group { |li| li.variant.product.supplier } + sort &:name + + organise do + group { |li| li.variant.product } + sort &:name + + summary_row do + column { |lis| supplier_name(lis) } + column { |lis| product_name(lis) } + column { |lis| group_buy_unit_size_f(lis) } + column { |lis| "" } + column { |lis| "" } + column { |lis| total_weight(lis) } + column { |lis| total_max_quantity_weight(lis) } + column { |lis| units_required(lis) } + column { |lis| remainder(lis) } + end + + organise do + group { |li| li.variant } + sort &:full_name + end + end + end + + columns do + column { |lis| supplier_name(lis) } + column { |lis| product_name(lis) } + column { |lis| group_buy_unit_size_f(lis) } + column { |lis| lis.first.variant.full_name } + column { |lis| lis.first.variant.weight || 0 } + column { |lis| lis.sum(&:quantity) } + column { |lis| lis.sum { |li| li.max_quantity || 0 } } + column { |lis| '' } + column { |lis| '' } + end + + + private + + class << self + def supplier_name(lis) + lis.first.variant.product.supplier.name + end + + def product_name(lis) + lis.first.variant.product.name + end + + def group_buy_unit_size(lis) + lis.first.variant.product.group_buy_unit_size || 0.0 + end + + def group_buy_unit_size_f(lis) + if lis.first.variant.product.group_buy + group_buy_unit_size(lis) + else + "" + end + end + + def total_weight(lis) + lis.sum { |li| (li.quantity || 0) * (li.variant.weight || 0) } + end + + def total_max_quantity_weight(lis) + lis.sum { |li| (li.max_quantity || 0) * (li.variant.weight || 0) } + end + + def units_required(lis) + if group_buy_unit_size(lis).zero? + 0 + else + ( max_weight(lis) / group_buy_unit_size(lis) ).floor + end + end + + def remainder(lis) + max_weight(lis) - (units_required(lis) * group_buy_unit_size(lis)) + end + + def max_weight(lis) + max_weight = lis.sum do |li| + max_quantity = [li.max_quantity || 0, li.quantity || 0].max + max_quantity * (li.variant.weight || 0) + end + end + end + end +end