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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +8 -0
- data/LICENSE +26 -0
- data/README.md +123 -0
- data/Rakefile +15 -0
- data/Versionfile +6 -0
- data/app/assets/javascripts/spree/backend/solidus_marketplace.js +5 -0
- data/app/assets/javascripts/spree/backend/solidus_marketplace_routes.js +1 -0
- data/app/assets/javascripts/spree/backend/suppliers_autocomplete.js +55 -0
- data/app/assets/javascripts/spree/frontend/solidus_marketplace.js +1 -0
- data/app/assets/stylesheets/spree/backend/solidus_marketplace.scss +22 -0
- data/app/assets/stylesheets/spree/frontend/solidus_marketplace.css +3 -0
- data/app/controllers/ckeditor/attachment_files_controller_decorator.rb +20 -0
- data/app/controllers/ckeditor/pictures_controller_decorator.rb +17 -0
- data/app/controllers/spree/admin/marketplace_settings_controller.rb +19 -0
- data/app/controllers/spree/admin/products_controller_decorator.rb +79 -0
- data/app/controllers/spree/admin/reports_controller_decorator.rb +68 -0
- data/app/controllers/spree/admin/shipments_controller.rb +47 -0
- data/app/controllers/spree/admin/stock_items_controller_decorator.rb +10 -0
- data/app/controllers/spree/admin/stock_locations_controller_decorator.rb +23 -0
- data/app/controllers/spree/admin/suppliers_controller.rb +54 -0
- data/app/controllers/spree/admin/users_controller_decorator.rb +34 -0
- data/app/controllers/spree/api/suppliers_controller.rb +16 -0
- data/app/controllers/spree/api/v1/stock_locations_controller_decorator.rb +18 -0
- data/app/controllers/spree/base_controller_decorator.rb +13 -0
- data/app/helpers/spree/api/api_helpers_decorator.rb +22 -0
- data/app/mailers/spree/marketplace_order_mailer.rb +13 -0
- data/app/mailers/spree/supplier_mailer.rb +12 -0
- data/app/models/ckeditor/asset_decorator.rb +5 -0
- data/app/models/spree.rb +5 -0
- data/app/models/spree/marketplace_configuration.rb +14 -0
- data/app/models/spree/order_decorator.rb +44 -0
- data/app/models/spree/payment_decorator.rb +7 -0
- data/app/models/spree/product_decorator.rb +52 -0
- data/app/models/spree/shipment_decorator.rb +40 -0
- data/app/models/spree/stock/splitter/marketplace.rb +47 -0
- data/app/models/spree/stock_location_decorator.rb +23 -0
- data/app/models/spree/supplier.rb +120 -0
- data/app/models/spree/supplier_ability.rb +35 -0
- data/app/models/spree/supplier_variant.rb +6 -0
- data/app/models/spree/user_decorator.rb +23 -0
- data/app/models/spree/variant_decorator.rb +24 -0
- data/app/overrides/spree/admin/menus.rb +15 -0
- data/app/overrides/spree/admin/products/_form/converted_admin_product_form_right.html.erb.deface +5 -0
- data/app/overrides/spree/admin/products/edit/override_rows.html.erb.deface +22 -0
- data/app/overrides/spree/admin/stock_locations/_form/add_supplier.html.erb.deface +12 -0
- data/app/views/spree/admin/marketplace_settings/edit.html.erb +21 -0
- data/app/views/spree/admin/orders/index.html.erb +187 -0
- data/app/views/spree/admin/products/_form.html.erb +198 -0
- data/app/views/spree/admin/reports/earnings.html.erb +34 -0
- data/app/views/spree/admin/shared/_marketplace_settings.html.erb +1 -0
- data/app/views/spree/admin/shared/_marketplace_tabs.html.erb +4 -0
- data/app/views/spree/admin/shipments/edit.html.erb +24 -0
- data/app/views/spree/admin/shipments/index.html.erb +93 -0
- data/app/views/spree/admin/suppliers/_form.html.erb +75 -0
- data/app/views/spree/admin/suppliers/edit.html.erb +22 -0
- data/app/views/spree/admin/suppliers/index.html.erb +68 -0
- data/app/views/spree/admin/suppliers/new.html.erb +17 -0
- data/app/views/spree/api/shared/_pagination.json.jbuilder +5 -0
- data/app/views/spree/api/suppliers/_supplier.json.jbuilder +1 -0
- data/app/views/spree/api/suppliers/index.json.jbuilder +4 -0
- data/app/views/spree/marketplace_order_mailer/supplier_order.html.erb +119 -0
- data/app/views/spree/shared/unauthorized.erb +1 -0
- data/app/views/spree/supplier_mailer/welcome.html.erb +53 -0
- data/config/locales/en.yml +107 -0
- data/config/locales/es.yml +133 -0
- data/config/routes.rb +24 -0
- data/db/default/spree/marketplace_roles.rb +14 -0
- data/db/migrate/20121006073854_create_suppliers.rb +20 -0
- data/db/migrate/20130216070944_product_belongs_to_supplier.rb +6 -0
- data/db/migrate/20130405005502_stock_locations_belongs_to_supplier.rb +6 -0
- data/db/migrate/20130405011127_user_belongs_to_supplier.rb +6 -0
- data/db/migrate/20130428063053_add_balanced_token_to_suppliers.rb +7 -0
- data/db/migrate/20130510181443_add_supplier_id_to_ckeditor_assets.rb +8 -0
- data/db/migrate/20130606220913_add_permalink_to_suppliers.rb +6 -0
- data/db/migrate/20140323170638_add_supplier_commission_to_shipments.rb +5 -0
- data/db/migrate/20140416184616_migrate_payment_and_commission.rb +7 -0
- data/db/migrate/20140529041325_create_spree_supplier_variants.rb +15 -0
- data/db/migrate/20171027180043_add_paypal_email_to_suppliers.rb +5 -0
- data/db/seeds.rb +8 -0
- data/lib/generators/solidus_marketplace/install/install_generator.rb +36 -0
- data/lib/solidus_marketplace.rb +6 -0
- data/lib/solidus_marketplace/engine.rb +53 -0
- data/lib/solidus_marketplace/factories.rb +107 -0
- data/lib/solidus_marketplace/version.rb +3 -0
- data/lib/spree/permitted_attributes_decorator.rb +18 -0
- data/lib/tasks/spree_sample.rake +72 -0
- data/log/awesome.log +1 -0
- data/script/rails +7 -0
- data/solidus_marketplace.gemspec +46 -0
- data/spec/features/admin/orders_spec.rb +11 -0
- data/spec/features/admin/products_spec.rb +25 -0
- data/spec/features/admin/return_authorizations_spec.rb +7 -0
- data/spec/features/admin/settings_spec.rb +33 -0
- data/spec/features/admin/shipments_spec.rb +80 -0
- data/spec/features/admin/stock_management_spec.rb +156 -0
- data/spec/features/admin/stock_spec.rb +98 -0
- data/spec/features/admin/suppliers_spec.rb +130 -0
- data/spec/models/spree/order_decorator_spec.rb +80 -0
- data/spec/models/spree/payment_decorator_spec.rb +7 -0
- data/spec/models/spree/product_decorator_spec.rb +56 -0
- data/spec/models/spree/shipment_decorator_spec.rb +48 -0
- data/spec/models/spree/stock/splitter/marketplace_spec.rb +62 -0
- data/spec/models/spree/stock_location_decorator_spec.rb +33 -0
- data/spec/models/spree/supplier_ability_spec.rb +182 -0
- data/spec/models/spree/supplier_spec.rb +123 -0
- data/spec/models/spree/supplier_variant_spec.rb +5 -0
- data/spec/models/spree/user_decorator_spec.rb +57 -0
- data/spec/models/spree/variant_decorator_spec.rb +7 -0
- data/spec/spec_helper.rb +91 -0
- data/spec/support/ability_helpers.rb +11 -0
- data/spec/support/integration_helpers.rb +15 -0
- metadata +473 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require 'csv'
|
|
2
|
+
|
|
3
|
+
Spree::Admin::ReportsController.class_eval do
|
|
4
|
+
before_action :add_marketplace_reports, only: [:index]
|
|
5
|
+
|
|
6
|
+
def earnings
|
|
7
|
+
@supplier_earnings = get_supplier_earnings
|
|
8
|
+
respond_to do |format|
|
|
9
|
+
format.html
|
|
10
|
+
format.csv { send_data earnings_csv }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def earnings_csv
|
|
15
|
+
header1 = ["Supplier Earnings"]
|
|
16
|
+
header2 = ["Supplier", "Earnings", "Paypal Email"]
|
|
17
|
+
|
|
18
|
+
CSV.generate do |csv|
|
|
19
|
+
csv << header1
|
|
20
|
+
csv << []
|
|
21
|
+
csv << header2
|
|
22
|
+
@supplier_earnings.each do |se|
|
|
23
|
+
csv << ["#{se[:name]}", "#{se[:earnings].to_html}", "#{se[:paypal_email]}"]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def add_marketplace_reports
|
|
31
|
+
marketplace_reports.each do |report|
|
|
32
|
+
Spree::Admin::ReportsController.add_available_report! report
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def marketplace_reports
|
|
37
|
+
[:earnings]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def get_supplier_earnings
|
|
41
|
+
grouped_supplier_earnings.each do |se|
|
|
42
|
+
se[:earnings] = se[:earnings].inject(Spree::Money.new(0)){ |e, c| c + e }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def grouped_supplier_earnings
|
|
47
|
+
params[:q] = search_params
|
|
48
|
+
@search = Spree::Order.complete.ransack(params[:q])
|
|
49
|
+
@orders = @search.result
|
|
50
|
+
|
|
51
|
+
supplier_earnings_map = @orders.map { |o| o.supplier_earnings_map }
|
|
52
|
+
grouped_suppliers_map = supplier_earnings_map.flatten.group_by { |e| e[:name] }.values
|
|
53
|
+
grouped_earnings = grouped_suppliers_map.map do |gs|
|
|
54
|
+
h = {}
|
|
55
|
+
h[:name] = nil
|
|
56
|
+
h[:paypal_email] = nil
|
|
57
|
+
h[:earnings] = []
|
|
58
|
+
gs.each do |s|
|
|
59
|
+
h[:name] = s[:name] if h[:name].nil?
|
|
60
|
+
h[:paypal_email] = s[:paypal_email] if h[:paypal_email].nil?
|
|
61
|
+
h[:earnings] << s[:earnings]
|
|
62
|
+
end
|
|
63
|
+
h
|
|
64
|
+
end
|
|
65
|
+
grouped_earnings
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
class ShipmentsController < Spree::Admin::ResourceController
|
|
4
|
+
|
|
5
|
+
def index
|
|
6
|
+
params[:q] ||= {}
|
|
7
|
+
# params[:q][:completed_at_null] ||= '1'
|
|
8
|
+
# @show_only_incomplete = params[:q][:completed_at_null].present?
|
|
9
|
+
# params[:q][:s] ||= @show_only_incomplete ? 'created_at desc' : 'completed_at desc'
|
|
10
|
+
|
|
11
|
+
# As date params are deleted if @show_only_incomplete, store
|
|
12
|
+
# the original date so we can restore them into the params
|
|
13
|
+
# after the search
|
|
14
|
+
created_at_gt = params[:q][:created_at_gt]
|
|
15
|
+
created_at_lt = params[:q][:created_at_lt]
|
|
16
|
+
|
|
17
|
+
if !params[:q][:created_at_gt].blank?
|
|
18
|
+
params[:q][:created_at_gt] = Time.zone.parse(params[:q][:created_at_gt]).beginning_of_day rescue ""
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if !params[:q][:created_at_lt].blank?
|
|
22
|
+
params[:q][:created_at_lt] = Time.zone.parse(params[:q][:created_at_lt]).end_of_day rescue ""
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
@search = Spree::Shipment.accessible_by(current_ability, :index).ransack(params[:q])
|
|
26
|
+
@shipments = @search.result.
|
|
27
|
+
page(params[:page]).
|
|
28
|
+
per(params[:per_page] || Spree::Config[:orders_per_page])
|
|
29
|
+
|
|
30
|
+
# Restore dates
|
|
31
|
+
params[:q][:created_at_gt] = created_at_gt
|
|
32
|
+
params[:q][:created_at_lt] = created_at_lt
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def find_resource
|
|
38
|
+
if parent_data.present?
|
|
39
|
+
parent.send(controller_name).find_by!(number: params[:id])
|
|
40
|
+
else
|
|
41
|
+
model_class.find_by!(number: params[:id])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Spree::Admin::StockItemsController.class_eval do
|
|
2
|
+
before_action :load_supplier_stock_location, only: :index
|
|
3
|
+
|
|
4
|
+
def load_supplier_stock_location
|
|
5
|
+
if try_spree_current_user.supplier
|
|
6
|
+
@stock_locations = Spree::StockLocation.by_supplier(try_spree_current_user.supplier).accessible_by(current_ability, :read)
|
|
7
|
+
@stock_item_stock_locations = params[:stock_location_id].present? ? @stock_locations.where(id: params[:stock_location_id]) : @stock_locations
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Spree::Admin::StockLocationsController.class_eval do
|
|
2
|
+
|
|
3
|
+
create.after :set_supplier
|
|
4
|
+
|
|
5
|
+
def index
|
|
6
|
+
@stock_locations = Spree::StockLocation.accessible_by(current_ability, :read)
|
|
7
|
+
.order('name ASC')
|
|
8
|
+
.ransack(params[:q])
|
|
9
|
+
.result
|
|
10
|
+
.page(params[:page])
|
|
11
|
+
.per(params[:per_page])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def set_supplier
|
|
17
|
+
if try_spree_current_user.supplier?
|
|
18
|
+
@object.supplier = try_spree_current_user.supplier
|
|
19
|
+
@object.save
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
class Spree::Admin::SuppliersController < Spree::Admin::ResourceController
|
|
2
|
+
|
|
3
|
+
def update
|
|
4
|
+
@object.address = Spree::Address.immutable_merge(@object.address, permitted_resource_params[:address_attributes])
|
|
5
|
+
|
|
6
|
+
if @object.update_attributes(permitted_resource_params.except(:address_attributes))
|
|
7
|
+
respond_with(@object) do |format|
|
|
8
|
+
format.html do
|
|
9
|
+
flash[:success] = flash_message_for(@object, :successfully_updated)
|
|
10
|
+
redirect_to location_after_save
|
|
11
|
+
end
|
|
12
|
+
format.js { render layout: false }
|
|
13
|
+
end
|
|
14
|
+
else
|
|
15
|
+
respond_with(@object) do |format|
|
|
16
|
+
format.html do
|
|
17
|
+
flash.now[:error] = @object.errors.full_messages.join(", ")
|
|
18
|
+
render_after_update_error
|
|
19
|
+
end
|
|
20
|
+
format.js { render layout: false }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def edit
|
|
26
|
+
@object.address = Spree::Address.build_default unless @object.address.present?
|
|
27
|
+
respond_with(@object) do |format|
|
|
28
|
+
format.html { render :layout => !request.xhr? }
|
|
29
|
+
format.js { render :layout => false }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def new
|
|
34
|
+
@object.address = Spree::Address.build_default
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def collection
|
|
40
|
+
params[:q] ||= {}
|
|
41
|
+
params[:q][:meta_sort] ||= "name.asc"
|
|
42
|
+
@search = Spree::Supplier.search(params[:q])
|
|
43
|
+
@collection = @search.result.page(params[:page]).per(Spree::Config[:orders_per_page])
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def find_resource
|
|
47
|
+
Spree::Supplier.friendly.find(params[:id])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def location_after_save
|
|
51
|
+
spree.edit_admin_supplier_path(@object)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Spree::Admin::UsersController.class_eval do
|
|
2
|
+
|
|
3
|
+
def create
|
|
4
|
+
current_supplier = try_spree_current_user.supplier
|
|
5
|
+
@user = Spree.user_class.new(user_params)
|
|
6
|
+
@user.supplier = current_supplier
|
|
7
|
+
if @user.save
|
|
8
|
+
set_roles
|
|
9
|
+
set_stock_locations
|
|
10
|
+
|
|
11
|
+
flash[:success] = Spree.t(:created_successfully)
|
|
12
|
+
redirect_to edit_admin_user_url(@user)
|
|
13
|
+
else
|
|
14
|
+
load_roles
|
|
15
|
+
load_stock_locations
|
|
16
|
+
|
|
17
|
+
flash.now[:error] = @user.errors.full_messages.join(", ")
|
|
18
|
+
render :new, status: :unprocessable_entity
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def build_resource
|
|
25
|
+
current_supplier = try_spree_current_user.supplier
|
|
26
|
+
|
|
27
|
+
if parent?
|
|
28
|
+
parent.send(controller_name).build
|
|
29
|
+
else
|
|
30
|
+
model_class.new(supplier: current_supplier)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
class SuppliersController < Spree::Api::BaseController
|
|
4
|
+
def index
|
|
5
|
+
if params[:ids]
|
|
6
|
+
@suppliers = Spree::Supplier.accessible_by(current_ability, :read).where(id: params[:ids].split(',')).order(:name)
|
|
7
|
+
else
|
|
8
|
+
@suppliers = Spree::Supplier.accessible_by(current_ability, :read).order(:name).ransack(params[:q]).result
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
@suppliers = paginate(@suppliers)
|
|
12
|
+
respond_with(@suppliers)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Spree::Api::StockLocationsController.class_eval do
|
|
2
|
+
|
|
3
|
+
before_action :supplier_locations, only: [:index]
|
|
4
|
+
before_action :supplier_transfers, only: [:index]
|
|
5
|
+
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def supplier_locations
|
|
9
|
+
params[:q] ||= {}
|
|
10
|
+
params[:q][:supplier_id_eq] = spree_current_user.supplier_id
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def supplier_transfers
|
|
14
|
+
params[:q] ||= {}
|
|
15
|
+
params[:q][:supplier_id_eq] = spree_current_user.supplier_id
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Spree::BaseController.class_eval do
|
|
2
|
+
|
|
3
|
+
prepend_before_action :redirect_supplier
|
|
4
|
+
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def redirect_supplier
|
|
8
|
+
if ['/admin', '/admin/authorization_failure'].include?(request.path) && try_spree_current_user.try(:supplier)
|
|
9
|
+
redirect_to '/admin/shipments' and return false
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module ApiHelpers
|
|
4
|
+
|
|
5
|
+
@@supplier_attributes = [
|
|
6
|
+
:id,
|
|
7
|
+
:address_id,
|
|
8
|
+
:commission_flat_rate,
|
|
9
|
+
:commission_percentage,
|
|
10
|
+
:email,
|
|
11
|
+
:name,
|
|
12
|
+
:url,
|
|
13
|
+
:deleted_at,
|
|
14
|
+
:tax_id,
|
|
15
|
+
:token,
|
|
16
|
+
:slug
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
mattr_reader(:supplier_attributes)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
class MarketplaceOrderMailer < Spree::BaseMailer
|
|
3
|
+
|
|
4
|
+
default from: Spree::Store.default.mail_from_address
|
|
5
|
+
|
|
6
|
+
def supplier_order(shipment_id)
|
|
7
|
+
@shipment = Shipment.find shipment_id
|
|
8
|
+
@supplier = @shipment.supplier
|
|
9
|
+
mail to: @supplier.email, subject: Spree.t('marketplace_order_mailer.supplier_order.subject', name: Spree::Store.current.name, number: @shipment.number)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
class SupplierMailer < Spree::BaseMailer
|
|
3
|
+
|
|
4
|
+
default from: Spree::Store.default.mail_from_address
|
|
5
|
+
|
|
6
|
+
def welcome(supplier_id)
|
|
7
|
+
@supplier = Supplier.find supplier_id
|
|
8
|
+
mail to: @supplier.email, subject: Spree.t('supplier_mailer.welcome.subject')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end
|
|
12
|
+
end
|
data/app/models/spree.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
class MarketplaceConfiguration < Preferences::Configuration
|
|
3
|
+
|
|
4
|
+
# Default flat rate to charge suppliers per order for commission.
|
|
5
|
+
preference :default_commission_flat_rate, :float, default: 0.0
|
|
6
|
+
|
|
7
|
+
# Default percentage to charge suppliers per order for commission.
|
|
8
|
+
preference :default_commission_percentage, :float, default: 0.0
|
|
9
|
+
|
|
10
|
+
# Determines whether or not to email a new supplier their welcome email.
|
|
11
|
+
preference :send_supplier_email, :boolean, default: true
|
|
12
|
+
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
Spree::Order.class_eval do
|
|
2
|
+
|
|
3
|
+
has_many :stock_locations, through: :shipments
|
|
4
|
+
has_many :suppliers, through: :stock_locations
|
|
5
|
+
|
|
6
|
+
def supplier_total(user_or_supplier)
|
|
7
|
+
supplier = user_or_supplier.is_a?(Spree::Supplier) ? user_or_supplier : user_or_supplier.supplier
|
|
8
|
+
shipments = self.shipments.by_supplier(supplier)
|
|
9
|
+
commissions = shipments.map(&:supplier_commission_total)
|
|
10
|
+
Spree::Money.new(commissions.sum)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def supplier_earnings_map
|
|
14
|
+
suppliers.map do |s|
|
|
15
|
+
{
|
|
16
|
+
name: s.name,
|
|
17
|
+
earnings: self.supplier_total(s),
|
|
18
|
+
paypal_email: s.paypal_email
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Once order is finalized we want to notify the suppliers of their drop ship orders.
|
|
24
|
+
# Here we are handling notification by emailing the suppliers.
|
|
25
|
+
# If you want to customize this you could override it as a hook for notifying a supplier with a API request instead.
|
|
26
|
+
def finalize_with_supplier!
|
|
27
|
+
finalize_without_supplier!
|
|
28
|
+
shipments.each do |shipment|
|
|
29
|
+
if SolidusMarketplace::Config[:send_supplier_email] && shipment.supplier.present?
|
|
30
|
+
begin
|
|
31
|
+
Spree::MarketplaceOrderMailer.supplier_order(shipment.id).deliver!
|
|
32
|
+
rescue => ex #Errno::ECONNREFUSED => ex
|
|
33
|
+
puts ex.message
|
|
34
|
+
puts ex.backtrace.join("\n")
|
|
35
|
+
Rails.logger.error ex.message
|
|
36
|
+
Rails.logger.error ex.backtrace.join("\n")
|
|
37
|
+
return true # always return true so that failed email doesn't crash app.
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
# alias_method :finalize!, :drop_ship
|
|
43
|
+
|
|
44
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Spree::Product.class_eval do
|
|
2
|
+
|
|
3
|
+
has_many :suppliers, -> { readonly }, through: :master
|
|
4
|
+
|
|
5
|
+
scope :of_supplier, -> (supplier_id) { joins(:suppliers).where('spree_suppliers.id = ?', supplier_id) }
|
|
6
|
+
|
|
7
|
+
def add_supplier!(supplier_or_id)
|
|
8
|
+
supplier = supplier_or_id.is_a?(Spree::Supplier) ? supplier_or_id : Spree::Supplier.find(supplier_or_id)
|
|
9
|
+
populate_for_supplier! supplier if supplier
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def add_suppliers!(supplier_ids)
|
|
13
|
+
Spree::Supplier.where(id: supplier_ids).each do |supplier|
|
|
14
|
+
populate_for_supplier! supplier
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def remove_suppliers!(supplier_ids)
|
|
19
|
+
Spree::Supplier.where(id: supplier_ids).each do |supplier|
|
|
20
|
+
unpopulate_for_supplier! supplier
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Returns true if the product has one or more suppliers.
|
|
25
|
+
def supplier?
|
|
26
|
+
suppliers.present?
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def populate_for_supplier!(supplier)
|
|
32
|
+
variants_including_master.each do |variant|
|
|
33
|
+
unless variant.suppliers.pluck(:id).include?(supplier.id)
|
|
34
|
+
variant.suppliers << supplier
|
|
35
|
+
supplier.stock_locations.each { |location| location.propagate_variant(variant) unless location.stock_item(variant) }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def unpopulate_for_supplier!(supplier)
|
|
41
|
+
variants_including_master.each do |variant|
|
|
42
|
+
if variant.suppliers.pluck(:id).include?(supplier.id)
|
|
43
|
+
variant.suppliers.delete(supplier)
|
|
44
|
+
|
|
45
|
+
supplier.stock_locations.each do |location|
|
|
46
|
+
location.unpropagate_variant(variant)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|