atkhayar-dev-spree-multi-vendor 0.0.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 (134) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +10 -0
  3. data/LICENSE +26 -0
  4. data/README.md +181 -0
  5. data/Rakefile +21 -0
  6. data/app/controllers/spree/admin/vendor_settings_controller.rb +34 -0
  7. data/app/controllers/spree/admin/vendors_controller.rb +68 -0
  8. data/app/controllers/spree/api/v1/vendors_controller.rb +62 -0
  9. data/app/controllers/spree/api/v2/platform/vendors_controller.rb +32 -0
  10. data/app/controllers/spree/api/v2/storefront/vendors_controller.rb +33 -0
  11. data/app/controllers/spree_multi_vendor/spree/admin/base_controller_decorator.rb +10 -0
  12. data/app/controllers/spree_multi_vendor/spree/admin/products_controller_decorator.rb +79 -0
  13. data/app/controllers/spree_multi_vendor/spree/admin/resource_controller_decorator.rb +8 -0
  14. data/app/controllers/spree_multi_vendor/spree/admin/shipping_methods_controller_decorator.rb +7 -0
  15. data/app/controllers/spree_multi_vendor/spree/admin/stock_locations_controller_decorator.rb +7 -0
  16. data/app/controllers/spree_multi_vendor/spree/admin/users_controller_decorator.rb +13 -0
  17. data/app/controllers/spree_multi_vendor/spree/admin/variants_controller_decorator.rb +7 -0
  18. data/app/controllers/spree_multi_vendor/spree/api/base_controller_decorator.rb +17 -0
  19. data/app/controllers/spree_multi_vendor/spree/api/v1/products_controller_decorator.rb +9 -0
  20. data/app/controllers/spree_multi_vendor/spree/api/v1/users_controller_decorator.rb +13 -0
  21. data/app/controllers/spree_multi_vendor/spree/api/v2/platform/products_controller_decorator.rb +65 -0
  22. data/app/finders/spree_multi_vendor/products_finder_decorator.rb +31 -0
  23. data/app/helpers/spree/admin/vendor_helper.rb +15 -0
  24. data/app/helpers/spree/api/vendor_helper.rb +13 -0
  25. data/app/helpers/spree_multi_vendor/spree/api/api_helpers_decorator.rb +19 -0
  26. data/app/mailers/spree/vendor_mailer.rb +15 -0
  27. data/app/models/concerns/spree/vendor_concern.rb +11 -0
  28. data/app/models/spree/order_commission.rb +11 -0
  29. data/app/models/spree/vendor.rb +77 -0
  30. data/app/models/spree/vendor_ability.rb +155 -0
  31. data/app/models/spree/vendor_image.rb +18 -0
  32. data/app/models/spree/vendor_order_totals.rb +28 -0
  33. data/app/models/spree/vendor_user.rb +16 -0
  34. data/app/models/spree_multi_vendor/configuration.rb +10 -0
  35. data/app/models/spree_multi_vendor/spree/ability_decorator.rb +9 -0
  36. data/app/models/spree_multi_vendor/spree/base_decorator.rb +13 -0
  37. data/app/models/spree_multi_vendor/spree/line_item_decorator.rb +48 -0
  38. data/app/models/spree_multi_vendor/spree/order_decorator.rb +107 -0
  39. data/app/models/spree_multi_vendor/spree/shipment_decorator.rb +8 -0
  40. data/app/models/spree_multi_vendor/spree/stock/package_decorator.rb +14 -0
  41. data/app/models/spree_multi_vendor/spree/user_decorator.rb +8 -0
  42. data/app/models/spree_multi_vendor/spree/variant_decorator.rb +40 -0
  43. data/app/overrides/spree/admin/orders/_form.rb +13 -0
  44. data/app/overrides/spree/admin/orders/_line_items.rb +6 -0
  45. data/app/overrides/spree/admin/orders/_line_items_edit_form.rb +6 -0
  46. data/app/overrides/spree/admin/orders/index.rb +6 -0
  47. data/app/overrides/spree/admin/products/form.rb +29 -0
  48. data/app/overrides/spree/admin/products/new.rb +16 -0
  49. data/app/overrides/spree/admin/shared/_main_menu.rb +23 -0
  50. data/app/overrides/spree/admin/shared/_order_summary.rb +35 -0
  51. data/app/overrides/spree/admin/users/_form.rb +13 -0
  52. data/app/serializers/spree/api/v2/platform/vendor_serializer.rb +12 -0
  53. data/app/serializers/spree/v2/storefront/vendor_image_serializer.rb +11 -0
  54. data/app/serializers/spree/v2/storefront/vendor_order_totals_serializer.rb +20 -0
  55. data/app/serializers/spree/v2/storefront/vendor_serializer.rb +15 -0
  56. data/app/serializers/spree_multi_vendor/cart_serializer_decorator.rb +19 -0
  57. data/app/serializers/spree_multi_vendor/serializer_decorator.rb +23 -0
  58. data/app/services/spree/orders/generate_commissions.rb +34 -0
  59. data/app/views/spree/admin/translations/vendor.html.erb +21 -0
  60. data/app/views/spree/admin/vendor_settings/edit.html.erb +47 -0
  61. data/app/views/spree/admin/vendors/_form.html.erb +36 -0
  62. data/app/views/spree/admin/vendors/edit.html.erb +11 -0
  63. data/app/views/spree/admin/vendors/index.html.erb +83 -0
  64. data/app/views/spree/admin/vendors/new.html.erb +11 -0
  65. data/app/views/spree/api/v1/vendors/index.rabl +3 -0
  66. data/app/views/spree/api/v1/vendors/show.rabl +2 -0
  67. data/app/views/spree/vendor_mailer/vendor_notification_email.html.erb +81 -0
  68. data/app/views/spree/vendor_mailer/vendor_notification_email.text.erb +36 -0
  69. data/bin/rails +7 -0
  70. data/config/initializers/spree.rb +31 -0
  71. data/config/initializers/spree_permitted_attributes.rb +12 -0
  72. data/config/locales/en.yml +34 -0
  73. data/config/locales/es.yml +36 -0
  74. data/config/locales/fr.yml +33 -0
  75. data/config/routes.rb +29 -0
  76. data/db/default/vendors.rb +13 -0
  77. data/db/migrate/20170406102250_create_spree_vendors.rb +9 -0
  78. data/db/migrate/20170406102944_add_vendor_id_to_spree_models.rb +10 -0
  79. data/db/migrate/20170410111150_add_state_to_vendors.rb +6 -0
  80. data/db/migrate/20170412124925_add_deleted_at_to_spree_vendors.rb +6 -0
  81. data/db/migrate/20170413094447_create_spree_vendor_users.rb +11 -0
  82. data/db/migrate/20190212161426_add_slug_to_spree_vendors.rb +6 -0
  83. data/db/migrate/20190214120226_add_about_us_to_spree_vendors.rb +5 -0
  84. data/db/migrate/20190214142526_add_contact_us_to_spree_vendors.rb +5 -0
  85. data/db/migrate/20190305120337_add_commission_to_spree_vendors.rb +5 -0
  86. data/db/migrate/20190308091546_add_priority_to_vendor.rb +8 -0
  87. data/db/migrate/20190312130754_create_spree_order_commissions.rb +14 -0
  88. data/db/migrate/20190322133128_add_notification_email_to_vendors.rb +5 -0
  89. data/db/migrate/20200416030721_add_translations_to_vendor.rb +19 -0
  90. data/db/migrate/20210728120649_change_vendorized_models_vendor_id_type.rb +10 -0
  91. data/db/migrate/20210728120910_change_vendor_id_and_user_id_type_for_spree_vendor_users.rb +14 -0
  92. data/db/migrate/20210728121024_change_vendor_id_and_order_id_type_for_spree_order_commissions.rb +14 -0
  93. data/db/migrate/20221123095256_add_code_to_vendors.rb +6 -0
  94. data/lib/generators/spree_multi_vendor/install/install_generator.rb +21 -0
  95. data/lib/generators/spree_multi_vendor/mailers_preview/mailers_preview_generator.rb +22 -0
  96. data/lib/generators/spree_multi_vendor/mailers_preview/templates/mailers/previews/vendor_notification_preview.rb +5 -0
  97. data/lib/spree_multi_vendor/engine.rb +24 -0
  98. data/lib/spree_multi_vendor/factories.rb +7 -0
  99. data/lib/spree_multi_vendor/version.rb +11 -0
  100. data/lib/spree_multi_vendor.rb +16 -0
  101. data/lib/tasks/vendors.rake +8 -0
  102. data/spec/factories/spree/vendor_factory.rb +28 -0
  103. data/spec/factories/spree/vendor_image_factory.rb +5 -0
  104. data/spec/factories/spree/vendor_user_factory.rb +6 -0
  105. data/spec/features/spree/admin/orders_spec.rb +86 -0
  106. data/spec/features/spree/admin/product_spec.rb +177 -0
  107. data/spec/features/spree/admin/shipping_method_spec.rb +72 -0
  108. data/spec/features/spree/admin/stock_location_spec.rb +90 -0
  109. data/spec/features/spree/admin/vendor_settings_spec.rb +74 -0
  110. data/spec/features/spree/admin/vendor_spec.rb +125 -0
  111. data/spec/fixtures/thinking-cat.jpg +0 -0
  112. data/spec/mailers/vendor_mailer_spec.rb +45 -0
  113. data/spec/models/spree/line_item_spec.rb +32 -0
  114. data/spec/models/spree/order_commission_spec.rb +8 -0
  115. data/spec/models/spree/order_spec.rb +193 -0
  116. data/spec/models/spree/product_spec.rb +19 -0
  117. data/spec/models/spree/variant_spec.rb +104 -0
  118. data/spec/models/spree/vendor_order_totals_spec.rb +33 -0
  119. data/spec/models/spree/vendor_spec.rb +57 -0
  120. data/spec/models/spree/vendor_user_spec.rb +12 -0
  121. data/spec/requests/spree/api/v1/products_spec.rb +221 -0
  122. data/spec/requests/spree/api/v1/users_spec.rb +31 -0
  123. data/spec/requests/spree/api/v1/vendors_spec.rb +210 -0
  124. data/spec/requests/spree/api/v2/storefront/cart_spec.rb +85 -0
  125. data/spec/requests/spree/api/v2/storefront/products_spec.rb +96 -0
  126. data/spec/requests/spree/api/v2/storefront/vendors_spec.rb +118 -0
  127. data/spec/serializers/spree/v2/storefront/stock_location_serializer_spec.rb +32 -0
  128. data/spec/serializers/spree/v2/storefront/vendor_image_serializer_spec.rb +18 -0
  129. data/spec/serializers/spree/v2/storefront/vendor_order_totals_serializer_spec.rb +54 -0
  130. data/spec/serializers/spree/v2/storefront/vendor_serializer_spec.rb +34 -0
  131. data/spec/spec_helper.rb +13 -0
  132. data/spec/support/shoulda_matchers.rb +6 -0
  133. data/spree_multi_vendor.gemspec +42 -0
  134. metadata +308 -0
