mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-06 22:36:07 +00:00
Product Import options and defaults
Added available_on test Obscure case fix and extra spec
This commit is contained in:
committed by
Rob Harrington
parent
f4511fc74d
commit
14fb40a996
@@ -1,4 +1,4 @@
|
||||
angular.module("ofn.admin").controller "FeedbackPanelsCtrl", ($scope) ->
|
||||
angular.module("ofn.admin").controller "DropdownPanelsCtrl", ($scope) ->
|
||||
$scope.active = false
|
||||
|
||||
$scope.togglePanel = ->
|
||||
@@ -1,6 +1,6 @@
|
||||
div.feedback-section {
|
||||
div.panel-section {
|
||||
|
||||
div.feedback-header {
|
||||
div.panel-header {
|
||||
width: 100%;
|
||||
//font-size: 1.5em;
|
||||
clear: both;
|
||||
@@ -22,7 +22,7 @@ div.feedback-section {
|
||||
div.header-icon {
|
||||
width: 2.5em;
|
||||
text-align: center;
|
||||
padding-top: 0.1em;
|
||||
padding-top: 0.18em;
|
||||
|
||||
.fa {
|
||||
font-size: 1.5em;
|
||||
@@ -48,17 +48,17 @@ div.feedback-section {
|
||||
|
||||
}
|
||||
|
||||
div.feedback-header:hover {
|
||||
div.panel-header:hover {
|
||||
cursor: pointer;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
div.feedback-header.active {
|
||||
div.panel-header.active {
|
||||
background-color: #efefef;
|
||||
text-shadow: 1px 1px 0px rgba(255,255,255,0.75);
|
||||
}
|
||||
|
||||
div.feedback-panel {
|
||||
div.panel-content {
|
||||
width: 100%;
|
||||
clear: both;
|
||||
//border: 1px solid #ccc;
|
||||
@@ -102,3 +102,61 @@ div.feedback-section {
|
||||
br.panels.clearfix {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
table.import-settings {
|
||||
background-color: transparent !important;
|
||||
width: auto;
|
||||
|
||||
//select {
|
||||
// width: 100%;
|
||||
//}
|
||||
tr {
|
||||
|
||||
}
|
||||
tbody tr:hover td {
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
td {
|
||||
border: 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
text-align: left;
|
||||
|
||||
input {
|
||||
width: 15em;
|
||||
}
|
||||
input[type="checkbox"] {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
}
|
||||
td.description {
|
||||
font-weight: bold;
|
||||
padding-right: 2.5em;
|
||||
}
|
||||
tr:first-child td {
|
||||
//border-top: 1px solid #eee;
|
||||
border-top: 0;
|
||||
}
|
||||
tr:last-child td {
|
||||
//border-top: 1px solid #eee;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.panel-section.import-settings {
|
||||
.header-icon {
|
||||
color: #BFBFBF;
|
||||
}
|
||||
.header-description {
|
||||
padding-left: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.select2-search {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select2-results {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class Admin::ProductImportController < Spree::Admin::BaseController
|
||||
end
|
||||
|
||||
def save
|
||||
@importer = ProductImporter.new(File.new(params[:filepath]), editable_enterprises)
|
||||
@importer = ProductImporter.new(File.new(params[:filepath]), editable_enterprises, params[:settings])
|
||||
@importer.save_all if @importer.has_valid_entries?
|
||||
end
|
||||
|
||||
|
||||
@@ -5,10 +5,9 @@ class ProductImporter
|
||||
include ActiveModel::Conversion
|
||||
include ActiveModel::Validations
|
||||
|
||||
def initialize(file, editable_enterprises, options={})
|
||||
def initialize(file, editable_enterprises, import_settings={})
|
||||
if file.is_a?(File)
|
||||
@file = file
|
||||
@options = options
|
||||
@sheet = open_spreadsheet
|
||||
@valid_entries = {}
|
||||
@invalid_entries = {}
|
||||
@@ -21,10 +20,11 @@ class ProductImporter
|
||||
@variants_created = 0
|
||||
@variants_updated = 0
|
||||
|
||||
@import_settings = import_settings
|
||||
@editable_enterprises = {}
|
||||
editable_enterprises.map { |e| @editable_enterprises[e.name] = e.id }
|
||||
|
||||
@non_display_attributes = 'id', 'product_id', 'variant_id', 'supplier_id', 'primary_taxon_id', 'category_id', 'shipping_category_id', 'tax_category_id'
|
||||
@non_display_attributes = 'id', 'product_id', 'variant_id', 'supplier_id', 'primary_taxon_id', 'category_id', 'shipping_category_id', 'tax_category_id', 'on_hand_nil'
|
||||
|
||||
validate_all if @sheet
|
||||
else
|
||||
@@ -144,12 +144,8 @@ class ProductImporter
|
||||
|
||||
supplier_validation(line_number, entry)
|
||||
category_validation(line_number, entry)
|
||||
|
||||
# Ensure on_hand isn't nil because Spree::Product and
|
||||
# Spree::Variant each validate it differently
|
||||
entry['on_hand'] = 0 if entry['on_hand'].nil?
|
||||
|
||||
set_update_status(line_number, entry)
|
||||
|
||||
mark_as_valid(line_number, entry) unless entry_invalid?(line_number)
|
||||
end
|
||||
|
||||
@@ -264,14 +260,9 @@ class ProductImporter
|
||||
|
||||
product = Spree::Product.new()
|
||||
product.assign_attributes(entry.except('id'))
|
||||
assign_defaults(product, entry)
|
||||
if product.save
|
||||
# Ensure display_name and on_demand are copied to new variant
|
||||
if entry['display_name'] || entry['on_demand']
|
||||
variant = product.variants.first
|
||||
variant.display_name = entry['display_name'] if entry['display_name']
|
||||
variant.on_demand = entry['on_demand'] if entry['on_demand']
|
||||
variant.save
|
||||
end
|
||||
ensure_variant_updated(entry, product)
|
||||
@products_created += 1
|
||||
else
|
||||
self.errors.add("Line #{line_number}:", product.errors.full_messages)
|
||||
@@ -282,6 +273,7 @@ class ProductImporter
|
||||
|
||||
@variants_to_update.each do |line_number, data|
|
||||
variant = data[:variant]
|
||||
assign_defaults(variant, data[:entry])
|
||||
if variant.valid? and variant.save
|
||||
@variants_updated += 1
|
||||
else
|
||||
@@ -291,6 +283,7 @@ class ProductImporter
|
||||
|
||||
@variants_to_create.each do |line_number, data|
|
||||
new_variant = data[:variant]
|
||||
assign_defaults(new_variant, data[:entry])
|
||||
if new_variant.valid? and new_variant.save
|
||||
@variants_created += 1
|
||||
else
|
||||
@@ -303,6 +296,29 @@ class ProductImporter
|
||||
total_saved_count
|
||||
end
|
||||
|
||||
def assign_defaults(object, entry)
|
||||
@import_settings[entry['supplier_id'].to_s]['defaults'].each do |attribute, setting|
|
||||
case setting['mode']
|
||||
when 'overwrite_all'
|
||||
object.assign_attributes(attribute => setting['value'])
|
||||
when 'overwrite_empty'
|
||||
if object.send(attribute).blank? or (attribute == 'on_hand' and entry['on_hand_nil'])
|
||||
object.assign_attributes(attribute => setting['value'])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_variant_updated(entry, product)
|
||||
# Ensure display_name and on_demand are copied to new product's variant
|
||||
if entry['display_name'] || entry['on_demand']
|
||||
variant = product.variants.first
|
||||
variant.display_name = entry['display_name'] if entry['display_name']
|
||||
variant.on_demand = entry['on_demand'] if entry['on_demand']
|
||||
variant.save
|
||||
end
|
||||
end
|
||||
|
||||
def set_update_status(line_number, entry)
|
||||
# Find product with matching supplier and name
|
||||
match = Spree::Product.where(supplier_id: entry['supplier_id'], name: entry['name'], deleted_at: nil).first
|
||||
@@ -337,6 +353,7 @@ class ProductImporter
|
||||
|
||||
def mark_as_existing_variant(line_number, entry, existing_variant)
|
||||
existing_variant.assign_attributes(entry.except('id', 'product_id'))
|
||||
check_on_hand_nil(entry, existing_variant)
|
||||
if existing_variant.valid?
|
||||
@variants_to_update[line_number] = {entry: entry, variant: existing_variant} unless entry_invalid?(line_number)
|
||||
else
|
||||
@@ -347,6 +364,7 @@ class ProductImporter
|
||||
def mark_as_new_variant(line_number, entry, product_id)
|
||||
new_variant = Spree::Variant.new(entry.except('id', 'product_id'))
|
||||
new_variant.product_id = product_id
|
||||
check_on_hand_nil(entry, new_variant)
|
||||
if new_variant.valid?
|
||||
@variants_to_create[line_number] = {entry: entry, variant: new_variant} unless entry_invalid?(line_number)
|
||||
else
|
||||
@@ -354,6 +372,13 @@ class ProductImporter
|
||||
end
|
||||
end
|
||||
|
||||
def check_on_hand_nil(entry, variant)
|
||||
if entry['on_hand'].blank?
|
||||
variant.on_hand = 0
|
||||
entry['on_hand_nil'] = true
|
||||
end
|
||||
end
|
||||
|
||||
def delete_uploaded_file
|
||||
# Only delete if file is in '/tmp/product_import' directory
|
||||
if @file.path == Rails.root.join('tmp', 'product_import').to_s
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
%h5 Import options and defaults
|
||||
%br
|
||||
|
||||
- @importer.suppliers_index.each do |name, id|
|
||||
- if name and id
|
||||
%div.panel-section.import-settings{ng: {controller: 'DropdownPanelsCtrl'}}
|
||||
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active}'}}
|
||||
%div.header-caret
|
||||
%i{ng: {class: "{'icon-chevron-down': active, 'icon-chevron-right': !active}"}}
|
||||
%div.header-icon
|
||||
%i.fa.fa-edit
|
||||
-#%div.header-count
|
||||
-# %strong.invalid-count= @importer.invalid_count
|
||||
%div.header-description
|
||||
= name
|
||||
%div.panel-content{ng: {hide: '!active'}}
|
||||
= render 'options_form', id: id, name: name
|
||||
|
||||
|
||||
%br.panels.clearfix
|
||||
%br
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
%h5 Import validation overview
|
||||
%br
|
||||
|
||||
%div.feedback-section
|
||||
%div.feedback-header
|
||||
%div.panel-section
|
||||
%div.panel-header
|
||||
%div.header-caret
|
||||
-#%i.icon-chevron-right{ng: {hide: 'active'}}
|
||||
-#%i.icon-chevron-down{ng: {hide: '!active'}}
|
||||
@@ -12,51 +12,48 @@
|
||||
%strong.item-count= @importer.item_count
|
||||
%div.header-description
|
||||
Entries found in imported file
|
||||
-#%div.feedback-panel{ng: {hide: '!active'}}
|
||||
-#%div.panel-content{ng: {hide: '!active'}}
|
||||
-# Content goes here
|
||||
|
||||
%div.feedback-section{ng: {controller: 'FeedbackPanelsCtrl', init: "count = #{@importer.invalid_count}"}}
|
||||
%div.feedback-header{ng: {click: 'togglePanel()', class: '{active: active && count}'}}
|
||||
%div.panel-section{ng: {controller: 'DropdownPanelsCtrl', init: "count = #{@importer.invalid_count}"}}
|
||||
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active && count}'}}
|
||||
%div.header-caret
|
||||
%i.icon-chevron-right{ng: {hide: 'active || count == 0'}}
|
||||
%i.icon-chevron-down{ng: {hide: '!active || count == 0'}}
|
||||
%i{ng: {class: "{'icon-chevron-down': active, 'icon-chevron-right': !active}", hide: 'count == 0'}}
|
||||
%div.header-icon
|
||||
%i.fa.fa-warning
|
||||
%div.header-count
|
||||
%strong.invalid-count= @importer.invalid_count
|
||||
%div.header-description
|
||||
Items contain errors and will not be imported
|
||||
%div.feedback-panel{ng: {hide: '!active || count == 0'}}
|
||||
%div.panel-content{ng: {hide: '!active || count == 0'}}
|
||||
= render 'errors_list'
|
||||
%br
|
||||
= render 'entries_table', entries: @importer.invalid_entries
|
||||
|
||||
%div.feedback-section{ng: {controller: 'FeedbackPanelsCtrl', init: "count = #{@importer.products_create_count}"}}
|
||||
%div.feedback-header{ng: {click: 'togglePanel()', class: '{active: active && count}'}}
|
||||
%div.panel-section{ng: {controller: 'DropdownPanelsCtrl', init: "count = #{@importer.products_create_count}"}}
|
||||
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active && count}'}}
|
||||
%div.header-caret
|
||||
%i.icon-chevron-right{ng: {hide: 'active || count == 0'}}
|
||||
%i.icon-chevron-down{ng: {hide: '!active || count == 0'}}
|
||||
%i{ng: {class: "{'icon-chevron-down': active, 'icon-chevron-right': !active}", hide: 'count == 0'}}
|
||||
%div.header-icon
|
||||
%i.fa.fa-check-circle
|
||||
%div.header-count
|
||||
%strong.create-count= @importer.products_create_count
|
||||
%div.header-description
|
||||
Products will be created
|
||||
%div.feedback-panel{ng: {hide: '!active || count == 0'}}
|
||||
%div.panel-content{ng: {hide: '!active || count == 0'}}
|
||||
= render 'entries_table', entries: @importer.products_to_create
|
||||
|
||||
%div.feedback-section{ng: {controller: 'FeedbackPanelsCtrl', init: "count = #{@importer.products_update_count}"}}
|
||||
%div.feedback-header{ng: {click: 'togglePanel()', class: '{active: active && count}'}}
|
||||
%div.panel-section{ng: {controller: 'DropdownPanelsCtrl', init: "count = #{@importer.products_update_count}"}}
|
||||
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active && count}'}}
|
||||
%div.header-caret
|
||||
%i.icon-chevron-right{ng: {hide: 'active || count == 0'}}
|
||||
%i.icon-chevron-down{ng: {hide: '!active || count == 0'}}
|
||||
%i{ng: {class: "{'icon-chevron-down': active, 'icon-chevron-right': !active}", hide: 'count == 0'}}
|
||||
%div.header-icon
|
||||
%i.fa.fa-check-circle
|
||||
%div.header-count
|
||||
%strong.update-count= @importer.products_update_count
|
||||
%div.header-description
|
||||
Products will be updated
|
||||
%div.feedback-panel{ng: {hide: '!active || count == 0'}}
|
||||
%div.panel-content{ng: {hide: '!active || count == 0'}}
|
||||
= render 'entries_table', entries: @importer.products_to_update
|
||||
|
||||
%br.panels.clearfix
|
||||
35
app/views/admin/product_import/_options_form.html.haml
Normal file
35
app/views/admin/product_import/_options_form.html.haml
Normal file
@@ -0,0 +1,35 @@
|
||||
%table.import-settings
|
||||
%tr
|
||||
%td.description
|
||||
Remove absent products?
|
||||
%td
|
||||
= check_box_tag "settings[#{id}][products_absent]", 1, false
|
||||
%td
|
||||
%tr
|
||||
%td.description
|
||||
Set default stock level
|
||||
%td
|
||||
= select_tag "settings[#{id}][defaults][on_hand][mode]", options_for_select({"Don't overwrite" => :overwrite_none, "Overwrite all" => :overwrite_all, "Overwrite if empty" => :overwrite_empty}), {class: 'select2 fullwidth'}
|
||||
%td
|
||||
= number_field_tag "settings[#{id}][defaults][on_hand][value]", 0
|
||||
%tr
|
||||
%td.description
|
||||
Set default tax category
|
||||
%td
|
||||
= select_tag "settings[#{id}][defaults][tax_category_id][mode]", options_for_select({"Don't overwrite" => :overwrite_none, "Overwrite all" => :overwrite_all, "Overwrite if empty" => :overwrite_empty}), {class: 'select2 fullwidth'}
|
||||
%td
|
||||
= select_tag "settings[#{id}][defaults][tax_category_id][value]", options_for_select(@tax_categories.map {|tc| [tc.name, tc.id]}), {prompt: 'None', class: 'select2 fullwidth'}
|
||||
%tr
|
||||
%td.description
|
||||
Set default shipping category
|
||||
%td
|
||||
= select_tag "settings[#{id}][defaults][shipping_category_id][mode]", options_for_select({"Don't overwrite" => :overwrite_none, "Overwrite all" => :overwrite_all, "Overwrite if empty" => :overwrite_empty}), {class: 'select2 fullwidth'}
|
||||
%td
|
||||
= select_tag "settings[#{id}][defaults][shipping_category_id][value]", options_for_select(@shipping_categories.map {|sc| [sc.name, sc.id]}), {prompt: 'None', class: 'select2 fullwidth'}
|
||||
%tr
|
||||
%td.description
|
||||
Set default available date
|
||||
%td
|
||||
= select_tag "settings[#{id}][defaults][available_on][mode]", options_for_select({"Don't overwrite" => :overwrite_none, "Overwrite all" => :overwrite_all, "Overwrite if empty" => :overwrite_empty}), {class: 'select2 fullwidth'}
|
||||
%td
|
||||
= text_field_tag "settings[#{id}][defaults][available_on][value]", nil, {class: 'datepicker', placeholder: 'Today'}
|
||||
@@ -10,6 +10,8 @@
|
||||
%p There are no entries that can be saved
|
||||
%br
|
||||
|
||||
= render 'import_options' if @importer.has_valid_entries?
|
||||
|
||||
= render 'import_review'
|
||||
|
||||
- if @importer.has_valid_entries?
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
%br
|
||||
|
||||
- if !@importer.errors.full_messages
|
||||
%h5 All #{importer.total_saved_count} items saved successfully
|
||||
- if @importer.errors.count == 0
|
||||
%h5 All #{@importer.total_saved_count} items saved successfully
|
||||
- else
|
||||
%h5 Errors
|
||||
- @importer.errors.full_messages.each do |error|
|
||||
|
||||
@@ -11,9 +11,11 @@ feature "Product Import", js: true do
|
||||
let!(:enterprise2) { create(:supplier_enterprise, owner: admin, name: "Another Enterprise") }
|
||||
let!(:category) { create(:taxon, name: 'Vegetables') }
|
||||
let!(:category2) { create(:taxon, name: 'Cake') }
|
||||
let!(:tax_category) { create(:tax_category) }
|
||||
let!(:tax_category2) { create(:tax_category) }
|
||||
let!(:shipping_category) { create(:shipping_category) }
|
||||
let!(:product) { create(:simple_product, supplier: enterprise, name: 'Hypothetical Cake') }
|
||||
let!(:variant) { create(:variant, product_id: product.id, price: '8.50', count_on_hand: '100', unit_value: '500', display_name: 'Preexisting Banana') }
|
||||
let(:permissions) { OpenFoodNetwork::Permissions.new(user) }
|
||||
|
||||
describe "when importing products from uploaded file" do
|
||||
before { quick_login_as_admin }
|
||||
@@ -77,7 +79,7 @@ feature "Product Import", js: true do
|
||||
carrots.price.should == 3.20
|
||||
end
|
||||
|
||||
it "displays info about invalid entries but no save button if all invalid" 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", "supplier", "category", "on_hand", "price", "unit_value", "variant_unit", "variant_unit_scale"]
|
||||
csv << ["Bad Carrots", "Unkown Enterprise", "Mouldy vegetables", "666", "3.20", "", "weight", ""]
|
||||
@@ -130,6 +132,37 @@ feature "Product Import", js: true do
|
||||
updated_banana.price.should == 5.50
|
||||
updated_banana.on_hand.should == 5
|
||||
end
|
||||
|
||||
it "can add a new product and sub-variants of that product at the same time" do
|
||||
csv_data = CSV.generate do |csv|
|
||||
csv << ["name", "supplier", "category", "on_hand", "price", "unit_value", "variant_unit", "variant_unit_scale", "display_name"]
|
||||
csv << ["Potatoes", "User Enterprise", "Vegetables", "5", "3.50", "500", "weight", "1000", "Small Bag"]
|
||||
csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "5.50", "2000", "weight", "1000", "Big Bag"]
|
||||
end
|
||||
File.write('/tmp/test.csv', csv_data)
|
||||
|
||||
visit main_app.admin_product_import_path
|
||||
attach_file 'file', '/tmp/test.csv'
|
||||
click_button 'Import'
|
||||
|
||||
expect(page).to have_selector '.item-count', text: "2"
|
||||
expect(page).to have_selector '.invalid-count', text: "0"
|
||||
expect(page).to have_selector '.create-count', text: "2"
|
||||
expect(page).to have_selector '.update-count', text: "0"
|
||||
|
||||
click_button 'Save'
|
||||
expect(page).to have_content "Products created: 2"
|
||||
|
||||
small_bag = Spree::Variant.find_by_display_name('Small Bag')
|
||||
small_bag.product.name.should == 'Potatoes'
|
||||
small_bag.price.should == 3.50
|
||||
small_bag.on_hand.should == 5
|
||||
|
||||
big_bag = Spree::Variant.find_by_display_name('Big Bag')
|
||||
big_bag.product.name.should == 'Potatoes'
|
||||
big_bag.price.should == 5.50
|
||||
big_bag.on_hand.should == 6
|
||||
end
|
||||
end
|
||||
|
||||
describe "when dealing with uploaded files" do
|
||||
@@ -200,4 +233,57 @@ feature "Product Import", js: true do
|
||||
end
|
||||
end
|
||||
|
||||
describe "applying settings and defaults on import" do
|
||||
before { quick_login_as_admin }
|
||||
|
||||
it "overwrites fields with selected defaults" do
|
||||
csv_data = CSV.generate do |csv|
|
||||
csv << ["name", "supplier", "category", "on_hand", "price", "unit_value", "variant_unit", "variant_unit_scale", "tax_category_id", "available_on"]
|
||||
csv << ["Carrots", "User Enterprise", "Vegetables", "5", "3.20", "500", "weight", "1", tax_category.id, ""]
|
||||
csv << ["Potatoes", "User Enterprise", "Vegetables", "6", "6.50", "1000", "weight", "1000", "", ""]
|
||||
end
|
||||
File.write('/tmp/test.csv', csv_data)
|
||||
|
||||
visit main_app.admin_product_import_path
|
||||
|
||||
attach_file 'file', '/tmp/test.csv'
|
||||
click_button 'Import'
|
||||
|
||||
within 'div.import-settings' do
|
||||
find('div.header-description').click # Import settings tab
|
||||
expect(page).to have_selector "#settings_#{enterprise.id}_defaults_on_hand_mode", visible: false
|
||||
|
||||
# Overwrite stock level of all items to 9000
|
||||
select 'Overwrite all', from: "settings_#{enterprise.id}_defaults_on_hand_mode", visible: false
|
||||
fill_in "settings_#{enterprise.id}_defaults_on_hand_value", with: '9000'
|
||||
|
||||
# Overwrite default tax category, but only where field is empty
|
||||
select 'Overwrite if empty', from: "settings_#{enterprise.id}_defaults_tax_category_id_mode", visible: false
|
||||
select tax_category2.name, from: "settings_#{enterprise.id}_defaults_tax_category_id_value", visible: false
|
||||
|
||||
# Set default shipping category (field not present in file)
|
||||
select 'Overwrite all', from: "settings_#{enterprise.id}_defaults_shipping_category_id_mode", visible: false
|
||||
select shipping_category.name, from: "settings_#{enterprise.id}_defaults_shipping_category_id_value", visible: false
|
||||
|
||||
# Set available_on date
|
||||
select 'Overwrite all', from: "settings_#{enterprise.id}_defaults_available_on_mode", visible: false
|
||||
find("input#settings_#{enterprise.id}_defaults_available_on_value").set '2020-01-01'
|
||||
end
|
||||
|
||||
click_button 'Save'
|
||||
expect(page).to have_content "Products created: 2"
|
||||
|
||||
carrots = Spree::Product.find_by_name('Carrots')
|
||||
carrots.on_hand.should == 9000
|
||||
carrots.tax_category_id.should == tax_category.id
|
||||
carrots.shipping_category_id.should == shipping_category.id
|
||||
carrots.available_on.should be_within(1.day).of(Time.zone.local(2020, 1, 1))
|
||||
|
||||
potatoes = Spree::Product.find_by_name('Potatoes')
|
||||
potatoes.on_hand.should == 9000
|
||||
potatoes.tax_category_id.should == tax_category2.id
|
||||
potatoes.shipping_category_id.should == shipping_category.id
|
||||
potatoes.available_on.should be_within(1.day).of(Time.zone.local(2020, 1, 1))
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user