solidus_marketplace 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +8 -0
  6. data/LICENSE +26 -0
  7. data/README.md +123 -0
  8. data/Rakefile +15 -0
  9. data/Versionfile +6 -0
  10. data/app/assets/javascripts/spree/backend/solidus_marketplace.js +5 -0
  11. data/app/assets/javascripts/spree/backend/solidus_marketplace_routes.js +1 -0
  12. data/app/assets/javascripts/spree/backend/suppliers_autocomplete.js +55 -0
  13. data/app/assets/javascripts/spree/frontend/solidus_marketplace.js +1 -0
  14. data/app/assets/stylesheets/spree/backend/solidus_marketplace.scss +22 -0
  15. data/app/assets/stylesheets/spree/frontend/solidus_marketplace.css +3 -0
  16. data/app/controllers/ckeditor/attachment_files_controller_decorator.rb +20 -0
  17. data/app/controllers/ckeditor/pictures_controller_decorator.rb +17 -0
  18. data/app/controllers/spree/admin/marketplace_settings_controller.rb +19 -0
  19. data/app/controllers/spree/admin/products_controller_decorator.rb +79 -0
  20. data/app/controllers/spree/admin/reports_controller_decorator.rb +68 -0
  21. data/app/controllers/spree/admin/shipments_controller.rb +47 -0
  22. data/app/controllers/spree/admin/stock_items_controller_decorator.rb +10 -0
  23. data/app/controllers/spree/admin/stock_locations_controller_decorator.rb +23 -0
  24. data/app/controllers/spree/admin/suppliers_controller.rb +54 -0
  25. data/app/controllers/spree/admin/users_controller_decorator.rb +34 -0
  26. data/app/controllers/spree/api/suppliers_controller.rb +16 -0
  27. data/app/controllers/spree/api/v1/stock_locations_controller_decorator.rb +18 -0
  28. data/app/controllers/spree/base_controller_decorator.rb +13 -0
  29. data/app/helpers/spree/api/api_helpers_decorator.rb +22 -0
  30. data/app/mailers/spree/marketplace_order_mailer.rb +13 -0
  31. data/app/mailers/spree/supplier_mailer.rb +12 -0
  32. data/app/models/ckeditor/asset_decorator.rb +5 -0
  33. data/app/models/spree.rb +5 -0
  34. data/app/models/spree/marketplace_configuration.rb +14 -0
  35. data/app/models/spree/order_decorator.rb +44 -0
  36. data/app/models/spree/payment_decorator.rb +7 -0
  37. data/app/models/spree/product_decorator.rb +52 -0
  38. data/app/models/spree/shipment_decorator.rb +40 -0
  39. data/app/models/spree/stock/splitter/marketplace.rb +47 -0
  40. data/app/models/spree/stock_location_decorator.rb +23 -0
  41. data/app/models/spree/supplier.rb +120 -0
  42. data/app/models/spree/supplier_ability.rb +35 -0
  43. data/app/models/spree/supplier_variant.rb +6 -0
  44. data/app/models/spree/user_decorator.rb +23 -0
  45. data/app/models/spree/variant_decorator.rb +24 -0
  46. data/app/overrides/spree/admin/menus.rb +15 -0
  47. data/app/overrides/spree/admin/products/_form/converted_admin_product_form_right.html.erb.deface +5 -0
  48. data/app/overrides/spree/admin/products/edit/override_rows.html.erb.deface +22 -0
  49. data/app/overrides/spree/admin/stock_locations/_form/add_supplier.html.erb.deface +12 -0
  50. data/app/views/spree/admin/marketplace_settings/edit.html.erb +21 -0
  51. data/app/views/spree/admin/orders/index.html.erb +187 -0
  52. data/app/views/spree/admin/products/_form.html.erb +198 -0
  53. data/app/views/spree/admin/reports/earnings.html.erb +34 -0
  54. data/app/views/spree/admin/shared/_marketplace_settings.html.erb +1 -0
  55. data/app/views/spree/admin/shared/_marketplace_tabs.html.erb +4 -0
  56. data/app/views/spree/admin/shipments/edit.html.erb +24 -0
  57. data/app/views/spree/admin/shipments/index.html.erb +93 -0
  58. data/app/views/spree/admin/suppliers/_form.html.erb +75 -0
  59. data/app/views/spree/admin/suppliers/edit.html.erb +22 -0
  60. data/app/views/spree/admin/suppliers/index.html.erb +68 -0
  61. data/app/views/spree/admin/suppliers/new.html.erb +17 -0
  62. data/app/views/spree/api/shared/_pagination.json.jbuilder +5 -0
  63. data/app/views/spree/api/suppliers/_supplier.json.jbuilder +1 -0
  64. data/app/views/spree/api/suppliers/index.json.jbuilder +4 -0
  65. data/app/views/spree/marketplace_order_mailer/supplier_order.html.erb +119 -0
  66. data/app/views/spree/shared/unauthorized.erb +1 -0
  67. data/app/views/spree/supplier_mailer/welcome.html.erb +53 -0
  68. data/config/locales/en.yml +107 -0
  69. data/config/locales/es.yml +133 -0
  70. data/config/routes.rb +24 -0
  71. data/db/default/spree/marketplace_roles.rb +14 -0
  72. data/db/migrate/20121006073854_create_suppliers.rb +20 -0
  73. data/db/migrate/20130216070944_product_belongs_to_supplier.rb +6 -0
  74. data/db/migrate/20130405005502_stock_locations_belongs_to_supplier.rb +6 -0
  75. data/db/migrate/20130405011127_user_belongs_to_supplier.rb +6 -0
  76. data/db/migrate/20130428063053_add_balanced_token_to_suppliers.rb +7 -0
  77. data/db/migrate/20130510181443_add_supplier_id_to_ckeditor_assets.rb +8 -0
  78. data/db/migrate/20130606220913_add_permalink_to_suppliers.rb +6 -0
  79. data/db/migrate/20140323170638_add_supplier_commission_to_shipments.rb +5 -0
  80. data/db/migrate/20140416184616_migrate_payment_and_commission.rb +7 -0
  81. data/db/migrate/20140529041325_create_spree_supplier_variants.rb +15 -0
  82. data/db/migrate/20171027180043_add_paypal_email_to_suppliers.rb +5 -0
  83. data/db/seeds.rb +8 -0
  84. data/lib/generators/solidus_marketplace/install/install_generator.rb +36 -0
  85. data/lib/solidus_marketplace.rb +6 -0
  86. data/lib/solidus_marketplace/engine.rb +53 -0
  87. data/lib/solidus_marketplace/factories.rb +107 -0
  88. data/lib/solidus_marketplace/version.rb +3 -0
  89. data/lib/spree/permitted_attributes_decorator.rb +18 -0
  90. data/lib/tasks/spree_sample.rake +72 -0
  91. data/log/awesome.log +1 -0
  92. data/script/rails +7 -0
  93. data/solidus_marketplace.gemspec +46 -0
  94. data/spec/features/admin/orders_spec.rb +11 -0
  95. data/spec/features/admin/products_spec.rb +25 -0
  96. data/spec/features/admin/return_authorizations_spec.rb +7 -0
  97. data/spec/features/admin/settings_spec.rb +33 -0
  98. data/spec/features/admin/shipments_spec.rb +80 -0
  99. data/spec/features/admin/stock_management_spec.rb +156 -0
  100. data/spec/features/admin/stock_spec.rb +98 -0
  101. data/spec/features/admin/suppliers_spec.rb +130 -0
  102. data/spec/models/spree/order_decorator_spec.rb +80 -0
  103. data/spec/models/spree/payment_decorator_spec.rb +7 -0
  104. data/spec/models/spree/product_decorator_spec.rb +56 -0
  105. data/spec/models/spree/shipment_decorator_spec.rb +48 -0
  106. data/spec/models/spree/stock/splitter/marketplace_spec.rb +62 -0
  107. data/spec/models/spree/stock_location_decorator_spec.rb +33 -0
  108. data/spec/models/spree/supplier_ability_spec.rb +182 -0
  109. data/spec/models/spree/supplier_spec.rb +123 -0
  110. data/spec/models/spree/supplier_variant_spec.rb +5 -0
  111. data/spec/models/spree/user_decorator_spec.rb +57 -0
  112. data/spec/models/spree/variant_decorator_spec.rb +7 -0
  113. data/spec/spec_helper.rb +91 -0
  114. data/spec/support/ability_helpers.rb +11 -0
  115. data/spec/support/integration_helpers.rb +15 -0
  116. 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,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Payment do
4
+
5
+ it { should belong_to(:payable) }
6
+
7
+ 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