spree_drop_ship 3.1.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 (96) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE +21 -0
  5. data/README.md +116 -0
  6. data/Rakefile +15 -0
  7. data/Versionfile +6 -0
  8. data/app/assets/javascripts/spree/backend/spree_drop_ship.js +2 -0
  9. data/app/assets/javascripts/spree/frontend/spree_drop_ship.js +1 -0
  10. data/app/assets/stylesheets/spree/backend/spree_drop_ship.scss +22 -0
  11. data/app/assets/stylesheets/spree/frontend/spree_drop_ship.css +3 -0
  12. data/app/controllers/ckeditor/attachment_files_controller_decorator.rb +20 -0
  13. data/app/controllers/ckeditor/pictures_controller_decorator.rb +17 -0
  14. data/app/controllers/spree/admin/drop_ship_settings_controller.rb +19 -0
  15. data/app/controllers/spree/admin/products_controller_decorator.rb +19 -0
  16. data/app/controllers/spree/admin/shipments_controller.rb +47 -0
  17. data/app/controllers/spree/admin/stock_locations_controller_decorator.rb +14 -0
  18. data/app/controllers/spree/admin/suppliers_controller.rb +32 -0
  19. data/app/controllers/spree/api/v1/stock_locations_controller_decorator.rb +18 -0
  20. data/app/controllers/spree/base_controller_decorator.rb +23 -0
  21. data/app/mailers/spree/drop_ship_order_mailer.rb +13 -0
  22. data/app/mailers/spree/supplier_mailer.rb +12 -0
  23. data/app/models/ckeditor/asset_decorator.rb +5 -0
  24. data/app/models/spree/drop_ship_configuration.rb +17 -0
  25. data/app/models/spree/order_decorator.rb +27 -0
  26. data/app/models/spree/payment_decorator.rb +7 -0
  27. data/app/models/spree/product_decorator.rb +32 -0
  28. data/app/models/spree/shipment_decorator.rb +39 -0
  29. data/app/models/spree/stock/splitter/drop_ship.rb +42 -0
  30. data/app/models/spree/stock_location_decorator.rb +18 -0
  31. data/app/models/spree/supplier.rb +117 -0
  32. data/app/models/spree/supplier_ability.rb +28 -0
  33. data/app/models/spree/supplier_variant.rb +6 -0
  34. data/app/models/spree/user_decorator.rb +11 -0
  35. data/app/models/spree/variant_decorator.rb +24 -0
  36. data/app/models/spree.rb +5 -0
  37. data/app/overrides/spree/admin/products/_form/converted_admin_product_form_right.html.erb.deface +5 -0
  38. data/app/overrides/spree/admin/products/index/override_rows.html.erb.deface +22 -0
  39. data/app/overrides/spree/admin/shared/sub_menu/_configuration/add_drop_ship_settings.html.erb.deface +3 -0
  40. data/app/overrides/spree/admin/stock_locations/_form/add_supplier.html.erb.deface +12 -0
  41. data/app/overrides/spree/admin/stock_movements/_form/fix_bootstrap_form.html.erb.deface +11 -0
  42. data/app/overrides/spree/layouts/admin/add_profile_admin_tabs.html.erb.deface +8 -0
  43. data/app/overrides/spree/layouts/admin/converted_admin_tabs.html.erb.deface +18 -0
  44. data/app/views/spree/admin/drop_ship_settings/edit.html.erb +21 -0
  45. data/app/views/spree/admin/shared/_header.html.erb +24 -0
  46. data/app/views/spree/admin/shipments/edit.html.erb +24 -0
  47. data/app/views/spree/admin/shipments/index.html.erb +95 -0
  48. data/app/views/spree/admin/suppliers/_form.html.erb +69 -0
  49. data/app/views/spree/admin/suppliers/edit.html.erb +22 -0
  50. data/app/views/spree/admin/suppliers/index.html.erb +71 -0
  51. data/app/views/spree/admin/suppliers/new.html.erb +17 -0
  52. data/app/views/spree/drop_ship_order_mailer/supplier_order.html.erb +119 -0
  53. data/app/views/spree/shared/unauthorized.erb +1 -0
  54. data/app/views/spree/supplier_mailer/welcome.html.erb +53 -0
  55. data/config/locales/en.yml +89 -0
  56. data/config/locales/es.yml +133 -0
  57. data/config/routes.rb +9 -0
  58. data/db/migrate/20121006073854_create_suppliers.rb +20 -0
  59. data/db/migrate/20130216070944_product_belongs_to_supplier.rb +6 -0
  60. data/db/migrate/20130405005502_stock_locations_belongs_to_supplier.rb +6 -0
  61. data/db/migrate/20130405011127_user_belongs_to_supplier.rb +6 -0
  62. data/db/migrate/20130428063053_add_balanced_token_to_suppliers.rb +7 -0
  63. data/db/migrate/20130510181443_add_supplier_id_to_ckeditor_assets.rb +8 -0
  64. data/db/migrate/20130606220913_add_permalink_to_suppliers.rb +6 -0
  65. data/db/migrate/20140323170638_add_supplier_commission_to_shipments.rb +5 -0
  66. data/db/migrate/20140416184616_migrate_payment_and_commission.rb +7 -0
  67. data/db/migrate/20140529041325_create_spree_supplier_variants.rb +15 -0
  68. data/lib/generators/spree_drop_ship/install/install_generator.rb +30 -0
  69. data/lib/spree_drop_ship/engine.rb +31 -0
  70. data/lib/spree_drop_ship/factories.rb +93 -0
  71. data/lib/spree_drop_ship.rb +6 -0
  72. data/lib/tasks/spree_sample.rake +72 -0
  73. data/script/rails +7 -0
  74. data/spec/features/admin/orders_spec.rb +12 -0
  75. data/spec/features/admin/products_spec.rb +25 -0
  76. data/spec/features/admin/return_authorizations_spec.rb +7 -0
  77. data/spec/features/admin/settings_spec.rb +33 -0
  78. data/spec/features/admin/shipments_spec.rb +80 -0
  79. data/spec/features/admin/stock_management_spec.rb +153 -0
  80. data/spec/features/admin/stock_spec.rb +98 -0
  81. data/spec/features/admin/suppliers_spec.rb +126 -0
  82. data/spec/models/spree/order_decorator_spec.rb +54 -0
  83. data/spec/models/spree/payment_decorator_spec.rb +7 -0
  84. data/spec/models/spree/product_decorator_spec.rb +13 -0
  85. data/spec/models/spree/shipment_decorator_spec.rb +47 -0
  86. data/spec/models/spree/stock/splitter/drop_ship_spec.rb +62 -0
  87. data/spec/models/spree/stock_location_decorator_spec.rb +33 -0
  88. data/spec/models/spree/supplier_ability_spec.rb +172 -0
  89. data/spec/models/spree/supplier_spec.rb +123 -0
  90. data/spec/models/spree/supplier_variant_spec.rb +5 -0
  91. data/spec/models/spree/user_decorator_spec.rb +17 -0
  92. data/spec/models/spree/variant_decorator_spec.rb +7 -0
  93. data/spec/spec_helper.rb +79 -0
  94. data/spec/support/integration_helpers.rb +15 -0
  95. data/spree_drop_ship.gemspec +42 -0
  96. metadata +411 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b8ec93dffafe0fa3317797b375deb1a2ac1de64e
