mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Updating price, on_hand, on_demand validations for product import
This commit is contained in:
@@ -39,6 +39,8 @@ module ProductImport
|
||||
enterprise_validation(entry)
|
||||
unit_fields_validation(entry)
|
||||
variant_of_product_validation(entry)
|
||||
price_validation(entry)
|
||||
on_hand_on_demand_validation(entry)
|
||||
|
||||
next if entry.enterprise_id.blank?
|
||||
|
||||
@@ -170,6 +172,11 @@ module ProductImport
|
||||
error: I18n.t('admin.product_import.model.blank'))
|
||||
end
|
||||
|
||||
unless is_numeric(entry.units) && entry.units.to_i > 0
|
||||
mark_as_invalid(entry, attribute: 'units',
|
||||
error: I18n.t('admin.product_import.model.incorrect_value'))
|
||||
end
|
||||
|
||||
return if import_into_inventory?
|
||||
|
||||
# unit_type must be valid type
|
||||
@@ -189,6 +196,43 @@ module ProductImport
|
||||
error: I18n.t('admin.product_import.model.conditional_blank'))
|
||||
end
|
||||
|
||||
def is_numeric(value)
|
||||
return true unless Float(value, exception: false).nil?
|
||||
end
|
||||
|
||||
def price_validation(entry)
|
||||
return if is_numeric(entry.price)
|
||||
|
||||
if empty_or_placeholder_value(entry.price)
|
||||
mark_as_invalid(entry, attribute: 'price',
|
||||
error: I18n.t('admin.product_import.model.blank'))
|
||||
else
|
||||
mark_as_invalid(entry, attribute: 'price',
|
||||
error: I18n.t('admin.product_import.model.incorrect_value'))
|
||||
end
|
||||
end
|
||||
|
||||
def on_hand_on_demand_validation(entry)
|
||||
on_hand_present_numeric = !empty_or_placeholder_value(entry.on_hand) &&
|
||||
is_numeric(entry.on_hand)
|
||||
on_hand_value = entry.on_hand&.to_i
|
||||
on_demand_present_numeric = !empty_or_placeholder_value(entry.on_demand) &&
|
||||
is_numeric(entry.on_demand)
|
||||
on_demand_value = entry.on_demand&.to_i
|
||||
|
||||
return if (on_hand_present_numeric && on_hand_value >= 0) ||
|
||||
(on_demand_present_numeric && on_demand_value == 1)
|
||||
|
||||
mark_as_invalid(entry, attribute: 'on_hand',
|
||||
error: I18n.t('admin.product_import.model.incorrect_value'))
|
||||
mark_as_invalid(entry, attribute: 'on_demand',
|
||||
error: I18n.t('admin.product_import.model.incorrect_value'))
|
||||
end
|
||||
|
||||
def empty_or_placeholder_value(value)
|
||||
!value&.present? || value.nil? || value.to_s.strip == '' || value.to_s.strip == "-"
|
||||
end
|
||||
|
||||
def variant_of_product_validation(entry)
|
||||
return if entry.producer.blank? || entry.name.blank?
|
||||
|
||||
@@ -287,8 +331,7 @@ module ProductImport
|
||||
entry.primary_taxon_id = @spreadsheet_data.categories_index[category_name]
|
||||
else
|
||||
mark_as_invalid(entry, attribute: "category",
|
||||
error: I18n.t(:error_not_found_in_database,
|
||||
name: category_name))
|
||||
error: I18n.t('admin.product_import.model.category_not_found'))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -37,7 +37,9 @@ describe ProductImport::EntryValidator do
|
||||
enterprise_id: enterprise.id,
|
||||
producer: enterprise,
|
||||
producer_id: enterprise.id,
|
||||
distributor: enterprise
|
||||
distributor: enterprise,
|
||||
price: "1.0",
|
||||
on_hand: "1"
|
||||
)
|
||||
end
|
||||
|
||||
@@ -51,7 +53,9 @@ describe ProductImport::EntryValidator do
|
||||
enterprise_id: enterprise.id,
|
||||
producer: enterprise,
|
||||
producer_id: enterprise.id,
|
||||
distributor: enterprise
|
||||
distributor: enterprise,
|
||||
price: "1.0",
|
||||
on_hand: "1"
|
||||
)
|
||||
end
|
||||
|
||||
@@ -99,7 +103,7 @@ describe ProductImport::EntryValidator do
|
||||
it "validates a product" do
|
||||
entries = [potato_variant]
|
||||
entry_validator.validate_all(entries)
|
||||
expect(potato_variant.errors.count).to eq 1
|
||||
expect(potato_variant.errors.count).to eq 4
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -651,7 +651,7 @@ describe ProductImport::ProductImporter do
|
||||
let(:csv_data) {
|
||||
CSV.generate do |csv|
|
||||
csv << ["name", "display_name", "distributor", "producer", "on_hand", "price", "units"]
|
||||
csv << ["Oats", "Porridge Oats", enterprise2.name, enterprise.name, "900", "", "500"]
|
||||
csv << ["Oats", "Porridge Oats", enterprise2.name, enterprise.name, "900", "1.0", "500"]
|
||||
end
|
||||
}
|
||||
let(:importer) { import_data csv_data, import_into: 'inventories' }
|
||||
@@ -679,7 +679,7 @@ describe ProductImport::ProductImporter do
|
||||
CSV.generate do |csv|
|
||||
csv << ["name", "distributor", "producer", "on_hand", "price", "units",
|
||||
"variant_unit_name"]
|
||||
csv << ["Cabbage", enterprise2.name, enterprise.name, "900", "", "1", "Whole"]
|
||||
csv << ["Cabbage", enterprise2.name, enterprise.name, "900", "1.0", "1", "Whole"]
|
||||
end
|
||||
}
|
||||
let(:importer) { import_data csv_data, import_into: 'inventories' }
|
||||
|
||||
@@ -376,7 +376,7 @@ describe "Product Import", js: true do
|
||||
csv << ["name", "distributor", "producer", "category", "on_hand", "price", "unit_type",
|
||||
"units", "on_demand"]
|
||||
csv << ["Beets", "Another Enterprise", "User Enterprise", "Vegetables", nil, "3.20", "kg",
|
||||
"1", "true"]
|
||||
"1", "1"]
|
||||
end
|
||||
|
||||
File.write('/tmp/test.csv', csv_data)
|
||||
@@ -415,7 +415,7 @@ describe "Product Import", js: true do
|
||||
csv << ["name", "distributor", "producer", "category", "on_hand", "price", "unit_type",
|
||||
"units", "on_demand", "variant_unit_name"]
|
||||
csv << ["Aubergine", "Another Enterprise", "User Enterprise", "Vegetables", "", "3.3",
|
||||
"kg", "1", "true", "Bag"]
|
||||
"kg", "1", "1", "Bag"]
|
||||
end
|
||||
|
||||
File.write('/tmp/test.csv', csv_data)
|
||||
@@ -445,9 +445,9 @@ describe "Product Import", js: true do
|
||||
csv << ["name", "distributor", "producer", "category", "on_hand", "price", "unit_type",
|
||||
"units", "on_demand", "variant_unit_name"]
|
||||
csv << ["Aubergine", "Another Enterprise", "User Enterprise", "Vegetables", "", "3.3",
|
||||
"kg", "1", "true", "Bag"]
|
||||
"kg", "1", "1", "Bag"]
|
||||
csv << ["Aubergine", "Another Enterprise", "User Enterprise", "Vegetables", "", "6.6",
|
||||
"kg", "1", "true", "Big-Bag"]
|
||||
"kg", "1", "1", "Big-Bag"]
|
||||
end
|
||||
|
||||
File.write('/tmp/test.csv', csv_data)
|
||||
@@ -466,6 +466,66 @@ describe "Product Import", js: true do
|
||||
|
||||
expect(page).not_to have_content "Aubergine"
|
||||
end
|
||||
|
||||
it "invalidates units value if 0 or non-numeric" do
|
||||
csv_data = CSV.generate do |csv|
|
||||
csv << ["name", "distributor", "producer", "category", "on_hand", "price", "unit_type",
|
||||
"units", "on_demand", "variant_unit_name"]
|
||||
csv << ["Aubergine", "Another Enterprise", "User Enterprise", "Vegetables", "", "3.3",
|
||||
"kg", "1", "1", "Bag"]
|
||||
csv << ["Beans", "Another Enterprise", "User Enterprise", "Vegetables", "3", "3.0",
|
||||
"kg", "0", "1", "Bag"]
|
||||
csv << ["Cabbage", "Another Enterprise", "User Enterprise", "Vegetables", "1", "4.3",
|
||||
"kg", "XX", "", "Bag"]
|
||||
end
|
||||
|
||||
File.write('/tmp/test.csv', csv_data)
|
||||
visit main_app.admin_product_import_path
|
||||
select 'Inventories', from: "settings_import_into"
|
||||
attach_file 'file', '/tmp/test.csv'
|
||||
click_button 'Upload'
|
||||
proceed_to_validation
|
||||
expect(page).to have_selector '.item-count', text: "3"
|
||||
expect(page).to have_selector '.invalid-count', text: "2"
|
||||
expect(page).to have_selector '.inv-create-count', text: '1'
|
||||
|
||||
find('div.header-description', text: 'Items contain errors').click
|
||||
expect(page).to have_content "line 4: Cabbage - Units incorrect value"
|
||||
expect(page).to have_content "line 3: Beans - Units incorrect value"
|
||||
expect(page).to have_content "Imported file contains invalid entries"
|
||||
expect(page).to have_no_selector 'input[type=submit][value="Save"]'
|
||||
expect(page).not_to have_content "line 2: Aubergine"
|
||||
end
|
||||
|
||||
it "Price validation" do
|
||||
csv_data = CSV.generate do |csv|
|
||||
csv << ["name", "distributor", "producer", "category", "on_hand", "price", "unit_type",
|
||||
"units", "on_demand", "variant_unit_name"]
|
||||
csv << ["Aubergine", "Another Enterprise", "User Enterprise", "Vegetables", "", "3.3",
|
||||
"kg", "1", "1", "Bag"]
|
||||
csv << ["Beans", "Another Enterprise", "User Enterprise", "Vegetables", "3", "",
|
||||
"kg", "2", "1", "Bag"]
|
||||
csv << ["Cabbage", "Another Enterprise", "User Enterprise", "Vegetables", "1", "t6",
|
||||
"kg", "3", "", "Bag"]
|
||||
end
|
||||
|
||||
File.write('/tmp/test.csv', csv_data)
|
||||
visit main_app.admin_product_import_path
|
||||
select 'Inventories', from: "settings_import_into"
|
||||
attach_file 'file', '/tmp/test.csv'
|
||||
click_button 'Upload'
|
||||
proceed_to_validation
|
||||
expect(page).to have_selector '.item-count', text: "3"
|
||||
expect(page).to have_selector '.invalid-count', text: "2"
|
||||
expect(page).to have_selector '.inv-create-count', text: '1'
|
||||
|
||||
find('div.header-description', text: 'Items contain errors').click
|
||||
expect(page).to have_content "line 4: Cabbage - Price incorrect value"
|
||||
expect(page).to have_content "line 3: Beans - Price can't be blank"
|
||||
expect(page).to have_content "Imported file contains invalid entries"
|
||||
expect(page).to have_no_selector 'input[type=submit][value="Save"]'
|
||||
expect(page).not_to have_content "line 2: Aubergine"
|
||||
end
|
||||
end
|
||||
|
||||
it "handles on_demand and on_hand validations with inventory" do
|
||||
@@ -473,11 +533,13 @@ describe "Product Import", js: true do
|
||||
csv << ["name", "distributor", "producer", "category", "on_hand", "price", "units",
|
||||
"on_demand"]
|
||||
csv << ["Beans", "Another Enterprise", "User Enterprise", "Vegetables", nil, "3.20", "500",
|
||||
"true"]
|
||||
"1"]
|
||||
csv << ["Sprouts", "Another Enterprise", "User Enterprise", "Vegetables", "6", "6.50",
|
||||
"500", "false"]
|
||||
csv << ["Cabbage", "Another Enterprise", "User Enterprise", "Vegetables", nil, "1.50",
|
||||
"500", "0"]
|
||||
csv << ["Cabbage", "Another Enterprise", "User Enterprise", "Vegetables", "", "1.50",
|
||||
"500", nil]
|
||||
csv << ["Aubergine", "Another Enterprise", "User Enterprise", "Vegetables", nil, "1.50",
|
||||
"500", "0"]
|
||||
end
|
||||
File.write('/tmp/test.csv', csv_data)
|
||||
|
||||
@@ -488,34 +550,17 @@ describe "Product Import", js: true do
|
||||
|
||||
proceed_to_validation
|
||||
|
||||
expect(page).to have_selector '.item-count', text: "3"
|
||||
expect(page).to have_no_selector '.invalid-count'
|
||||
expect(page).to have_selector '.item-count', text: "4"
|
||||
expect(page).to have_selector '.inv-create-count', text: '2'
|
||||
expect(page).to have_selector '.inv-update-count', text: '1'
|
||||
expect(page).to have_selector '.invalid-count', text: "2"
|
||||
|
||||
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
|
||||
find('div.header-description', text: 'Items contain errors').click
|
||||
expect(page).to have_content "line 4: Cabbage - On_hand incorrect value - On_demand incorrect value"
|
||||
expect(page).to have_content "line 5: Aubergine - On_hand incorrect value - On_demand incorrect value"
|
||||
expect(page).to have_content "Imported file contains invalid entries"
|
||||
expect(page).to have_no_selector 'input[type=submit][value="Save"]'
|
||||
expect(page).not_to have_content "line 2: Beans"
|
||||
expect(page).not_to have_content "line 3: Sprouts"
|
||||
end
|
||||
|
||||
it "imports lines with all allowed units" do
|
||||
|
||||
Reference in New Issue
Block a user