diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 13d9769853..f8e25f898e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -190,7 +190,7 @@ Layout/LineLength: - 'spec/lib/reports/order_grouper_spec.rb' - 'spec/lib/reports/orders_and_fulfillment/orders_and_fulfillment_report_spec.rb' - 'spec/lib/reports/packing/packing_report_spec.rb' - - 'spec/lib/reports/products_and_inventory_default_report_spec.rb' + - 'spec/lib/reports/products_and_inventory_report_spec.rb' - 'spec/lib/reports/users_and_enterprises_report_spec.rb' - 'spec/lib/reports/xero_invoices_report_spec.rb' - 'spec/lib/stripe/authorize_response_patcher_spec.rb' @@ -646,7 +646,7 @@ Metrics/ModuleLength: - 'spec/lib/reports/order_grouper_spec.rb' - 'spec/lib/reports/orders_and_fulfillment/customer_totals_report_spec.rb' - 'spec/lib/reports/orders_and_fulfillment/orders_and_fulfillment_report_spec.rb' - - 'spec/lib/reports/products_and_inventory_default_report_spec.rb' + - 'spec/lib/reports/products_and_inventory_report_spec.rb' - 'spec/lib/reports/users_and_enterprises_report_spec.rb' - 'spec/models/spree/adjustment_spec.rb' - 'spec/models/spree/credit_card_spec.rb' diff --git a/lib/reporting/reports/products_and_inventory/all_products.rb b/lib/reporting/reports/products_and_inventory/all_products.rb new file mode 100644 index 0000000000..f433f83287 --- /dev/null +++ b/lib/reporting/reports/products_and_inventory/all_products.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module ProductsAndInventory + class AllProducts < Base + def filter_on_hand(variants) + variants # do not filter + end + end + end + end +end diff --git a/lib/reporting/reports/products_and_inventory/products_and_inventory_report.rb b/lib/reporting/reports/products_and_inventory/base.rb similarity index 68% rename from lib/reporting/reports/products_and_inventory/products_and_inventory_report.rb rename to lib/reporting/reports/products_and_inventory/base.rb index b8dc78977b..b0928cf0fb 100644 --- a/lib/reporting/reports/products_and_inventory/products_and_inventory_report.rb +++ b/lib/reporting/reports/products_and_inventory/base.rb @@ -5,37 +5,32 @@ require 'open_food_network/scope_variant_to_hub' module Reporting module Reports module ProductsAndInventory - class ProductsAndInventoryReport < ReportObjectTemplate - delegate :table_rows, :table_headers, :rules, :columns, :sku_for, to: :report - - def report - @report ||= report_klass.new(self) - end - - def report_type - params[:report_subtype] - end - - def report_klass - if report_type == 'lettuce_share' - LettuceShareReport - else - ProductsAndInventoryDefaultReport - end - end - - def permissions - @permissions ||= OpenFoodNetwork::Permissions.new(@user) - end - - def visible_products - @visible_products ||= permissions.visible_products - end - - def variants + class Base < ReportObjectTemplate + def query_result filter(child_variants) end + # rubocop:disable Metrics/AbcSize + def columns + { + supplier: proc { |variant| variant.product.supplier.name }, + producer_suburb: proc { |variant| variant.product.supplier.address.city }, + product: proc { |variant| variant.product.name }, + product_properties: proc { |v| v.product.properties.map(&:name).join(", ") }, + taxons: proc { |variant| variant.product.taxons.map(&:name).join(", ") }, + variant_value: proc { |variant| variant.full_name }, + price: proc { |variant| variant.price }, + group_buy_unit_quantity: proc { |variant| variant.product.group_buy_unit_size }, + amount: proc { |_variant| "" }, + sku: proc { |variant| variant.sku.presence || variant.product.sku }, + } + end + # rubocop:enable Metrics/AbcSize + + def filter(variants) + filter_on_hand filter_to_distributor filter_to_order_cycle filter_to_supplier variants + end + def child_variants Spree::Variant. where(is_master: false). @@ -45,17 +40,23 @@ module Reporting order('spree_products.name') end - def filter(variants) - filter_on_hand filter_to_distributor filter_to_order_cycle filter_to_supplier variants + private + + def report_type + params[:report_subtype] + end + + def visible_products + @visible_products ||= permissions.visible_products + end + + def permissions + @permissions ||= OpenFoodNetwork::Permissions.new(@user) end # Using the `in_stock?` method allows overrides by distributors. def filter_on_hand(variants) - if report_type == 'inventory' - variants.select(&:in_stock?) - else - variants - end + variants.select(&:in_stock?) end def filter_to_supplier(variants) diff --git a/lib/reporting/reports/products_and_inventory/inventory.rb b/lib/reporting/reports/products_and_inventory/inventory.rb new file mode 100644 index 0000000000..b89fde6c32 --- /dev/null +++ b/lib/reporting/reports/products_and_inventory/inventory.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Reporting + module Reports + module ProductsAndInventory + class Inventory < Base + end + end + end +end diff --git a/lib/reporting/reports/products_and_inventory/lettuce_share_report.rb b/lib/reporting/reports/products_and_inventory/lettuce_share.rb similarity index 50% rename from lib/reporting/reports/products_and_inventory/lettuce_share_report.rb rename to lib/reporting/reports/products_and_inventory/lettuce_share.rb index 7f3ec04a93..96100b1ecb 100644 --- a/lib/reporting/reports/products_and_inventory/lettuce_share_report.rb +++ b/lib/reporting/reports/products_and_inventory/lettuce_share.rb @@ -1,59 +1,39 @@ # frozen_string_literal: true -# require 'variant_units/option_value_namer' - module Reporting module Reports module ProductsAndInventory - class LettuceShareReport - attr_reader :context - - delegate :variants, :render_table, to: :context - - def initialize(context) - @context = context - end - - def table_headers - # NOTE: These are NOT to be translated, they need to be in this exact format to work with LettucShare - [ - "PRODUCT", - "Description", - "Qty", - "Pack Size", - "Unit", - "Unit Price", - "Total", - "GST incl.", - "Grower and growing method", - "Taxon" - ] - end - - def table_rows - variants.select(&:in_stock?) - .map do |variant| - [ - variant.product.name, - variant.full_name, - '', - VariantUnits::OptionValueNamer.new(variant).value, - VariantUnits::OptionValueNamer.new(variant).unit, - variant.price, - '', - gst(variant), - grower_and_method(variant), - variant.product.primary_taxon.name - ] - end - end - - def rules - [] + class LettuceShare < Base + # NOTE: These are NOT to be translated, they need to be in this exact format + # to work with LettucShare + def custom_headers + { + product: "PRODUCT", + description: "Description", + quantity: "Qty", + pack_size: "Pack Size", + unit: "Unit", + unit_price: "Unit Price", + total: "Total", + gst: "GST incl.", + grower: "Grower and growing method", + taxon: "Taxon" + } end def columns - {} + { + product: proc { |variant| variant.product.name }, + description: proc { |variant| variant.full_name }, + quantity: proc { |_variant| '' }, + pack_size: proc { |variant| VariantUnits::OptionValueNamer.new(variant).value }, + unit: proc { |variant| VariantUnits::OptionValueNamer.new(variant).unit }, + unit_price: proc { |variant| variant.price }, + total: proc { |_variant| '' }, + gst: proc { |variant| gst(variant) }, + grower: proc { |variant| grower_and_method(variant) }, + taxon: proc { |variant| variant.product.primary_taxon.name } + } end private diff --git a/lib/reporting/reports/products_and_inventory/products_and_inventory_default_report.rb b/lib/reporting/reports/products_and_inventory/products_and_inventory_default_report.rb deleted file mode 100644 index 6d8307a611..0000000000 --- a/lib/reporting/reports/products_and_inventory/products_and_inventory_default_report.rb +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: true - -module Reporting - module Reports - module ProductsAndInventory - class ProductsAndInventoryDefaultReport - attr_reader :context - - delegate :variants, :render_table, to: :context - - def initialize(context) - @context = context - end - - def table_headers - [ - I18n.t(:report_header_supplier), - I18n.t(:report_header_producer_suburb), - I18n.t(:report_header_product), - I18n.t(:report_header_product_properties), - I18n.t(:report_header_taxons), - I18n.t(:report_header_variant_value), - I18n.t(:report_header_price), - I18n.t(:report_header_group_buy_unit_quantity), - I18n.t(:report_header_amount), - I18n.t(:report_header_sku) - ] - end - - def table_rows - variants.map do |variant| - [ - variant.product.supplier.name, - variant.product.supplier.address.city, - variant.product.name, - variant.product.properties.map(&:name).join(", "), - variant.product.taxons.map(&:name).join(", "), - variant.full_name, - variant.price, - variant.product.group_buy_unit_size, - "", - sku_for(variant) - ] - end - end - - def rules - [] - end - - def columns - {} - end - - def sku_for(variant) - return variant.sku if variant.sku.present? - - variant.product.sku - end - end - end - end -end diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb index 584d0a135e..c306451f95 100644 --- a/spec/controllers/admin/reports_controller_spec.rb +++ b/spec/controllers/admin/reports_controller_spec.rb @@ -246,7 +246,7 @@ describe Admin::ReportsController, type: :controller do end it "creates a ProductAndInventoryReport" do - allow(Reporting::Reports::ProductsAndInventory::ProductsAndInventoryReport).to receive(:new) + allow(Reporting::Reports::ProductsAndInventory::Base).to receive(:new) .and_return(report = double(:report)) allow(report).to receive(:table_headers).and_return [] allow(report).to receive(:table_rows).and_return [] diff --git a/spec/lib/reports/lettuce_share_report_spec.rb b/spec/lib/reports/lettuce_share_report_spec.rb index f0c1e3d554..d9af25be08 100644 --- a/spec/lib/reports/lettuce_share_report_spec.rb +++ b/spec/lib/reports/lettuce_share_report_spec.rb @@ -5,12 +5,9 @@ require 'spec_helper' module Reporting module Reports module ProductsAndInventory - describe LettuceShareReport do + describe LettuceShare do let(:user) { create(:user) } - let(:base_report) { - ProductsAndInventoryReport.new(user, { report_subtype: 'lettuce_share' }) - } - let(:report) { base_report.report } + let(:report) { LettuceShare.new(user) } let(:variant) { create(:variant) } describe "grower and method" do @@ -54,18 +51,17 @@ module Reporting } it "all items" do - allow(base_report).to receive(:child_variants) { - Spree::Variant.where(id: [variant, variant2, variant3]) - } + allow(report).to receive(:child_variants) { + Spree::Variant.where(id: [variant, variant2, variant3]) + } expect(report.table_rows.count).to eq 3 end it "only available items" do variant.on_hand = 0 - allow(base_report).to receive(:child_variants) { - Spree::Variant.where(id: [variant, variant2, variant3, - variant4]) - } + allow(report).to receive(:child_variants) { + Spree::Variant.where(id: [variant, variant2, variant3, variant4]) + } expect(report.table_rows.count).to eq 3 end @@ -75,10 +71,10 @@ module Reporting # create the overrides variant2_override variant3_override - allow(base_report).to receive(:child_variants) { - Spree::Variant.where(id: [variant, variant2, variant3]) - } - allow(base_report).to receive(:params) { + allow(report).to receive(:child_variants) { + Spree::Variant.where(id: [variant, variant2, variant3]) + } + allow(report).to receive(:params) { { distributor_id: hub.id, report_subtype: 'lettuce_share' } } rows = report.table_rows diff --git a/spec/lib/reports/products_and_inventory_default_report_spec.rb b/spec/lib/reports/products_and_inventory_report_spec.rb similarity index 93% rename from spec/lib/reports/products_and_inventory_default_report_spec.rb rename to spec/lib/reports/products_and_inventory_report_spec.rb index f57a775844..7ed6034437 100644 --- a/spec/lib/reports/products_and_inventory_default_report_spec.rb +++ b/spec/lib/reports/products_and_inventory_report_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' module Reporting module Reports module ProductsAndInventory - describe ProductsAndInventoryDefaultReport do + describe Base do context "As a site admin" do let(:user) do user = create(:user) @@ -13,7 +13,7 @@ module Reporting user end subject do - ProductsAndInventoryReport.new user, {} + Base.new user, {} end it "Should return headers" do @@ -48,7 +48,7 @@ module Reporting :taxons).and_return [double(name: "taxon1"), double(name: "taxon2")] allow(variant).to receive_message_chain(:product, :group_buy_unit_size).and_return(21) - allow(subject).to receive(:variants).and_return [variant] + allow(subject).to receive(:query_result).and_return [variant] expect(subject.table_rows).to eq([[ "Supplier", @@ -67,7 +67,7 @@ module Reporting it "fetches variants for some params" do expect(subject).to receive(:child_variants).and_return ["children"] expect(subject).to receive(:filter).with(['children']).and_return ["filter_children"] - expect(subject.variants).to eq(["filter_children"]) + expect(subject.query_result).to eq(["filter_children"]) end end @@ -82,7 +82,7 @@ module Reporting end subject do - ProductsAndInventoryReport.new enterprise_user, {} + Base.new enterprise_user, {} end describe "fetching child variants" do @@ -112,7 +112,7 @@ module Reporting product1 = create(:simple_product, supplier: supplier, on_hand: 99) product2 = create(:simple_product, supplier: supplier, on_hand: 0) - allow(subject).to receive(:params).and_return(report_subtype: 'inventory') + subject = Inventory.new enterprise_user expect(subject.filter(variants)).to eq([product1.variants.first]) end end @@ -225,17 +225,17 @@ module Reporting ] ) + subject = Inventory.new enterprise_user allow(subject).to receive(:params).and_return( order_cycle_id: order_cycle.id, supplier_id: supplier.id, - distributor_id: distributor.id, - report_subtype: 'inventory' + distributor_id: distributor.id ) expect(subject.filter(variants)).to match_array [not_filtered_variant] # And it integrates with the ordering of the `variants` method. - expect(subject.variants).to match_array [not_filtered_variant] + expect(subject.query_result).to match_array [not_filtered_variant] end end @@ -243,12 +243,15 @@ module Reporting let(:variant) { create(:variant) } let(:product) { variant.product } - before { product.update_attribute(:sku, "Product SKU") } + before { + product.update_attribute(:sku, "Product SKU") + allow(subject).to receive(:query_result).and_return([variant]) + } context "when the variant has an SKU set" do before { variant.update_attribute(:sku, "Variant SKU") } it "returns it" do - expect(subject.__send__(:sku_for, variant)).to eq "Variant SKU" + expect(subject.rows.first.sku).to eq "Variant SKU" end end @@ -256,7 +259,7 @@ module Reporting before { variant.update_attribute(:sku, "") } it "returns the product's SKU" do - expect(subject.__send__(:sku_for, variant)).to eq "Product SKU" + expect(subject.rows.first.sku).to eq "Product SKU" end end end