mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Merge pull request #2778 from coopdevs/refactor-entry-processor
Refactor entry processor
This commit is contained in:
@@ -4,12 +4,14 @@
|
||||
|
||||
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, :supplier_products,
|
||||
:total_supplier_products, :products_reset_count
|
||||
|
||||
def initialize(importer, validator, import_settings, spreadsheet_data, editable_enterprises, import_time, updated_ids)
|
||||
@importer = importer
|
||||
@validator = validator
|
||||
@import_settings = import_settings
|
||||
@settings = Settings.new(import_settings)
|
||||
@spreadsheet_data = spreadsheet_data
|
||||
@editable_enterprises = editable_enterprises
|
||||
@import_time = import_time
|
||||
@@ -43,7 +45,7 @@ module ProductImport
|
||||
next unless supplier_id && permission_by_id?(supplier_id)
|
||||
|
||||
products_count =
|
||||
if importing_into_inventory?
|
||||
if settings.importing_into_inventory?
|
||||
VariantOverride.where('variant_overrides.hub_id IN (?)', supplier_id).count
|
||||
else
|
||||
Spree::Variant.
|
||||
@@ -60,45 +62,39 @@ 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 = []
|
||||
return unless settings.data_for_stock_reset? && settings.reset_all_absent?
|
||||
|
||||
settings = @import_settings[:settings]
|
||||
@products_reset_count = reset_absent.call
|
||||
end
|
||||
|
||||
@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?
|
||||
def reset_absent
|
||||
@reset_absent ||= ResetAbsent.new(self, settings, reset_stock_strategy)
|
||||
end
|
||||
|
||||
def reset_stock_strategy_factory
|
||||
if settings.importing_into_inventory?
|
||||
InventoryResetStrategy
|
||||
else
|
||||
ProductsResetStrategy
|
||||
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)
|
||||
def reset_stock_strategy
|
||||
@reset_stock_strategy ||= reset_stock_strategy_factory
|
||||
.new(settings.updated_ids)
|
||||
end
|
||||
|
||||
def total_saved_count
|
||||
@products_created + @variants_created + @variants_updated + @inventory_created + @inventory_updated
|
||||
end
|
||||
|
||||
def permission_by_id?(supplier_id)
|
||||
@editable_enterprises.value?(Integer(supplier_id))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def data_for_stock_reset?
|
||||
@import_settings[:settings] && @import_settings[:updated_ids] && @import_settings[:enterprises_to_reset]
|
||||
end
|
||||
attr_reader :settings
|
||||
|
||||
def save_to_inventory(entry)
|
||||
save_new_inventory_item entry if entry.validates_as? 'new_inventory_item'
|
||||
@@ -126,7 +122,7 @@ module ProductImport
|
||||
end
|
||||
|
||||
def import_into_inventory?(entry)
|
||||
entry.supplier_id && @import_settings[:settings]['import_into'] == 'inventories'
|
||||
entry.supplier_id && settings.importing_into_inventory?
|
||||
end
|
||||
|
||||
def save_new_inventory_item(entry)
|
||||
@@ -201,9 +197,9 @@ module ProductImport
|
||||
# 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
|
||||
# in the spreadsheet (overwrite_empty), depending on selected import settings
|
||||
return unless @import_settings.key?(:settings) && @import_settings[:settings][entry.supplier_id.to_s] && @import_settings[:settings][entry.supplier_id.to_s]['defaults']
|
||||
return unless settings.defaults(entry)
|
||||
|
||||
@import_settings[:settings][entry.supplier_id.to_s]['defaults'].each do |attribute, setting|
|
||||
settings.defaults(entry).each do |attribute, setting|
|
||||
next unless setting['active']
|
||||
|
||||
case setting['mode']
|
||||
@@ -239,13 +235,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
|
||||
|
||||
28
app/models/product_import/inventory_reset_strategy.rb
Normal file
28
app/models/product_import/inventory_reset_strategy.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
module ProductImport
|
||||
class InventoryResetStrategy
|
||||
def initialize(excluded_items_ids)
|
||||
@excluded_items_ids = excluded_items_ids
|
||||
end
|
||||
|
||||
def reset(supplier_ids)
|
||||
@supplier_ids = supplier_ids
|
||||
|
||||
if supplier_ids.present?
|
||||
relation.update_all(count_on_hand: 0)
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :excluded_items_ids, :supplier_ids
|
||||
|
||||
def relation
|
||||
relation = VariantOverride.where(hub_id: supplier_ids)
|
||||
return relation if excluded_items_ids.blank?
|
||||
|
||||
relation.where('id NOT IN (?)', excluded_items_ids)
|
||||
end
|
||||
end
|
||||
end
|
||||
34
app/models/product_import/products_reset_strategy.rb
Normal file
34
app/models/product_import/products_reset_strategy.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
module ProductImport
|
||||
class ProductsResetStrategy
|
||||
def initialize(excluded_items_ids)
|
||||
@excluded_items_ids = excluded_items_ids
|
||||
end
|
||||
|
||||
def reset(supplier_ids)
|
||||
@supplier_ids = supplier_ids
|
||||
|
||||
if supplier_ids.present?
|
||||
relation.update_all(count_on_hand: 0)
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :excluded_items_ids, :supplier_ids
|
||||
|
||||
def relation
|
||||
relation = Spree::Variant
|
||||
.joins(:product)
|
||||
.where(
|
||||
spree_products: { supplier_id: supplier_ids },
|
||||
spree_variants: { is_master: false, deleted_at: nil }
|
||||
)
|
||||
|
||||
return relation if excluded_items_ids.blank?
|
||||
|
||||
relation.where('spree_variants.id NOT IN (?)', excluded_items_ids)
|
||||
end
|
||||
end
|
||||
end
|
||||
31
app/models/product_import/reset_absent.rb
Normal file
31
app/models/product_import/reset_absent.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
module ProductImport
|
||||
class ResetAbsent
|
||||
def initialize(entry_processor, settings, reset_stock_strategy)
|
||||
@entry_processor = entry_processor
|
||||
@settings = settings
|
||||
@reset_stock_strategy = reset_stock_strategy
|
||||
end
|
||||
|
||||
# For selected enterprises; set stock to zero for all products/inventory
|
||||
# that were not listed in the newly uploaded spreadsheet
|
||||
#
|
||||
# @return [Integer] number of items affected by the reset
|
||||
def call
|
||||
reset_stock_strategy.reset(authorized_enterprises)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :settings, :reset_stock_strategy, :entry_processor
|
||||
|
||||
# Returns the enterprises that have permissions to be reset
|
||||
#
|
||||
# @return [Array<Integer>] array of Enterprise ids
|
||||
def authorized_enterprises
|
||||
settings.enterprises_to_reset.map do |enterprise_id|
|
||||
next unless entry_processor.permission_by_id?(enterprise_id)
|
||||
enterprise_id.to_i
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
37
app/models/product_import/settings.rb
Normal file
37
app/models/product_import/settings.rb
Normal file
@@ -0,0 +1,37 @@
|
||||
module ProductImport
|
||||
class Settings
|
||||
def initialize(import_settings)
|
||||
@import_settings = import_settings
|
||||
end
|
||||
|
||||
def defaults(entry)
|
||||
@import_settings.key?(:settings) &&
|
||||
settings[entry.supplier_id.to_s] &&
|
||||
settings[entry.supplier_id.to_s]['defaults']
|
||||
end
|
||||
|
||||
def settings
|
||||
@import_settings[:settings]
|
||||
end
|
||||
|
||||
def updated_ids
|
||||
@import_settings[:updated_ids]
|
||||
end
|
||||
|
||||
def enterprises_to_reset
|
||||
@import_settings[:enterprises_to_reset]
|
||||
end
|
||||
|
||||
def importing_into_inventory?
|
||||
settings && settings['import_into'] == 'inventories'
|
||||
end
|
||||
|
||||
def reset_all_absent?
|
||||
settings['reset_all_absent']
|
||||
end
|
||||
|
||||
def data_for_stock_reset?
|
||||
!!(settings && updated_ids && enterprises_to_reset)
|
||||
end
|
||||
end
|
||||
end
|
||||
151
spec/models/product_import/entry_processor_spec.rb
Normal file
151
spec/models/product_import/entry_processor_spec.rb
Normal file
@@ -0,0 +1,151 @@
|
||||
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) do
|
||||
instance_double(ProductImport::ResetAbsent, call: true)
|
||||
end
|
||||
|
||||
before do
|
||||
allow(ProductImport::ResetAbsent).to receive(:new) { reset_absent }
|
||||
allow(ProductImport::Settings).to receive(:new) { settings }
|
||||
end
|
||||
|
||||
context 'when there is no data' do
|
||||
let(:settings) do
|
||||
instance_double(
|
||||
ProductImport::Settings,
|
||||
data_for_stock_reset?: false,
|
||||
reset_all_absent?: true
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not call ResetAbsent' do
|
||||
entry_processor.reset_absent_items
|
||||
expect(reset_absent).not_to have_received(:call)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when reset_all_absent is not set' do
|
||||
let(:settings) do
|
||||
instance_double(
|
||||
ProductImport::Settings,
|
||||
data_for_stock_reset?: true,
|
||||
reset_all_absent?: false
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not call ResetAbsent' do
|
||||
entry_processor.reset_absent_items
|
||||
expect(reset_absent).not_to have_received(:call)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is data and reset_all_absent is set' do
|
||||
let(:settings) do
|
||||
instance_double(
|
||||
ProductImport::Settings,
|
||||
data_for_stock_reset?: true,
|
||||
reset_all_absent?: true,
|
||||
updated_ids: [1]
|
||||
)
|
||||
end
|
||||
|
||||
context 'when importing into inventory' do
|
||||
let(:reset_stock_strategy) do
|
||||
instance_double(ProductImport::InventoryResetStrategy)
|
||||
end
|
||||
|
||||
before do
|
||||
allow(settings).to receive(:importing_into_inventory?) { true }
|
||||
|
||||
allow(ProductImport::InventoryResetStrategy)
|
||||
.to receive(:new).with([1]) { reset_stock_strategy }
|
||||
end
|
||||
|
||||
it 'delegates to ResetAbsent passing the appropriate reset_stock_strategy' do
|
||||
entry_processor.reset_absent_items
|
||||
|
||||
expect(ProductImport::ResetAbsent)
|
||||
.to have_received(:new)
|
||||
.with(entry_processor, settings, reset_stock_strategy)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not importing into inventory' do
|
||||
let(:reset_stock_strategy) do
|
||||
instance_double(ProductImport::ProductsResetStrategy)
|
||||
end
|
||||
|
||||
before do
|
||||
allow(settings).to receive(:importing_into_inventory?) { false }
|
||||
|
||||
allow(ProductImport::ProductsResetStrategy)
|
||||
.to receive(:new).with([1]) { reset_stock_strategy }
|
||||
end
|
||||
|
||||
it 'delegates to ResetAbsent passing the appropriate reset_stock_strategy' do
|
||||
entry_processor.reset_absent_items
|
||||
|
||||
expect(ProductImport::ResetAbsent)
|
||||
.to have_received(:new)
|
||||
.with(entry_processor, settings, reset_stock_strategy)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#products_reset_count' do
|
||||
let(:settings) do
|
||||
instance_double(
|
||||
ProductImport::Settings,
|
||||
data_for_stock_reset?: true,
|
||||
reset_all_absent?: true,
|
||||
importing_into_inventory?: false,
|
||||
updated_ids: [1]
|
||||
)
|
||||
end
|
||||
|
||||
context 'when reset_absent_items was executed' do
|
||||
let(:reset_absent) do
|
||||
instance_double(ProductImport::ResetAbsent, call: 2)
|
||||
end
|
||||
|
||||
before do
|
||||
allow(ProductImport::Settings).to receive(:new) { settings }
|
||||
allow(ProductImport::ResetAbsent).to receive(:new) { reset_absent }
|
||||
end
|
||||
|
||||
it 'returns the number of items affected by the last reset' do
|
||||
entry_processor.reset_absent_items
|
||||
expect(entry_processor.products_reset_count).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ResetAbsent was not called' do
|
||||
it 'returns 0' do
|
||||
expect(entry_processor.products_reset_count).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
148
spec/models/product_import/inventory_reset_strategy_spec.rb
Normal file
148
spec/models/product_import/inventory_reset_strategy_spec.rb
Normal file
@@ -0,0 +1,148 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe ProductImport::InventoryResetStrategy do
|
||||
let(:inventory_reset) { described_class.new(excluded_items_ids) }
|
||||
|
||||
describe '#reset' do
|
||||
let(:supplier_ids) { enterprise.id }
|
||||
let(:enterprise) { variant.product.supplier }
|
||||
let(:variant) { create(:variant) }
|
||||
|
||||
let!(:variant_override) do
|
||||
create(
|
||||
:variant_override,
|
||||
count_on_hand: 10,
|
||||
hub: enterprise,
|
||||
variant: variant
|
||||
)
|
||||
end
|
||||
|
||||
context 'when there are excluded_items_ids' do
|
||||
let(:excluded_items_ids) { [variant_override.id] }
|
||||
|
||||
context 'and supplier_ids is []' do
|
||||
let(:supplier_ids) { [] }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
inventory_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is nil' do
|
||||
let(:supplier_ids) { nil }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
inventory_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is set' do
|
||||
it 'does not update the count_on_hand of the excluded items' do
|
||||
inventory_reset.reset(supplier_ids)
|
||||
expect(variant_override.reload.count_on_hand).to eq(10)
|
||||
end
|
||||
|
||||
it 'updates the count_on_hand of the non-excluded items' do
|
||||
non_excluded_variant_override = create(
|
||||
:variant_override,
|
||||
count_on_hand: 3,
|
||||
hub: enterprise,
|
||||
variant: variant
|
||||
)
|
||||
inventory_reset.reset(supplier_ids)
|
||||
expect(non_excluded_variant_override.reload.count_on_hand).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no excluded_items_ids' do
|
||||
let(:excluded_items_ids) { [] }
|
||||
|
||||
context 'and supplier_ids is []' do
|
||||
let(:supplier_ids) { [] }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
inventory_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is nil' do
|
||||
let(:supplier_ids) { nil }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
inventory_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is set' do
|
||||
it 'sets all count_on_hand to 0' do
|
||||
inventory_reset.reset(supplier_ids)
|
||||
expect(variant_override.reload.count_on_hand).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when excluded_items_ids is nil' do
|
||||
let(:excluded_items_ids) { nil }
|
||||
|
||||
context 'and supplier_ids is []' do
|
||||
let(:supplier_ids) { [] }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
inventory_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is nil' do
|
||||
let(:supplier_ids) { nil }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
inventory_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is set' do
|
||||
it 'sets all count_on_hand to 0' do
|
||||
inventory_reset.reset(supplier_ids)
|
||||
expect(variant_override.reload.count_on_hand).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
138
spec/models/product_import/products_reset_strategy_spec.rb
Normal file
138
spec/models/product_import/products_reset_strategy_spec.rb
Normal file
@@ -0,0 +1,138 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe ProductImport::ProductsResetStrategy do
|
||||
let(:products_reset) { described_class.new(excluded_items_ids) }
|
||||
|
||||
describe '#reset' do
|
||||
let(:supplier_ids) { enterprise.id }
|
||||
let(:enterprise) { variant.product.supplier }
|
||||
let(:variant) { create(:variant, count_on_hand: 2) }
|
||||
|
||||
context 'when there are excluded_items_ids' do
|
||||
let(:excluded_items_ids) { [variant.id] }
|
||||
|
||||
context 'and supplier_ids is []' do
|
||||
let(:supplier_ids) { [] }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
products_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is nil' do
|
||||
let(:supplier_ids) { nil }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
products_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is set' do
|
||||
it 'does not update the count_on_hand of the excluded items' do
|
||||
products_reset.reset(supplier_ids)
|
||||
expect(variant.reload.count_on_hand).to eq(2)
|
||||
end
|
||||
|
||||
it 'updates the count_on_hand of the non-excluded items' do
|
||||
non_excluded_variant = create(
|
||||
:variant,
|
||||
count_on_hand: 3,
|
||||
product: variant.product
|
||||
)
|
||||
products_reset.reset(supplier_ids)
|
||||
expect(non_excluded_variant.reload.count_on_hand).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no excluded_items_ids' do
|
||||
let(:excluded_items_ids) { [] }
|
||||
|
||||
context 'and supplier_ids is []' do
|
||||
let(:supplier_ids) { [] }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
products_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is nil' do
|
||||
let(:supplier_ids) { nil }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
products_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is nil' do
|
||||
it 'sets all count_on_hand to 0' do
|
||||
products_reset.reset(supplier_ids)
|
||||
expect(variant.reload.count_on_hand).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when excluded_items_ids is nil' do
|
||||
let(:excluded_items_ids) { nil }
|
||||
|
||||
context 'and supplier_ids is []' do
|
||||
let(:supplier_ids) { [] }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
products_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is nil' do
|
||||
let(:supplier_ids) { nil }
|
||||
let(:relation) do
|
||||
instance_double(ActiveRecord::Relation, update_all: true)
|
||||
end
|
||||
|
||||
before { allow(VariantOverride).to receive(:where) { relation } }
|
||||
|
||||
it 'does not update any DB record' do
|
||||
products_reset.reset(supplier_ids)
|
||||
expect(relation).not_to have_received(:update_all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and supplier_ids is nil' do
|
||||
it 'sets all count_on_hand to 0' do
|
||||
products_reset.reset(supplier_ids)
|
||||
expect(variant.reload.count_on_hand).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
90
spec/models/product_import/reset_absent_spec.rb
Normal file
90
spec/models/product_import/reset_absent_spec.rb
Normal file
@@ -0,0 +1,90 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module ProductImport
|
||||
describe ResetAbsent do
|
||||
let(:entry_processor) { instance_double(EntryProcessor) }
|
||||
|
||||
let(:reset_absent) do
|
||||
described_class.new(entry_processor, settings, reset_stock_strategy)
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
context 'when there are no enterprises_to_reset' do
|
||||
let(:settings) { instance_double(Settings, enterprises_to_reset: []) }
|
||||
let(:reset_stock_strategy) { instance_double(InventoryResetStrategy) }
|
||||
|
||||
before do
|
||||
allow(reset_stock_strategy).to receive(:reset).with([]) { 0 }
|
||||
end
|
||||
|
||||
it 'returns 0' do
|
||||
expect(reset_absent.call).to eq(0)
|
||||
end
|
||||
|
||||
it 'calls the strategy' do
|
||||
reset_absent.call
|
||||
expect(reset_stock_strategy).to have_received(:reset)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are enterprises_to_reset' do
|
||||
let(:enterprise) { instance_double(Enterprise, id: 1) }
|
||||
|
||||
let(:settings) do
|
||||
instance_double(
|
||||
Settings,
|
||||
enterprises_to_reset: [enterprise.id.to_s]
|
||||
)
|
||||
end
|
||||
|
||||
let(:reset_stock_strategy) { instance_double(ProductsResetStrategy) }
|
||||
|
||||
before do
|
||||
allow(entry_processor)
|
||||
.to receive(:permission_by_id?).with(enterprise.id.to_s) { true }
|
||||
|
||||
allow(reset_stock_strategy)
|
||||
.to receive(:reset).with([enterprise.id]) { 2 }
|
||||
end
|
||||
|
||||
it 'returns the number of products reset' do
|
||||
expect(reset_absent.call).to eq(2)
|
||||
end
|
||||
|
||||
it 'resets the products of the specified suppliers' do
|
||||
reset_absent.call
|
||||
expect(reset_stock_strategy).to have_received(:reset)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the enterprise has no permission' do
|
||||
let(:enterprise) { instance_double(Enterprise, id: 1) }
|
||||
|
||||
let(:settings) do
|
||||
instance_double(
|
||||
Settings,
|
||||
enterprises_to_reset: [enterprise.id.to_s]
|
||||
)
|
||||
end
|
||||
|
||||
let(:reset_stock_strategy) { instance_double(InventoryResetStrategy) }
|
||||
|
||||
before do
|
||||
allow(entry_processor)
|
||||
.to receive(:permission_by_id?).with(enterprise.id.to_s) { false }
|
||||
|
||||
allow(reset_stock_strategy).to receive(:reset).with([nil]) { 0 }
|
||||
end
|
||||
|
||||
it 'calls the strategy' do
|
||||
reset_absent.call
|
||||
expect(reset_stock_strategy).to have_received(:reset)
|
||||
end
|
||||
|
||||
it 'returns 0' do
|
||||
expect(reset_absent.call).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
230
spec/models/product_import/settings_spec.rb
Normal file
230
spec/models/product_import/settings_spec.rb
Normal file
@@ -0,0 +1,230 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe ProductImport::Settings do
|
||||
let(:settings) { described_class.new(import_settings) }
|
||||
|
||||
describe '#defaults' do
|
||||
let(:entry) { instance_double(ProductImport::SpreadsheetEntry) }
|
||||
let(:import_settings) { {} }
|
||||
|
||||
context 'when there are no settings' do
|
||||
it 'returns false' do
|
||||
expect(settings.defaults(entry)).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are settings' do
|
||||
let(:entry) do
|
||||
instance_double(ProductImport::SpreadsheetEntry, supplier_id: 1)
|
||||
end
|
||||
let(:import_settings) { { settings: {} } }
|
||||
|
||||
context 'and there is no data for the specified entry' do
|
||||
it 'returns a falsey' do
|
||||
expect(settings.defaults(entry)).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'and there is data for the specified entry' do
|
||||
context 'and it has no defaults' do
|
||||
let(:import_settings) do
|
||||
{ settings: { '1' => { 'foo' => 'bar' } } }
|
||||
end
|
||||
|
||||
it 'returns a falsey' do
|
||||
expect(settings.defaults(entry)).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'and it has defaults' do
|
||||
let(:import_settings) do
|
||||
{ settings: { '1' => { 'defaults' => 'default value' } } }
|
||||
end
|
||||
|
||||
it 'returns a truthy' do
|
||||
expect(settings.defaults(entry)).to eq('default value')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#settings' do
|
||||
context 'when settings are specified' do
|
||||
let(:import_settings) { { settings: { foo: 'bar' } } }
|
||||
|
||||
it 'returns them' do
|
||||
expect(settings.settings).to eq(foo: 'bar')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when settings are not specified' do
|
||||
let(:import_settings) { {} }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(settings.settings).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#updated_ids' do
|
||||
context 'when updated_ids are specified' do
|
||||
let(:import_settings) { { updated_ids: [2] } }
|
||||
|
||||
it 'returns them' do
|
||||
expect(settings.updated_ids).to eq([2])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when updated_ids are not specified' do
|
||||
let(:import_settings) { {} }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(settings.updated_ids).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#enterprises_to_reset' do
|
||||
context 'when enterprises_to_reset are specified' do
|
||||
let(:import_settings) { { enterprises_to_reset: [2] } }
|
||||
|
||||
it 'returns them' do
|
||||
expect(settings.enterprises_to_reset).to eq([2])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when enterprises_to_reset are not specified' do
|
||||
let(:import_settings) { {} }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(settings.enterprises_to_reset).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#importing_into_inventory?' do
|
||||
context 'when :settings is specified' do
|
||||
context 'and import_into is not specified' do
|
||||
let(:import_settings) { { settings: {} } }
|
||||
|
||||
it 'returns false' do
|
||||
expect(settings.importing_into_inventory?).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and import_into is equal to inventories' do
|
||||
let(:import_settings) do
|
||||
{ settings: { 'import_into' => 'inventories' } }
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
expect(settings.importing_into_inventory?).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and import_into is not equal to inventories' do
|
||||
let(:import_settings) do
|
||||
{ settings: { 'import_into' => 'other' } }
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
expect(settings.importing_into_inventory?).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when :settings is not specified' do
|
||||
let(:import_settings) { {} }
|
||||
|
||||
it 'returns falsy' do
|
||||
expect(settings.importing_into_inventory?).to be_falsy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reset_all_absent?' do
|
||||
context 'when :settings is not specified' do
|
||||
let(:import_settings) { {} }
|
||||
|
||||
it 'raises' do
|
||||
expect { settings.reset_all_absent? }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when reset_all_absent is not set' do
|
||||
let(:import_settings) do
|
||||
{ settings: {} }
|
||||
end
|
||||
|
||||
it 'returns nil' do
|
||||
expect(settings.reset_all_absent?).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when reset_all_absent is set' do
|
||||
let(:import_settings) do
|
||||
{ settings: { 'reset_all_absent' => true } }
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
expect(settings.reset_all_absent?).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#data_for_stock_reset?' do
|
||||
context 'when there are no settings' do
|
||||
let(:import_settings) do
|
||||
{
|
||||
updated_ids: [],
|
||||
enterprises_to_reset: []
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
expect(settings.data_for_stock_reset?).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no updated_ids' do
|
||||
let(:import_settings) do
|
||||
{
|
||||
settings: [],
|
||||
enterprises_to_reset: []
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
expect(settings.data_for_stock_reset?).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no enterprises_to_reset' do
|
||||
let(:import_settings) do
|
||||
{
|
||||
settings: [],
|
||||
updated_ids: []
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
expect(settings.data_for_stock_reset?).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are settings, updated_ids and enterprises_to_reset' do
|
||||
let(:import_settings) do
|
||||
{
|
||||
settings: { 'something' => true },
|
||||
updated_ids: [0],
|
||||
enterprises_to_reset: [0]
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
expect(settings.data_for_stock_reset?).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user