<NME> bulk_coop_supplier_report.rb
<BEF> ADDFILE
<MSG> Extract bulk coop supplier report into Report DSL

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

{'commit': 'diff --git a/lib/open_food_network/bulk_coop_report.rb b/lib/open_food_network/bulk_coop_report.rb\nindex 1dc3be5a0..2c1c4bce9 100644\n--- a/lib/open_food_network/bulk_coop_report.rb\n+++ b/lib/open_food_network/bulk_coop_report.rb\n@@ -1,15 +1,19 @@\n+require \'open_food_network/reports/bulk_coop_supplier_report\'\n+\n module OpenFoodNetwork\n   class BulkCoopReport\n     attr_reader :params\n     def initialize(user, params = {})\n       @params = params\n       @user = user\n+\n+      @supplier_report = OpenFoodNetwork::Reports::BulkCoopSupplierReport.new\n     end\n \n     def header\n       case params[:report_type]\n       when "bulk_coop_supplier_report"\n-        ["Supplier", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total", "Units Required", "Remainder"]\n+        @supplier_report.header\n       when "bulk_coop_allocation"\n         ["Customer", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total", "Total Allocated", "Remainder"]\n       when "bulk_coop_packing_sheets"\n@@ -33,21 +37,8 @@ module OpenFoodNetwork\n     def rules\n       case params[:report_type]\n       when "bulk_coop_supplier_report"\n-        [ { group_by: proc { |li| li.variant.product.supplier },\n-          sort_by: proc { |supplier| supplier.name } },\n-          { group_by: proc { |li| li.variant.product },\n-          sort_by: proc { |product| product.name },\n-          summary_columns: [ proc { |lis| lis.first.variant.product.supplier.name },\n-            proc { |lis| lis.first.variant.product.name },\n-            proc { |lis| lis.first.variant.product.group_buy ? (lis.first.variant.product.group_buy_unit_size || 0.0) : "" },\n-            proc { |lis| "" },\n-            proc { |lis| "" },\n-            proc { |lis| lis.sum { |li| (li.quantity || 0) * (li.variant.weight || 0) } },\n-            proc { |lis| lis.sum { |li| (li.max_quantity || 0) * (li.variant.weight || 0) } },\n-            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 },\n-            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) ) } ] },\n-          { group_by: proc { |li| li.variant },\n-          sort_by: proc { |variant| variant.full_name } } ]\n+        @supplier_report.rules\n+\n       when "bulk_coop_allocation"\n         [ { group_by: proc { |li| li.variant.product },\n           sort_by: proc { |product| product.name },\n@@ -96,15 +87,7 @@ module OpenFoodNetwork\n     def columns\n       case params[:report_type]\n       when "bulk_coop_supplier_report"\n-        [ proc { |lis| lis.first.variant.product.supplier.name },\n-          proc { |lis| lis.first.variant.product.name },\n-          proc { |lis| lis.first.variant.product.group_buy ? (lis.first.variant.product.group_buy_unit_size || 0.0) : "" },\n-          proc { |lis| lis.first.variant.full_name },\n-          proc { |lis| lis.first.variant.weight || 0 },\n-          proc { |lis|  lis.sum { |li| li.quantity } },\n-          proc { |lis| lis.sum { |li| li.max_quantity || 0 } },\n-          proc { |lis| "" },\n-          proc { |lis| "" } ]\n+        @supplier_report.columns\n       when "bulk_coop_allocation"\n         [ proc { |lis| lis.first.order.bill_address.firstname + " " + lis.first.order.bill_address.lastname },\n           proc { |lis| lis.first.variant.product.name },\ndiff --git a/lib/open_food_network/reports/bulk_coop_supplier_report.rb b/lib/open_food_network/reports/bulk_coop_supplier_report.rb\nnew file mode 100644\nindex 000000000..078037e4b\n--- /dev/null\n+++ b/lib/open_food_network/reports/bulk_coop_supplier_report.rb\n@@ -0,0 +1,98 @@\n+require \'open_food_network/reports/report\'\n+\n+module OpenFoodNetwork::Reports\n+  class BulkCoopSupplierReport < Report\n+    header "Supplier", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total", "Units Required", "Remainder"\n+\n+    organise do\n+      group { |li| li.variant.product.supplier }\n+      sort &:name\n+\n+      organise do\n+        group { |li| li.variant.product }\n+        sort &:name\n+\n+        summary_row do\n+          column { |lis| supplier_name(lis) }\n+          column { |lis| product_name(lis) }\n+          column { |lis| group_buy_unit_size_f(lis) }\n+          column { |lis| "" }\n+          column { |lis| "" }\n+          column { |lis| total_weight(lis) }\n+          column { |lis| total_max_quantity_weight(lis) }\n+          column { |lis| units_required(lis) }\n+          column { |lis| remainder(lis) }\n+        end\n+\n+        organise do\n+          group { |li| li.variant }\n+          sort &:full_name\n+        end\n+      end\n+    end\n+\n+    columns do\n+      column { |lis| supplier_name(lis) }\n+      column { |lis| product_name(lis) }\n+      column { |lis| group_buy_unit_size_f(lis) }\n+      column { |lis| lis.first.variant.full_name }\n+      column { |lis| lis.first.variant.weight || 0 }\n+      column { |lis| lis.sum(&:quantity) }\n+      column { |lis| lis.sum { |li| li.max_quantity || 0 } }\n+      column { |lis| \'\' }\n+      column { |lis| \'\' }\n+    end\n+\n+\n+    private\n+\n+    class << self\n+      def supplier_name(lis)\n+        lis.first.variant.product.supplier.name\n+      end\n+\n+      def product_name(lis)\n+        lis.first.variant.product.name\n+      end\n+\n+      def group_buy_unit_size(lis)\n+        lis.first.variant.product.group_buy_unit_size || 0.0\n+      end\n+\n+      def group_buy_unit_size_f(lis)\n+        if lis.first.variant.product.group_buy\n+          group_buy_unit_size(lis)\n+        else\n+          ""\n+        end\n+      end\n+\n+      def total_weight(lis)\n+        lis.sum { |li| (li.quantity || 0)     * (li.variant.weight || 0) }\n+      end\n+\n+      def total_max_quantity_weight(lis)\n+        lis.sum { |li| (li.max_quantity || 0) * (li.variant.weight || 0) }\n+      end\n+\n+      def units_required(lis)\n+        if group_buy_unit_size(lis).zero?\n+          0\n+        else\n+          ( max_weight(lis) / group_buy_unit_size(lis) ).floor\n+        end\n+      end\n+\n+      def remainder(lis)\n+        max_weight(lis) - (units_required(lis) * group_buy_unit_size(lis))\n+      end\n+\n+      def max_weight(lis)\n+        max_weight = lis.sum do |li|\n+          max_quantity = [li.max_quantity || 0, li.quantity || 0].max\n+          max_quantity * (li.variant.weight || 0)\n+        end\n+      end\n+    end\n+  end\n+end\n', 'commit_subject': 'Extract bulk coop supplier report into Report DSL', 'repo_name': 'openfoodfoundation/openfoodnetwork', 'committer': {'name': 'Rohan Mitchell', 'email': '9671c73253cee9b18b8df367e3e627fab2863fe8@rohanmitchell.com', 'time_sec': '1437616944', 'tz_offset': '600', 'date': {'seconds': '1437616944'}}, 'commit_tree': '3f67aaf120062b94ebf01d02e5b88c4283904281', 'commit_message': 'Extract bulk coop supplier report into Report DSL\n', 'language_name': 'JavaScript', 'license': 'agpl-3.0', 'hunks': '@@ -0,0 +1,98 @@\n+require \'open_food_network/reports/report\'\n+\n+module OpenFoodNetwork::Reports\n+  class BulkCoopSupplierReport < Report\n+    header "Supplier", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total", "Units Required", "Remainder"\n+\n+    organise do\n+      group { |li| li.variant.product.supplier }\n+      sort &:name\n+\n+      organise do\n+        group { |li| li.variant.product }\n+        sort &:name\n+\n+        summary_row do\n+          column { |lis| supplier_name(lis) }\n+          column { |lis| product_name(lis) }\n+          column { |lis| group_buy_unit_size_f(lis) }\n+          column { |lis| "" }\n+          column { |lis| "" }\n+          column { |lis| total_weight(lis) }\n+          column { |lis| total_max_quantity_weight(lis) }\n+          column { |lis| units_required(lis) }\n+          column { |lis| remainder(lis) }\n+        end\n+\n+        organise do\n+          group { |li| li.variant }\n+          sort &:full_name\n+        end\n+      end\n+    end\n+\n+    columns do\n+      column { |lis| supplier_name(lis) }\n+      column { |lis| product_name(lis) }\n+      column { |lis| group_buy_unit_size_f(lis) }\n+      column { |lis| lis.first.variant.full_name }\n+      column { |lis| lis.first.variant.weight || 0 }\n+      column { |lis| lis.sum(&:quantity) }\n+      column { |lis| lis.sum { |li| li.max_quantity || 0 } }\n+      column { |lis| \'\' }\n+      column { |lis| \'\' }\n+    end\n+\n+\n+    private\n+\n+    class << self\n+      def supplier_name(lis)\n+        lis.first.variant.product.supplier.name\n+      end\n+\n+      def product_name(lis)\n+        lis.first.variant.product.name\n+      end\n+\n+      def group_buy_unit_size(lis)\n+        lis.first.variant.product.group_buy_unit_size || 0.0\n+      end\n+\n+      def group_buy_unit_size_f(lis)\n+        if lis.first.variant.product.group_buy\n+          group_buy_unit_size(lis)\n+        else\n+          ""\n+        end\n+      end\n+\n+      def total_weight(lis)\n+        lis.sum { |li| (li.quantity || 0)     * (li.variant.weight || 0) }\n+      end\n+\n+      def total_max_quantity_weight(lis)\n+        lis.sum { |li| (li.max_quantity || 0) * (li.variant.weight || 0) }\n+      end\n+\n+      def units_required(lis)\n+        if group_buy_unit_size(lis).zero?\n+          0\n+        else\n+          ( max_weight(lis) / group_buy_unit_size(lis) ).floor\n+        end\n+      end\n+\n+      def remainder(lis)\n+        max_weight(lis) - (units_required(lis) * group_buy_unit_size(lis))\n+      end\n+\n+      def max_weight(lis)\n+        max_weight = lis.sum do |li|\n+          max_quantity = [li.max_quantity || 0, li.quantity || 0].max\n+          max_quantity * (li.variant.weight || 0)\n+        end\n+      end\n+    end\n+  end\n+end\n', 'addition_count': 98, 'deletion_count': 0, 'src_file': '/dev/null', 'tgt_file': 'b/lib/open_food_network/reports/bulk_coop_supplier_report.rb', 'file_extension': '.rb', 'before_file': 'ADDFILE', 'message': 'Extract bulk coop supplier report into Report DSL\n', 'author_name': 'Rohan Mitchell', 'lang': 'rb'}