mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Require product import rows to match unit of preceding rows
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user