From 924f6568d6cb6e56141dbcfe6c0656d77cb87df1 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 26 Aug 2021 19:35:03 +0100 Subject: [PATCH] Replace data loading with new Reports::QueryInterface --- app/controllers/admin/reports_controller.rb | 2 +- app/controllers/api/v0/reports_controller.rb | 10 +- app/controllers/concerns/reports_actions.rb | 2 +- .../spree/admin/reports_controller.rb | 2 +- app/helpers/reports_helper.rb | 2 +- app/models/application_record.rb | 3 + .../reports/_rendering_options.html.haml | 6 +- config/application.rb | 4 +- config/locales/en.yml | 1 + lib/{reports => reporting}/errors.rb | 2 +- lib/{reports => reporting}/frontend_data.rb | 2 +- lib/reporting/queries/joins.rb | 52 ++++++++ lib/reporting/queries/query_builder.rb | 88 ++++++++++++ lib/reporting/queries/query_interface.rb | 125 ++++++++++++++++++ lib/reporting/queries/tables.rb | 51 +++++++ lib/{reports => reporting}/report_loader.rb | 8 +- lib/reporting/report_renderer.rb | 39 ++++++ lib/reporting/report_template.rb | 52 ++++++++ lib/reporting/reports/packing/base.rb | 41 ++++++ lib/reporting/reports/packing/customer.rb | 49 +++++++ lib/reporting/reports/packing/supplier.rb | 48 +++++++ lib/reports/packing/base.rb | 17 --- lib/reports/packing/customer.rb | 9 -- lib/reports/packing/supplier.rb | 9 -- lib/reports/report_renderer.rb | 67 ---------- lib/reports/report_template.rb | 42 ------ .../reports/packing/packing_report_spec.rb | 2 +- spec/lib/reports/report_loader_spec.rb | 28 ++-- spec/lib/reports/report_renderer_spec.rb | 4 +- 29 files changed, 587 insertions(+), 180 deletions(-) rename lib/{reports => reporting}/errors.rb (97%) rename lib/{reports => reporting}/frontend_data.rb (97%) create mode 100644 lib/reporting/queries/joins.rb create mode 100644 lib/reporting/queries/query_builder.rb create mode 100644 lib/reporting/queries/query_interface.rb create mode 100644 lib/reporting/queries/tables.rb rename lib/{reports => reporting}/report_loader.rb (81%) create mode 100644 lib/reporting/report_renderer.rb create mode 100644 lib/reporting/report_template.rb create mode 100644 lib/reporting/reports/packing/base.rb create mode 100644 lib/reporting/reports/packing/customer.rb create mode 100644 lib/reporting/reports/packing/supplier.rb delete mode 100644 lib/reports/packing/base.rb delete mode 100644 lib/reports/packing/customer.rb delete mode 100644 lib/reports/packing/supplier.rb delete mode 100644 lib/reports/report_renderer.rb delete mode 100644 lib/reports/report_template.rb diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb index c9436136ef..79e5176792 100644 --- a/app/controllers/admin/reports_controller.rb +++ b/app/controllers/admin/reports_controller.rb @@ -44,7 +44,7 @@ module Admin def load_form_options return unless form_options_required? - form_options = Reports::FrontendData.new(spree_current_user) + form_options = Reporting::FrontendData.new(spree_current_user) @distributors = form_options.distributors.to_a @suppliers = form_options.suppliers.to_a diff --git a/app/controllers/api/v0/reports_controller.rb b/app/controllers/api/v0/reports_controller.rb index cfcb6c0d0d..ecbdc7ed4b 100644 --- a/app/controllers/api/v0/reports_controller.rb +++ b/app/controllers/api/v0/reports_controller.rb @@ -5,7 +5,7 @@ module Api class ReportsController < Api::V0::BaseController include ReportsActions - rescue_from Reports::Errors::Base, with: :render_error + rescue_from ::Reporting::Errors::Base, with: :render_error before_action :validate_report, :authorize_report, :validate_query @@ -18,7 +18,7 @@ module Api private def render_report - render json: @report.as_hashes + render json: @report.as_json end def render_error(error) @@ -26,12 +26,12 @@ module Api end def validate_report - raise Reports::Errors::NoReportType if report_type.blank? - raise Reports::Errors::ReportNotFound if report_class.blank? + raise ::Reporting::Errors::NoReportType if report_type.blank? + raise ::Reporting::Errors::ReportNotFound if report_class.blank? end def validate_query - raise Reports::Errors::MissingQueryParams if ransack_params.blank? + raise ::Reporting::Errors::MissingQueryParams if ransack_params.blank? end end end diff --git a/app/controllers/concerns/reports_actions.rb b/app/controllers/concerns/reports_actions.rb index 7916264bf1..7ff6e0c461 100644 --- a/app/controllers/concerns/reports_actions.rb +++ b/app/controllers/concerns/reports_actions.rb @@ -16,7 +16,7 @@ module ReportsActions end def report_loader - @report_loader ||= Reports::ReportLoader.new(report_type, report_subtype) + @report_loader ||= ::Reporting::ReportLoader.new(report_type, report_subtype) end def report_type diff --git a/app/controllers/spree/admin/reports_controller.rb b/app/controllers/spree/admin/reports_controller.rb index ac8549c6eb..de57236dbf 100644 --- a/app/controllers/spree/admin/reports_controller.rb +++ b/app/controllers/spree/admin/reports_controller.rb @@ -198,7 +198,7 @@ module Spree end def load_associated_data - form_options = Reports::FrontendData.new(spree_current_user) + form_options = Reporting::FrontendData.new(spree_current_user) @distributors = form_options.distributors @suppliers = form_options.suppliers diff --git a/app/helpers/reports_helper.rb b/app/helpers/reports_helper.rb index 174e9bd157..bfcc4232db 100644 --- a/app/helpers/reports_helper.rb +++ b/app/helpers/reports_helper.rb @@ -10,6 +10,6 @@ module ReportsHelper end def report_subtypes(report) - Reports::ReportLoader.new(report).report_subtypes + Reporting::ReportLoader.new(report).report_subtypes end end diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 4149333756..d36b82d6f7 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -5,6 +5,9 @@ class ApplicationRecord < ActiveRecord::Base include Spree::Core::Permalinks include Spree::Preferences::Preferable include Searchable + include ArelHelpers::ArelTable + include ArelHelpers::Aliases + include ArelHelpers::JoinAssociation self.abstract_class = true end diff --git a/app/views/admin/reports/_rendering_options.html.haml b/app/views/admin/reports/_rendering_options.html.haml index 5f4f97f7fc..0967df8999 100644 --- a/app/views/admin/reports/_rendering_options.html.haml +++ b/app/views/admin/reports/_rendering_options.html.haml @@ -3,6 +3,6 @@ %br = select_tag :report_format, options_for_select({t('.on_screen') => '', t('.csv_spreadsheet') => 'csv', t('.excel_spreadsheet') => 'xlsx', t('.openoffice_spreadsheet') => 'ods'}) - .inline-checkbox - = check_box_tag "options[exclude_summaries]", true, params[:options].andand[:exclude_summaries] - = label_tag t(".hide_summary_rows") + -#.inline-checkbox + -# = check_box_tag "options[exclude_summaries]", true, params[:options].andand[:exclude_summaries] + -# = label_tag t(".hide_summary_rows") diff --git a/config/application.rb b/config/application.rb index d8c6ad9abc..a5606d443f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -153,9 +153,9 @@ module Openfoodnetwork ) initializer "ofn.reports" do |_app| - module ::Reports; end + module ::Reporting; end loader = Zeitwerk::Loader.new - loader.push_dir("#{Rails.root}/lib/reports", namespace: ::Reports) + loader.push_dir("#{Rails.root}/lib/reporting", namespace: ::Reporting) loader.setup loader.eager_load end diff --git a/config/locales/en.yml b/config/locales/en.yml index a0163b465d..a130fd9a98 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1213,6 +1213,7 @@ en: variant: "Variant" quantity: "Quantity" is_temperature_controlled: "TempControlled?" + temp_controlled: "TempControlled?" rendering_options: generate_report: "Generate report:" on_screen: "On screen" diff --git a/lib/reports/errors.rb b/lib/reporting/errors.rb similarity index 97% rename from lib/reports/errors.rb rename to lib/reporting/errors.rb index af729aab55..d00a95618e 100644 --- a/lib/reports/errors.rb +++ b/lib/reporting/errors.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module Reports +module Reporting module Errors class Base < StandardError def i18n_error_scope diff --git a/lib/reports/frontend_data.rb b/lib/reporting/frontend_data.rb similarity index 97% rename from lib/reports/frontend_data.rb rename to lib/reporting/frontend_data.rb index 8a90111ce6..aad748b1ff 100644 --- a/lib/reports/frontend_data.rb +++ b/lib/reporting/frontend_data.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module Reports +module Reporting class FrontendData def initialize(current_user) @current_user = current_user diff --git a/lib/reporting/queries/joins.rb b/lib/reporting/queries/joins.rb new file mode 100644 index 0000000000..88690d2ac7 --- /dev/null +++ b/lib/reporting/queries/joins.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Reporting + module Queries + module Joins + def joins_order + reflect query.join(association(Spree::LineItem, :order)) + end + + def joins_order_distributor + reflect query.join(association(Spree::Order, :distributor, distributor_alias)) + end + + def joins_variant + reflect query.join(association(Spree::LineItem, :variant)) + end + + def joins_variant_product + reflect query.join(association(Spree::Variant, :product)) + end + + def joins_product_supplier + reflect query.join(association(Spree::Product, :supplier, supplier_alias)) + end + + def joins_product_shipping_category + reflect query.join(association(Spree::Product, :shipping_category)) + end + + def joins_order_and_distributor + reflect query. + join(association(Spree::LineItem, :order)). + join(association(Spree::Order, :distributor, distributor_alias)) + end + + def joins_order_customer + reflect query.join(association(Spree::Order, :customer)) + end + + def joins_order_bill_address + reflect query.join(association(Spree::Order, :bill_address, bill_address_alias)) + end + + def join_line_item_option_values + reflect query. + join(association(Spree::LineItem, :option_values)). + join(association(Spree::OptionValuesLineItem, :option_value) + ) + end + end + end +end diff --git a/lib/reporting/queries/query_builder.rb b/lib/reporting/queries/query_builder.rb new file mode 100644 index 0000000000..60da091fff --- /dev/null +++ b/lib/reporting/queries/query_builder.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Reporting + module Queries + class QueryBuilder < QueryInterface + include Joins + include Tables + + attr_reader :grouping_fields + + def initialize(model, grouping_fields = []) + @grouping_fields = instance_exec(&grouping_fields) + + super model.arel_table + end + + def selecting(lambda) + fields = instance_exec(&lambda).map{ |key, value| value.public_send(:as, key.to_s) } + + reflect query.project(*fields) + end + + def scoped_to_orders(orders_relation) + reflect query.where( + line_item_table[:order_id].in(Arel.sql(orders_relation.to_sql)) + ) + end + + def with_managed_orders(orders_relation) + reflect query. + outer_join(managed_orders_alias). + on( + managed_orders_alias[:id].eq(line_item_table[:order_id]). + and(managed_orders_alias[:distributor_id].in(Arel.sql(orders_relation.to_sql))) + ) + end + + def grouped_in_sets(group_sets) + reflect query.group(*instance_exec(&group_sets)) + end + + def ordered_by(ordering_fields) + reflect query.order(*instance_exec(&ordering_fields)) + end + + def masked(field, message = nil, mask_rule = nil) + Case.new. + when(mask_rule || default_mask_rule). + then(field). + else(quoted(message || I18n.t("hidden_field", scope: i18n_scope))) + end + + def distinct_results(fields = nil) + return reflect query.distinct if fields.blank? + + reflect query.distinct_on(fields) + end + + def variant_full_name + display_name = variant_table[:display_name] + display_as = variant_table[:display_as] + options_text = option_value_table[:presentation] + + unit_to_display = coalesce(nullify_empty_strings(display_as), options_text) + combined_description = sql_concat(display_name, raw("' ('"), unit_to_display, raw("')'")) + + Case.new. + when(nullify_empty_strings(display_name).eq(nil)).then(unit_to_display). + when(nullify_empty_strings(unit_to_display).not_eq(nil)).then(combined_description). + else(display_name) + end + + private + + def default_mask_rule + line_item_table[:order_id].in(raw("#{managed_orders_alias.name}.id")) + end + + def summary_row_title + I18n.t("total_items", scope: i18n_scope) + end + + def i18n_scope + "admin.reports" + end + end + end +end diff --git a/lib/reporting/queries/query_interface.rb b/lib/reporting/queries/query_interface.rb new file mode 100644 index 0000000000..b2b26b5f27 --- /dev/null +++ b/lib/reporting/queries/query_interface.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: true + +require "arel-helpers" + +module Reporting + module Queries + class QueryInterface < ::ArelHelpers::QueryBuilder + include Arel::Nodes + + def coalesce(field, default = 0) + NamedFunction.new("COALESCE", [field, default]) + end + + def sum_values(field, default = 0) + NamedFunction.new("SUM", [coalesce(field, default)]) + end + + def sum_grouped(field, default = 0) + Case.new(sql_grouping(grouping_fields)).when(0).then(field.maximum).else(field.sum) + end + + def sum_new(field, default = 0) + Case.new(sql_grouping(grouping_fields)).when(0).then(field.maximum).else(sum_values(field)) + end + + def round(field, places: 2) + NamedFunction.new("ROUND", [field, places]) + end + + def association(base_class, association, alias_node = nil, join_type = InnerJoin) + options = alias_node.present? ? { aliases: [alias_node] } : {} + + Arel.sql(base_class.join_association(association, join_type, options).first.to_sql) + end + + def arel_join(join) + Arel.sql(join.first.to_sql) + end + + def join_source(join_association) + join_association[0].right + end + + def default_value(field) + field.maximum + end + + def default_blank(field) + Case.new(sql_grouping(grouping_fields)).when(0).then(field.maximum).else(empty_string) + end + + def default_string(field, string) + Case.new(sql_grouping(grouping_fields)).when(0).then(field.maximum).else(quoted(string)) + end + + def default_summary(field) + Case.new(sql_grouping(grouping_fields)).when(0).then(field.maximum).else(empty_string) + end + + def boolean_blank(field, true_string = I18n.t(:yes), false_string = I18n.t(:no)) + Case.new(sql_grouping(grouping_fields)).when(0). + then(pretty_boolean(field, true_string, false_string).maximum). + else(empty_string) + end + + def pretty_boolean(field, true_string, false_string) + Case.new(field).when(true). + then(Arel.sql("'#{true_string}'")). + else(Arel.sql("'#{false_string}'")) + end + + def cast(field, type) + NamedFunction.new("CAST", [field.as(type)]) + end + + def null_if(field, nullif) + NamedFunction.new("NULLIF", [field, nullif]) + end + + def parenthesise(args) + Grouping.new(args) + end + + def nullify_empty_strings(field) + null_if(field, empty_string) + end + + def empty_string + raw("''") + end + + def sql_concat(*args) + NamedFunction.new("CONCAT", args) + end + + def raw(string) + SqlLiteral.new(string) + end + + def quoted(string) + Quoted.new(string) + end + + def sql_grouping(groupings = grouping_fields) + NamedFunction.new("GROUPING", [groupings]) + end + + def grouping_sets(groupings) + GroupingSet.new(groupings) + end + + def sql_case(expression) + Case.new(expression) + end + + def rollup(groupings) + RollUp.new(groupings) + end + + def raw_result + ActiveRecord::Base.connection.exec_query(query.to_sql) + end + end + end +end diff --git a/lib/reporting/queries/tables.rb b/lib/reporting/queries/tables.rb new file mode 100644 index 0000000000..a6843706f4 --- /dev/null +++ b/lib/reporting/queries/tables.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Reporting + module Queries + module Tables + def order_table + Spree::Order.arel_table + end + + def line_item_table + Spree::LineItem.arel_table + end + + def product_table + Spree::Product.arel_table + end + + def variant_table + Spree::Variant.arel_table + end + + def customer_table + ::Customer.arel_table + end + + def distributor_alias + Enterprise.arel_table.alias(:order_distributor) + end + + def supplier_alias + Enterprise.arel_table.alias(:product_supplier) + end + + def bill_address_alias + Spree::Address.arel_table.alias(:bill_address) + end + + def managed_orders_alias + Spree::Order.arel_table.alias(:managed_orders) + end + + def option_value_table + Spree::OptionValue.arel_table + end + + def shipping_category_table + Spree::ShippingCategory.arel_table + end + end + end +end diff --git a/lib/reports/report_loader.rb b/lib/reporting/report_loader.rb similarity index 81% rename from lib/reports/report_loader.rb rename to lib/reporting/report_loader.rb index dc8dba6a6f..b40f03b4ca 100644 --- a/lib/reports/report_loader.rb +++ b/lib/reporting/report_loader.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module Reports +module Reporting class ReportLoader delegate :report_subtypes, to: :base_class @@ -12,7 +12,7 @@ module Reports def report_class "#{report_module}::#{report_subtype_class}".constantize rescue NameError - raise Reports::Errors::ReportNotFound + raise Reporting::Errors::ReportNotFound end def default_report_subtype @@ -24,7 +24,7 @@ module Reports attr_reader :report_type, :report_subtype def report_module - "Reports::#{report_type.camelize}" + "Reporting::Reports::#{report_type.camelize}" end def report_subtype_class @@ -34,7 +34,7 @@ module Reports def base_class "#{report_module}::Base".constantize rescue NameError - raise Reports::Errors::ReportNotFound + raise Reporting::Errors::ReportNotFound end end end diff --git a/lib/reporting/report_renderer.rb b/lib/reporting/report_renderer.rb new file mode 100644 index 0000000000..b9027ae60d --- /dev/null +++ b/lib/reporting/report_renderer.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spreadsheet_architect' + +module Reporting + class ReportRenderer + def initialize(report) + @report = report + end + + def table_headers + @report.report_data.columns + end + + def table_rows + @report.report_data.rows + end + + def as_json + @report.report_data.as_json + end + + def as_arrays + @as_arrays ||= [table_headers] + table_rows + end + + def to_csv + SpreadsheetArchitect.to_csv(headers: table_headers, data: table_rows) + end + + def to_ods + SpreadsheetArchitect.to_ods(headers: table_headers, data: table_rows) + end + + def to_xlsx + SpreadsheetArchitect.to_xlsx(headers: table_headers, data: table_rows) + end + end +end diff --git a/lib/reporting/report_template.rb b/lib/reporting/report_template.rb new file mode 100644 index 0000000000..f7cb7a7d99 --- /dev/null +++ b/lib/reporting/report_template.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Reporting + class ReportTemplate + delegate :as_json, :as_arrays, :table_headers, :table_rows, + :to_csv, :to_xlsx, :to_ods, :to_json, to: :renderer + + attr_reader :options + + SUBTYPES = [] + + def self.report_subtypes + self::SUBTYPES + end + + def initialize(current_user, ransack_params, options = {}) + @current_user = current_user + @ransack_params = ransack_params.with_indifferent_access + @options = ( options || {} ).with_indifferent_access + end + + def report_data + @report_data ||= report_query.raw_result + end + + private + + attr_reader :current_user, :ransack_params + + def renderer + @renderer ||= ReportRenderer.new(self) + end + + def scoped_orders_relation + visible_orders_relation.ransack(ransack_params).result + end + + def visible_orders_relation + ::Permissions::Order.new(current_user). + visible_orders.complete.not_state(:canceled). + select(:id).distinct + end + + def managed_orders_relation + ::Enterprise.managed_by(current_user).select(:id).distinct + end + + def i18n_scope + "admin.reports" + end + end +end diff --git a/lib/reporting/reports/packing/base.rb b/lib/reporting/reports/packing/base.rb new file mode 100644 index 0000000000..5968ba7a9b --- /dev/null +++ b/lib/reporting/reports/packing/base.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module Packing + class Base < ReportTemplate + SUBTYPES = ["customer", "supplier"] + + def primary_model + Spree::LineItem + end + + def report_query + Queries::QueryBuilder.new(primary_model, grouping_fields). + scoped_to_orders(scoped_orders_relation). + with_managed_orders(managed_orders_relation). + joins_order_and_distributor. + joins_order_customer. + joins_order_bill_address. + joins_variant. + joins_variant_product. + joins_product_supplier. + joins_product_shipping_category. + join_line_item_option_values. + selecting(select_fields). + grouped_in_sets(group_sets). + ordered_by(ordering_fields) + end + + def grouping_fields + lambda do + [ + order_table[:id], + line_item_table[:id] + ] + end + end + end + end + end +end diff --git a/lib/reporting/reports/packing/customer.rb b/lib/reporting/reports/packing/customer.rb new file mode 100644 index 0000000000..f12b83a3b5 --- /dev/null +++ b/lib/reporting/reports/packing/customer.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module Packing + class Customer < Base + def select_fields + lambda do + { + hub: default_blank(distributor_alias[:name]), + customer_code: default_blank(masked(customer_table[:code])), + first_name: default_blank(masked(bill_address_alias[:firstname])), + last_name: default_blank(masked(bill_address_alias[:lastname])), + supplier: default_blank(supplier_alias[:name]), + product: default_string(product_table[:name], summary_row_title), + variant: default_blank(variant_full_name), + quantity: sum_values(line_item_table[:quantity]), + temp_controlled: boolean_blank(shipping_category_table[:temperature_controlled]), + } + end + end + + def ordering_fields + lambda do + [ + distributor_alias[:name], + bill_address_alias[:lastname], + order_table[:id], + sql_grouping(grouping_fields), + Arel.sql("supplier"), + Arel.sql("product"), + Arel.sql("variant"), + ] + end + end + + def group_sets + lambda do + [ + distributor_alias[:name], + bill_address_alias[:lastname], + grouping_sets([parenthesise(order_table[:id]), parenthesise(grouping_fields)]) + ] + end + end + end + end + end +end diff --git a/lib/reporting/reports/packing/supplier.rb b/lib/reporting/reports/packing/supplier.rb new file mode 100644 index 0000000000..fa6837c867 --- /dev/null +++ b/lib/reporting/reports/packing/supplier.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module Packing + class Supplier < Base + def select_fields + lambda do + { + hub: default_blank(distributor_alias[:name]), + supplier: default_blank(supplier_alias[:name]), + customer_code: default_blank(customer_table[:code]), + first_name: default_blank(bill_address_alias[:firstname]), + last_name: default_blank(bill_address_alias[:lastname]), + product: default_string(product_table[:name], summary_row_title), + variant: default_blank(variant_full_name), + quantity: sum_values(line_item_table[:quantity]), + temp_controlled: boolean_blank(shipping_category_table[:temperature_controlled]), + } + end + end + + def group_sets + lambda do + [ + distributor_alias[:name], + supplier_alias[:name], + grouping_sets([parenthesise(supplier_alias[:name]), parenthesise(grouping_fields)]) + ] + end + end + + def ordering_fields + lambda do + [ + distributor_alias[:name], + supplier_alias[:name], + sql_grouping(grouping_fields), + Arel.sql("product"), + Arel.sql("variant"), + Arel.sql("supplier"), + ] + end + end + end + end + end +end diff --git a/lib/reports/packing/base.rb b/lib/reports/packing/base.rb deleted file mode 100644 index eb6c93eb82..0000000000 --- a/lib/reports/packing/base.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Reports - module Packing - class Base < ReportTemplate - SUBTYPES = ["customer", "supplier"] - - - - private - - def i18n_scope - "admin.reports" - end - end - end -end diff --git a/lib/reports/packing/customer.rb b/lib/reports/packing/customer.rb deleted file mode 100644 index 49ae4c92a9..0000000000 --- a/lib/reports/packing/customer.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module Reports - module Packing - class Customer < Base - - end - end -end diff --git a/lib/reports/packing/supplier.rb b/lib/reports/packing/supplier.rb deleted file mode 100644 index 489f68f0cb..0000000000 --- a/lib/reports/packing/supplier.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module Reports - module Packing - class Supplier < Base - - end - end -end diff --git a/lib/reports/report_renderer.rb b/lib/reports/report_renderer.rb deleted file mode 100644 index d29e4e5e00..0000000000 --- a/lib/reports/report_renderer.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -require 'spreadsheet_architect' - -module Reports - class ReportRenderer - def initialize(report) - @report = report - end - - def table_headers - as_arrays.first - end - - def table_rows - as_arrays.drop(1) - end - - def as_hashes - report_rows - end - - def as_arrays - @as_arrays ||= rows_as_arrays - end - - def to_csv - SpreadsheetArchitect.to_csv(headers: table_headers, data: table_rows) - end - - def to_ods - SpreadsheetArchitect.to_ods(headers: table_headers, data: table_rows) - end - - def to_xlsx - SpreadsheetArchitect.to_xlsx(headers: table_headers, data: table_rows) - end - - private - - def report_rows - @report.report_rows - end - - def rows_as_arrays - report_array = [header_row] - - report_rows.each do |row| - report_array << row_or_summary(row) - end - - report_array - end - - def header_row - report_rows.first.keys - [:summary_row_title] - end - - def row_or_summary(row) - summary_row_title = row.delete :summary_row_title - row_values = row.values - row_values[0] = summary_row_title if summary_row_title - - row_values - end - end -end diff --git a/lib/reports/report_template.rb b/lib/reports/report_template.rb deleted file mode 100644 index dc0a5bd02a..0000000000 --- a/lib/reports/report_template.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -module Reports - class ReportTemplate - delegate :as_hashes, :as_arrays, :table_headers, :table_rows, - :to_csv, :to_xlsx, :to_ods, :to_json, to: :report_renderer - - attr_reader :options - attr_accessor :report_rows - - SUBTYPES = [] - - def self.report_subtypes - self::SUBTYPES - end - - def initialize(current_user, ransack_params, options = {}) - @current_user = current_user - @ransack_params = ransack_params.with_indifferent_access - @options = ( options || {} ).with_indifferent_access - @report_rows = [] - - build_report - end - - def headers - report_rows.first&.keys || [] - end - - private - - attr_reader :current_user, :ransack_params - - def build_report - # TODO - end - - def report_renderer - @report_renderer ||= ReportRenderer.new(self) - end - end -end diff --git a/spec/lib/reports/packing/packing_report_spec.rb b/spec/lib/reports/packing/packing_report_spec.rb index 563d9bf030..7087bacfdf 100644 --- a/spec/lib/reports/packing/packing_report_spec.rb +++ b/spec/lib/reports/packing/packing_report_spec.rb @@ -59,7 +59,7 @@ describe "Packing Reports" do it "shows line items supplied by my producers, with names hidden" do expect(subject.collection).to eq([line_item2]) - expect(subject.as_hashes.first[:first_name]).to eq( + expect(subject.as_json.first[:first_name]).to eq( I18n.t('admin.reports.hidden_field') ) end diff --git a/spec/lib/reports/report_loader_spec.rb b/spec/lib/reports/report_loader_spec.rb index dd53b51ca0..5341ae641f 100644 --- a/spec/lib/reports/report_loader_spec.rb +++ b/spec/lib/reports/report_loader_spec.rb @@ -2,17 +2,19 @@ require 'spec_helper' -module Reports - module Bananas - class Base; end - class Green; end - class Yellow; end +module Reporting + module Reports + module Bananas + class Base; end + class Green; end + class Yellow; end + end end end -describe Reports::ReportLoader do - let(:service) { Reports::ReportLoader.new(*arguments) } - let(:report_base_class) { Reports::Bananas::Base } +describe Reporting::ReportLoader do + let(:service) { Reporting::ReportLoader.new(*arguments) } + let(:report_base_class) { Reporting::Reports::Bananas::Base } let(:report_subtypes) { ["green", "yellow"] } before do @@ -24,7 +26,7 @@ describe Reports::ReportLoader do let(:arguments) { ["bananas", "yellow"] } it "returns a report class when given type and subtype" do - expect(service.report_class).to eq Reports::Bananas::Yellow + expect(service.report_class).to eq Reporting::Reports::Bananas::Yellow end end @@ -33,7 +35,7 @@ describe Reports::ReportLoader do let(:arguments) { ["bananas"] } it "returns first listed report type" do - expect(service.report_class).to eq Reports::Bananas::Green + expect(service.report_class).to eq Reporting::Reports::Bananas::Green end end @@ -42,7 +44,7 @@ describe Reports::ReportLoader do let(:report_subtypes) { [] } it "returns base class" do - expect(service.report_class).to eq Reports::Bananas::Base + expect(service.report_class).to eq Reporting::Reports::Bananas::Base end end @@ -51,7 +53,7 @@ describe Reports::ReportLoader do let(:report_subtypes) { [] } it "raises an error" do - expect{ service.report_class }.to raise_error(Reports::Errors::ReportNotFound) + expect{ service.report_class }.to raise_error(Reporting::Errors::ReportNotFound) end end end @@ -80,7 +82,7 @@ describe Reports::ReportLoader do let(:report_subtypes) { [] } it "raises an error" do - expect{ service.report_class }.to raise_error(Reports::Errors::ReportNotFound) + expect{ service.report_class }.to raise_error(Reporting::Errors::ReportNotFound) end end end diff --git a/spec/lib/reports/report_renderer_spec.rb b/spec/lib/reports/report_renderer_spec.rb index 2865b67784..2566ccf30a 100644 --- a/spec/lib/reports/report_renderer_spec.rb +++ b/spec/lib/reports/report_renderer_spec.rb @@ -27,9 +27,9 @@ describe Reports::ReportRenderer do end end - describe "#as_hashes" do + describe "#as_json" do it "returns the report's data as hashes" do - expect(service.as_hashes).to eq report_rows + expect(service.as_json).to eq report_rows end end