diff --git a/app/models/product_import/entry_validator.rb b/app/models/product_import/entry_validator.rb index 11c0aab7dd..7582330a0a 100644 --- a/app/models/product_import/entry_validator.rb +++ b/app/models/product_import/entry_validator.rb @@ -189,7 +189,7 @@ module ProductImport products.flat_map(&:variants).each do |existing_variant| unit_scale = existing_variant.product.variant_unit_scale unscaled_units = entry.unscaled_units || 0 - entry.unit_value = unscaled_units * unit_scale + entry.unit_value = unscaled_units * unit_scale unless unit_scale.nil? if entry_matches_existing_variant?(entry, existing_variant) variant_override = create_inventory_item(entry, existing_variant) diff --git a/public/inventory_template.csv b/public/inventory_template.csv index d52cecded6..dc2f10e3be 100644 --- a/public/inventory_template.csv +++ b/public/inventory_template.csv @@ -1 +1 @@ -producer,distributor,name,display_name,units,unit_type,price,on_hand +producer,distributor,name,display_name,variant_unit_name,sku,units,unit_type,price,on_hand,on_demand diff --git a/spec/features/admin/product_import_spec.rb b/spec/features/admin/product_import_spec.rb index a903a1b9e4..3cff57b16d 100644 --- a/spec/features/admin/product_import_spec.rb +++ b/spec/features/admin/product_import_spec.rb @@ -292,6 +292,49 @@ feature "Product Import", js: true do expect(page).to have_content 'Cabbage' end end + + it "handles on_demand and on_hand validations with inventory" do + csv_data = CSV.generate do |csv| + csv << ["name", "distributor", "producer", "category", "on_hand", "price", "units", "on_demand"] + csv << ["Beans", "Another Enterprise", "User Enterprise", "Vegetables", nil, "3.20", "500", "true"] + csv << ["Sprouts", "Another Enterprise", "User Enterprise", "Vegetables", "6", "6.50", "500", "false"] + csv << ["Cabbage", "Another Enterprise", "User Enterprise", "Vegetables", nil, "1.50", "500", nil] + end + File.write('/tmp/test.csv', csv_data) + + visit main_app.admin_product_import_path + select2_select I18n.t('admin.product_import.index.inventories'), from: "settings_import_into" + attach_file 'file', '/tmp/test.csv' + click_button 'Upload' + + import_data + + expect(page).to have_selector '.item-count', text: "3" + expect(page).to have_no_selector '.invalid-count' + expect(page).to have_selector '.inv-create-count', text: '2' + expect(page).to have_selector '.inv-update-count', text: '1' + + save_data + + expect(page).to have_selector '.inv-created-count', text: '2' + expect(page).to have_selector '.inv-updated-count', text: '1' + + beans_override = VariantOverride.where(variant_id: product2.variants.first.id, hub_id: enterprise2.id).first + sprouts_override = VariantOverride.where(variant_id: product3.variants.first.id, hub_id: enterprise2.id).first + cabbage_override = VariantOverride.where(variant_id: product4.variants.first.id, hub_id: enterprise2.id).first + + expect(Float(beans_override.price)).to eq 3.20 + expect(beans_override.count_on_hand).to be_nil + expect(beans_override.on_demand).to be_truthy + + expect(Float(sprouts_override.price)).to eq 6.50 + expect(sprouts_override.count_on_hand).to eq 6 + expect(sprouts_override.on_demand).to eq false + + expect(Float(cabbage_override.price)).to eq 1.50 + expect(cabbage_override.count_on_hand).to be_nil + expect(cabbage_override.on_demand).to be_nil + end end describe "when dealing with uploaded files" do diff --git a/spec/models/product_importer_spec.rb b/spec/models/product_importer_spec.rb index f05816e538..7a259f53fe 100644 --- a/spec/models/product_importer_spec.rb +++ b/spec/models/product_importer_spec.rb @@ -26,7 +26,7 @@ describe ProductImport::ProductImporter do let!(:variant) { create(:variant, product_id: product.id, price: '8.50', on_hand: '100', unit_value: '500', display_name: 'Preexisting Banana') } let!(:product2) { create(:simple_product, supplier: enterprise, on_hand: '100', name: 'Beans', unit_value: '500', primary_taxon_id: category.id, description: nil) } let!(:product3) { create(:simple_product, supplier: enterprise, on_hand: '100', name: 'Sprouts', unit_value: '500', primary_taxon_id: category.id) } - let!(:product4) { create(:simple_product, supplier: enterprise, on_hand: '100', name: 'Cabbage', unit_value: '500', primary_taxon_id: category.id) } + let!(:product4) { create(:simple_product, supplier: enterprise, on_hand: '100', name: 'Cabbage', unit_value: '1', variant_unit_scale: nil, variant_unit: "items", variant_unit_name: "Whole", primary_taxon_id: category.id) } let!(:product5) { create(:simple_product, supplier: enterprise2, on_hand: '100', name: 'Lettuce', unit_value: '500', primary_taxon_id: category.id) } let!(:product6) { create(:simple_product, supplier: enterprise3, on_hand: '100', name: 'Beetroot', unit_value: '500', on_demand: true, variant_unit_scale: 1, variant_unit: 'weight', primary_taxon_id: category.id, description: nil) } let!(:product7) { create(:simple_product, supplier: enterprise3, on_hand: '100', name: 'Tomato', unit_value: '500', variant_unit_scale: 1, variant_unit: 'weight', primary_taxon_id: category.id, description: nil) } @@ -465,50 +465,106 @@ describe ProductImport::ProductImporter do end describe "importing items into inventory" do - before do - csv_data = CSV.generate do |csv| - csv << ["name", "distributor", "producer", "on_hand", "price", "units", "unit_type"] - csv << ["Beans", "Another Enterprise", "User Enterprise", "5", "3.20", "500", "g"] - csv << ["Sprouts", "Another Enterprise", "User Enterprise", "6", "6.50", "500", "g"] - csv << ["Cabbage", "Another Enterprise", "User Enterprise", "2001", "1.50", "500", "g"] + describe "creating and updating inventory" do + before do + csv_data = CSV.generate do |csv| + csv << ["name", "distributor", "producer", "on_hand", "price", "units", "unit_type", "variant_unit_name"] + csv << ["Beans", "Another Enterprise", "User Enterprise", "5", "3.20", "500", "g", ""] + csv << ["Sprouts", "Another Enterprise", "User Enterprise", "6", "6.50", "500", "g", ""] + csv << ["Cabbage", "Another Enterprise", "User Enterprise", "2001", "1.50", "1", "", "Whole"] + end + File.write('/tmp/test-m.csv', csv_data) + file = File.new('/tmp/test-m.csv') + settings = {'import_into' => 'inventories'} + @importer = ProductImport::ProductImporter.new(file, admin, start: 1, end: 100, settings: settings) end - File.write('/tmp/test-m.csv', csv_data) - file = File.new('/tmp/test-m.csv') - settings = {'import_into' => 'inventories'} - @importer = ProductImport::ProductImporter.new(file, admin, start: 1, end: 100, settings: settings) - end - after { File.delete('/tmp/test-m.csv') } + after { File.delete('/tmp/test-m.csv') } - it "validates entries" do - @importer.validate_entries - entries = JSON.parse(@importer.entries_json) + it "validates entries" do + @importer.validate_entries + entries = JSON.parse(@importer.entries_json) - expect(filter('valid', entries)).to eq 3 - expect(filter('invalid', entries)).to eq 0 - expect(filter('create_inventory', entries)).to eq 2 - expect(filter('update_inventory', entries)).to eq 1 + expect(filter('valid', entries)).to eq 3 + expect(filter('invalid', entries)).to eq 0 + expect(filter('create_inventory', entries)).to eq 2 + expect(filter('update_inventory', entries)).to eq 1 + end + + it "saves and updates inventory" do + @importer.save_entries + + expect(@importer.inventory_created_count).to eq 2 + expect(@importer.inventory_updated_count).to eq 1 + expect(@importer.updated_ids).to be_a(Array) + expect(@importer.updated_ids.count).to eq 3 + + beans_override = VariantOverride.where(variant_id: product2.variants.first.id, hub_id: enterprise2.id).first + sprouts_override = VariantOverride.where(variant_id: product3.variants.first.id, hub_id: enterprise2.id).first + cabbage_override = VariantOverride.where(variant_id: product4.variants.first.id, hub_id: enterprise2.id).first + + expect(Float(beans_override.price)).to eq 3.20 + expect(beans_override.count_on_hand).to eq 5 + + expect(Float(sprouts_override.price)).to eq 6.50 + expect(sprouts_override.count_on_hand).to eq 6 + + expect(Float(cabbage_override.price)).to eq 1.50 + expect(cabbage_override.count_on_hand).to eq 2001 + end end - it "saves and updates inventory" do - @importer.save_entries + describe "updating existing inventory referenced by display_name" do + before do + csv_data = CSV.generate do |csv| + csv << ["name", "display_name", "distributor", "producer", "on_hand", "price", "units"] + csv << ["Oats", "Porridge Oats", "Another Enterprise", "User Enterprise", "900", "", "500"] + end + File.write('/tmp/test-m.csv', csv_data) + file = File.new('/tmp/test-m.csv') + settings = {'import_into' => 'inventories'} + @importer = ProductImport::ProductImporter.new(file, admin, start: 1, end: 100, settings: settings) + end + after { File.delete('/tmp/test-m.csv') } - expect(@importer.inventory_created_count).to eq 2 - expect(@importer.inventory_updated_count).to eq 1 - expect(@importer.updated_ids).to be_a(Array) - expect(@importer.updated_ids.count).to eq 3 + it "updates inventory item correctly" do + @importer.save_entries - beans_override = VariantOverride.where(variant_id: product2.variants.first.id, hub_id: enterprise2.id).first - sprouts_override = VariantOverride.where(variant_id: product3.variants.first.id, hub_id: enterprise2.id).first - cabbage_override = VariantOverride.where(variant_id: product4.variants.first.id, hub_id: enterprise2.id).first + expect(@importer.inventory_created_count).to eq 1 - expect(Float(beans_override.price)).to eq 3.20 - expect(beans_override.count_on_hand).to eq 5 + override = VariantOverride.where(variant_id: variant2.id, hub_id: enterprise2.id).first + visible = InventoryItem.where(variant_id: variant2.id, enterprise_id: enterprise2.id).first.visible - expect(Float(sprouts_override.price)).to eq 6.50 - expect(sprouts_override.count_on_hand).to eq 6 + expect(override.count_on_hand).to eq 900 + expect(visible).to be_truthy + end + end - expect(Float(cabbage_override.price)).to eq 1.50 - expect(cabbage_override.count_on_hand).to eq 2001 + describe "updating existing item that was set to hidden in inventory" do + before do + InventoryItem.create(variant_id: product4.variants.first.id, enterprise_id: enterprise2.id, visible: false) + + csv_data = CSV.generate do |csv| + csv << ["name", "distributor", "producer", "on_hand", "price", "units", "variant_unit_name"] + csv << ["Cabbage", "Another Enterprise", "User Enterprise", "900", "", "1", "Whole"] + end + File.write('/tmp/test-m.csv', csv_data) + file = File.new('/tmp/test-m.csv') + settings = {'import_into' => 'inventories'} + @importer = ProductImport::ProductImporter.new(file, admin, start: 1, end: 100, settings: settings) + end + after { File.delete('/tmp/test-m.csv') } + + it "sets the item to visible in inventory when the item is updated" do + @importer.save_entries + + expect(@importer.inventory_updated_count).to eq 1 + + override = VariantOverride.where(variant_id: product4.variants.first.id, hub_id: enterprise2.id).first + visible = InventoryItem.where(variant_id: product4.variants.first.id, enterprise_id: enterprise2.id).first.visible + + expect(override.count_on_hand).to eq 900 + expect(visible).to be_truthy + end end end