spree_multi_vendor 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +44 -0
  5. data/Appraisals +11 -0
  6. data/Gemfile +7 -0
  7. data/LICENSE +26 -0
  8. data/README.md +166 -0
  9. data/Rakefile +21 -0
  10. data/app/controllers/spree/admin/vendor_settings_controller.rb +34 -0
  11. data/app/controllers/spree/admin/vendors_controller.rb +60 -0
  12. data/app/controllers/spree/api/v2/storefront/vendors_controller.rb +28 -0
  13. data/app/controllers/spree_multi_vendor/spree/admin/base_controller_decorator.rb +10 -0
  14. data/app/controllers/spree_multi_vendor/spree/admin/option_types_controller_decorator.rb +7 -0
  15. data/app/controllers/spree_multi_vendor/spree/admin/products_controller_decorator.rb +24 -0
  16. data/app/controllers/spree_multi_vendor/spree/admin/properties_controller_decorator.rb +7 -0
  17. data/app/controllers/spree_multi_vendor/spree/admin/resource_controller_decorator.rb +8 -0
  18. data/app/controllers/spree_multi_vendor/spree/admin/shipping_methods_controller_decorator.rb +7 -0
  19. data/app/controllers/spree_multi_vendor/spree/admin/stock_locations_controller_decorator.rb +7 -0
  20. data/app/controllers/spree_multi_vendor/spree/admin/users_controller_decorator.rb +13 -0
  21. data/app/controllers/spree_multi_vendor/spree/admin/variants_controller_decorator.rb +7 -0
  22. data/app/controllers/spree_multi_vendor/spree/api/v1/variants_controller_decorator.rb +22 -0
  23. data/app/finders/spree_multi_vendor/products_finder_decorator.rb +31 -0
  24. data/app/helpers/spree/admin/vendor_helper.rb +15 -0
  25. data/app/mailers/spree/vendor_mailer.rb +15 -0
  26. data/app/models/concerns/spree/vendor_concern.rb +11 -0
  27. data/app/models/spree/order_commission.rb +11 -0
  28. data/app/models/spree/vendor.rb +77 -0
  29. data/app/models/spree/vendor_ability.rb +140 -0
  30. data/app/models/spree/vendor_image.rb +18 -0
  31. data/app/models/spree/vendor_order_totals.rb +28 -0
  32. data/app/models/spree/vendor_user.rb +16 -0
  33. data/app/models/spree_multi_vendor/configuration.rb +10 -0
  34. data/app/models/spree_multi_vendor/spree/ability_decorator.rb +9 -0
  35. data/app/models/spree_multi_vendor/spree/base_decorator.rb +13 -0
  36. data/app/models/spree_multi_vendor/spree/line_item_decorator.rb +48 -0
  37. data/app/models/spree_multi_vendor/spree/order_decorator.rb +105 -0
  38. data/app/models/spree_multi_vendor/spree/shipment_decorator.rb +8 -0
  39. data/app/models/spree_multi_vendor/spree/stock/package_decorator.rb +14 -0
  40. data/app/models/spree_multi_vendor/spree/user_decorator.rb +8 -0
  41. data/app/models/spree_multi_vendor/spree/variant_decorator.rb +41 -0
  42. data/app/overrides/spree/admin/orders/_form.rb +13 -0
  43. data/app/overrides/spree/admin/orders/_line_items.rb +6 -0
  44. data/app/overrides/spree/admin/orders/_line_items_edit_form.rb +6 -0
  45. data/app/overrides/spree/admin/orders/index.rb +6 -0
  46. data/app/overrides/spree/admin/products/form.rb +29 -0
  47. data/app/overrides/spree/admin/products/new.rb +16 -0
  48. data/app/overrides/spree/admin/shared/_main_menu.rb +23 -0
  49. data/app/overrides/spree/admin/shared/_order_summary.rb +35 -0
  50. data/app/overrides/spree/admin/users/_form.rb +13 -0
  51. data/app/serializers/spree/v2/storefront/vendor_image_serializer.rb +11 -0
  52. data/app/serializers/spree/v2/storefront/vendor_order_totals_serializer.rb +18 -0
  53. data/app/serializers/spree/v2/storefront/vendor_serializer.rb +14 -0
  54. data/app/serializers/spree_multi_vendor/cart_serializer_decorator.rb +19 -0
  55. data/app/serializers/spree_multi_vendor/serializer_decorator.rb +23 -0
  56. data/app/services/spree/orders/generate_commissions.rb +34 -0
  57. data/app/views/spree/admin/translations/vendor.html.erb +21 -0
  58. data/app/views/spree/admin/vendor_settings/edit.html.erb +47 -0
  59. data/app/views/spree/admin/vendors/_form.html.erb +36 -0
  60. data/app/views/spree/admin/vendors/edit.html.erb +11 -0
  61. data/app/views/spree/admin/vendors/index.html.erb +83 -0
  62. data/app/views/spree/admin/vendors/new.html.erb +11 -0
  63. data/app/views/spree/vendor_mailer/vendor_notification_email.html.erb +81 -0
  64. data/app/views/spree/vendor_mailer/vendor_notification_email.text.erb +36 -0
  65. data/bin/rails +7 -0
  66. data/config/initializers/spree_permitted_attributes.rb +10 -0
  67. data/config/locales/en.yml +34 -0
  68. data/config/locales/es.yml +33 -0
  69. data/config/locales/fr.yml +33 -0
  70. data/config/routes.rb +19 -0
  71. data/db/default/vendors.rb +13 -0
  72. data/db/migrate/20170406102250_create_spree_vendors.rb +9 -0
  73. data/db/migrate/20170406102944_add_vendor_id_to_spree_models.rb +10 -0
  74. data/db/migrate/20170410111150_add_state_to_vendors.rb +6 -0
  75. data/db/migrate/20170412124925_add_deleted_at_to_spree_vendors.rb +6 -0
  76. data/db/migrate/20170413094447_create_spree_vendor_users.rb +11 -0
  77. data/db/migrate/20190212161426_add_slug_to_spree_vendors.rb +6 -0
  78. data/db/migrate/20190214120226_add_about_us_to_spree_vendors.rb +5 -0
  79. data/db/migrate/20190214142526_add_contact_us_to_spree_vendors.rb +5 -0
  80. data/db/migrate/20190305120337_add_commission_to_spree_vendors.rb +5 -0
  81. data/db/migrate/20190308091546_add_priority_to_vendor.rb +8 -0
  82. data/db/migrate/20190312130754_create_spree_order_commissions.rb +14 -0
  83. data/db/migrate/20190322133128_add_notification_email_to_vendors.rb +5 -0
  84. data/db/migrate/20200416030721_add_translations_to_vendor.rb +19 -0
  85. data/gemfiles/spree_4_2.gemfile +9 -0
  86. data/gemfiles/spree_master.gemfile +9 -0
  87. data/lib/generators/spree_multi_vendor/install/install_generator.rb +21 -0
  88. data/lib/generators/spree_multi_vendor/mailers_preview/mailers_preview_generator.rb +22 -0
  89. data/lib/generators/spree_multi_vendor/mailers_preview/templates/mailers/previews/vendor_notification_preview.rb +5 -0
  90. data/lib/spree_multi_vendor.rb +14 -0
  91. data/lib/spree_multi_vendor/engine.rb +24 -0
  92. data/lib/spree_multi_vendor/factories.rb +7 -0
  93. data/lib/spree_multi_vendor/version.rb +11 -0
  94. data/lib/tasks/vendors.rake +8 -0
  95. data/spec/factories/spree/vendor_factory.rb +22 -0
  96. data/spec/factories/spree/vendor_image_factory.rb +5 -0
  97. data/spec/factories/spree/vendor_user_factory.rb +6 -0
  98. data/spec/features/spree/admin/orders_spec.rb +36 -0
  99. data/spec/features/spree/admin/product_spec.rb +177 -0
  100. data/spec/features/spree/admin/shipping_method_spec.rb +72 -0
  101. data/spec/features/spree/admin/stock_location_spec.rb +90 -0
  102. data/spec/features/spree/admin/vendor_settings_spec.rb +76 -0
  103. data/spec/features/spree/admin/vendor_spec.rb +125 -0
  104. data/spec/fixtures/thinking-cat.jpg +0 -0
  105. data/spec/mailers/vendor_mailer_spec.rb +45 -0
  106. data/spec/models/spree/line_item_spec.rb +32 -0
  107. data/spec/models/spree/order_commission_spec.rb +8 -0
  108. data/spec/models/spree/order_spec.rb +179 -0
  109. data/spec/models/spree/product_spec.rb +19 -0
  110. data/spec/models/spree/variant_spec.rb +104 -0
  111. data/spec/models/spree/vendor_order_totals_spec.rb +33 -0
  112. data/spec/models/spree/vendor_spec.rb +57 -0
  113. data/spec/models/spree/vendor_user_spec.rb +12 -0
  114. data/spec/requests/spree/api/v2/storefront/cart_spec.rb +67 -0
  115. data/spec/requests/spree/api/v2/storefront/products_spec.rb +93 -0
  116. data/spec/requests/spree/api/v2/storefront/vendors_spec.rb +52 -0
  117. data/spec/serializers/spree/v2/storefront/stock_location_serializer_spec.rb +32 -0
  118. data/spec/serializers/spree/v2/storefront/vendor_image_serializer_spec.rb +18 -0
  119. data/spec/serializers/spree/v2/storefront/vendor_order_totals_serializer_spec.rb +54 -0
  120. data/spec/serializers/spree/v2/storefront/vendor_serializer_spec.rb +34 -0
  121. data/spec/spec_helper.rb +11 -0
  122. data/spec/support/shoulda_matchers.rb +6 -0
  123. data/spree_multi_vendor.gemspec +41 -0
  124. metadata +313 -0
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.feature 'Admin Vendor Settings', :js do
4
+ let(:vendor) { create(:active_vendor) }
5
+ let(:blocked_vendor) { create(:blocked_vendor)}
6
+ let!(:user) { create(:user, vendors: [vendor]) }
7
+ let!(:user_with_blocked_vendor) { create(:user, vendors: [blocked_vendor]) }
8
+
9
+ context 'edit' do
10
+ background do
11
+ login_as(user, scope: :spree_user)
12
+ visit spree.admin_vendor_settings_path
13
+ end
14
+
15
+ scenario 'can update current vendor' do
16
+ fill_in 'vendor_name', with: 'Testing edit'
17
+ fill_in 'vendor_about_us', with: 'Testing about us edit'
18
+ fill_in 'vendor_contact_us', with: 'Testing contact us edit'
19
+ expect {
20
+ click_button 'Update'
21
+ }.to change { vendor.reload.slug }.from('active-vendor').to('testing-edit')
22
+ expect(page).to have_text 'Testing edit'
23
+ expect(page).to have_text 'Testing about us edit'
24
+ expect(page).to have_text 'Testing contact us edit'
25
+ end
26
+
27
+ scenario 'shows validation error with blank name' do
28
+ fill_in 'vendor_name', with: ''
29
+ click_button 'Update'
30
+ expect(page).to have_text 'name can\'t be blank'
31
+ end
32
+
33
+ scenario 'does not show validation error with blank about_us' do
34
+ fill_in 'vendor_about_us', with: ''
35
+ click_button 'Update'
36
+ expect(page).not_to have_text 'about_us can\'t be blank'
37
+ end
38
+
39
+ scenario 'does not show validation error with blank contact_us' do
40
+ fill_in 'vendor_contact_us', with: ''
41
+ click_button 'Update'
42
+ expect(page).not_to have_text 'contact_us can\'t be blank'
43
+ end
44
+
45
+ if Spree.version.to_f >= 3.6
46
+ scenario 'can update an existing vendor image' do
47
+ create(:vendor, name: 'New vendor')
48
+ page.attach_file("vendor_image", Spree::Core::Engine.root + 'spec/fixtures' + 'thinking-cat.jpg')
49
+ click_button 'Update'
50
+ expect(page).to have_css("img[src*='thinking-cat.jpg']")
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'no vendor present' do
56
+ before do
57
+ vendor.destroy!
58
+ end
59
+
60
+ it 'renders page without errors' do
61
+ visit spree.admin_vendor_settings_path
62
+ expect(page).to have_current_path('/admin/login')
63
+ end
64
+ end
65
+
66
+ context 'blocked vendor present' do
67
+ background do
68
+ login_as(user_with_blocked_vendor, scope: :spree_user)
69
+ end
70
+
71
+ it 'renders forbidden page' do
72
+ visit spree.admin_vendor_settings_path
73
+ expect(current_path).to eq spree.forbidden_path
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,125 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.feature 'Admin Vendors', :js do
4
+ let!(:admin) { create(:admin_user) }
5
+ let!(:vendor_user) { create(:user) }
6
+
7
+ background do
8
+ login_as(admin, scope: :spree_user)
9
+ create(:active_vendor, users: [vendor_user]) if Spree::Vendor.find_by(name: 'Active vendor').nil?
10
+ create(:pending_vendor)
11
+ create(:blocked_vendor)
12
+ visit spree.admin_vendors_path
13
+ end
14
+
15
+ context 'index' do
16
+ scenario 'displays existing vendors' do
17
+ within_row(1) do
18
+ expect(column_text(1)).to eq vendor_user.email
19
+ expect(column_text(2)).to eq 'Active vendor'
20
+ expect(column_text(3)).to eq 'active'
21
+ end
22
+ end
23
+
24
+ scenario 'filter by multiple states' do
25
+ click_button 'Filter'
26
+ select2 'Active', from: 'State'
27
+ select2 'Pending', from: 'State'
28
+
29
+ click_button 'Filter Results'
30
+
31
+ expect(page).to have_content('active')
32
+ expect(page).to have_content('pending')
33
+ expect(page).not_to have_content('blocked')
34
+ end
35
+ end
36
+
37
+ context 'create' do
38
+ scenario 'can create a new vendor' do
39
+ click_link 'New Vendor'
40
+ expect(current_path).to eq spree.new_admin_vendor_path
41
+
42
+ fill_in 'vendor_name', with: 'Test'
43
+ fill_in 'vendor_about_us', with: 'About...'
44
+ fill_in 'vendor_contact_us', with: 'Contact...'
45
+ expect(find_field('vendor_commission_rate').value).to eq '5.0'
46
+ select 'Blocked'
47
+
48
+ click_button 'Create'
49
+
50
+ expect(page).to have_text 'successfully created!'
51
+ expect(current_path).to eq spree.admin_vendors_path
52
+ end
53
+
54
+ scenario 'shows validation error with blank name' do
55
+ click_link 'New Vendor'
56
+ expect(current_path).to eq spree.new_admin_vendor_path
57
+
58
+ fill_in 'vendor_name', with: ''
59
+ click_button 'Create'
60
+
61
+ expect(page).to have_text 'name can\'t be blank'
62
+ end
63
+
64
+ scenario 'shows validation error with repeated name' do
65
+ click_link 'New Vendor'
66
+ expect(current_path).to eq spree.new_admin_vendor_path
67
+
68
+ fill_in 'vendor_name', with: 'Active vendor'
69
+ click_button 'Create'
70
+
71
+ expect(page).to have_text 'name has already been taken'
72
+ end
73
+ end
74
+
75
+ context 'edit' do
76
+ background do
77
+ within_row(1) { click_icon :edit }
78
+ expect(current_path).to eq spree.edit_admin_vendor_path('active-vendor')
79
+ end
80
+
81
+ scenario 'can update an existing vendor' do
82
+ fill_in 'vendor_name', with: 'Testing edit'
83
+ fill_in 'vendor_about_us', with: 'Testing about us'
84
+ fill_in 'vendor_contact_us', with: 'Testing contact us'
85
+ fill_in 'vendor_commission_rate', with: '5.5'
86
+ click_button 'Update'
87
+ expect(page).to have_text 'successfully updated!'
88
+ expect(page).to have_text 'Testing edit'
89
+ end
90
+
91
+ if Spree.version.to_f >= 3.6
92
+ scenario 'can update an existing vendor image' do
93
+ page.attach_file("vendor_image", Spree::Core::Engine.root + 'spec/fixtures' + 'thinking-cat.jpg')
94
+ expect { click_button 'Update' }.to change(Spree::VendorImage, :count).by(1)
95
+ expect(page).to have_text 'successfully updated!'
96
+ end
97
+ end
98
+
99
+ scenario 'shows validation error with blank name' do
100
+ fill_in 'vendor_name', with: ''
101
+ click_button 'Update'
102
+ expect(page).to have_text 'name can\'t be blank'
103
+ end
104
+
105
+ scenario 'does not show validation error with blank about_us' do
106
+ fill_in 'vendor_about_us', with: ''
107
+ click_button 'Update'
108
+ expect(page).not_to have_text 'about_us can\'t be blank'
109
+ end
110
+
111
+ scenario 'does not show validation error with blank contact_us' do
112
+ fill_in 'vendor_contact_us', with: ''
113
+ click_button 'Update'
114
+ expect(page).not_to have_text 'contact_us can\'t be blank'
115
+ end
116
+
117
+ scenario 'shows validation error with repeated name' do
118
+ create(:vendor, name: 'New vendor')
119
+
120
+ fill_in 'vendor_name', with: 'New vendor'
121
+ click_button 'Update'
122
+ expect(page).to have_text 'name has already been taken'
123
+ end
124
+ end
125
+ end
Binary file
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::VendorMailer, type: :mailer do
4
+ let(:store) { create(:store)}
5
+ let(:vendor) { Spree::Vendor.new(id: 1, name: 'Test vendor', state: 'active', notification_email: 'test-vendor@example.com') }
6
+ let(:other_vendor) { Spree::Vendor.new(id: 2, name: 'Other vendor', state: 'active', notification_email: 'other-vendor@example.com') }
7
+ let(:order) { create(:completed_order_with_totals, line_items_count: 5) }
8
+
9
+ context 'vendor notification email' do
10
+ before do
11
+ order.line_items.first.product.update(vendor: vendor)
12
+ order.line_items.last.product.update(vendor: other_vendor)
13
+ end
14
+
15
+ it 'is sent from current store email address' do
16
+ notification_email = Spree::VendorMailer.vendor_notification_email(order.id, vendor.id)
17
+ expect(notification_email.from).to have_content(Spree::Store.current.mail_from_address)
18
+ end
19
+
20
+ it 'is sent to vendors email address' do
21
+ notification_email = Spree::VendorMailer.vendor_notification_email(order.id, vendor.id)
22
+ expect(notification_email.to).to have_content(vendor.contact_us)
23
+ end
24
+
25
+ it 'subject contains order number' do
26
+ notification_email = Spree::VendorMailer.vendor_notification_email(order.id, vendor.id)
27
+ expect(notification_email.subject).to have_content(order.number)
28
+ end
29
+
30
+ it 'body contains vendors items' do
31
+ notification_email = Spree::VendorMailer.vendor_notification_email(order.id, vendor.id)
32
+ vendors_item = order.line_items.select { |line_item| line_item.product.vendor == vendor }.first
33
+ expect(notification_email.body.parts.first).to have_text(vendors_item.product.name)
34
+ expect(notification_email.body.parts.last).to have_text(vendors_item.product.name)
35
+ end
36
+
37
+ it 'body does not contain other vendors items' do
38
+ notification_email = Spree::VendorMailer.vendor_notification_email(order.id, vendor.id)
39
+ other_vendors_item = order.line_items.select { |line_item| line_item.product.vendor != vendor }.first
40
+ expect(notification_email.body.parts.first).not_to have_text(other_vendors_item.product.name)
41
+ expect(notification_email.body.parts.last).not_to have_text(other_vendors_item.product.name)
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::LineItem do
4
+ let(:vendor) { create(:vendor) }
5
+
6
+ describe '#vendor' do
7
+ context 'vendorized product' do
8
+ let(:product) { create(:product, vendor: vendor) }
9
+ let(:line_item) { build(:line_item, product: product, variant: product.default_variant) }
10
+
11
+ it { expect(line_item.vendor).not_to be_nil }
12
+ it { expect(line_item.vendor).to eq(product.vendor) }
13
+ end
14
+
15
+ context 'vendorized variant' do
16
+ let(:product) { create(:product) }
17
+ let(:variant) { create(:variant, vendor: vendor, product: product) }
18
+ let(:line_item) { build(:line_item, product: product, variant: variant) }
19
+
20
+ before do
21
+ SpreeMultiVendor::Config[:vendorized_models] = ['variant']
22
+ end
23
+
24
+ after do
25
+ SpreeMultiVendor::Config[:vendorized_models] = SpreeMultiVendor::Configuration::DEFAULT_VENDORIZED_MODELS
26
+ end
27
+
28
+ it { expect(line_item.vendor).not_to be_nil }
29
+ it { expect(line_item.vendor).to eq(variant.vendor) }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::OrderCommission do
4
+ describe 'associations' do
5
+ it { is_expected.to belong_to(:order) }
6
+ it { is_expected.to belong_to(:vendor) }
7
+ end
8
+ end
@@ -0,0 +1,179 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Order do
4
+ let(:vendor) { create(:vendor, name: 'Vendor 1') }
5
+ let(:vendor_2) { create(:vendor, name: 'Vendor 2') }
6
+
7
+ let(:order) { create(:order_with_line_items, state: 'payment', line_items_count: 6, line_items_price: 100, shipment_cost: 50) }
8
+
9
+ before do
10
+ order.line_items.each_with_index do |li, idx|
11
+ product = li.product
12
+ product.vendor = idx.odd? ? vendor : vendor_2
13
+ product.save
14
+ end
15
+ end
16
+
17
+ context 'associations' do
18
+ it { is_expected.to have_many(:commissions) }
19
+ end
20
+
21
+ context 'complete with spree_multi_vendor' do
22
+ before { allow(order).to receive_messages payment_required?: false }
23
+
24
+ it 'generates commission records' do
25
+ expect do
26
+ order.next!
27
+ order.reload
28
+ end.to change { Spree::OrderCommission.count }.by(2).and change { vendor.commissions.count }.by(1)
29
+ .and change { vendor_2.commissions.count }.by(1)
30
+
31
+ order.line_items.includes(product: :vendor).group_by { |li| li.product.vendor }.each do |v, line_items|
32
+ commission_ammount = v.commission_rate * line_items.pluck(:pre_tax_amount).sum.to_f / 100
33
+
34
+ expect(v.commissions.sum(:amount)).to eq(commission_ammount)
35
+ end
36
+ end
37
+ end
38
+
39
+ context 'vendor methods' do
40
+ let!(:shipment) { create(:shipment, order: order, cost: 20, pre_tax_amount: 20, stock_location: vendor.stock_locations.first) }
41
+ let!(:promotion) { create(:promotion_with_item_adjustment, adjustment_rate: 10, code: '10off') }
42
+
43
+ before do
44
+ order.coupon_code = '10off'
45
+ Spree::PromotionHandler::Coupon.new(order).apply
46
+ order.reload
47
+ end
48
+
49
+ describe '#vendor_line_items' do
50
+ it { expect(order.vendor_line_items(vendor)).to eq(order.line_items.for_vendor(vendor)) }
51
+ it { expect(order.vendor_line_items(vendor).count).to eq(3) }
52
+ end
53
+
54
+ describe '#vendor_shipments' do
55
+ it { expect(order.vendor_shipments(vendor).to_a).to eq([shipment]) }
56
+ it { expect(order.vendor_shipments(vendor).count).to eq(1) }
57
+ end
58
+
59
+ describe '#vendor_subtotal' do
60
+ it { expect(order.vendor_subtotal(vendor)).to eq(270) }
61
+ end
62
+
63
+ describe '#display_subtotal' do
64
+ it { expect(order.display_vendor_subtotal(vendor).to_s).to eq('$270.00') }
65
+ end
66
+
67
+ describe '#vendor_pre_tax_item_amount' do
68
+ it { expect(order.vendor_pre_tax_item_amount(vendor)).to eq(300) }
69
+ end
70
+
71
+ describe '#displayvendor_pre_tax_item_amount' do
72
+ it { expect(order.display_vendor_pre_tax_item_amount(vendor).to_s).to eq('$300.00') }
73
+ end
74
+
75
+ describe '#vendor_pre_tax_total' do
76
+ it { expect(order.vendor_pre_tax_total(vendor)).to eq(320) }
77
+ end
78
+
79
+ describe '#displayvendor_pre_tax_total' do
80
+ it { expect(order.display_vendor_pre_tax_total(vendor).to_s).to eq('$320.00') }
81
+ end
82
+
83
+ context 'ship total' do
84
+ before do
85
+ order.vendor_shipments(vendor).update_all(adjustment_total: 5)
86
+ end
87
+
88
+ describe '#vendor_ship_total' do
89
+ it { expect(order.vendor_ship_total(vendor)).to eq(25) }
90
+ end
91
+
92
+ describe '#display_vendor_ship_total' do
93
+ it { expect(order.display_vendor_ship_total(vendor).to_s).to eq('$25.00') }
94
+ end
95
+
96
+ describe '#vendor_pre_tax_ship_amount' do
97
+ it { expect(order.vendor_pre_tax_ship_amount(vendor)).to eq(20) }
98
+ end
99
+
100
+ describe '#display_vendor_pre_tax_ship_amount' do
101
+ it { expect(order.display_vendor_pre_tax_ship_amount(vendor).to_s).to eq('$20.00') }
102
+ end
103
+ end
104
+
105
+ describe '#vendor_promo_total' do
106
+ it { expect(order.vendor_promo_total(vendor)).to eq(-30) }
107
+ end
108
+
109
+ describe '#display_vendor_promo_total' do
110
+ it { expect(order.display_vendor_promo_total(vendor).to_s).to eq('-$30.00') }
111
+ end
112
+
113
+ context 'additional tax' do
114
+ before do
115
+ order.vendor_line_items(vendor).update_all(additional_tax_total: 10)
116
+ order.vendor_shipments(vendor).update_all(additional_tax_total: 1)
117
+ end
118
+
119
+ describe '#vendor_additional_tax_total' do
120
+ it { expect(order.vendor_additional_tax_total(vendor)).to eq(31) }
121
+ end
122
+
123
+ describe '#display_vendor_additional_tax_total' do
124
+ it { expect(order.display_vendor_additional_tax_total(vendor).to_s).to eq('$31.00') }
125
+ end
126
+ end
127
+
128
+ context 'included tax' do
129
+ before do
130
+ order.vendor_line_items(vendor).update_all(included_tax_total: 5)
131
+ order.vendor_shipments(vendor).update_all(included_tax_total: 1)
132
+ end
133
+
134
+ describe '#vendor_included_tax_total' do
135
+ it { expect(order.vendor_included_tax_total(vendor)).to eq(16) }
136
+ end
137
+
138
+ describe '#display_vendor_included_tax_total' do
139
+ it { expect(order.display_vendor_included_tax_total(vendor).to_s).to eq('$16.00') }
140
+ end
141
+ end
142
+
143
+ describe '#vendor_total' do
144
+ it { expect(order.vendor_total(vendor)).to eq(290) }
145
+ end
146
+
147
+ describe '#display_vendor_total' do
148
+ it { expect(order.display_vendor_total(vendor).to_s).to eq('$290.00') }
149
+
150
+ context 'respects currency' do
151
+ before { order.currency = 'GBP' }
152
+
153
+ it { expect(order.display_vendor_total(vendor).to_s).to eq('£290.00') }
154
+ end
155
+ end
156
+
157
+ describe '#vendor_item_count' do
158
+ before { order.vendor_line_items(vendor).last.update(quantity: 2) }
159
+
160
+ it { expect(order.vendor_item_count(vendor)).to eq(4) }
161
+ end
162
+
163
+ describe '#vendor_ids' do
164
+ it { expect(order.vendor_ids).to match_array([vendor.id, vendor_2.id]) }
165
+
166
+ context 'when a line item does not belong to any vendor' do
167
+ before { order.vendor_line_items(vendor_2).each { |li| li.product.update_columns(vendor_id: nil) } }
168
+ it { expect(order.vendor_ids).to match_array([vendor.id]) }
169
+ end
170
+ end
171
+
172
+ describe '#vendor_totals' do
173
+ it { expect(order.vendor_totals).to be_kind_of(Array) }
174
+ it { expect(order.vendor_totals).not_to be_empty }
175
+ it { expect(order.vendor_totals.first.order).to eq(order) }
176
+ it { expect(order.vendor_totals.map(&:vendor)).to match_array([vendor, vendor_2]) }
177
+ end
178
+ end
179
+ end