@@ -0,0 +1,14 @@
1
+ module SpreeMultiVendor::Spree::Stock::PackageDecorator
2
+ def shipping_methods
3
+ vendor = Spree::StockLocation.method_defined?(:vendor) ? stock_location.vendor : nil
4
+
5
+ # return only shipping methods for this Vendor
6
+ if vendor && Spree::ShippingMethod.method_defined?(:vendor)
7
+ vendor.shipping_methods.to_a
8
+ else
9
+ shipping_categories.map(&:shipping_methods).reduce(:&).to_a
10
+ end
11
+ end
12
+ end
13
+
14
+ Spree::Stock::Package.prepend SpreeMultiVendor::Spree::Stock::PackageDecorator
@@ -0,0 +1,8 @@
1
+ module SpreeMultiVendor::Spree::UserDecorator
2
+ def self.prepended(base)
3
+ base.has_many :vendor_users, class_name: 'Spree::VendorUser'
4
+ base.has_many :vendors, through: :vendor_users, class_name: 'Spree::Vendor'
5
+ end
6
+ end
7
+
8
+ Spree.user_class.prepend SpreeMultiVendor::Spree::UserDecorator
@@ -0,0 +1,40 @@
1
+ module SpreeMultiVendor::Spree::VariantDecorator
2
+ def self.prepended(base)
3
+ base.before_create :assign_vendor
4
+
5
+ base.scope :for_vendor_user, ->(user) { where(vendor_id: user.vendor_ids) }
6
+ end
7
+
8
+ def vendor
9
+ @vendor ||= if self.class.reflect_on_association(:vendor) && self[:vendor_id].present?
10
+ ::Spree::Vendor.unscoped.find(self[:vendor_id])
11
+ elsif Spree::Product.reflect_on_association(:vendor) && product.vendor_id.present?
12
+ product.vendor
13
+ end
14
+ end
15
+
16
+ def vendor_id
17
+ @vendor_id ||= if self.class.reflect_on_association(:vendor) && self[:vendor_id].present?
18
+ self[:vendor_id]
19
+ elsif Spree::Product.reflect_on_association(:vendor) && product.vendor_id.present?
20
+ product.vendor_id
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def assign_vendor
27
+ return if !product.class.reflect_on_association(:vendor) || product.vendor.blank?
28
+ return if !self.class.reflect_on_association(:vendor) || self[:vendor_id].present?
29
+
30
+ self.vendor = product.vendor
31
+ end
32
+
33
+ def create_stock_items
34
+ Spree::StockLocation.where(propagate_all_variants: true, vendor_id: vendor_id).each do |stock_location|
35
+ stock_location.propagate_variant(self)
36
+ end
37
+ end
38
+ end
39
+
40
+ Spree::Variant.prepend SpreeMultiVendor::Spree::VariantDecorator
@@ -0,0 +1,13 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/orders/_form',
3
+ name: 'vendorize_shipments',
4
+ replace: "erb[loud]:contains('render partial: \"spree/admin/orders/shipment\", collection: @order.shipments.order(:created_at), locals: {order: order}')",
5
+ text: "<%= render partial: \"spree/admin/orders/shipment\", collection: (current_spree_vendor ? @order.shipments.for_vendor(current_spree_vendor).order(:created_at) : @order.shipments.order(:created_at)), locals: {order: order} %>"
6
+ )
7
+
8
+ Deface::Override.new(
9
+ virtual_path: 'spree/admin/orders/_form',
10
+ name: 'display_vendor_total',
11
+ replace: "erb[loud]:contains('order.display_total')",
12
+ text: "<%= current_spree_vendor ? order.display_vendor_total(current_spree_vendor).to_html : order.display_total.to_html %>"
13
+ )
@@ -0,0 +1,6 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/orders/_line_items',
3
+ name: 'vendorize_line_items',
4
+ replace: "erb[silent]:contains('order.line_items.each do |item|')",
5
+ text: "<% (current_spree_vendor ? order.line_items.for_vendor(current_spree_vendor) : order.line_items).each do |item| %>"
6
+ )
@@ -0,0 +1,6 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/orders/_line_items_edit_form',
3
+ name: 'display_vendor_total',
4
+ replace: "erb[loud]:contains('order.display_total')",
5
+ text: "<%= current_spree_vendor ? order.display_vendor_total(current_spree_vendor).to_html : order.display_total.to_html %>"
6
+ )
@@ -0,0 +1,6 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/orders/index',
3
+ name: 'display_vendor_total',
4
+ replace: "erb[loud]:contains('order.display_total.to_html')",
5
+ text: "<%= current_spree_vendor ? order.display_vendor_total(current_spree_vendor).to_html : order.display_total.to_html %>"
6
+ )
@@ -0,0 +1,29 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/products/_form',
3
+ name: 'Enable vendors to manage product master price',
4
+ replace: 'div[data-hook="admin_product_form_price"]',
5
+ text: <<-HTML
6
+ <%= f.field_container :price, class: ['form-group'] do %>
7
+ <%= f.label :price, raw(Spree.t(:master_price) + content_tag(:span, ' *', class: "required")) %>
8
+ <%= f.text_field :price, value: number_to_currency(@product.price, unit: ''), class: 'form-control', disabled: (cannot? :update, Spree::Price) %>
9
+ <%= f.error_message_on :price %>
10
+ <% end %>
11
+ HTML
12
+ )
13
+
14
+ Deface::Override.new(
15
+ virtual_path: 'spree/admin/products/_form',
16
+ name: 'Enable admin to menage product vendor',
17
+ insert_before: 'div[data-hook="admin_product_form_taxons"]',
18
+ text: <<-HTML
19
+ <% if current_spree_user.respond_to?(:has_spree_role?) && current_spree_user.has_spree_role?(:admin) %>
20
+ <div data-hook="admin_product_form_vendor">
21
+ <%= f.field_container :vendor, class: ['form-group'] do %>
22
+ <%= f.label :vendor_id, Spree.t(:vendor) %>
23
+ <%= f.collection_select(:vendor_id, @vendors, :id, :name, { include_blank: Spree.t('match_choices.none') }, { class: 'select2' }) %>
24
+ <%= f.error_message_on :vendor %>
25
+ <% end %>
26
+ </div>
27
+ <% end %>
28
+ HTML
29
+ )
@@ -0,0 +1,16 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/products/new',
3
+ name: 'Enable admin to create product with assigned vendor',
4
+ insert_after: 'div[data-hook="new_product_shipping_category"]',
5
+ text: <<-HTML
6
+ <% if current_spree_user.respond_to?(:has_spree_role?) && current_spree_user.has_spree_role?(:admin) %>
7
+ <div data-hook="new_product_vendor" class="col-12 col-md-4">
8
+ <%= f.field_container :vendor, class: ['form-group'] do %>
9
+ <%= f.label :vendor_id, Spree.t(:vendor) %>
10
+ <%= f.collection_select(:vendor_id, @vendors, :id, :name, { include_blank: Spree.t('match_choices.none') }, { class: 'select2' }) %>
11
+ <%= f.error_message_on :vendor %>
12
+ <% end %>
13
+ </div>
14
+ <% end %>
15
+ HTML
16
+ )
@@ -0,0 +1,23 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/shared/_main_menu',
3
+ name: 'Display configuration tab for vendors',
4
+ replace: 'erb[silent]:contains("current_store")',
5
+ text: '<% if can?(:admin, current_store) || current_spree_user&.vendors&.any? %>'
6
+ )
7
+ Deface::Override.new(
8
+ virtual_path: 'spree/admin/shared/_main_menu',
9
+ name: 'vendors_main_menu_tabs',
10
+ insert_bottom: 'nav',
11
+ text: <<-HTML
12
+ <% if current_spree_user.respond_to?(:has_spree_role?) && current_spree_user.has_spree_role?(:admin) %>
13
+ <ul class="nav nav-sidebar border-bottom">
14
+ <%= tab plural_resource_name(Spree::Vendor), url: admin_vendors_path, icon: 'money' %>
15
+ </ul>
16
+ <% end %>
17
+ <% if defined?(current_spree_vendor) && current_spree_vendor %>
18
+ <ul class="nav nav-sidebar border-bottom">
19
+ <%= tab Spree::Vendor.model_name.human, url: admin_vendor_settings_path, icon: 'money' %>
20
+ </ul>
21
+ <% end %>
22
+ HTML
23
+ )
@@ -0,0 +1,35 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/shared/_order_summary',
3
+ name: 'display_vendor_subtotal',
4
+ replace: "erb[loud]:contains('@order.display_item_total.to_html')",
5
+ text: "<%= current_spree_vendor ? @order.display_vendor_subtotal(current_spree_vendor).to_html : @order.display_item_total.to_html %>"
6
+ )
7
+
8
+ Deface::Override.new(
9
+ virtual_path: 'spree/admin/shared/_order_summary',
10
+ name: 'display_vendor_ship_total',
11
+ replace: "erb[loud]:contains('@order.display_ship_total.to_html')",
12
+ text: "<%= current_spree_vendor ? @order.display_vendor_ship_total(current_spree_vendor).to_html : @order.display_ship_total.to_html %>"
13
+ )
14
+
15
+ Deface::Override.new(
16
+ virtual_path: 'spree/admin/shared/_order_summary',
17
+ name: 'display_vendor_total',
18
+ replace: "erb[loud]:contains('@order.display_total.to_html')",
19
+ text: "<%= current_spree_vendor ? @order.display_vendor_total(current_spree_vendor).to_html : @order.display_total.to_html %>"
20
+ )
21
+ Deface::Override.new(
22
+ virtual_path: 'spree/admin/shared/_order_summary',
23
+ name: 'display_commission',
24
+ insert_after: 'td[id="item_total"]',
25
+ text: <<-HTML
26
+ <tr>
27
+ <td data-hook='admin_order_tab_commission'>
28
+ <strong><%= Spree.t(:commission) %></strong>
29
+ </td>
30
+ <td id='order_commission'>
31
+ <%= current_spree_vendor ? @order.display_vendor_commission(current_spree_vendor) : @order.display_order_commission %>
32
+ </td>
33
+ </tr>
34
+ HTML
35
+ )
@@ -0,0 +1,13 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/users/_form',
3
+ name: 'Add vendor select in user form',
4
+ insert_bottom: 'div[data-hook="admin_user_form_roles"]',
5
+ text: <<-HTML
6
+ <% if current_spree_user.respond_to?(:has_spree_role?) && current_spree_user.has_spree_role?(:admin) %>
7
+ <%= f.field_container :vendor_ids, class: ['form-group'] do %>
8
+ <%= f.label :vendor_ids, plural_resource_name(Spree::Vendor) %>
9
+ <%= f.collection_select(:vendor_ids, Spree::Vendor.all, :id, :name, { }, { class: 'select2', multiple: true }) %>
10
+ <% end %>
11
+ <% end %>
12
+ HTML
13
+ )
@@ -0,0 +1,12 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class VendorSerializer < BaseSerializer
6
+ include ResourceSerializerConcern
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module V2
3
+ module Storefront
4
+ class VendorImageSerializer < BaseSerializer
5
+ set_type :vendor_image
6
+
7
+ attributes :styles
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ module Spree
2
+ module V2
3
+ module Storefront
4
+ class VendorOrderTotalsSerializer < BaseSerializer
5
+ set_type :vendor_totals
6
+
7
+ cache_options store: nil
8
+
9
+ attributes :name, :subtotal, :ship_total, :total, :display_subtotal,
10
+ :display_ship_total, :display_total, :promo_total,
11
+ :display_promo_total, :included_tax_total,
12
+ :display_included_tax_total, :additional_tax_total,
13
+ :display_additional_tax_total, :item_count,
14
+ :pre_tax_item_amount, :display_pre_tax_item_amount,
15
+ :pre_tax_ship_amount, :display_pre_tax_ship_amount,
16
+ :pre_tax_total, :display_pre_tax_total
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module V2
3
+ module Storefront
4
+ class VendorSerializer < BaseSerializer
5
+ set_type :vendor
6
+
7
+ attributes :name, :about_us, :slug, :code, :contact_us
8
+
9
+ has_one :image, serializer: :vendor_image
10
+ has_many :products
11
+ has_many :stock_locations
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ module SpreeMultiVendor
2
+ module CartSerializerDecorator
3
+ def self.prepended(base)
4
+ base.has_many :vendors,
5
+ serializer: ::Spree::V2::Storefront::VendorSerializer,
6
+ record_type: :vendor,
7
+ id_method_name: :vendor_ids,
8
+ object_method_name: :vendor_list
9
+
10
+ base.has_many :vendor_totals,
11
+ serializer: ::Spree::V2::Storefront::VendorOrderTotalsSerializer,
12
+ record_type: :vendor_totals,
13
+ id_method_name: :vendor_ids,
14
+ object_method_name: :vendor_totals
15
+ end
16
+ end
17
+ end
18
+
19
+ Spree::V2::Storefront::CartSerializer.prepend(SpreeMultiVendor::CartSerializerDecorator)
@@ -0,0 +1,23 @@
1
+ module SpreeMultiVendor
2
+ module SerializerDecorator
3
+ def self.prepended(base)
4
+ base.belongs_to :vendor, serializer: ::Spree::V2::Storefront::VendorSerializer
5
+ end
6
+ end
7
+ end
8
+
9
+ SpreeMultiVendor.vendorized_models.each do |model|
10
+ serializer_class_name = "Spree::V2::Storefront::#{model.to_s.demodulize}Serializer".constantize
11
+
12
+ serializer_class_name.prepend(SpreeMultiVendor::SerializerDecorator)
13
+ rescue
14
+ end
15
+
16
+ # Variant model accesses Vendor via Product if not associated directly
17
+ unless SpreeMultiVendor.vendorized_models.include?(Spree::Variant)
18
+ Spree::V2::Storefront::VariantSerializer.prepend(SpreeMultiVendor::SerializerDecorator)
19
+ end
20
+
21
+ unless SpreeMultiVendor.vendorized_models.include?(Spree::LineItem)
22
+ Spree::V2::Storefront::LineItemSerializer.prepend(SpreeMultiVendor::SerializerDecorator)
23
+ end
@@ -0,0 +1,34 @@
1
+ module Spree
2
+ module Orders
3
+ class GenerateCommissions
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call(order:)
7
+ ActiveRecord::Base.transaction do
8
+ run :generate_order_commissions
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def generate_order_commissions(order:)
15
+ return failure(order) unless order.state == 'complete'
16
+
17
+ order.vendor_list.each do |vendor|
18
+ amount = if vendor.commission_rate.zero?
19
+ 0.0
20
+ else
21
+ order.vendor_pre_tax_item_amount(vendor) * vendor.commission_rate / 100
22
+ end
23
+
24
+ order.commissions.create!(
25
+ amount: amount,
26
+ vendor_id: vendor.id
27
+ )
28
+ end
29
+
30
+ success(order: order)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_resource, resource: Spree::Vendor.model_name.human) %>
3
+ <% end %>
4
+
5
+ <%= render 'settings' %>
6
+
7
+ <div class="row translations">
8
+ <div class="col-md-4">
9
+ <%= render 'fields' %>
10
+ </div>
11
+ <div class="col-md-8">
12
+ <%= form_for [:admin, @resource.id, @resource], url: spree.admin_vendor_path(@vendor.id) do |f| %>
13
+ <%= render 'form_fields', f: f %>
14
+ <div class="form-actions" data-hook="buttons">
15
+ <%= button Spree.t(:update), 'update' %>
16
+ <span class="or"><%= Spree.t(:or) %></span>
17
+ <%= button_link_to Spree.t(:cancel), spree.edit_admin_vendor_url(@vendor.id), icon: 'remove' %>
18
+ </div>
19
+ <% end %>
20
+ </div>
21
+ </div>
@@ -0,0 +1,47 @@
1
+ <% content_for :page_title do %>
2
+ <%= @vendor.name %>
3
+ <% end %>
4
+
5
+ <%= form_for [:admin, @vendor], url: admin_vendor_settings_url do |f| %>
6
+ <fieldset>
7
+ <%= render partial: 'spree/admin/shared/error_messages', locals: { target: @vendor } %>
8
+ <div class="form-group">
9
+ <%= f.field_container :name do %>
10
+ <%= f.label :name %>
11
+ <%= f.text_field :name, class: 'form-control' %>
12
+ <% end %>
13
+ </div>
14
+ <% if Spree.version.to_f >= 3.6 %>
15
+ <div class="form-group">
16
+ <%= f.field_container :image do %>
17
+ <%= f.label :image %>
18
+ <%= f.file_field :image %>
19
+ <%= image_tag main_app.url_for(@vendor.image.url(:small)) if @vendor.image %>
20
+ <% end %>
21
+ </div>
22
+ <% end %>
23
+ <div class="form-group">
24
+ <%= f.field_container :about_us do %>
25
+ <%= f.label :about_us %>
26
+ <%= f.text_area :about_us, class: 'form-control' %>
27
+ <% end %>
28
+ </div>
29
+ <div class="form-group">
30
+ <%= f.field_container :contact_us do %>
31
+ <%= f.label :contact_us %>
32
+ <%= f.text_area :contact_us, class: 'form-control' %>
33
+ <% end %>
34
+ </div>
35
+ <div class="form-group">
36
+ <%= f.field_container :notification_email do %>
37
+ <%= f.label :notification_email %>
38
+ <%= f.email_field :notification_email, class: 'form-control' %>
39
+ <% end %>
40
+ </div>
41
+ <div class="form-actions" data-hook="buttons">
42
+ <%= button Spree.t('actions.update'), 'save' %>
43
+ <span class="or"><%= Spree.t(:or) %></span>
44
+ <%= button_link_to Spree.t('actions.cancel'), admin_vendor_settings_url, icon: 'delete' %>
45
+ </div>
46
+ </fieldset>
47
+ <% end %>
@@ -0,0 +1,36 @@
1
+ <%= render partial: 'spree/admin/shared/error_messages', locals: { target: @vendor } %>
2
+ <div class="form-group">
3
+ <%= f.field_container :name do %>
4
+ <%= f.label :name %>
5
+ <%= f.text_field :name, class: 'form-control' %>
6
+ <% end %>
7
+ <%= f.field_container :about_us do %>
8
+ <%= f.label :about_us %>
9
+ <%= f.text_area :about_us, class: 'form-control' %>
10
+ <% end %>
11
+ <%= f.field_container :contact_us do %>
12
+ <%= f.label :contact_us %>
13
+ <%= f.text_area :contact_us, class: 'form-control' %>
14
+ <% end %>
15
+ <%= f.field_container :state do %>
16
+ <%= f.label :state %>
17
+ <%= f.select :state,
18
+ options_for_select(vendor_state_options, selected: @vendor.state),
19
+ {}, class: 'select2', required: :required %>
20
+ <% end %>
21
+ <% if Spree.version.to_f >= 3.6 %>
22
+ <%= f.field_container :image do %>
23
+ <%= f.label :image %>
24
+ <%= f.file_field :image %>
25
+ <%= image_tag main_app.url_for(@vendor.image.url(:small)) if @vendor.image %>
26
+ <% end %>
27
+ <% end %>
28
+ <%= f.field_container :commission_rate do %>
29
+ <%= f.label :commission_rate %>
30
+ <%= f.number_field :commission_rate, step: '0.01', class: 'form-control' %>
31
+ <% end %>
32
+ <%= f.field_container :notification_email do%>
33
+ <%= f.label :notification_email %>
34
+ <%= f.email_field :notification_email, class: 'form-control' %>
35
+ <% end %>
36
+ </div>
@@ -0,0 +1,11 @@
1
+ <% content_for :page_title do %>
2
+ <%= link_to plural_resource_name(Spree::Vendor), spree.admin_vendors_url %> /
3
+ <%= @vendor.name %>
4
+ <% end %>
5
+
6
+ <%= form_for [:admin, @vendor] do |f| %>
7
+ <fieldset>
8
+ <%= render partial: 'form', locals: { f: f } %>
9
+ <%= render partial: 'spree/admin/shared/edit_resource_links' %>
10
+ </fieldset>
11
+ <% end %>
@@ -0,0 +1,83 @@
1
+ <% content_for :page_title do %>
2
+ <%= plural_resource_name(Spree::Vendor) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:new_vendor), new_object_url, { class: "btn-success", icon: 'add', id: 'admin_new_vendor' } %>
7
+ <% end if can?(:create, Spree::Vendor) %>
8
+
9
+ <% content_for :table_filter do %>
10
+ <div data-hook="admin_vendors_index_search">
11
+ <%= search_form_for [:admin, @search] do |f| %>
12
+ <div class="row">
13
+ <div class="col-md-6">
14
+ <div class="form-group">
15
+ <%= label_tag :q_name_cont, Spree.t(:name) %>
16
+ <%= f.text_field :name_cont, tabindex: 1, class: "form-control js-quick-search-target" %>
17
+ </div>
18
+ </div>
19
+ <div class="col-md-6">
20
+ <div class="form-group">
21
+ <%= label_tag :q_state_in, Spree.t(:state) %>
22
+ <%= f.select :state_in, options_for_select(vendor_state_options), { multiple: 'please select' }, class: 'select2', multiple: true %>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ <div data-hook="admin_vendors_index_search_buttons" class="form-actions">
27
+ <%= button Spree.t(:filter_results), 'search' %>
28
+ </div>
29
+ <% end %>
30
+ </div>
31
+ <% end %>
32
+
33
+ <%= render partial: 'spree/admin/shared/index_table_options', locals: { collection: @collection } %>
34
+
35
+ <% if @vendors.any? %>
36
+ <table class="table sortable" data-hook="vendors_table" data-sortable-link="<%= update_positions_admin_vendors_url %>">
37
+ <thead>
38
+ <tr data-hook="vendors_header">
39
+ <th>
40
+ <%= Spree.t(:user) %>
41
+ </th>
42
+ <th>
43
+ <%= sort_link @search, :name, I18n.t(:name, scope: 'activerecord.attributes.spree/vendor') %>
44
+ </th>
45
+ <th>
46
+ <%= sort_link @search, :state, I18n.t(:state, scope: 'activerecord.attributes.spree/vendor') %>
47
+ </th>
48
+ <th class="actions"></th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+ <% @vendors.each do |vendor| %>
53
+ <tr id="<%= spree_dom_id vendor %>" data-hook="vendors_row">
54
+ <td>
55
+ <%= vendor.users.first.email rescue nil %>
56
+ </td>
57
+ <td>
58
+ <%= vendor.name %>
59
+ </td>
60
+ <td>
61
+ <span class="label label-<%= vendor.state.downcase %>"><%= vendor.state.humanize.downcase %></span>
62
+ <span class="icon icon-filter filterable js-add-filter" data-ransack-field="q_state_eq" data-ransack-value="<%= vendor.state %>"></span>
63
+ </td>
64
+ <td class="actions actions-2 text-right">
65
+ <%= link_to_edit vendor, no_text: true, class: 'edit' if can?(:edit, vendor) %>
66
+ <!-- Add translation icon support -->
67
+ <%= link_to_with_icon 'translate',
68
+ nil,
69
+ spree.admin_translations_path('vendor', vendor.id),
70
+ title: Spree.t(:'i18n.translations'),
71
+ class: 'btn btn-sm btn-primary' if defined? (SpreeGlobalize)%>
72
+ </td>
73
+ </tr>
74
+ <% end %>
75
+ </tbody>
76
+ </table>
77
+ <% else %>
78
+ <div class="alert alert-info alpha twelve columns no-objects-found">
79
+ <%= Spree.t(:no_resource_found, resource: plural_resource_name(Spree::Vendor)) %>
80
+ </div>
81
+ <% end %>
82
+
83
+ <%= render partial: 'spree/admin/shared/index_table_options', locals: { collection: @collection } %>
@@ -0,0 +1,11 @@
1
+ <% content_for :page_title do %>
2
+ <%= link_to plural_resource_name(Spree::Vendor), spree.admin_vendors_url %> /
3
+ <%= Spree.t(:new_vendor) %>
4
+ <% end %>
5
+
6
+ <%= form_for [:admin, @vendor] do |f| %>
7
+ <fieldset>
8
+ <%= render partial: 'form', locals: { f: f } %>
9
+ <%= render partial: 'spree/admin/shared/new_resource_links' %>
10
+ </fieldset>
11
+ <% end %>
@@ -0,0 +1,3 @@
1
+ collection @vendors
2
+
3
+ extends 'spree/api/v1/vendors/show'
@@ -0,0 +1,2 @@
1
+ object @vendor
2
+ attributes *vendor_attributes