solidus_marketplace 0.1.0
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/.rspec +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +8 -0
- data/LICENSE +26 -0
- data/README.md +123 -0
- data/Rakefile +15 -0
- data/Versionfile +6 -0
- data/app/assets/javascripts/spree/backend/solidus_marketplace.js +5 -0
- data/app/assets/javascripts/spree/backend/solidus_marketplace_routes.js +1 -0
- data/app/assets/javascripts/spree/backend/suppliers_autocomplete.js +55 -0
- data/app/assets/javascripts/spree/frontend/solidus_marketplace.js +1 -0
- data/app/assets/stylesheets/spree/backend/solidus_marketplace.scss +22 -0
- data/app/assets/stylesheets/spree/frontend/solidus_marketplace.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/marketplace_settings_controller.rb +19 -0
- data/app/controllers/spree/admin/products_controller_decorator.rb +79 -0
- data/app/controllers/spree/admin/reports_controller_decorator.rb +68 -0
- data/app/controllers/spree/admin/shipments_controller.rb +47 -0
- data/app/controllers/spree/admin/stock_items_controller_decorator.rb +10 -0
- data/app/controllers/spree/admin/stock_locations_controller_decorator.rb +23 -0
- data/app/controllers/spree/admin/suppliers_controller.rb +54 -0
- data/app/controllers/spree/admin/users_controller_decorator.rb +34 -0
- data/app/controllers/spree/api/suppliers_controller.rb +16 -0
- data/app/controllers/spree/api/v1/stock_locations_controller_decorator.rb +18 -0
- data/app/controllers/spree/base_controller_decorator.rb +13 -0
- data/app/helpers/spree/api/api_helpers_decorator.rb +22 -0
- data/app/mailers/spree/marketplace_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.rb +5 -0
- data/app/models/spree/marketplace_configuration.rb +14 -0
- data/app/models/spree/order_decorator.rb +44 -0
- data/app/models/spree/payment_decorator.rb +7 -0
- data/app/models/spree/product_decorator.rb +52 -0
- data/app/models/spree/shipment_decorator.rb +40 -0
- data/app/models/spree/stock/splitter/marketplace.rb +47 -0
- data/app/models/spree/stock_location_decorator.rb +23 -0
- data/app/models/spree/supplier.rb +120 -0
- data/app/models/spree/supplier_ability.rb +35 -0
- data/app/models/spree/supplier_variant.rb +6 -0
- data/app/models/spree/user_decorator.rb +23 -0
- data/app/models/spree/variant_decorator.rb +24 -0
- data/app/overrides/spree/admin/menus.rb +15 -0
- data/app/overrides/spree/admin/products/_form/converted_admin_product_form_right.html.erb.deface +5 -0
- data/app/overrides/spree/admin/products/edit/override_rows.html.erb.deface +22 -0
- data/app/overrides/spree/admin/stock_locations/_form/add_supplier.html.erb.deface +12 -0
- data/app/views/spree/admin/marketplace_settings/edit.html.erb +21 -0
- data/app/views/spree/admin/orders/index.html.erb +187 -0
- data/app/views/spree/admin/products/_form.html.erb +198 -0
- data/app/views/spree/admin/reports/earnings.html.erb +34 -0
- data/app/views/spree/admin/shared/_marketplace_settings.html.erb +1 -0
- data/app/views/spree/admin/shared/_marketplace_tabs.html.erb +4 -0
- data/app/views/spree/admin/shipments/edit.html.erb +24 -0
- data/app/views/spree/admin/shipments/index.html.erb +93 -0
- data/app/views/spree/admin/suppliers/_form.html.erb +75 -0
- data/app/views/spree/admin/suppliers/edit.html.erb +22 -0
- data/app/views/spree/admin/suppliers/index.html.erb +68 -0
- data/app/views/spree/admin/suppliers/new.html.erb +17 -0
- data/app/views/spree/api/shared/_pagination.json.jbuilder +5 -0
- data/app/views/spree/api/suppliers/_supplier.json.jbuilder +1 -0
- data/app/views/spree/api/suppliers/index.json.jbuilder +4 -0
- data/app/views/spree/marketplace_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 +107 -0
- data/config/locales/es.yml +133 -0
- data/config/routes.rb +24 -0
- data/db/default/spree/marketplace_roles.rb +14 -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/db/migrate/20171027180043_add_paypal_email_to_suppliers.rb +5 -0
- data/db/seeds.rb +8 -0
- data/lib/generators/solidus_marketplace/install/install_generator.rb +36 -0
- data/lib/solidus_marketplace.rb +6 -0
- data/lib/solidus_marketplace/engine.rb +53 -0
- data/lib/solidus_marketplace/factories.rb +107 -0
- data/lib/solidus_marketplace/version.rb +3 -0
- data/lib/spree/permitted_attributes_decorator.rb +18 -0
- data/lib/tasks/spree_sample.rake +72 -0
- data/log/awesome.log +1 -0
- data/script/rails +7 -0
- data/solidus_marketplace.gemspec +46 -0
- data/spec/features/admin/orders_spec.rb +11 -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 +156 -0
- data/spec/features/admin/stock_spec.rb +98 -0
- data/spec/features/admin/suppliers_spec.rb +130 -0
- data/spec/models/spree/order_decorator_spec.rb +80 -0
- data/spec/models/spree/payment_decorator_spec.rb +7 -0
- data/spec/models/spree/product_decorator_spec.rb +56 -0
- data/spec/models/spree/shipment_decorator_spec.rb +48 -0
- data/spec/models/spree/stock/splitter/marketplace_spec.rb +62 -0
- data/spec/models/spree/stock_location_decorator_spec.rb +33 -0
- data/spec/models/spree/supplier_ability_spec.rb +182 -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 +57 -0
- data/spec/models/spree/variant_decorator_spec.rb +7 -0
- data/spec/spec_helper.rb +91 -0
- data/spec/support/ability_helpers.rb +11 -0
- data/spec/support/integration_helpers.rb +15 -0
- metadata +473 -0
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
feature 'Admin - Suppliers', js: true do
|
4
|
+
|
5
|
+
before do
|
6
|
+
country = create(:country, name: "United States")
|
7
|
+
create(:state, name: "Vermont", country: country)
|
8
|
+
@supplier = create :supplier
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'as an MarketMaker (aka admin)' do
|
12
|
+
|
13
|
+
before do
|
14
|
+
login_user create(:admin_user)
|
15
|
+
visit spree.admin_path
|
16
|
+
within '[data-hook=admin_tabs]' do
|
17
|
+
click_link 'Suppliers'
|
18
|
+
end
|
19
|
+
expect(page).to have_content('Suppliers')
|
20
|
+
end
|
21
|
+
|
22
|
+
xscenario 'should be able to create new supplier' do
|
23
|
+
click_link 'New Supplier'
|
24
|
+
check 'supplier_active'
|
25
|
+
fill_in 'supplier[name]', with: 'Test Supplier'
|
26
|
+
fill_in 'supplier[email]', with: 'spree@example.com'
|
27
|
+
fill_in 'supplier[url]', with: 'http://www.test.com'
|
28
|
+
fill_in 'supplier[commission_flat_rate]', with: '0'
|
29
|
+
fill_in 'supplier[commission_percentage]', with: '0'
|
30
|
+
fill_in 'supplier[address_attributes][firstname]', with: 'First'
|
31
|
+
fill_in 'supplier[address_attributes][lastname]', with: 'Last'
|
32
|
+
fill_in 'supplier[address_attributes][address1]', with: '1 Test Drive'
|
33
|
+
fill_in 'supplier[address_attributes][city]', with: 'Test City'
|
34
|
+
fill_in 'supplier[address_attributes][zipcode]', with: '55555'
|
35
|
+
select2 'United States of America', from: 'Country'
|
36
|
+
select2 'Vermont', from: 'State'
|
37
|
+
fill_in 'supplier[address_attributes][phone]', with: '555-555-5555'
|
38
|
+
click_button 'Create'
|
39
|
+
expect(page).to have_content('Supplier "Test Supplier" has been successfully created!')
|
40
|
+
end
|
41
|
+
|
42
|
+
xscenario 'should be able to delete supplier' do
|
43
|
+
click_icon 'delete'
|
44
|
+
page.driver.browser.switch_to.alert.accept
|
45
|
+
within 'table' do
|
46
|
+
expect(page).to_not have_content(@supplier.name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
xscenario 'should be able to edit supplier' do
|
51
|
+
click_icon 'edit'
|
52
|
+
check 'supplier_active'
|
53
|
+
fill_in 'supplier[name]', with: 'Test Supplier'
|
54
|
+
fill_in 'supplier[email]', with: 'spree@example.com'
|
55
|
+
fill_in 'supplier[url]', with: 'http://www.test.com'
|
56
|
+
fill_in 'supplier[commission_flat_rate]', with: '0'
|
57
|
+
fill_in 'supplier[commission_percentage]', with: '0'
|
58
|
+
fill_in 'supplier[address_attributes][firstname]', with: 'First'
|
59
|
+
fill_in 'supplier[address_attributes][lastname]', with: 'Last'
|
60
|
+
fill_in 'supplier[address_attributes][address1]', with: '1 Test Drive'
|
61
|
+
fill_in 'supplier[address_attributes][city]', with: 'Test City'
|
62
|
+
fill_in 'supplier[address_attributes][zipcode]', with: '55555'
|
63
|
+
select2 'United States', from: 'Country'
|
64
|
+
select2 'Vermont', from: 'State'
|
65
|
+
fill_in 'supplier[address_attributes][phone]', with: '555-555-5555'
|
66
|
+
click_button 'Update'
|
67
|
+
expect(page).to have_content('Supplier "Test Supplier" has been successfully updated!')
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'as a Supplier' do
|
73
|
+
before do
|
74
|
+
@user = create(:supplier_admin)
|
75
|
+
login_user @user
|
76
|
+
visit spree.edit_admin_supplier_path(@user.supplier)
|
77
|
+
end
|
78
|
+
|
79
|
+
scenario 'should only see tabs they have access to' do
|
80
|
+
within '[data-hook=admin_tabs]' do
|
81
|
+
expect(page).to have_link('Products')
|
82
|
+
expect(page).to have_link('Stock')
|
83
|
+
expect(page).to have_link('Stock Locations')
|
84
|
+
expect(page).to have_link('Profile')
|
85
|
+
expect(page).to have_link('Orders')
|
86
|
+
expect(page).to have_link('Suppliers')
|
87
|
+
|
88
|
+
expect(page).to_not have_link('Overview')
|
89
|
+
expect(page).to_not have_link('Reports')
|
90
|
+
expect(page).to_not have_link('Configuration')
|
91
|
+
expect(page).to_not have_link('Promotions')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
xscenario 'should be able to update supplier' do
|
96
|
+
fill_in 'supplier[name]', with: 'Test Supplier'
|
97
|
+
fill_in 'supplier[email]', with: @user.email
|
98
|
+
fill_in 'supplier[url]', with: 'http://www.test.com'
|
99
|
+
fill_in 'supplier[address_attributes][firstname]', with: 'First'
|
100
|
+
fill_in 'supplier[address_attributes][lastname]', with: 'Last'
|
101
|
+
fill_in 'supplier[address_attributes][address1]', with: '1 Test Drive'
|
102
|
+
fill_in 'supplier[address_attributes][city]', with: 'Test City'
|
103
|
+
fill_in 'supplier[address_attributes][zipcode]', with: '55555'
|
104
|
+
select2 'United States', from: 'Country'
|
105
|
+
select2 'Vermont', from: 'State'
|
106
|
+
fill_in 'supplier[address_attributes][phone]', with: '555-555-5555'
|
107
|
+
expect(page).to_not have_css('#supplier_active') # cannot edit active
|
108
|
+
expect(page).to_not have_css('#supplier_featured') # cannot edit featured
|
109
|
+
expect(page).to_not have_css('#s2id_supplier_user_ids') # cannot edit assigned users
|
110
|
+
expect(page).to_not have_css('#supplier_commission_flat_rate') # cannot edit flat rate commission
|
111
|
+
expect(page).to_not have_css('#supplier_commission_percentage') # cannot edit comission percentage
|
112
|
+
click_button 'Update'
|
113
|
+
expect(page).to have_content('Supplier "Test Supplier" has been successfully updated!')
|
114
|
+
expect(page.current_path).to eql(spree.edit_admin_supplier_path(@user.reload.supplier))
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'as a User other than the suppliers' do
|
120
|
+
|
121
|
+
scenario 'should be unauthorized' do
|
122
|
+
supplier = create(:supplier)
|
123
|
+
login_user create(:user)
|
124
|
+
visit spree.edit_admin_supplier_path(supplier)
|
125
|
+
expect(page).to have_content('Authorization Failure')
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::Order do
|
4
|
+
|
5
|
+
context '#finalize_with_supplier!' do
|
6
|
+
|
7
|
+
after do
|
8
|
+
SolidusMarketplace::Config[:send_supplier_email] = true
|
9
|
+
end
|
10
|
+
|
11
|
+
xit 'should deliver marketplace orders when SolidusMarketplace::Config[:send_supplier_email] == true' do
|
12
|
+
order = create(:order_with_totals, ship_address: create(:address))
|
13
|
+
order.line_items = [create(:line_item, variant: create(:variant_with_supplier)), create(:line_item, variant: create(:variant_with_supplier))]
|
14
|
+
order.create_proposed_shipments
|
15
|
+
|
16
|
+
order.shipments.each do |shipment|
|
17
|
+
expect(Spree::MarketplaceOrderMailer).to receive(:supplier_order).with(shipment.id).and_return(double(Mail, :deliver! => true))
|
18
|
+
end
|
19
|
+
|
20
|
+
order.finalize!
|
21
|
+
order.reload
|
22
|
+
|
23
|
+
# Check orders are properly split.
|
24
|
+
expect(order.shipments.size).to eql(2)
|
25
|
+
order.shipments.each do |shipment|
|
26
|
+
expect(shipment.line_items.size).to eql(1)
|
27
|
+
expect(shipment.line_items.first.variant.suppliers.first).to eql(shipment.supplier)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should NOT deliver marketplace orders when SolidusMarketplace::Config[:send_supplier_email] == false' do
|
32
|
+
SolidusMarketplace::Config[:send_supplier_email] = false
|
33
|
+
order = create(:order_with_totals, ship_address: create(:address))
|
34
|
+
order.line_items = [create(:line_item, variant: create(:variant_with_supplier)), create(:line_item, variant: create(:variant_with_supplier))]
|
35
|
+
order.create_proposed_shipments
|
36
|
+
|
37
|
+
order.shipments.each do |shipment|
|
38
|
+
expect(Spree::MarketplaceOrderMailer).not_to receive(:supplier_order).with(shipment.id)
|
39
|
+
end
|
40
|
+
|
41
|
+
order.finalize!
|
42
|
+
order.reload
|
43
|
+
|
44
|
+
# Check orders are properly split.
|
45
|
+
expect(order.shipments.size).to eql(2)
|
46
|
+
order.shipments.each do |shipment|
|
47
|
+
expect(shipment.line_items.size).to eql(1)
|
48
|
+
expect(shipment.line_items.first.variant.suppliers.first).to eql(shipment.supplier)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#supplier_total" do
|
55
|
+
context "when passed a supplier" do
|
56
|
+
it "returns the total commission earned for the order for a given supplier" do
|
57
|
+
order = create(:completed_order_from_supplier_with_totals, ship_address: create(:address))
|
58
|
+
supplier = order.suppliers.first
|
59
|
+
expected_supplier_total = Spree::Money.new(15.00)
|
60
|
+
expect(order.total).to eq(150.0)
|
61
|
+
expect(order.suppliers.count).to eq(1)
|
62
|
+
expect(order.supplier_total(supplier)).to eq(expected_supplier_total)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when passed a user associated with a supplier" do
|
67
|
+
it "returns the total commission earned for the order for a given supplier" do
|
68
|
+
order = create(:completed_order_from_supplier_with_totals, ship_address: create(:address))
|
69
|
+
supplier = order.suppliers.first
|
70
|
+
supplier_user = create(:supplier_user, supplier: supplier)
|
71
|
+
|
72
|
+
expected_supplier_total = Spree::Money.new(15.00)
|
73
|
+
expect(order.total).to eq(150.0)
|
74
|
+
expect(order.suppliers.count).to eq(1)
|
75
|
+
expect(order.supplier_total(supplier_user)).to eq(expected_supplier_total)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::Product do
|
4
|
+
|
5
|
+
let(:product) { create :product }
|
6
|
+
let(:supplier1) { create(:supplier) }
|
7
|
+
let(:supplier2) { create(:supplier) }
|
8
|
+
|
9
|
+
describe "#add_supplier!" do
|
10
|
+
context "when passed a supplier" do
|
11
|
+
it "adds the supplier to product's list of supppliers" do
|
12
|
+
expect(product.suppliers).to be_empty
|
13
|
+
product.add_supplier!(supplier1)
|
14
|
+
expect(product.reload.suppliers).to include(supplier1)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when passed a supplier_id" do
|
19
|
+
it "adds the supplier to product's list of supppliers" do
|
20
|
+
expect(product.suppliers).to be_empty
|
21
|
+
product.add_supplier!(supplier2.id)
|
22
|
+
expect(product.reload.suppliers).to include(supplier2)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#add_suppliers!" do
|
28
|
+
it "adds multiple suppliers to the product's list of suppliers" do
|
29
|
+
expect(product.suppliers).to be_empty
|
30
|
+
product.add_suppliers!([supplier1.id, supplier2.id])
|
31
|
+
expect(product.reload.suppliers).to include(supplier1)
|
32
|
+
expect(product.reload.suppliers).to include(supplier2)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#remove_suppliers!" do
|
37
|
+
it "removes multiple suppliers from the product's list of suppliers" do
|
38
|
+
product.add_suppliers!([supplier1.id, supplier2.id])
|
39
|
+
expect(product.reload.suppliers).to include(supplier1)
|
40
|
+
expect(product.reload.suppliers).to include(supplier2)
|
41
|
+
|
42
|
+
product.remove_suppliers!([supplier1.id, supplier2.id])
|
43
|
+
expect(product.suppliers).to be_empty
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#supplier?' do
|
48
|
+
it "returns true if one or more suppliers are present" do
|
49
|
+
expect(product.supplier?).to eq false
|
50
|
+
product.add_supplier! create(:supplier)
|
51
|
+
expect(product.reload.supplier?).to eq true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::Shipment do
|
4
|
+
|
5
|
+
describe 'Scopes' do
|
6
|
+
|
7
|
+
it '#by_supplier' do
|
8
|
+
supplier = create(:supplier)
|
9
|
+
stock_location_1 = supplier.stock_locations.first
|
10
|
+
stock_location_2 = create(:stock_location, supplier: supplier)
|
11
|
+
shipment_1 = create(:shipment)
|
12
|
+
shipment_2 = create(:shipment, stock_location: stock_location_1)
|
13
|
+
shipment_3 = create(:shipment)
|
14
|
+
shipment_4 = create(:shipment, stock_location: stock_location_2)
|
15
|
+
shipment_5 = create(:shipment)
|
16
|
+
shipment_6 = create(:shipment, stock_location: stock_location_1)
|
17
|
+
|
18
|
+
expect(subject.class.by_supplier(supplier.id)).to match_array([shipment_2, shipment_4, shipment_6])
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#after_ship' do
|
24
|
+
|
25
|
+
it 'should capture payment if balance due' do
|
26
|
+
skip 'TODO make it so!'
|
27
|
+
end
|
28
|
+
|
29
|
+
xit 'should track commission for shipment' do
|
30
|
+
supplier = create(:supplier_with_commission)
|
31
|
+
shipment = create(:shipment, stock_location: supplier.stock_locations.first)
|
32
|
+
|
33
|
+
expect(shipment.supplier_commission.to_f).to eql(0.0)
|
34
|
+
allow(shipment).to receive(:final_price_with_items).and_return(10.0)
|
35
|
+
shipment.send(:after_ship)
|
36
|
+
expect(shipment.reload.supplier_commission.to_f).to eql(1.5)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
it '#final_price_with_items' do
|
42
|
+
shipment = build :shipment
|
43
|
+
allow(shipment).to receive(:item_cost).and_return(50.0)
|
44
|
+
allow(shipment).to receive(:final_price).and_return(5.5)
|
45
|
+
expect(shipment.final_price_with_items.to_f).to eql(55.5)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
module Stock
|
5
|
+
module Splitter
|
6
|
+
describe Marketplace do
|
7
|
+
|
8
|
+
let(:supplier_1) { create(:supplier) }
|
9
|
+
let(:supplier_2) { create(:supplier) }
|
10
|
+
|
11
|
+
let(:variant_1) {
|
12
|
+
v = create(:variant)
|
13
|
+
v.product.add_supplier! supplier_1
|
14
|
+
v.reload.supplier_variants.find_by_supplier_id(supplier_1.id).update_column(:cost, 5)
|
15
|
+
v.product.add_supplier! supplier_2
|
16
|
+
v.reload.supplier_variants.find_by_supplier_id(supplier_2.id).update_column(:cost, 6)
|
17
|
+
v
|
18
|
+
}
|
19
|
+
let(:variant_2) {
|
20
|
+
v = create(:variant)
|
21
|
+
v.product.add_supplier! supplier_1
|
22
|
+
v.reload.supplier_variants.find_by_supplier_id(supplier_1.id).update_column(:cost, 5)
|
23
|
+
v.product.add_supplier! supplier_2
|
24
|
+
v.reload.supplier_variants.find_by_supplier_id(supplier_2.id).update_column(:cost, 4)
|
25
|
+
v
|
26
|
+
}
|
27
|
+
let(:variant_3) {
|
28
|
+
v = create(:variant)
|
29
|
+
v.product.add_supplier! supplier_1
|
30
|
+
v.product.add_supplier! supplier_2
|
31
|
+
v.reload
|
32
|
+
}
|
33
|
+
let(:variant_4) { create(:variant) }
|
34
|
+
|
35
|
+
let(:variants){
|
36
|
+
[variant_1, variant_2, variant_3, variant_4]
|
37
|
+
}
|
38
|
+
|
39
|
+
let(:packer) { build(:stock_packer) }
|
40
|
+
|
41
|
+
subject { Marketplace.new(packer.stock_location) }
|
42
|
+
|
43
|
+
it 'splits packages for suppliers to ship' do
|
44
|
+
package = Package.new(packer.stock_location)
|
45
|
+
package = Package.new(packer.stock_location)
|
46
|
+
4.times { |i| package.add build(:inventory_unit, variant: variants[i]) }
|
47
|
+
|
48
|
+
packages = subject.split([package])
|
49
|
+
expect(packages.count).to eq 3
|
50
|
+
|
51
|
+
expect(packages[0].stock_location).to eq(packer.stock_location)
|
52
|
+
expect(packages[0].contents.count).to eq(1)
|
53
|
+
expect(packages[1].stock_location).to eq(supplier_1.stock_locations.first)
|
54
|
+
expect(packages[1].contents.count).to eq(2)
|
55
|
+
expect(packages[2].stock_location).to eq(supplier_2.stock_locations.first)
|
56
|
+
expect(packages[2].contents.count).to eq(1)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::StockLocation do
|
4
|
+
|
5
|
+
it { should belong_to(:supplier) }
|
6
|
+
|
7
|
+
subject { create(:stock_location, backorderable_default: true) }
|
8
|
+
|
9
|
+
context "propagate variants" do
|
10
|
+
|
11
|
+
let(:variant) { build(:variant) }
|
12
|
+
let(:stock_item) { subject.propagate_variant(variant) }
|
13
|
+
|
14
|
+
context "passes backorderable default config" do
|
15
|
+
context "true" do
|
16
|
+
before { subject.backorderable_default = true }
|
17
|
+
xit { expect(stock_item.backorderable).to eq true }
|
18
|
+
end
|
19
|
+
|
20
|
+
context "false" do
|
21
|
+
before { subject.backorderable_default = false }
|
22
|
+
xit { expect(stock_item.backorderable).to eq false }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'does not propagate for non supplier variants' do
|
27
|
+
before { subject.supplier_id = create(:supplier).id }
|
28
|
+
it { expect(stock_item).to be_nil }
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'cancan/matchers'
|
3
|
+
require 'spree/testing_support/ability_helpers'
|
4
|
+
|
5
|
+
describe Spree::SupplierAbility do
|
6
|
+
|
7
|
+
let(:supplier) { create(:supplier) }
|
8
|
+
let(:supplier_admin_role) { build :role, name: "supplier_admin" }
|
9
|
+
let(:user) { create(:user, supplier: supplier) }
|
10
|
+
let(:ability) { Spree::SupplierAbility.new(user) }
|
11
|
+
let(:token) { nil }
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
user.spree_roles << supplier_admin_role
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'for Dash' do
|
18
|
+
let(:resource) { Spree::Admin::RootController }
|
19
|
+
|
20
|
+
context 'requested by supplier' do
|
21
|
+
it_should_behave_like 'access denied'
|
22
|
+
it_should_behave_like 'no index allowed'
|
23
|
+
it_should_behave_like 'admin denied'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'for Product' do
|
28
|
+
let(:resource) { create(:product) }
|
29
|
+
|
30
|
+
before(:each) do
|
31
|
+
resource.add_supplier!(user.supplier)
|
32
|
+
resource.reload
|
33
|
+
end
|
34
|
+
|
35
|
+
it_should_behave_like 'index allowed'
|
36
|
+
it_should_behave_like 'read and update access granted'
|
37
|
+
it_should_behave_like 'admin granted'
|
38
|
+
|
39
|
+
context 'requested by another suppliers user' do
|
40
|
+
let(:other_resource) {
|
41
|
+
product = create(:product)
|
42
|
+
product.add_supplier!(create(:supplier))
|
43
|
+
product
|
44
|
+
}
|
45
|
+
it { expect(ability).to_not be_able_to :read, other_resource }
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'requested by suppliers user' do
|
49
|
+
let(:resource) {
|
50
|
+
product = create(:product)
|
51
|
+
product.add_supplier!(user.supplier)
|
52
|
+
product.reload
|
53
|
+
}
|
54
|
+
# it_should_behave_like 'access granted'
|
55
|
+
it { expect(ability).to be_able_to :read, resource }
|
56
|
+
it { expect(ability).to be_able_to :stock, resource }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'for Shipment' do
|
61
|
+
context 'requested by another suppliers user' do
|
62
|
+
let(:resource) { Spree::Shipment.new({stock_location: create(:stock_location, supplier: create(:supplier))}) }
|
63
|
+
it_should_behave_like 'access denied'
|
64
|
+
it_should_behave_like 'no index allowed'
|
65
|
+
it_should_behave_like 'admin denied'
|
66
|
+
it { expect(ability).to_not be_able_to :ready, resource }
|
67
|
+
it { expect(ability).to_not be_able_to :ship, resource }
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'requested by suppliers user' do
|
71
|
+
context 'when order is complete' do
|
72
|
+
let(:resource) {
|
73
|
+
order = create(:completed_order_from_supplier_with_totals)
|
74
|
+
order.stock_locations.first.update_attribute :supplier, user.supplier
|
75
|
+
Spree::Shipment.new({order: order, stock_location: order.stock_locations.first })
|
76
|
+
}
|
77
|
+
it_should_behave_like 'read only'
|
78
|
+
it_should_behave_like 'index allowed'
|
79
|
+
it_should_behave_like 'admin granted'
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when order is incomplete' do
|
83
|
+
let(:resource) { Spree::Shipment.new({stock_location: create(:stock_location, supplier: user.supplier)}) }
|
84
|
+
it_should_behave_like 'access denied'
|
85
|
+
it { expect(ability).to_not be_able_to :ready, resource }
|
86
|
+
it { expect(ability).to_not be_able_to :ship, resource }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'for StockItem' do
|
92
|
+
let(:resource) { Spree::StockItem }
|
93
|
+
|
94
|
+
it_should_behave_like 'index allowed'
|
95
|
+
it_should_behave_like 'admin granted'
|
96
|
+
|
97
|
+
context 'requested by another suppliers user' do
|
98
|
+
let(:resource) {
|
99
|
+
supplier = create(:supplier)
|
100
|
+
variant = create(:product).master
|
101
|
+
variant.product.add_supplier! supplier
|
102
|
+
supplier.stock_locations.first.stock_items.first
|
103
|
+
}
|
104
|
+
it_should_behave_like 'access denied'
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'requested by suppliers user' do
|
108
|
+
let(:resource) {
|
109
|
+
variant = create(:product).master
|
110
|
+
variant.product.add_supplier! user.supplier
|
111
|
+
user.supplier.stock_locations.first.stock_items.first
|
112
|
+
}
|
113
|
+
it_should_behave_like 'access granted'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'for StockLocation' do
|
118
|
+
context 'requsted by another suppliers user' do
|
119
|
+
let(:resource) {
|
120
|
+
supplier = create(:supplier)
|
121
|
+
variant = create(:product).master
|
122
|
+
variant.product.add_supplier! supplier
|
123
|
+
supplier.stock_locations.first
|
124
|
+
}
|
125
|
+
it_should_behave_like 'access denied'
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'requested by suppliers user' do
|
129
|
+
let(:resource) {
|
130
|
+
variant = create(:product).master
|
131
|
+
variant.product.add_supplier! user.supplier
|
132
|
+
user.supplier.stock_locations.first
|
133
|
+
}
|
134
|
+
it_should_behave_like 'access granted'
|
135
|
+
it_should_behave_like 'admin granted'
|
136
|
+
it_should_behave_like 'index allowed'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'for StockMovement' do
|
141
|
+
let(:resource) { Spree::StockMovement }
|
142
|
+
|
143
|
+
it_should_behave_like 'index allowed'
|
144
|
+
it_should_behave_like 'admin granted'
|
145
|
+
|
146
|
+
context 'requested by another suppliers user' do
|
147
|
+
let(:resource) {
|
148
|
+
supplier = create(:supplier)
|
149
|
+
variant = create(:product).master
|
150
|
+
variant.product.add_supplier! supplier
|
151
|
+
Spree::StockMovement.new({ stock_item: supplier.stock_locations.first.stock_items.first })
|
152
|
+
}
|
153
|
+
it_should_behave_like 'admin denied'
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'requested by suppliers user' do
|
157
|
+
let(:resource) {
|
158
|
+
variant = create(:product).master
|
159
|
+
variant.product.add_supplier! user.supplier
|
160
|
+
Spree::StockMovement.new({ stock_item: user.supplier.stock_locations.first.stock_items.first })
|
161
|
+
}
|
162
|
+
it_should_behave_like 'access granted'
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'for Supplier' do
|
167
|
+
context 'requested by any user' do
|
168
|
+
let(:ability) { Spree::SupplierAbility.new(create(:user)) }
|
169
|
+
let(:resource) { Spree::Supplier }
|
170
|
+
|
171
|
+
it_should_behave_like 'admin denied'
|
172
|
+
it_should_behave_like 'access denied'
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'requested by suppliers user' do
|
176
|
+
let(:resource) { user.supplier }
|
177
|
+
it_should_behave_like 'admin granted'
|
178
|
+
it_should_behave_like 'read and update access granted'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|