spree_drop_ship 3.1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +9 -0
- data/LICENSE +21 -0
- data/README.md +116 -0
- data/Rakefile +15 -0
- data/Versionfile +6 -0
- data/app/assets/javascripts/spree/backend/spree_drop_ship.js +2 -0
- data/app/assets/javascripts/spree/frontend/spree_drop_ship.js +1 -0
- data/app/assets/stylesheets/spree/backend/spree_drop_ship.scss +22 -0
- data/app/assets/stylesheets/spree/frontend/spree_drop_ship.css +3 -0
- data/app/controllers/ckeditor/attachment_files_controller_decorator.rb +20 -0
- data/app/controllers/ckeditor/pictures_controller_decorator.rb +17 -0
- data/app/controllers/spree/admin/drop_ship_settings_controller.rb +19 -0
- data/app/controllers/spree/admin/products_controller_decorator.rb +19 -0
- data/app/controllers/spree/admin/shipments_controller.rb +47 -0
- data/app/controllers/spree/admin/stock_locations_controller_decorator.rb +14 -0
- data/app/controllers/spree/admin/suppliers_controller.rb +32 -0
- data/app/controllers/spree/api/v1/stock_locations_controller_decorator.rb +18 -0
- data/app/controllers/spree/base_controller_decorator.rb +23 -0
- data/app/mailers/spree/drop_ship_order_mailer.rb +13 -0
- data/app/mailers/spree/supplier_mailer.rb +12 -0
- data/app/models/ckeditor/asset_decorator.rb +5 -0
- data/app/models/spree/drop_ship_configuration.rb +17 -0
- data/app/models/spree/order_decorator.rb +27 -0
- data/app/models/spree/payment_decorator.rb +7 -0
- data/app/models/spree/product_decorator.rb +32 -0
- data/app/models/spree/shipment_decorator.rb +39 -0
- data/app/models/spree/stock/splitter/drop_ship.rb +42 -0
- data/app/models/spree/stock_location_decorator.rb +18 -0
- data/app/models/spree/supplier.rb +117 -0
- data/app/models/spree/supplier_ability.rb +28 -0
- data/app/models/spree/supplier_variant.rb +6 -0
- data/app/models/spree/user_decorator.rb +11 -0
- data/app/models/spree/variant_decorator.rb +24 -0
- data/app/models/spree.rb +5 -0
- data/app/overrides/spree/admin/products/_form/converted_admin_product_form_right.html.erb.deface +5 -0
- data/app/overrides/spree/admin/products/index/override_rows.html.erb.deface +22 -0
- data/app/overrides/spree/admin/shared/sub_menu/_configuration/add_drop_ship_settings.html.erb.deface +3 -0
- data/app/overrides/spree/admin/stock_locations/_form/add_supplier.html.erb.deface +12 -0
- data/app/overrides/spree/admin/stock_movements/_form/fix_bootstrap_form.html.erb.deface +11 -0
- data/app/overrides/spree/layouts/admin/add_profile_admin_tabs.html.erb.deface +8 -0
- data/app/overrides/spree/layouts/admin/converted_admin_tabs.html.erb.deface +18 -0
- data/app/views/spree/admin/drop_ship_settings/edit.html.erb +21 -0
- data/app/views/spree/admin/shared/_header.html.erb +24 -0
- data/app/views/spree/admin/shipments/edit.html.erb +24 -0
- data/app/views/spree/admin/shipments/index.html.erb +95 -0
- data/app/views/spree/admin/suppliers/_form.html.erb +69 -0
- data/app/views/spree/admin/suppliers/edit.html.erb +22 -0
- data/app/views/spree/admin/suppliers/index.html.erb +71 -0
- data/app/views/spree/admin/suppliers/new.html.erb +17 -0
- data/app/views/spree/drop_ship_order_mailer/supplier_order.html.erb +119 -0
- data/app/views/spree/shared/unauthorized.erb +1 -0
- data/app/views/spree/supplier_mailer/welcome.html.erb +53 -0
- data/config/locales/en.yml +89 -0
- data/config/locales/es.yml +133 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20121006073854_create_suppliers.rb +20 -0
- data/db/migrate/20130216070944_product_belongs_to_supplier.rb +6 -0
- data/db/migrate/20130405005502_stock_locations_belongs_to_supplier.rb +6 -0
- data/db/migrate/20130405011127_user_belongs_to_supplier.rb +6 -0
- data/db/migrate/20130428063053_add_balanced_token_to_suppliers.rb +7 -0
- data/db/migrate/20130510181443_add_supplier_id_to_ckeditor_assets.rb +8 -0
- data/db/migrate/20130606220913_add_permalink_to_suppliers.rb +6 -0
- data/db/migrate/20140323170638_add_supplier_commission_to_shipments.rb +5 -0
- data/db/migrate/20140416184616_migrate_payment_and_commission.rb +7 -0
- data/db/migrate/20140529041325_create_spree_supplier_variants.rb +15 -0
- data/lib/generators/spree_drop_ship/install/install_generator.rb +30 -0
- data/lib/spree_drop_ship/engine.rb +31 -0
- data/lib/spree_drop_ship/factories.rb +93 -0
- data/lib/spree_drop_ship.rb +6 -0
- data/lib/tasks/spree_sample.rake +72 -0
- data/script/rails +7 -0
- data/spec/features/admin/orders_spec.rb +12 -0
- data/spec/features/admin/products_spec.rb +25 -0
- data/spec/features/admin/return_authorizations_spec.rb +7 -0
- data/spec/features/admin/settings_spec.rb +33 -0
- data/spec/features/admin/shipments_spec.rb +80 -0
- data/spec/features/admin/stock_management_spec.rb +153 -0
- data/spec/features/admin/stock_spec.rb +98 -0
- data/spec/features/admin/suppliers_spec.rb +126 -0
- data/spec/models/spree/order_decorator_spec.rb +54 -0
- data/spec/models/spree/payment_decorator_spec.rb +7 -0
- data/spec/models/spree/product_decorator_spec.rb +13 -0
- data/spec/models/spree/shipment_decorator_spec.rb +47 -0
- data/spec/models/spree/stock/splitter/drop_ship_spec.rb +62 -0
- data/spec/models/spree/stock_location_decorator_spec.rb +33 -0
- data/spec/models/spree/supplier_ability_spec.rb +172 -0
- data/spec/models/spree/supplier_spec.rb +123 -0
- data/spec/models/spree/supplier_variant_spec.rb +5 -0
- data/spec/models/spree/user_decorator_spec.rb +17 -0
- data/spec/models/spree/variant_decorator_spec.rb +7 -0
- data/spec/spec_helper.rb +79 -0
- data/spec/support/integration_helpers.rb +15 -0
- data/spree_drop_ship.gemspec +42 -0
- metadata +411 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
FactoryGirl.define do
|
|
2
|
+
|
|
3
|
+
factory :order_for_drop_ship, parent: :order do
|
|
4
|
+
bill_address
|
|
5
|
+
ship_address
|
|
6
|
+
|
|
7
|
+
ignore do
|
|
8
|
+
line_items_count 5
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
after(:create) do |order, evaluator|
|
|
12
|
+
supplier = create(:supplier)
|
|
13
|
+
product = create(:product)
|
|
14
|
+
product.add_supplier! supplier
|
|
15
|
+
# product.stock_items.where(variant_id: product.master.id).first.adjust_count_on_hand(10)
|
|
16
|
+
|
|
17
|
+
product_2 = create(:product)
|
|
18
|
+
product_2.add_supplier! create(:supplier)
|
|
19
|
+
|
|
20
|
+
create_list(:line_item, evaluator.line_items_count,
|
|
21
|
+
order: order,
|
|
22
|
+
variant: product_2.master
|
|
23
|
+
)
|
|
24
|
+
order.line_items.reload
|
|
25
|
+
|
|
26
|
+
create(:shipment, order: order, stock_location: supplier.stock_locations.first)
|
|
27
|
+
order.shipments.reload
|
|
28
|
+
|
|
29
|
+
order.update!
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
factory :completed_order_for_drop_ship_with_totals do
|
|
33
|
+
state 'complete'
|
|
34
|
+
|
|
35
|
+
after(:create) do |order|
|
|
36
|
+
order.refresh_shipment_rates
|
|
37
|
+
order.update_column(:completed_at, Time.now)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
factory :order_ready_for_drop_ship do
|
|
41
|
+
payment_state 'paid'
|
|
42
|
+
shipment_state 'ready'
|
|
43
|
+
|
|
44
|
+
after(:create) do |order|
|
|
45
|
+
create(:payment, amount: order.total, order: order, state: 'completed')
|
|
46
|
+
order.shipments.each do |shipment|
|
|
47
|
+
shipment.inventory_units.each { |u| u.update_column('state', 'on_hand') }
|
|
48
|
+
shipment.update_column('state', 'ready')
|
|
49
|
+
end
|
|
50
|
+
order.reload
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
factory :shipped_order_for_drop_ship do
|
|
54
|
+
after(:create) do |order|
|
|
55
|
+
order.shipments.each do |shipment|
|
|
56
|
+
shipment.inventory_units.each { |u| u.update_column('state', 'shipped') }
|
|
57
|
+
shipment.update_column('state', 'shipped')
|
|
58
|
+
end
|
|
59
|
+
order.reload
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
factory :supplier, :class => Spree::Supplier do
|
|
67
|
+
sequence(:name) { |i| "Big Store #{i}" }
|
|
68
|
+
email { FFaker::Internet.email }
|
|
69
|
+
url "http://example.com"
|
|
70
|
+
address
|
|
71
|
+
# Creating a stock location with a factory instead of letting the model handle it
|
|
72
|
+
# so that we can run tests with backorderable defaulting to true.
|
|
73
|
+
before :create do |supplier|
|
|
74
|
+
supplier.stock_locations << build(:stock_location, name: supplier.name, supplier: supplier)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
factory :supplier_with_commission do
|
|
78
|
+
commission_flat_rate 0.5
|
|
79
|
+
commission_percentage 10
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
factory :supplier_user, parent: :user do
|
|
84
|
+
supplier
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
factory :variant_with_supplier, parent: :variant do
|
|
88
|
+
after :create do |variant|
|
|
89
|
+
variant.product.add_supplier! create(:supplier)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
namespace :spree_sample do
|
|
2
|
+
desc "Create sample drop ship orders"
|
|
3
|
+
task :drop_ship_orders => :environment do
|
|
4
|
+
if Spree::Order.count == 0
|
|
5
|
+
puts "Please run `rake spree_sample:load` first to create products and orders"
|
|
6
|
+
exit
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
if Spree::Supplier.count == 0
|
|
10
|
+
puts "Please run `rake spree_sample:suppliers` first to create suppliers"
|
|
11
|
+
exit
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
count = 0
|
|
15
|
+
@orders = Spree::Order.complete.includes(:line_items).all
|
|
16
|
+
@suppliers = Spree::Supplier.all
|
|
17
|
+
|
|
18
|
+
puts "Linking existing line items to suppliers"
|
|
19
|
+
Spree::LineItem.all.each do |li|
|
|
20
|
+
print "*" if li.product.add_supplier! @suppliers.shuffle.first.id and li.save
|
|
21
|
+
end
|
|
22
|
+
puts
|
|
23
|
+
|
|
24
|
+
puts "Creating drop ship orders for existing orders"
|
|
25
|
+
Spree::Order.all.each do |order|
|
|
26
|
+
print "*" if order.finalize!
|
|
27
|
+
end
|
|
28
|
+
puts
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
desc "Create sample suppliers and randomly link to products"
|
|
32
|
+
task :suppliers => :environment do
|
|
33
|
+
old_send_value = SpreeDropShip::Config[:send_supplier_email]
|
|
34
|
+
SpreeDropShip::Config[:send_supplier_email] = false
|
|
35
|
+
|
|
36
|
+
@usa = Spree::Country.find_by_iso("US")
|
|
37
|
+
@ca = @usa.states.find_by_abbr("CA")
|
|
38
|
+
|
|
39
|
+
count = Spree::Supplier.count
|
|
40
|
+
puts "Creating Suppliers..."
|
|
41
|
+
5.times{|i|
|
|
42
|
+
name = "Supplier #{count + i + 1}"
|
|
43
|
+
supplier = Spree::Supplier.new(:name => name,
|
|
44
|
+
:email => "#{name.parameterize}@example.com",
|
|
45
|
+
:url => "http://example.com")
|
|
46
|
+
supplier.build_address(:firstname => name, :lastname => name,
|
|
47
|
+
:address1 => "100 State St",
|
|
48
|
+
:city => "Santa Barbara", :zipcode => "93101",
|
|
49
|
+
:state_id => @ca.id, :country_id => @usa.id,
|
|
50
|
+
:phone => '1234567890')
|
|
51
|
+
print "*" if supplier.save
|
|
52
|
+
}
|
|
53
|
+
puts
|
|
54
|
+
puts "#{Spree::Supplier.count - count} suppliers created"
|
|
55
|
+
|
|
56
|
+
puts "Randomly linking Products & Suppliers..."
|
|
57
|
+
|
|
58
|
+
@supplier_ids = Spree::Supplier.pluck(:id).shuffle
|
|
59
|
+
@products = Spree::Product.all
|
|
60
|
+
count = 0
|
|
61
|
+
|
|
62
|
+
@products.each do |product|
|
|
63
|
+
product.add_supplier! Spree::Supplier.find(@supplier_ids[rand(@supplier_ids.length)])
|
|
64
|
+
product.save
|
|
65
|
+
count += 1
|
|
66
|
+
print "*"
|
|
67
|
+
end
|
|
68
|
+
puts
|
|
69
|
+
puts "#{count} products linked."
|
|
70
|
+
SpreeDropShip::Config[:send_supplier_email] = old_send_value
|
|
71
|
+
end
|
|
72
|
+
end
|
data/script/rails
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
2
|
+
|
|
3
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
|
4
|
+
ENGINE_PATH = File.expand_path('../../lib/spree_drop_ship/engine', __FILE__)
|
|
5
|
+
|
|
6
|
+
require 'rails/all'
|
|
7
|
+
require 'rails/engine/commands'
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Admin - Orders', js: true do
|
|
4
|
+
|
|
5
|
+
it 'Supplier should not be authorized' do
|
|
6
|
+
create(:user) # create extra user so admin role isnt assigned to the user we login as
|
|
7
|
+
login_user create(:supplier_user)
|
|
8
|
+
visit spree.admin_orders_path
|
|
9
|
+
page.should have_content('Authorization Failure')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Admin - Products', js: true do
|
|
4
|
+
|
|
5
|
+
context 'as Admin' do
|
|
6
|
+
|
|
7
|
+
xit 'should be able to change supplier' do
|
|
8
|
+
s1 = create(:supplier)
|
|
9
|
+
s2 = create(:supplier)
|
|
10
|
+
product = create :product
|
|
11
|
+
product.add_supplier! s1
|
|
12
|
+
|
|
13
|
+
login_user create(:admin_user)
|
|
14
|
+
visit spree.admin_product_path(product)
|
|
15
|
+
|
|
16
|
+
select2 s2.name, from: 'Supplier'
|
|
17
|
+
click_button 'Update'
|
|
18
|
+
|
|
19
|
+
expect(page).to have_content("Product \"#{product.name}\" has been successfully updated!")
|
|
20
|
+
expect(product.reload.suppliers.first.id).to eql(s2.id)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Admin - DropShip Settings', js: true do
|
|
4
|
+
|
|
5
|
+
before do
|
|
6
|
+
login_user create(:admin_user)
|
|
7
|
+
|
|
8
|
+
visit spree.admin_path
|
|
9
|
+
within '[data-hook=admin_tabs]' do
|
|
10
|
+
click_link 'Configuration'
|
|
11
|
+
end
|
|
12
|
+
within 'ul[data-hook=admin_configurations_sidebar_menu]' do
|
|
13
|
+
click_link 'Drop Ship Settings'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should be able to be updated' do
|
|
18
|
+
# Change settings
|
|
19
|
+
uncheck 'send_supplier_email'
|
|
20
|
+
fill_in 'default_commission_flat_rate', with: 0.30
|
|
21
|
+
fill_in 'default_commission_percentage', with: 10
|
|
22
|
+
click_button 'Update'
|
|
23
|
+
expect(page).to have_content('Drop ship settings successfully updated.')
|
|
24
|
+
|
|
25
|
+
# Verify update saved properly by reversing checkboxes or checking field values.
|
|
26
|
+
check 'send_supplier_email'
|
|
27
|
+
click_button 'Update'
|
|
28
|
+
find_field('default_commission_flat_rate').value.to_f.should eql(0.3)
|
|
29
|
+
find_field('default_commission_percentage').value.to_f.should eql(10.0)
|
|
30
|
+
expect(page).to have_content('Drop ship settings successfully updated.')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Admin - Shipments', js: true do
|
|
4
|
+
|
|
5
|
+
context 'as Supplier' do
|
|
6
|
+
|
|
7
|
+
let!(:order) { build(:order_ready_for_drop_ship, state: 'complete', completed_at: "2011-02-01 12:36:15", number: "R100") }
|
|
8
|
+
let!(:supplier) { create(:supplier) }
|
|
9
|
+
|
|
10
|
+
let!(:product) {
|
|
11
|
+
p = create(:product, name: 'spree t-shirt', price: 20.00)
|
|
12
|
+
p.add_supplier! supplier.id
|
|
13
|
+
p
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let!(:shipment) { create(:shipment, order: order, stock_location: supplier.stock_locations.first) }
|
|
17
|
+
let!(:shipping_method) { create(:shipping_method, name: "Default") }
|
|
18
|
+
|
|
19
|
+
before do
|
|
20
|
+
# Adjust qoh so shipment will be ready
|
|
21
|
+
shipment.stock_location.stock_items.where(variant_id: product.master.id).first.adjust_count_on_hand(10)
|
|
22
|
+
# Add product and update shipment
|
|
23
|
+
order.contents.add(product.master, 2)
|
|
24
|
+
shipment.refresh_rates
|
|
25
|
+
shipment.update!(order)
|
|
26
|
+
shipment.update_amounts
|
|
27
|
+
|
|
28
|
+
# TODO this is a hack until capture_on_dispatch finished https://github.com/spree/spree/issues/4727
|
|
29
|
+
shipment.update_attribute :state, 'ready'
|
|
30
|
+
|
|
31
|
+
user = create(:user, supplier: supplier)
|
|
32
|
+
user.generate_spree_api_key!
|
|
33
|
+
login_user user
|
|
34
|
+
|
|
35
|
+
visit spree.edit_admin_shipment_path(shipment)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context 'edit page' do
|
|
39
|
+
|
|
40
|
+
it "can add tracking information" do
|
|
41
|
+
within '.table tr.show-tracking' do
|
|
42
|
+
click_icon :edit
|
|
43
|
+
end
|
|
44
|
+
within '.table tr.edit-tracking' do
|
|
45
|
+
fill_in "tracking", with: "FOOBAR"
|
|
46
|
+
click_icon :save
|
|
47
|
+
end
|
|
48
|
+
wait_for_ajax
|
|
49
|
+
within '.table tr.show-tracking' do
|
|
50
|
+
page.should have_content("Tracking: FOOBAR")
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "can change the shipping method" do
|
|
55
|
+
within(".table tr.show-method") do
|
|
56
|
+
click_icon :edit
|
|
57
|
+
end
|
|
58
|
+
select2 "Default", from: "Shipping Method"
|
|
59
|
+
click_icon :save
|
|
60
|
+
wait_for_ajax
|
|
61
|
+
|
|
62
|
+
page.should have_content("Default $0.00")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "can ship a completed order" do
|
|
66
|
+
click_on "Ship"
|
|
67
|
+
wait_for_ajax
|
|
68
|
+
|
|
69
|
+
page.should have_content("shipped package")
|
|
70
|
+
order.reload.shipment_state.should == "shipped"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'should render unauthorized visiting another suppliers shipment' do
|
|
75
|
+
visit spree.edit_admin_shipment_path(create(:shipment))
|
|
76
|
+
page.should have_content('Authorization Failure')
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Stock Management", js: true do
|
|
4
|
+
|
|
5
|
+
before do
|
|
6
|
+
@user = create(:supplier_user)
|
|
7
|
+
login_user @user
|
|
8
|
+
visit spree.admin_shipments_path
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
context "as supplier user" do
|
|
12
|
+
|
|
13
|
+
context "given a product with a variant and a stock location" do
|
|
14
|
+
before do
|
|
15
|
+
@secondary = create(:stock_location, name: 'Secondary', supplier: @user.supplier)
|
|
16
|
+
@product = create(:product, name: 'apache baseball cap', price: 10)
|
|
17
|
+
@v = @product.variants.create!(sku: 'FOOBAR')
|
|
18
|
+
@user.supplier.reload.stock_locations.update_all backorderable_default: false # True database default is false.
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'with single variant' do
|
|
22
|
+
before do
|
|
23
|
+
@product.add_supplier! @user.supplier
|
|
24
|
+
@v.stock_items.first.update_column(:count_on_hand, 10)
|
|
25
|
+
@secondary.stock_item(@v).destroy
|
|
26
|
+
click_link "Products"
|
|
27
|
+
within '#sidebar-product' do
|
|
28
|
+
click_link 'Products'
|
|
29
|
+
end
|
|
30
|
+
click_link @product.name
|
|
31
|
+
within '[data-hook=admin_product_tabs]' do
|
|
32
|
+
click_link "Stock"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should not show deleted stock_items" do
|
|
37
|
+
within(:css, '.stock_location_info') do
|
|
38
|
+
page.should have_content(@user.supplier.name)
|
|
39
|
+
page.should_not have_content('Secondary')
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "can toggle backorderable for a variant's stock item", js: true do
|
|
44
|
+
backorderable = find(".stock_item_backorderable")
|
|
45
|
+
backorderable.should_not be_checked
|
|
46
|
+
|
|
47
|
+
backorderable.set(true)
|
|
48
|
+
|
|
49
|
+
visit current_path
|
|
50
|
+
|
|
51
|
+
backorderable = find(".stock_item_backorderable")
|
|
52
|
+
backorderable.should be_checked
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Regression test for #2896
|
|
56
|
+
# The regression was that unchecking the last checkbox caused a redirect
|
|
57
|
+
# to happen. By ensuring that we're still on an /admin/products URL, we
|
|
58
|
+
# assert that the redirect is *not* happening.
|
|
59
|
+
it "can toggle backorderable for the second variant stock item", js: true do
|
|
60
|
+
new_location = create(:stock_location, name: "Another Location", supplier: @user.supplier)
|
|
61
|
+
visit page.current_path
|
|
62
|
+
|
|
63
|
+
new_location_backorderable = find "#stock_item_backorderable_#{new_location.id}"
|
|
64
|
+
new_location_backorderable.set(false)
|
|
65
|
+
# Wait for API request to complete.
|
|
66
|
+
sleep(1)
|
|
67
|
+
|
|
68
|
+
page.current_url.should include("/admin/products")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "can create a new stock movement", js: true do
|
|
72
|
+
fill_in "stock_movement_quantity", with: 5
|
|
73
|
+
select2 @user.supplier.name, from: "Stock Location"
|
|
74
|
+
click_button "Add Stock"
|
|
75
|
+
|
|
76
|
+
page.should have_content('successfully created')
|
|
77
|
+
within(:css, '.stock_location_info table') do
|
|
78
|
+
column_text(2).should eq '15'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "can create a new negative stock movement", js: true do
|
|
83
|
+
fill_in "stock_movement_quantity", with: -5
|
|
84
|
+
select2 @user.supplier.name, from: "Stock Location"
|
|
85
|
+
click_button "Add Stock"
|
|
86
|
+
|
|
87
|
+
page.should have_content('successfully created')
|
|
88
|
+
|
|
89
|
+
within(:css, '.stock_location_info table') do
|
|
90
|
+
column_text(2).should eq '5'
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "can create a new negative stock movement", js: true do
|
|
95
|
+
fill_in "stock_movement_quantity", with: -5
|
|
96
|
+
select2 @user.supplier.name, from: "Stock Location"
|
|
97
|
+
click_button "Add Stock"
|
|
98
|
+
|
|
99
|
+
page.should have_content('successfully created')
|
|
100
|
+
|
|
101
|
+
within(:css, '.stock_location_info table') do
|
|
102
|
+
column_text(2).should eq '5'
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context "with multiple variants" do
|
|
108
|
+
before do
|
|
109
|
+
v = @product.variants.create!(sku: 'SPREEC')
|
|
110
|
+
@product.add_supplier! @user.supplier
|
|
111
|
+
v.stock_items.first.update_column(:count_on_hand, 30)
|
|
112
|
+
|
|
113
|
+
click_link "Products"
|
|
114
|
+
within '#sidebar-product' do
|
|
115
|
+
click_link 'Products'
|
|
116
|
+
end
|
|
117
|
+
click_link @product.name
|
|
118
|
+
within '[data-hook=admin_product_tabs]' do
|
|
119
|
+
click_link "Stock"
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "can create a new stock movement for the specified variant", js: true do
|
|
124
|
+
fill_in "stock_movement_quantity", with: 10
|
|
125
|
+
select2 "SPREEC", from: "Variant"
|
|
126
|
+
click_button "Add Stock"
|
|
127
|
+
|
|
128
|
+
page.should have_content('successfully created')
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Regression test for #3304
|
|
134
|
+
context "with no stock location" do
|
|
135
|
+
before do
|
|
136
|
+
@product = create(:product, name: 'apache baseball cap', price: 10)
|
|
137
|
+
@product.add_supplier! @user.supplier
|
|
138
|
+
@product.variants.create!(sku: 'FOOBAR')
|
|
139
|
+
Spree::StockLocation.delete_all
|
|
140
|
+
click_link "Products"
|
|
141
|
+
within '#sidebar-product' do
|
|
142
|
+
click_link 'Products'
|
|
143
|
+
end
|
|
144
|
+
click_link @product.name
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "redirects to stock locations page" do
|
|
148
|
+
page.should have_content(Spree.t(:stock_management_requires_a_stock_location))
|
|
149
|
+
page.current_url.should include("admin/stock_locations")
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
feature 'Admin - Product Stock Management', js: true do
|
|
4
|
+
|
|
5
|
+
before do
|
|
6
|
+
@user = create(:supplier_user)
|
|
7
|
+
@supplier1 = @user.supplier
|
|
8
|
+
@supplier2 = create(:supplier)
|
|
9
|
+
@product = create :product
|
|
10
|
+
@product.add_supplier! @supplier1
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'as Admin' do
|
|
14
|
+
|
|
15
|
+
scenario 'should display all existing stock item locations' do
|
|
16
|
+
login_user create(:admin_user)
|
|
17
|
+
visit spree.stock_admin_product_path(@product)
|
|
18
|
+
|
|
19
|
+
within '.stock_location_info' do
|
|
20
|
+
page.should have_content(@supplier1.name)
|
|
21
|
+
# Stock item doesn't exist
|
|
22
|
+
page.should_not have_content(@supplier2.name)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'as Supplier' do
|
|
29
|
+
|
|
30
|
+
before(:each) do
|
|
31
|
+
login_user @user
|
|
32
|
+
visit '/admin/products'
|
|
33
|
+
click_link "Stock Locations"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
scenario 'should only display suppliers stock locations' do
|
|
37
|
+
visit spree.stock_admin_product_path(@product)
|
|
38
|
+
|
|
39
|
+
within '.stock_location_info' do
|
|
40
|
+
page.should have_content(@supplier1.name)
|
|
41
|
+
page.should_not have_content(@supplier2.name)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
scenario "can create a new stock location" do
|
|
46
|
+
visit spree.new_admin_stock_location_path
|
|
47
|
+
fill_in "Name", with: "London"
|
|
48
|
+
check "Active"
|
|
49
|
+
click_button "Create"
|
|
50
|
+
|
|
51
|
+
page.should have_content("successfully created")
|
|
52
|
+
page.should have_content("London")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
scenario "can delete an existing stock location", js: true do
|
|
56
|
+
create(:stock_location, supplier: @user.supplier)
|
|
57
|
+
visit current_path
|
|
58
|
+
|
|
59
|
+
find('#listing_stock_locations').should have_content("NY Warehouse")
|
|
60
|
+
within_row(2) { click_icon :delete }
|
|
61
|
+
page.driver.browser.switch_to.alert.accept
|
|
62
|
+
# Wait for API request to complete.
|
|
63
|
+
sleep(1)
|
|
64
|
+
visit current_path
|
|
65
|
+
|
|
66
|
+
find('#listing_stock_locations').should_not have_content("NY Warehouse")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
scenario "can update an existing stock location" do
|
|
70
|
+
create(:stock_location, supplier: @user.supplier)
|
|
71
|
+
visit current_path
|
|
72
|
+
|
|
73
|
+
page.should have_content("Big Store")
|
|
74
|
+
|
|
75
|
+
within_row(1) { click_icon :edit }
|
|
76
|
+
fill_in "Name", with: "London"
|
|
77
|
+
click_button "Update"
|
|
78
|
+
|
|
79
|
+
page.should have_content("successfully updated")
|
|
80
|
+
page.should have_content("London")
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
scenario "can deactivate an existing stock location" do
|
|
84
|
+
create(:stock_location, supplier: @user.supplier)
|
|
85
|
+
visit current_path
|
|
86
|
+
|
|
87
|
+
page.should have_content("Big Store")
|
|
88
|
+
|
|
89
|
+
within_row(1) { click_icon :edit }
|
|
90
|
+
uncheck "Active"
|
|
91
|
+
click_button "Update"
|
|
92
|
+
|
|
93
|
+
find('#listing_stock_locations').should have_content("Inactive")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|