Require product import rows to match unit of preceding rows

This commit is contained in:
Kristina Lim
2019-06-07 16:27:50 +08:00
parent 5d282f7e9f
commit 70614de955
4 changed files with 60 additions and 14 deletions

View File

@@ -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

View File

@@ -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?

View File

@@ -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)

View File

@@ -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