4
+ data.tar.gz: 5550de66c5fcaf3adc6994e9892ebf554b70c705
5
+ SHA512:
6
+ metadata.gz: 22e0e8ff176b4c628b1db7ea4f92eb7af1425af8bde1548395c0ca16b797cebe52c808ed027ea5c265927bfd3234bb4de3bf75a7e321af4e695994e17cd1a7e2
7
+ data.tar.gz: 882264fb878a354f141fe3e78eca54e1e3300b2d560cc46d65952bd8adbfea993a6109a58d3614dbdc6525b5422db90842adcf2c2173205c0449e5897f08b659
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ \#*
2
+ *~
3
+ .#*
4
+ .bundle
5
+ .DS_Store
6
+ .idea
7
+ .project
8
+ .ruby-gemset
9
+ .ruby-version
10
+ .sass-cache
11
+ coverage
12
+ Gemfile.lock
13
+ tmp
14
+ nbproject
15
+ pkg
16
+ *.swp
17
+ spec/dummy
18
+ spec/vcr_cassettes
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :development, :test do
4
+ spree_branch = 'master'
5
+ gem 'spree', github: 'spree/spree', branch: spree_branch
6
+ gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: spree_branch
7
+ end
8
+
9
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2016 Yad Faeq
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # Spree Drop Ship
2
+
3
+
4
+ * Notice: This [gem](https://github.com/spree-contrib/spree_drop_ship)'s skeleton was on Spree Contrib, and then I forked [this](https://github.com/mattfran/spree_drop_ship/tree/master). Credits to their work, though both were broken and left behind. This is a new version with few changes.
5
+
6
+ * current state :
7
+
8
+ 1. fixed the original issue #73 Ransack related `state_eq`
9
+ 2. Version Spree `3.1.0`
10
+ 3. also some smaller errors from the gem.
11
+
12
+
13
+
14
+
15
+ What is drop shipping?
16
+
17
+ "Drop shipping is a supply chain management technique in which the retailer does not keep goods in stock, but instead transfers customer orders
18
+ and shipment details to either the manufacturer or a wholesaler, who then ships the goods directly to the customer." - [wikipedia](http://en.wikipedia.org/wiki/Drop_shipping)
19
+
20
+ So the main goal with spree_drop_ship is to link products to suppliers and forward orders to the appropriate suppliers.
21
+
22
+ Once an order is placed for a product that belongs to a supplier a shipment is created for the product's supplier.
23
+ This shipment is then sent to the supplier (via Email by default). The supplier then follows a link to the shipment
24
+ within the email where they are prompted to confirm the shipment.
25
+
26
+ Spree Drop Ship used with [Spree Marketplace](https://github.com/jdutil/spree_marketplace) allows handling payments to your suppliers via ACH direct deposits.
27
+ This is still currently a work in progress, and any input is welcome.
28
+ .
29
+
30
+
31
+ Installation
32
+ ------------
33
+
34
+ Here's how to install spree_drop_ship into your existing spree site AFTER you've installed Spree:
35
+
36
+ Add the following to your Gemfile:
37
+
38
+ gem 'spree_drop_ship', github: '0bserver07/spree_drop_ship'
39
+
40
+ Make your bundle happy:
41
+
42
+ bundle install
43
+
44
+ Now run the generator:
45
+
46
+ rails g spree_drop_ship:install
47
+
48
+ Then migrate your database if you did not run during installation generator:
49
+
50
+ bundle exec rake db:migrate
51
+
52
+ And reboot your server:
53
+
54
+ rails s
55
+
56
+ You should be up and running now!
57
+
58
+ Sample Data
59
+ -----------
60
+
61
+ If you'd like to generate sample data, use the included rake tasks:
62
+
63
+ ```shell
64
+ rake spree_sample:load # Loads sample data into the store
65
+ rake spree_sample:suppliers # Create sample suppliers and randomly link to products
66
+ rake spree_sample:drop_ship_orders # Create sample drop ship orders
67
+ ```
68
+
69
+ Demo
70
+ ----
71
+
72
+ You can easily use the spec/dummy app as a demo of spree_drop_ship. Just `cd` to where you develop and run:
73
+
74
+ ```shell
75
+ git clone git://github.com/spree-contrib/spree_drop_ship.git
76
+ cd spree_drop_ship
77
+ bundle install
78
+ bundle exec rake test_app
79
+ cd spec/dummy
80
+ rake db:migrate db:seed spree_sample:load spree_sample:suppliers spree_sample:drop_ship_orders
81
+ rails s
82
+ ```
83
+
84
+ Testing
85
+ -------
86
+
87
+ * Needs To be updated
88
+
89
+ Todo
90
+ ----
91
+
92
+ - Stock Items should automatically be set to backorderable false if the variant doesnt belong to the stock locations supplier.
93
+ - Must allow suppliers to edit their stock location addresses & require it.
94
+ - Return Authorization UI
95
+ - Better documentation
96
+ - related products should only allow suppliers own products to be related
97
+
98
+ Contributing
99
+ ------------
100
+
101
+ In the spirit of [free software](http://www.fsf.org/licensing/essays/free-sw.html), **everyone** is encouraged to help improve this project.
102
+
103
+ Here are some ways *you* can contribute:
104
+
105
+ * by using prerelease versions
106
+ * by reporting [bugs](https://github.com/spree-contrib/spree_drop_ship/issues)
107
+ * by suggesting new features
108
+ * by [translating to a new language](https://github.com/spree-contrib/spree_drop_ship/tree/master/config/locales)
109
+ * by writing or editing documentation
110
+ * by writing specifications
111
+ * by writing code (*no patch is too small*: fix typos, add comments, clean up inconsistent whitespace)
112
+ * by refactoring code
113
+ * by resolving [issues](https://github.com/spree-contrib/spree_drop_ship/issues)
114
+ * by reviewing patches
115
+
116
+
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ require 'spree/testing_support/common_rake'
6
+
7
+ RSpec::Core::RakeTask.new
8
+
9
+ task :default => [:spec]
10
+
11
+ desc 'Generates a dummy app for testing'
12
+ task :test_app do
13
+ ENV['LIB_NAME'] = 'spree_drop_ship'
14
+ Rake::Task['common:test_app'].invoke 'Spree::User'
15
+ end
data/Versionfile ADDED
@@ -0,0 +1,6 @@
1
+ # This file is used to designate compatibilty with different versions of Spree
2
+ # Please see http://spreecommerce.com/documentation/extensions.html#versionfile for details
3
+ # '1.3.x' => { :ref => 'e5624f7' } # Not going to be maintained but most of the works there if your looking for a starting point to branch off of.
4
+
5
+ '2.4.x' => { :branch => 'master' }
6
+ '2.3.x' => { :branch => '2-3-stable' }
@@ -0,0 +1,2 @@
1
+ //= require spree/backend
2
+ // Shipments AJAX API
@@ -0,0 +1 @@
1
+ //= require spree/frontend
@@ -0,0 +1,22 @@
1
+ /*
2
+ *= require spree/backend
3
+ */
4
+
5
+ .center {
6
+ text-align: center;
7
+ }
8
+
9
+ .state.delivered:before,
10
+ .state.confirmed:before {
11
+ background-color: #ff9300;
12
+ }
13
+
14
+ .supplier-banks ol li {
15
+ margin-left: 20px;
16
+ margin-bottom: 5px;
17
+ text-align: left;
18
+ }
19
+
20
+ a .without-textdecor{
21
+ text-decoration: none;
22
+ }
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require spree/frontend
3
+ */
@@ -0,0 +1,20 @@
1
+ if defined?(Ckeditor::AttachmentFilesController)
2
+ Ckeditor::AttachmentFilesController.class_eval do
3
+
4
+ load_and_authorize_resource :class => 'Ckeditor::AttachmentFile'
5
+ after_filter :set_supplier, only: [:create]
6
+
7
+ def index
8
+ end
9
+
10
+ private
11
+
12
+ def set_supplier
13
+ if try_spree_current_user.supplier? and @attachment
14
+ @attachment.supplier = try_spree_current_user.supplier
15
+ @attachment.save
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ if defined?(Ckeditor::PicturesController)
2
+ Ckeditor::PicturesController.class_eval do
3
+ load_and_authorize_resource :class => 'Ckeditor::Picture'
4
+ after_filter :set_supplier, only: [:create]
5
+
6
+ def index
7
+ end
8
+
9
+ private
10
+ def set_supplier
11
+ if spree_current_user.supplier? and @picture
12
+ @picture.supplier = spree_current_user.supplier
13
+ @picture.save
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ class Spree::Admin::DropShipSettingsController < Spree::Admin::BaseController
2
+
3
+ def edit
4
+ @config = Spree::DropShipConfiguration.new
5
+ end
6
+
7
+ def update
8
+ config = Spree::DropShipConfiguration.new
9
+
10
+ params.each do |name, value|
11
+ next unless config.has_preference? name
12
+ config[name] = value
13
+ end
14
+
15
+ flash[:success] = Spree.t('admin.drop_ship_settings.update.success')
16
+ redirect_to spree.edit_admin_drop_ship_settings_path
17
+ end
18
+
19
+ end
@@ -0,0 +1,19 @@
1
+ Spree::Admin::ProductsController.class_eval do
2
+
3
+ before_filter :get_suppliers, only: [:edit, :update]
4
+ before_filter :supplier_collection, only: [:index]
5
+
6
+ private
7
+
8
+ def get_suppliers
9
+ @suppliers = Spree::Supplier.order(:name)
10
+ end
11
+
12
+ # Scopes the collection to the Supplier.
13
+ def supplier_collection
14
+ if try_spree_current_user && !try_spree_current_user.admin? && try_spree_current_user.supplier?
15
+ @collection = @collection.joins(:suppliers).where('spree_suppliers.id = ?', try_spree_current_user.supplier_id)
16
+ end
17
+ end
18
+
19
+ 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,14 @@
1
+ Spree::Admin::StockLocationsController.class_eval do
2
+
3
+ create.after :set_supplier
4
+
5
+ private
6
+
7
+ def set_supplier
8
+ if try_spree_current_user.supplier?
9
+ @object.supplier = try_spree_current_user.supplier
10
+ @object.save
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,32 @@
1
+ class Spree::Admin::SuppliersController < Spree::Admin::ResourceController
2
+
3
+ def edit
4
+ @object.address = Spree::Address.default unless @object.address.present?
5
+ respond_with(@object) do |format|
6
+ format.html { render :layout => !request.xhr? }
7
+ format.js { render :layout => false }
8
+ end
9
+ end
10
+
11
+ def new
12
+ @object = Spree::Supplier.new(address_attributes: {country_id: Spree::Address.default.country_id})
13
+ end
14
+
15
+ private
16
+
17
+ def collection
18
+ params[:q] ||= {}
19
+ params[:q][:meta_sort] ||= "name.asc"
20
+ @search = Spree::Supplier.search(params[:q])
21
+ @collection = @search.result.page(params[:page]).per(Spree::Config[:orders_per_page])
22
+ end
23
+
24
+ def find_resource
25
+ Spree::Supplier.friendly.find(params[:id])
26
+ end
27
+
28
+ def location_after_save
29
+ spree.edit_admin_supplier_path(@object)
30
+ end
31
+
32
+ end
@@ -0,0 +1,18 @@
1
+ Spree::Api::V1::StockLocationsController.class_eval do
2
+
3
+ before_filter :supplier_locations, only: [:index]
4
+ before_filter :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,23 @@
1
+ Spree::BaseController.class_eval do
2
+
3
+ prepend_before_filter :redirect_supplier
4
+ # before_action :authorize_supplier
5
+
6
+ private
7
+
8
+ def authorize_supplier
9
+ if respond_to?(:model_class, true) && model_class
10
+ record = model_class
11
+ else
12
+ record = controller_name.to_sym
13
+ end
14
+ authorize! :supplier, record
15
+ authorize! :action, record
16
+ end
17
+
18
+ def redirect_supplier
19
+ if ['/admin', '/admin/authorization_failure'].include?(request.path) && try_spree_current_user.try(:supplier)
20
+ redirect_to '/admin/shipments' and return false
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ module Spree
2
+ class DropShipOrderMailer < Spree::BaseMailer
3
+
4
+ default from: Spree::Store.current.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('drop_ship_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.current.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
@@ -0,0 +1,5 @@
1
+ if defined?(Ckeditor)
2
+ Ckeditor::Asset.class_eval do
3
+ belongs_to :supplier, class_name: 'Spree::Supplier'
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ class DropShipConfiguration < Preferences::Configuration
3
+
4
+ # Automatically deliver drop ship orders by default.
5
+ preference :automatically_deliver_orders_to_supplier, :boolean, default: true
6
+
7
+ # Default flat rate to charge suppliers per order for commission.
8
+ preference :default_commission_flat_rate, :float, default: 0.0
9
+
10
+ # Default percentage to charge suppliers per order for commission.
11
+ preference :default_commission_percentage, :float, default: 0.0
12
+
13
+ # Determines whether or not to email a new supplier their welcome email.
14
+ preference :send_supplier_email, :boolean, default: true
15
+
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ Spree::Order.class_eval do
2
+
3
+ has_many :stock_locations, through: :shipments
4
+ has_many :suppliers, through: :stock_locations
5
+
6
+ # Once order is finalized we want to notify the suppliers of their drop ship orders.
7
+ # Here we are handling notification by emailing the suppliers.
8
+ # If you want to customize this you could override it as a hook for notifying a supplier with a API request instead.
9
+ def finalize_with_drop_ship!
10
+ finalize_without_drop_ship!
11
+ shipments.each do |shipment|
12
+ if SpreeDropShip::Config[:send_supplier_email] && shipment.supplier.present?
13
+ begin
14
+ Spree::DropShipOrderMailer.supplier_order(shipment.id).deliver!
15
+ rescue => ex #Errno::ECONNREFUSED => ex
16
+ puts ex.message
17
+ puts ex.backtrace.join("\n")
18
+ Rails.logger.error ex.message
19
+ Rails.logger.error ex.backtrace.join("\n")
20
+ return true # always return true so that failed email doesn't crash app.
21
+ end
22
+ end
23
+ end
24
+ end
25
+ alias_method_chain :finalize!, :drop_ship
26
+
27
+ end
@@ -0,0 +1,7 @@
1
+ module Spree
2
+ Payment.class_eval do
3
+
4
+ belongs_to :payable, polymorphic: true
5
+
6
+ end
7
+ end
@@ -0,0 +1,32 @@
1
+ Spree::Product.class_eval do
2
+
3
+ has_many :suppliers, through: :master
4
+
5
+ def add_supplier!(supplier_or_id)
6
+ supplier = supplier_or_id.is_a?(Spree::Supplier) ? supplier_or_id : Spree::Supplier.find(supplier_or_id)
7
+ populate_for_supplier! supplier if supplier
8
+ end
9
+
10
+ def add_suppliers!(supplier_ids)
11
+ Spree::Supplier.where(id: supplier_ids).each do |supplier|
12
+ populate_for_supplier! supplier
13
+ end
14
+ end
15
+
16
+ # Returns true if the product has a drop shipping supplier.
17
+ def supplier?
18
+ suppliers.present?
19
+ end
20
+
21
+ private
22
+
23
+ def populate_for_supplier!(supplier)
24
+ variants_including_master.each do |variant|
25
+ unless variant.suppliers.pluck(:id).include?(supplier.id)
26
+ variant.suppliers << supplier
27
+ supplier.stock_locations.each { |location| location.propagate_variant(variant) }
28
+ end
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,39 @@
1
+ Spree::Shipment.class_eval do
2
+ self.whitelisted_ransackable_attributes = ['number', 'state']
3
+ # TODO here to fix cancan issue thinking its just Order
4
+ belongs_to :order, class_name: 'Spree::Order', touch: true, inverse_of: :shipments
5
+
6
+ has_many :payments, as: :payable
7
+
8
+ scope :by_supplier, -> (supplier_id) { joins(:stock_location).where(spree_stock_locations: { supplier_id: supplier_id }) }
9
+
10
+ delegate :supplier, to: :stock_location
11
+
12
+ def display_final_price_with_items
13
+ Spree::Money.new final_price_with_items
14
+ end
15
+
16
+ def final_price_with_items
17
+ self.item_cost + self.final_price
18
+ end
19
+
20
+ # TODO move commission to spree_marketplace?
21
+ def supplier_commission_total
22
+ ((self.final_price_with_items * self.supplier.commission_percentage / 100) + self.supplier.commission_flat_rate)
23
+ end
24
+
25
+ private
26
+
27
+ durably_decorate :after_ship, mode: 'soft', sha: 'e8eca7f8a50ad871f5753faae938d4d01c01593d' do
28
+ original_after_ship
29
+
30
+ if supplier.present?
31
+ update_commission
32
+ end
33
+ end
34
+
35
+ def update_commission
36
+ update_column :supplier_commission, self.supplier_commission_total
37
+ end
38
+
39
+ end
@@ -0,0 +1,42 @@
1
+ module Spree
2
+ module Stock
3
+ module Splitter
4
+ class DropShip < Spree::Stock::Splitter::Base
5
+
6
+ def split(packages)
7
+ split_packages = []
8
+ packages.each do |package|
9
+ # Package fulfilled items together.
10
+ fulfilled = package.contents.select { |content| content.variant.suppliers.count == 0 }
11
+ split_packages << build_package(fulfilled)
12
+ # Determine which supplier to package drop shipped items.
13
+ drop_ship = package.contents.select { |content| content.variant.suppliers.count > 0 }
14
+ drop_ship.each do |content|
15
+ # Select the related variant
16
+ variant = content.variant
17
+ # Select suppliers ordering ascending according to cost.
18
+ suppliers = variant.supplier_variants.order("spree_supplier_variants.cost ASC").map(&:supplier)
19
+ # Select first supplier that has stock location with avialable stock item.
20
+ available_supplier = suppliers.detect do |supplier|
21
+ supplier.stock_locations_with_available_stock_items(variant).any?
22
+ end
23
+ # Select the first available stock location with in the available_supplier stock locations.
24
+ stock_location = nil
25
+ if available_supplier.present?
26
+ stock_location = available_supplier.stock_locations_with_available_stock_items(variant).first
27
+ end
28
+ # Add to any existing packages or create a new one.
29
+ if existing_package = split_packages.detect { |p| p.stock_location == stock_location }
30
+ existing_package.contents << content
31
+ else
32
+ split_packages << Spree::Stock::Package.new(stock_location, [content])
33
+ end
34
+ end
35
+ end
36
+ return_next split_packages
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end