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,10 @@
1
+ module SpreeMultiVendor::Spree::Admin::BaseControllerDecorator
2
+ Spree::Admin::BaseController.include(Spree::Admin::VendorHelper)
3
+
4
+ def self.prepended(base)
5
+ base.helper_method :current_spree_vendor
6
+ base.helper_method :vendor_state_options
7
+ end
8
+ end
9
+
10
+ Spree::Admin::BaseController.prepend SpreeMultiVendor::Spree::Admin::BaseControllerDecorator
@@ -0,0 +1,7 @@
1
+ module SpreeMultiVendor::Spree::Admin::OptionTypesControllerDecorator
2
+ def self.prepended(base)
3
+ base.before_action :set_vendor_id, only: [:create, :update]
4
+ end
5
+ end
6
+
7
+ Spree::Admin::OptionTypesController.prepend SpreeMultiVendor::Spree::Admin::OptionTypesControllerDecorator
@@ -0,0 +1,24 @@
1
+ module SpreeMultiVendor::Spree::Admin::ProductsControllerDecorator
2
+ def self.prepended(base)
3
+ base.before_action :set_vendor_id, only: [:create, :update]
4
+ base.before_action :load_vendors, only: [:new, :edit, :update]
5
+ end
6
+
7
+ def stock
8
+ @variants = @product.variants.includes(*variant_stock_includes)
9
+ @variants = [@product.master] if @variants.empty?
10
+ @stock_locations = Spree::StockLocation.accessible_by(current_ability, :read).where(vendor_id: @product.vendor_id)
11
+ if @stock_locations.empty?
12
+ flash[:error] = Spree.t(:stock_management_requires_a_stock_location)
13
+ redirect_to admin_stock_locations_path
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def load_vendors
20
+ @vendors = Spree::Vendor.order(Arel.sql('LOWER(name)'))
21
+ end
22
+ end
23
+
24
+ Spree::Admin::ProductsController.prepend SpreeMultiVendor::Spree::Admin::ProductsControllerDecorator
@@ -0,0 +1,7 @@
1
+ module SpreeMultiVendor::Spree::Admin::PropertiesControllerDecorator
2
+ def self.prepended(base)
3
+ base.before_action :set_vendor_id, only: [:create, :update]
4
+ end
5
+ end
6
+
7
+ Spree::Admin::PropertiesController.prepend SpreeMultiVendor::Spree::Admin::PropertiesControllerDecorator
@@ -0,0 +1,8 @@
1
+ module SpreeMultiVendor::Spree::Admin::ResourceControllerDecorator
2
+ def set_vendor_id
3
+ return unless current_spree_vendor
4
+ params[resource.object_name.to_sym][:vendor_id] = current_spree_vendor.id
5
+ end
6
+ end
7
+
8
+ Spree::Admin::ResourceController.prepend SpreeMultiVendor::Spree::Admin::ResourceControllerDecorator
@@ -0,0 +1,7 @@
1
+ module SpreeMultiVendor::Spree::Admin::ShippingMethodsControllerDecorator
2
+ def self.prepended(base)
3
+ base.before_action :set_vendor_id, only: [:create, :update]
4
+ end
5
+ end
6
+
7
+ Spree::Admin::ShippingMethodsController.prepend SpreeMultiVendor::Spree::Admin::ShippingMethodsControllerDecorator
@@ -0,0 +1,7 @@
1
+ module SpreeMultiVendor::Spree::Admin::StockLocationsControllerDecorator
2
+ def self.prepended(base)
3
+ base.before_action :set_vendor_id, only: [:create, :update]
4
+ end
5
+ end
6
+
7
+ Spree::Admin::StockLocationsController.prepend SpreeMultiVendor::Spree::Admin::StockLocationsControllerDecorator
@@ -0,0 +1,13 @@
1
+ module SpreeMultiVendor::Spree::Admin::UsersControllerDecorator
2
+ private
3
+
4
+ def user_params
5
+ params.require(:user).permit(permitted_user_attributes |
6
+ [spree_role_ids: [],
7
+ vendor_ids: [],
8
+ ship_address_attributes: permitted_address_attributes,
9
+ bill_address_attributes: permitted_address_attributes])
10
+ end
11
+ end
12
+
13
+ Spree::Admin::UsersController.prepend SpreeMultiVendor::Spree::Admin::UsersControllerDecorator
@@ -0,0 +1,7 @@
1
+ module SpreeMultiVendor::Spree::Admin::VariantsControllerDecorator
2
+ def self.prepended(base)
3
+ base.before_action :set_vendor_id, only: [:create, :update]
4
+ end
5
+ end
6
+
7
+ Spree::Admin::VariantsController.prepend SpreeMultiVendor::Spree::Admin::VariantsControllerDecorator
@@ -0,0 +1,22 @@
1
+ module SpreeMultiVendor::Spree::Api::V1::VariantsControllerDecorator
2
+ private
3
+
4
+ def scope
5
+ variants = if @product
6
+ @product.variants_including_master
7
+ else
8
+ Spree::Variant
9
+ end
10
+
11
+ if current_ability.can?(:manage, Spree::Variant) && params[:show_deleted]
12
+ variants = variants.with_deleted
13
+ end
14
+
15
+ variants = variants.for_vendor_user(current_spree_user) unless @current_user_roles.include?('admin')
16
+ variants = variants.eligible if Spree.version.to_f >= 3.7
17
+
18
+ variants.accessible_by(current_ability, :read)
19
+ end
20
+ end
21
+
22
+ Spree::Api::V1::VariantsController.prepend SpreeMultiVendor::Spree::Api::V1::VariantsControllerDecorator
@@ -0,0 +1,31 @@
1
+ module SpreeMultiVendor
2
+ module ProductsFinderDecorator
3
+ def initialize(scope:, params:, current_currency:)
4
+ super
5
+
6
+ @vendors = params.dig(:filter, :vendor_ids)&.split(',')
7
+ end
8
+
9
+ def execute
10
+ products = by_vendors(super)
11
+
12
+ products.distinct
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :vendors
18
+
19
+ def vendors?
20
+ vendors.present?
21
+ end
22
+
23
+ def by_vendors(products)
24
+ return products unless vendors?
25
+
26
+ products.where(vendor_id: vendors)
27
+ end
28
+ end
29
+ end
30
+
31
+ ::Spree::Products::Find.prepend(SpreeMultiVendor::ProductsFinderDecorator)
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module Admin
3
+ module VendorHelper
4
+ def current_spree_vendor
5
+ if current_spree_user.vendors.any? && (!current_spree_user.respond_to?(:has_spree_role?) || !current_spree_user.has_spree_role?(:admin))
6
+ current_spree_user.vendors.first
7
+ end
8
+ end
9
+
10
+ def vendor_state_options
11
+ @vendor_state_options ||= Spree::Vendor.state_machines[:state].states.collect { |s| [Spree.t("vendor_states.#{s.name}"), s.value] }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ class VendorMailer < ::Spree::BaseMailer
3
+ def vendor_notification_email(order_id, vendor_id)
4
+ @vendor = Spree::Vendor.find(vendor_id)
5
+ return unless @vendor.notification_email.present?
6
+
7
+ @order = Spree::Order.find(order_id)
8
+ @line_items = @order.line_items.for_vendor(@vendor)
9
+ @subtotal = @order.vendor_subtotal(@vendor)
10
+ @total = @order.vendor_total(@vendor)
11
+ subject = "#{Spree::Store.current.name} #{Spree.t('order_mailer.vendor_notification_email.subject')} ##{@order.number}"
12
+ mail(to: @vendor.notification_email, from: from_address, subject: subject)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module VendorConcern
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ belongs_to :vendor, class_name: 'Spree::Vendor', touch: true, optional: true
7
+
8
+ scope :with_vendor, ->(vendor_id) { where(vendor_id: vendor_id) }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ class OrderCommission < Base
3
+ belongs_to :order, required: Spree.version.to_f >= 3.5
4
+ belongs_to :vendor, required: Spree.version.to_f >= 3.5
5
+
6
+ validates :order, :vendor, presence: true
7
+ validates :vendor_id, uniqueness: { scope: :order_id }
8
+
9
+ scope :for_vendor, ->(vendor) { where(vendor_id: vendor.id) }
10
+ end
11
+ end
@@ -0,0 +1,77 @@
1
+ module Spree
2
+ class Vendor < Spree::Base
3
+ extend FriendlyId
4
+
5
+ acts_as_paranoid
6
+ acts_as_list column: :priority
7
+ friendly_id :name, use: %i[slugged history]
8
+
9
+ validates :name,
10
+ presence: true,
11
+ uniqueness: { case_sensitive: false }
12
+
13
+ validates :slug, uniqueness: true
14
+ validates_associated :image if Spree.version.to_f >= 3.6
15
+
16
+ validates :notification_email, email: true, allow_blank: true
17
+
18
+ with_options dependent: :destroy do
19
+ has_one :image, as: :viewable, dependent: :destroy, class_name: 'Spree::VendorImage'
20
+ has_many :commissions, class_name: 'Spree::OrderCommission'
21
+ has_many :vendor_users
22
+
23
+ SpreeMultiVendor::Config[:vendorized_models].uniq.compact.each do |model|
24
+ has_many model.pluralize.to_sym
25
+ end
26
+ end
27
+
28
+ has_many :users, through: :vendor_users, class_name: Spree.user_class.to_s
29
+
30
+ after_create :create_stock_location
31
+ after_update :update_stock_location_names
32
+
33
+ state_machine :state, initial: :pending do
34
+ event :activate do
35
+ transition to: :active
36
+ end
37
+
38
+ event :block do
39
+ transition to: :blocked
40
+ end
41
+ end
42
+
43
+ scope :active, -> { where(state: 'active') }
44
+
45
+ self.whitelisted_ransackable_attributes = %w[name state]
46
+
47
+ def update_notification_email(email)
48
+ update(notification_email: email)
49
+ end
50
+
51
+ # Spree Globalize support
52
+ # https://github.com/spree-contrib/spree_multi_vendor/issues/104
53
+ if defined?(SpreeGlobalize)
54
+ attr_accessor :translations_attributes
55
+ translates :name,
56
+ :about_us,
57
+ :contact_us,
58
+ :slug, fallbacks_for_empty_translations: true
59
+ end
60
+
61
+ private
62
+
63
+ def create_stock_location
64
+ stock_locations.where(name: name, country: Spree::Country.default).first_or_create!
65
+ end
66
+
67
+ def should_generate_new_friendly_id?
68
+ slug.blank? || name_changed?
69
+ end
70
+
71
+ def update_stock_location_names
72
+ if (Spree.version.to_f < 3.5 && self.name_changed?) || (Spree.version.to_f >= 3.5 && saved_changes&.include?(:name))
73
+ stock_locations.update_all({ name: name })
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,140 @@
1
+ class Spree::VendorAbility
2
+ include CanCan::Ability
3
+
4
+ def initialize(user)
5
+ @vendor_ids = user.vendors.active.ids
6
+
7
+ if @vendor_ids.any?
8
+ apply_classifications_permissions
9
+ apply_order_permissions
10
+ apply_image_permissions
11
+ apply_option_type_permissions
12
+ apply_price_permissions
13
+ apply_product_option_type_permissions
14
+ apply_product_permissions
15
+ apply_product_properties_permissions
16
+ apply_properties_permissions
17
+ apply_prototypes_permissions
18
+ apply_shipment_permissions
19
+ apply_shipping_methods_permissions
20
+ apply_stock_permissions
21
+ apply_stock_item_permissions
22
+ apply_stock_location_permissions
23
+ apply_stock_movement_permissions
24
+ apply_variant_permissions
25
+ apply_vendor_permissions
26
+ apply_vendor_settings_permissions
27
+ apply_state_changes_permissions
28
+ end
29
+ end
30
+
31
+ protected
32
+
33
+ def apply_classifications_permissions
34
+ can :manage, Spree::Classification, product: { vendor_id: @vendor_ids }
35
+ end
36
+
37
+ def apply_order_permissions
38
+ cannot :create, Spree::Order
39
+ can [:admin, :index, :edit, :update, :cart], Spree::Order do |order|
40
+ (order.vendor_ids & @vendor_ids).any?
41
+ end
42
+ end
43
+
44
+ def apply_image_permissions
45
+ can :create, Spree::Image
46
+
47
+ can [:manage, :modify], Spree::Image, ['viewable_type = ?', 'Spree::Variant'] do |image|
48
+ vendor_id = image.viewable.try(:vendor_id)
49
+ vendor_id.present? && @vendor_ids.include?(vendor_id)
50
+ end
51
+ end
52
+
53
+ def apply_option_type_permissions
54
+ cannot_display_model(Spree::OptionType)
55
+ can :manage, Spree::OptionType, vendor_id: @vendor_ids
56
+ can :create, Spree::OptionType
57
+ end
58
+
59
+ def apply_price_permissions
60
+ can :modify, Spree::Price, variant: { vendor_id: @vendor_ids }
61
+ end
62
+
63
+ def apply_product_option_type_permissions
64
+ can :display, Spree::OptionType
65
+ can :display, Spree::OptionValue
66
+ can :manage, Spree::ProductOptionType, product: { vendor_id: @vendor_ids }
67
+ can :create, Spree::ProductOptionType
68
+ can :manage, Spree::OptionValueVariant, variant: { vendor_id: @vendor_ids }
69
+ can :create, Spree::OptionValueVariant
70
+ end
71
+
72
+ def apply_product_permissions
73
+ cannot_display_model(Spree::Product)
74
+ can :manage, Spree::Product, vendor_id: @vendor_ids
75
+ can :create, Spree::Product
76
+ end
77
+
78
+ def apply_properties_permissions
79
+ can :display, Spree::Property
80
+ end
81
+
82
+ def apply_product_properties_permissions
83
+ can :manage, Spree::ProductProperty, product: { vendor_id: @vendor_ids }
84
+ can :create, Spree::ProductProperty
85
+ end
86
+
87
+ def apply_prototypes_permissions
88
+ can [:read, :admin], Spree::Prototype
89
+ end
90
+
91
+ def apply_shipment_permissions
92
+ can :update, Spree::Shipment, inventory_units: { line_item: { product: { vendor_id: @vendor_ids } } }
93
+ end
94
+
95
+ def apply_shipping_methods_permissions
96
+ can :manage, Spree::ShippingMethod, vendor_id: @vendor_ids
97
+ can :create, Spree::ShippingMethod
98
+ end
99
+
100
+ def apply_stock_permissions
101
+ can :admin, Spree::Stock
102
+ end
103
+
104
+ def apply_stock_item_permissions
105
+ can [:admin, :modify, :read], Spree::StockItem, stock_location: { vendor_id: @vendor_ids }
106
+ end
107
+
108
+ def apply_stock_location_permissions
109
+ can :manage, Spree::StockLocation, vendor_id: @vendor_ids
110
+ can :create, Spree::StockLocation
111
+ end
112
+
113
+ def apply_stock_movement_permissions
114
+ can :create, Spree::StockMovement
115
+ can :manage, Spree::StockMovement, stock_item: { stock_location: { vendor_id: @vendor_ids } }
116
+ end
117
+
118
+ def apply_variant_permissions
119
+ can :manage, Spree::Variant, vendor_id: @vendor_ids
120
+ can :create, Spree::Variant
121
+ end
122
+
123
+ def apply_vendor_permissions
124
+ can [:admin, :update], Spree::Vendor, id: @vendor_ids
125
+ end
126
+
127
+ def apply_vendor_settings_permissions
128
+ can :manage, :vendor_settings
129
+ end
130
+
131
+ def apply_state_changes_permissions
132
+ can [:admin, :index], Spree::StateChange do |state_change|
133
+ (@vendor_ids & state_change.user.vendor_ids).any?
134
+ end
135
+ end
136
+
137
+ def cannot_display_model(model)
138
+ Spree.version.to_f < 4.0 ? (cannot :display, model) : (cannot :read, model)
139
+ end
140
+ end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ class VendorImage < Asset
3
+ include Spree::Image::Configuration::ActiveStorage
4
+ include Rails.application.routes.url_helpers
5
+
6
+ def styles
7
+ self.class.styles.map do |_, size|
8
+ width, height = size[/(\d+)x(\d+)/].split('x')
9
+
10
+ {
11
+ url: polymorphic_path(attachment.variant(resize: size), only_path: true),
12
+ width: width,
13
+ height: height
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end