spree_drop_ship 3.1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|