diff --git a/app/models/product_import/entry_processor.rb b/app/models/product_import/entry_processor.rb index 028b973454..323b4859b8 100644 --- a/app/models/product_import/entry_processor.rb +++ b/app/models/product_import/entry_processor.rb @@ -4,7 +4,7 @@ module ProductImport class EntryProcessor - attr_reader :inventory_created, :inventory_updated, :products_created, :variants_created, :variants_updated, :products_reset_count, :supplier_products, :total_supplier_products + attr_reader :inventory_created, :inventory_updated, :products_created, :variants_created, :variants_updated, :products_reset_count, :supplier_products, :total_supplier_products, :import_settings def initialize(importer, validator, import_settings, spreadsheet_data, editable_enterprises, import_time, updated_ids) @importer = importer @@ -60,46 +60,23 @@ module ProductImport end def reset_absent_items - # For selected enterprises; set stock to zero for all products/inventory - # that were not listed in the newly uploaded spreadsheet - return unless data_for_stock_reset? - suppliers_to_reset_products = [] - suppliers_to_reset_inventories = [] - - settings = @import_settings[:settings] - - @import_settings[:enterprises_to_reset].each do |enterprise_id| - suppliers_to_reset_products.push Integer(enterprise_id) if settings['reset_all_absent'] && permission_by_id?(enterprise_id) && !importing_into_inventory? - suppliers_to_reset_inventories.push Integer(enterprise_id) if settings['reset_all_absent'] && permission_by_id?(enterprise_id) && importing_into_inventory? - end - - unless suppliers_to_reset_inventories.empty? - @products_reset_count += VariantOverride. - where('variant_overrides.hub_id IN (?) - AND variant_overrides.id NOT IN (?)', suppliers_to_reset_inventories, @import_settings[:updated_ids]). - update_all(count_on_hand: 0) - end - - return if suppliers_to_reset_products.empty? - - @products_reset_count += Spree::Variant.joins(:product). - where('spree_products.supplier_id IN (?) - AND spree_variants.id NOT IN (?) - AND spree_variants.is_master = false - AND spree_variants.deleted_at IS NULL', suppliers_to_reset_products, @import_settings[:updated_ids]). - update_all(count_on_hand: 0) + ResetAbsent.new(self).call end def total_saved_count @products_created + @variants_created + @variants_updated + @inventory_created + @inventory_updated end - private - - def data_for_stock_reset? - @import_settings[:settings] && @import_settings[:updated_ids] && @import_settings[:enterprises_to_reset] + def permission_by_id?(supplier_id) + @editable_enterprises.value?(Integer(supplier_id)) end + def importing_into_inventory? + import_settings[:settings] && import_settings[:settings]['import_into'] == 'inventories' + end + + private + def save_to_inventory(entry) save_new_inventory_item entry if entry.validates_as? 'new_inventory_item' save_existing_inventory_item entry if entry.validates_as? 'existing_inventory_item' @@ -126,7 +103,7 @@ module ProductImport end def import_into_inventory?(entry) - entry.supplier_id && @import_settings[:settings]['import_into'] == 'inventories' + entry.supplier_id && import_settings[:settings]['import_into'] == 'inventories' end def save_new_inventory_item(entry) @@ -198,7 +175,7 @@ module ProductImport end def assign_defaults(object, entry) - settings = Settings.new(@import_settings) + settings = Settings.new(import_settings) # Assigns a default value for a specified field e.g. category='Vegetables', setting this value # either for all entries (overwrite_all), or only for those entries where the field was blank @@ -241,13 +218,5 @@ module ProductImport variant.import_date = @import_time variant.save end - - def permission_by_id?(supplier_id) - @editable_enterprises.value?(Integer(supplier_id)) - end - - def importing_into_inventory? - @import_settings[:settings] && @import_settings[:settings]['import_into'] == 'inventories' - end end end diff --git a/app/models/product_import/reset_absent.rb b/app/models/product_import/reset_absent.rb new file mode 100644 index 0000000000..aad5ed4de9 --- /dev/null +++ b/app/models/product_import/reset_absent.rb @@ -0,0 +1,53 @@ +require 'delegate' + +module ProductImport + class ResetAbsent < SimpleDelegator + def call + # For selected enterprises; set stock to zero for all products/inventory + # that were not listed in the newly uploaded spreadsheet + return unless data_for_stock_reset? + suppliers_to_reset_products = [] + suppliers_to_reset_inventories = [] + + settings = import_settings[:settings] + + import_settings[:enterprises_to_reset].each do |enterprise_id| + if settings['reset_all_absent'] && + permission_by_id?(enterprise_id) && + !importing_into_inventory? + suppliers_to_reset_products.push(Integer(enterprise_id)) + end + + if settings['reset_all_absent'] && + permission_by_id?(enterprise_id) && + importing_into_inventory? + suppliers_to_reset_inventories.push(Integer(enterprise_id)) + end + end + + unless suppliers_to_reset_inventories.empty? + @products_reset_count += VariantOverride. + where('variant_overrides.hub_id IN (?) + AND variant_overrides.id NOT IN (?)', suppliers_to_reset_inventories, import_settings[:updated_ids]). + update_all(count_on_hand: 0) + end + + return if suppliers_to_reset_products.empty? + + @products_reset_count += Spree::Variant.joins(:product). + where('spree_products.supplier_id IN (?) + AND spree_variants.id NOT IN (?) + AND spree_variants.is_master = false + AND spree_variants.deleted_at IS NULL', suppliers_to_reset_products, import_settings[:updated_ids]). + update_all(count_on_hand: 0) + end + + private + + def data_for_stock_reset? + import_settings[:settings] && + import_settings[:updated_ids] && + import_settings[:enterprises_to_reset] + end + end +end diff --git a/spec/models/product_import/entry_processor_spec.rb b/spec/models/product_import/entry_processor_spec.rb new file mode 100644 index 0000000000..866bf742b8 --- /dev/null +++ b/spec/models/product_import/entry_processor_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe ProductImport::EntryProcessor do + let(:importer) { double(:importer) } + let(:validator) { double(:validator) } + let(:import_settings) { double(:import_settings) } + let(:spreadsheet_data) { double(:spreadsheet_data) } + let(:editable_enterprises) { double(:editable_enterprises) } + let(:import_time) { double(:import_time) } + let(:updated_ids) { double(:updated_ids) } + + let(:entry_processor) do + described_class.new( + importer, + validator, + import_settings, + spreadsheet_data, + editable_enterprises, + import_time, + updated_ids + ) + end + + describe '#reset_absent_items' do + let(:reset_absent) { double(ProductImport::ResetAbsent, call: true) } + + before do + allow(ProductImport::ResetAbsent) + .to receive(:new) + .and_return(reset_absent) + end + + it 'delegates to ResetAbsent' do + entry_processor.reset_absent_items + + expect(ProductImport::ResetAbsent) + .to have_received(:new).with(entry_processor) + end + end +end diff --git a/spec/models/product_import/reset_absent_spec.rb b/spec/models/product_import/reset_absent_spec.rb new file mode 100644 index 0000000000..2be1df43c7 --- /dev/null +++ b/spec/models/product_import/reset_absent_spec.rb @@ -0,0 +1,86 @@ +require 'spec_helper' + +describe ProductImport::ResetAbsent do + let(:importer) { double(:importer) } + let(:validator) { double(:validator) } + let(:spreadsheet_data) { double(:spreadsheet_data) } + let(:editable_enterprises) { double(:editable_enterprises) } + let(:import_time) { double(:import_time) } + let(:updated_ids) { double(:updated_ids) } + + let(:entry_processor) do + ProductImport::EntryProcessor.new( + importer, + validator, + import_settings, + spreadsheet_data, + editable_enterprises, + import_time, + updated_ids + ) + end + + let(:reset_absent) { described_class.new(entry_processor) } + + describe '#call' do + context 'when there are no settings' do + let(:import_settings) { { updated_ids: [], enterprises_to_reset: [] } } + + it 'returns nil' do + expect(reset_absent.call).to be_nil + end + end + + context 'when there are no updated_ids' do + let(:import_settings) { { settings: [], enterprises_to_reset: [] } } + + it 'returns nil' do + expect(reset_absent.call).to be_nil + end + end + + context 'when there are no enterprises_to_reset' do + let(:import_settings) { { settings: [], updated_ids: [] } } + + it 'returns nil' do + expect(reset_absent.call).to be_nil + end + end + + context 'when there are settings, updated_ids and enterprises_to_reset' do + let(:import_settings) do + { + settings: { 'reset_all_absent' => true }, + updated_ids: [1], + enterprises_to_reset: [2] + } + end + + before do + allow(entry_processor).to receive(:permission_by_id?).with(2) { true } + end + + context 'and not importing into inventory' do + before do + allow(entry_processor) + .to receive(:importing_into_inventory?) { false } + end + + it 'returns true' do + expect(reset_absent.call).to eq(true) + end + end + + context 'and importing into inventory' do + before do + allow(entry_processor) + .to receive(:importing_into_inventory?) { true } + end + + it 'returns true' do + expect(reset_absent.call).to eq(true) + end + end + end + end +end