diff --git a/app/models/product_import/entry_validator.rb b/app/models/product_import/entry_validator.rb index 915e78b6f6..8eb545e170 100644 --- a/app/models/product_import/entry_validator.rb +++ b/app/models/product_import/entry_validator.rb @@ -4,7 +4,8 @@ module ProductImport class EntryValidator - def initialize(current_user, import_time, spreadsheet_data, editable_enterprises, inventory_permissions, reset_counts, import_settings) + def initialize(current_user, import_time, spreadsheet_data, editable_enterprises, + inventory_permissions, reset_counts, import_settings, all_entries) @current_user = current_user @import_time = import_time @spreadsheet_data = spreadsheet_data @@ -12,6 +13,7 @@ module ProductImport @inventory_permissions = inventory_permissions @reset_counts = reset_counts @import_settings = import_settings + @all_entries = all_entries end def self.non_updatable_fields @@ -30,6 +32,7 @@ module ProductImport assign_enterprise_field(entry) enterprise_validation(entry) unit_fields_validation(entry) + variant_of_product_validation(entry) next if entry.enterprise_id.blank? @@ -158,6 +161,17 @@ module ProductImport mark_as_invalid(entry, attribute: 'variant_unit_name', error: I18n.t('admin.product_import.model.conditional_blank')) unless entry.variant_unit_name && entry.variant_unit_name.present? end + def variant_of_product_validation(entry) + return if entry.producer.blank? || entry.name.blank? + + reference_entry = all_entries_for_product(entry).first + if entry.unit_type.present? && entry.unit_type.to_s != reference_entry.unit_type.to_s + mark_as_not_updatable(entry, "unit_type") + elsif entry.variant_unit_name.present? && entry.variant_unit_name.to_s != reference_entry.variant_unit_name.to_s + mark_as_not_updatable(entry, "variant_unit_name") + end + end + def producer_validation(entry) producer_name = entry.producer @@ -332,6 +346,11 @@ module ProductImport entry.product_validations = options[:product_validations] if options[:product_validations] end + def mark_as_not_updatable(entry, attribute) + mark_as_invalid(entry, attribute: attribute, + error: I18n.t("admin.product_import.model.not_updatable")) + end + def import_into_inventory? @import_settings[:settings].andand['import_into'] == 'inventories' end @@ -386,5 +405,19 @@ module ProductImport object.on_demand = object.count_on_hand.blank? if entry.on_demand.blank? entry.on_hand_nil = object.count_on_hand.blank? end + + def all_entries_for_product(entry) + all_entries_by_product[entries_by_product_key(entry)] + end + + def all_entries_by_product + @all_entries_by_product ||= @all_entries.group_by do |entry| + entries_by_product_key(entry) + end + end + + def entries_by_product_key(entry) + [entry.producer.to_s, entry.name.to_s] + end end end diff --git a/app/models/product_import/product_importer.rb b/app/models/product_import/product_importer.rb index 11ca0bd382..fec8292298 100644 --- a/app/models/product_import/product_importer.rb +++ b/app/models/product_import/product_importer.rb @@ -182,7 +182,7 @@ module ProductImport @spreadsheet_data = SpreadsheetData.new(@entries, @import_settings) @validator = EntryValidator.new(@current_user, @import_time, @spreadsheet_data, @editable_enterprises, @inventory_permissions, @reset_counts, - @import_settings) + @import_settings, build_all_entries) @processor = EntryProcessor.new(self, @validator, @import_settings, @spreadsheet_data, @editable_enterprises, @import_time, @updated_ids) @@ -251,6 +251,10 @@ module ProductImport @entries = build_entries_from_rows(rows) end + def build_all_entries + build_entries_from_rows(rows) + end + def save_all_valid @processor.save_all(@entries) @processor.reset_absent_items unless staged_import? diff --git a/spec/features/admin/product_import_spec.rb b/spec/features/admin/product_import_spec.rb index 7277a6ac47..bc6a5a94d5 100644 --- a/spec/features/admin/product_import_spec.rb +++ b/spec/features/admin/product_import_spec.rb @@ -79,8 +79,10 @@ feature "Product Import", js: true do it "displays info about invalid entries but no save button if all items are invalid" do csv_data = CSV.generate do |csv| - csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type"] - csv << ["Bad Carrots", "Unkown Enterprise", "Mouldy vegetables", "666", "3.20", "", "g"] + csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "shipping_category_id"] + csv << ["Carrots", "User Enterprise", "Vegetables", "5", "3.20", "500", "g", shipping_category_id_str] + csv << ["Carrots", "User Enterprise", "Vegetables", "5", "5.50", "1", "kg", shipping_category_id_str] + csv << ["Bad Carrots", "Unkown Enterprise", "Mouldy vegetables", "666", "3.20", "", "g", shipping_category_id_str] csv << ["Bad Potatoes", "", "Vegetables", "6", "6", "6", ""] end File.write('/tmp/test.csv', csv_data) @@ -93,9 +95,9 @@ feature "Product Import", js: true do proceed_to_validation - expect(page).to have_selector '.item-count', text: "2" - expect(page).to have_selector '.invalid-count', text: "2" - expect(page).to have_no_selector '.create-count' + expect(page).to have_selector '.item-count', text: "4" + expect(page).to have_selector '.invalid-count', text: "3" + expect(page).to have_selector ".create-count", text: "1" expect(page).to have_no_selector '.update-count' expect(page).to have_no_selector 'input[type=submit][value="Save"]' @@ -206,7 +208,7 @@ feature "Product Import", js: true do csv_data = CSV.generate do |csv| csv << ["name", "producer", "category", "on_hand", "price", "units", "unit_type", "display_name", "shipping_category_id"] csv << ["Potatoes", "User Enterprise", "Vegetables", "5", "3.50", "500", "g", "Small Bag", shipping_category_id_str] - csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "5.50", "2", "kg", "Big Bag", shipping_category_id_str] + csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "5.50", "2000", "g", "Big Bag", shipping_category_id_str] csv << ["Beans", "User Enterprise", "Vegetables", "7", "2.50", "250", "g", nil, shipping_category_id_str] end File.write('/tmp/test.csv', csv_data) diff --git a/spec/models/product_importer_spec.rb b/spec/models/product_importer_spec.rb index 6a3a93a19e..2bcb118e97 100644 --- a/spec/models/product_importer_spec.rb +++ b/spec/models/product_importer_spec.rb @@ -254,6 +254,8 @@ describe ProductImport::ProductImporter do csv << ["Potatoes", "User Enterprise", "Vegetables", "5", "3.50", "500", "g", "Small Bag", shipping_category.name] csv << ["Chives", "User Enterprise", "Vegetables", "6", "4.50", "500", "g", "Small Bag", shipping_category.name] csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "5.50", "2", "kg", "Big Bag", shipping_category.name] + csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "22.00", "10000", "g", "Small Sack", shipping_category.name] + csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "60.00", "30000", "", "Big Sack", shipping_category.name] end @importer = import_data csv_data end @@ -263,7 +265,7 @@ describe ProductImport::ProductImporter do entries = JSON.parse(@importer.entries_json) expect(filter('valid', entries)).to eq 3 - expect(filter('invalid', entries)).to eq 0 + expect(filter('invalid', entries)).to eq 2 expect(filter('create_product', entries)).to eq 3 end @@ -279,12 +281,17 @@ describe ProductImport::ProductImporter do expect(small_bag.price).to eq 3.50 expect(small_bag.on_hand).to eq 5 - big_bag = Spree::Variant.find_by_display_name('Big Bag') - expect(big_bag.product.name).to eq 'Potatoes' - expect(big_bag.price).to eq 5.50 - expect(big_bag.on_hand).to eq 6 + big_bag = Spree::Variant.find_by_display_name("Big Bag") + expect(big_bag).to be_blank - expect(big_bag.product.id).to eq small_bag.product.id + small_sack = Spree::Variant.find_by_display_name("Small Sack") + expect(small_sack.product.name).to eq "Potatoes" + expect(small_sack.price).to eq 22.00 + expect(small_sack.on_hand).to eq 6 + expect(small_sack.product.id).to eq small_bag.product.id + + big_sack = Spree::Variant.find_by_display_name("Big Sack") + expect(big_sack).to be_blank end end