solidus_marketplace 0.1.0

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.
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