spree_marketplace 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +14 -0
  6. data/LICENSE +21 -0
  7. data/README.md +87 -0
  8. data/Rakefile +15 -0
  9. data/Versionfile +12 -0
  10. data/app/assets/javascripts/spree/backend/spree_marketplace.js.coffee +24 -0
  11. data/app/assets/javascripts/spree/frontend/spree_marketplace.js +2 -0
  12. data/app/assets/javascripts/spree/frontend/supplier_address.js.coffee +56 -0
  13. data/app/assets/stylesheets/spree/backend/spree_marketplace.css +3 -0
  14. data/app/assets/stylesheets/spree/frontend/spree_marketplace.css +10 -0
  15. data/app/controllers/spree/admin/marketplace_settings_controller.rb +19 -0
  16. data/app/controllers/spree/admin/supplier_bank_accounts_controller.rb +24 -0
  17. data/app/controllers/spree/suppliers_controller.rb +67 -0
  18. data/app/models/spree/marketplace_ability.rb +14 -0
  19. data/app/models/spree/marketplace_configuration.rb +27 -0
  20. data/app/models/spree/supplier_ability.rb +76 -0
  21. data/app/models/spree/supplier_bank_account.rb +15 -0
  22. data/app/models/spree/supplier_decorator.rb +55 -0
  23. data/app/overrides/spree/admin/shared/_configuration_menu/add_marketplace_settings.html.erb.deface +3 -0
  24. data/app/overrides/spree/admin/suppliers/edit/add_bank_accounts.html.erb.deface +14 -0
  25. data/app/overrides/spree/layouts/admin/add_stripe_js_to_head.html.erb.deface +6 -0
  26. data/app/overrides/spree/users/show/add_supplier_info.html.erb.deface +17 -0
  27. data/app/views/spree/admin/marketplace_settings/edit.html.erb +23 -0
  28. data/app/views/spree/admin/supplier_bank_accounts/new.html.erb +28 -0
  29. data/app/views/spree/suppliers/new.html.erb +29 -0
  30. data/config/locales/en.yml +14 -0
  31. data/config/locales/es.yml +30 -0
  32. data/config/routes.rb +9 -0
  33. data/db/migrate/20130424201333_create_supplier_bank_accounts.rb +12 -0
  34. data/db/migrate/20131209022116_convert_to_stripe.rb +6 -0
  35. data/lib/generators/spree_marketplace/install/install_generator.rb +31 -0
  36. data/lib/spree_marketplace.rb +4 -0
  37. data/lib/spree_marketplace/engine.rb +47 -0
  38. data/lib/spree_marketplace/factories.rb +29 -0
  39. data/script/rails +7 -0
  40. data/spec/features/admin/bank_accounts_spec.rb +50 -0
  41. data/spec/features/admin/products_spec.rb +225 -0
  42. data/spec/features/admin/properties_spec.rb +91 -0
  43. data/spec/features/admin/relations_spec.rb +31 -0
  44. data/spec/features/admin/return_authorizations_spec.rb +7 -0
  45. data/spec/features/admin/settings_spec.rb +29 -0
  46. data/spec/features/admin/suppliers_controller_spec.rb +43 -0
  47. data/spec/features/supplier_signup_spec.rb +134 -0
  48. data/spec/models/spree/marketplace_ability_spec.rb +32 -0
  49. data/spec/models/spree/supplier_ability_spec.rb +337 -0
  50. data/spec/models/spree/supplier_bank_account_spec.rb +13 -0
  51. data/spec/models/spree/supplier_spec.rb +7 -0
  52. data/spec/spec_helper.rb +85 -0
  53. data/spec/support/integration_helpers.rb +15 -0
  54. data/spree_marketplace.gemspec +90 -0
  55. metadata +391 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 55a3f2de019a78f33daeee1a1b12972b687a69be
4
+ data.tar.gz: 8ace935b041cdaddbac915f24e1f735d2ef8e78c
5
+ SHA512:
6
+ metadata.gz: 506f87f91fda55fd15dd70693447400403ebdc4a6bded334a54fbb24470ef6a44a6475e1e41454fd624f7b00dec90f97c4c2f1e0d1210151a0bee5f4c38da82f
7
+ data.tar.gz: 8ebec64b83071775c28771b856da7860806f0ee828c43255215ba7f356c25e404e0af2588679e7dcc94d97c03d6e7f2553c020f870a8f918326eecac3a25f986
@@ -0,0 +1,15 @@
1
+ .bundle
2
+ \#*
3
+ *~
4
+ .#*
5
+ .DS_Store
6
+ .idea
7
+ .project
8
+ .sass-cache
9
+ coverage
10
+ Gemfile.lock
11
+ tmp
12
+ nbproject
13
+ pkg
14
+ *.swp
15
+ spec/dummy
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,13 @@
1
+ before_script:
2
+ - "sh -e /etc/init.d/xvfb start"
3
+ - "bundle exec rake test_app"
4
+ script:
5
+ - "export DISPLAY=:99.0"
6
+ - "bundle exec rspec spec"
7
+ rvm:
8
+ - 2.0.0
9
+ - 2.1.2
10
+ language: ruby
11
+ notifications:
12
+ recipients:
13
+ - JDutil@SpreeCommerce.com
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :development, :test do
4
+ spree_branch = '2-4-stable'
5
+ gem 'spree', github: 'spree/spree', branch: spree_branch
6
+ gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: spree_branch
7
+ gem 'spree_drop_ship', path: '../spree_drop_ship', branch: "2-4-beta"
8
+ gem 'spree_digital', github: 'halo/spree_digital', branch: spree_branch
9
+ gem 'spree_editor', github: 'spree/spree_editor', branch: spree_branch
10
+ gem 'spree_group_pricing', github: 'jdutil/spree_group_pricing', branch: 'master'
11
+ gem 'spree_related_products', github: 'spree/spree_related_products', branch: spree_branch
12
+ end
13
+
14
+ 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.
@@ -0,0 +1,87 @@
1
+ SpreeMarketplace
2
+ ================
3
+
4
+ *Notice:* This gem is a [fork of](https://github.com/spree-contrib/spree_marketplace) another fork, the code had broken database migrations issues, parts of it have been removed/updated.
5
+
6
+
7
+
8
+ Spree Marketplace uses the Spree Drop Ship [(this version)](https://github.com/0bserver07/spree_drop_ship) extension in order to enable using Spree as a Marketplace. Mainly all that really means is that this extension enables sending payments to your drop ship suppliers through [Stripe](https://stripe.com) with their payment service.
9
+
10
+ All the other main marketplace functionality - such as - vendors, product setup, shipment details etc... is all accomplished by [Spree Drop Ship](hhttps://github.com/0bserver07/spree_drop_ship).
11
+
12
+ Integrations
13
+ ------------
14
+
15
+ Spree Marketplace will support several other Spree extensions being used by scoping information by supplier.
16
+
17
+ Some extensions that can be used in conjunction with Spree Marketplace:
18
+
19
+ * spree_digital
20
+ * spree_editor (assumes use of ckeditor & you should delete the generated models & initializer in your app to use spree_editors copies)
21
+ * spree_group_pricing
22
+ * spree_marketplace
23
+ * spree_related_products
24
+
25
+ Please Note: If you intend to use any of these extensions you should install them before installing spree_marketplace so that spree_marketplace's migrations are run last. You should also place spree_drop_ship & spree_marketplace AFTER all other extensions in your Gemfile.
26
+
27
+ Installation
28
+ ------------
29
+
30
+ Add spree_marketplace to your Gemfile:
31
+
32
+ ```ruby
33
+ gem 'spree_marketplace', github: 'jdutil/spree_marketplace'
34
+ ```
35
+
36
+ Bundle your dependencies and run the installation generator:
37
+
38
+ ```shell
39
+ bundle
40
+ bundle exec rails g spree_marketplace:install
41
+ ```
42
+
43
+ Configuration
44
+ -------------
45
+
46
+ Once installed you must configure your [Stripe](https://stripe.com) API keys. To do so you have two options:
47
+
48
+ 1) Simply setup either as your payment processing method and spree_marketplace will use your payment methods api key.
49
+
50
+ 2) Configure in an initializer by adding the following to the end of your `config/intializers/spree.rb`:
51
+
52
+ SpreeMarketplace::Config[:stripe_publishable_key] = 'YourPublishableKey'
53
+ SpreeMarketplace::Config[:stripe_secret_key] = 'YourSecretKey'
54
+
55
+ 3) Currently you must implement your own payment code as this varies between applications, but once the TODO list is complete this will be an optional configuration likely in a rake task.
56
+
57
+ Testing
58
+ -------
59
+
60
+ Be sure to bundle your dependencies and then create a dummy test app for the specs to run against.
61
+
62
+ ```shell
63
+ bundle
64
+ bundle exec rake test_app
65
+ bundle exec rspec spec
66
+ ```
67
+
68
+ When testing your applications integration with this extension you may use it's factories.
69
+ Simply add this require statement to your spec_helper:
70
+
71
+ ```ruby
72
+ require 'spree_marketplace/factories'
73
+ ```
74
+
75
+ TODO
76
+ ----
77
+
78
+ - stop overridding spree_drop_ship's supplier ability if possible
79
+ - update product management of products
80
+ - permit attributes in controller
81
+ - On dso complete credit supplier bank account
82
+ - On order complete credit marketplace bank account w/commission
83
+ - On order complete credit marketplace bank account w/tax?
84
+ - Refactor to not rely on stripe & be interchangeable.
85
+ - suppliers should be able to manage option types and values (unsure about whether to scope to supplier or not, but thats probably best solution for everyone)
86
+
87
+ Copyright (c) 2013-2014+ [Jeff Dutil](https://github.com/jdutil), released under the New BSD License
@@ -0,0 +1,15 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ require 'spree/testing_support/extension_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_marketplace'
14
+ Rake::Task['common:test_app'].invoke 'Spree::User'
15
+ end
@@ -0,0 +1,12 @@
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
+
4
+ # Examples
5
+ #
6
+ # '1.2.x' => { :branch => 'master' }
7
+ # '1.1.x' => { :branch => '1-1-stable' }
8
+ # '1.0.x' => { :branch => '1-0-stable' }
9
+ # '0.70.x' => { :branch => '0-70-stable' }
10
+ # '0.40.x' => { :tag => 'v1.0.0', :version => '1.0.0' }
11
+
12
+ '2.0.x' => { :branch => 'master' }
@@ -0,0 +1,24 @@
1
+ #= require spree/backend
2
+
3
+ $(document).ready ->
4
+ if $('.new_supplier_bank_account').length > 0
5
+ $('.new_supplier_bank_account').submit ->
6
+ if $('#supplier_bank_account_token').val() == ''
7
+ Stripe.bankAccount.createToken({
8
+ country: $('#supplier_bank_account_country_iso').val(),
9
+ routingNumber: $('#supplier_bank_account_routing_number').val(),
10
+ accountNumber: $('#supplier_bank_account_account_number').val(),
11
+ }, stripeBankAccountResponseHandler);
12
+ return false
13
+
14
+ stripeBankAccountResponseHandler = (status, response) ->
15
+ if response.error
16
+ $('#stripeError').html(response.error.message)
17
+ $('#stripeError').show()
18
+ else
19
+ $('#supplier_bank_account_account_number').prop("disabled" , true);
20
+ $('#supplier_bank_account_routing_number').prop("disabled" , true);
21
+ $('#supplier_bank_account_masked_number').val('xxxxxx' + response['bank_account']['last4'])
22
+ $('#supplier_bank_account_name').val(response['bank_account']['bank_name'])
23
+ $('#supplier_bank_account_token').val(response['id'])
24
+ $('.new_supplier_bank_account').submit()
@@ -0,0 +1,2 @@
1
+ //= require spree/frontend
2
+ //= require_tree .
@@ -0,0 +1,56 @@
1
+ Spree.ready ($) ->
2
+
3
+ if ($ '#new_supplier').is('*')
4
+ ($ '#new_supplier').validate()
5
+
6
+ getCountryId = (region) ->
7
+ $('p#' + region + 'country select').val()
8
+
9
+ updateState = (region) ->
10
+ countryId = getCountryId(region)
11
+ if countryId?
12
+ unless Spree.Checkout[countryId]?
13
+ $.get Spree.routes.states_search + "/?country_id=#{countryId}", (data) ->
14
+ Spree.Checkout[countryId] =
15
+ states: data.states
16
+ states_required: data.states_required
17
+ fillStates(Spree.Checkout[countryId], region)
18
+ else
19
+ fillStates(Spree.Checkout[countryId], region)
20
+
21
+ fillStates = (data, region) ->
22
+ statesRequired = data.states_required
23
+ states = data.states
24
+
25
+ statePara = ($ 'p#' + region + 'state')
26
+ stateSelect = statePara.find('select')
27
+ stateInput = statePara.find('input')
28
+ stateSpanRequired = statePara.find('state-required')
29
+ if states.length > 0
30
+ selected = parseInt stateSelect.val()
31
+ stateSelect.html ''
32
+ statesWithBlank = [{ name: '', id: ''}].concat(states)
33
+ $.each statesWithBlank, (idx, state) ->
34
+ opt = ($ document.createElement('option')).attr('value', state.id).html(state.name)
35
+ opt.prop 'selected', true if selected is state.id
36
+ stateSelect.append opt
37
+
38
+ stateSelect.prop('disabled', false).show()
39
+ stateInput.hide().prop 'disabled', true
40
+ statePara.show()
41
+ stateSpanRequired.show()
42
+ else
43
+ stateSelect.hide().prop 'disabled', true
44
+ stateInput.show()
45
+ if statesRequired
46
+ stateSpanRequired.show()
47
+ else
48
+ stateInput.val ''
49
+ stateSpanRequired.hide()
50
+ statePara.toggle(!!statesRequired)
51
+ stateInput.prop('disabled', !statesRequired)
52
+
53
+ ($ 'p#ccountry select').change ->
54
+ updateState 'c'
55
+
56
+ updateState 'c'
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require spree/backend
3
+ */
@@ -0,0 +1,10 @@
1
+ #supplier-title h1 { margin-bottom: 5px; font-size: 48px; }
2
+ #supplier-location { padding-bottom: 20px; color: #525252; }
3
+ #supplier-title {
4
+ h1 {margin-bottom: 5px; font-size: 48px; }
5
+ span { font-size: 18px; }
6
+ }
7
+ #supplier_profile_picture_field { padding-bottom: 30px; }
8
+
9
+ #supplier-location span.glyphicon.glyphicon-map-marker { margin-left: 10px }
10
+ #supplier_left_part { padding-left: 0px; }
@@ -0,0 +1,19 @@
1
+ class Spree::Admin::MarketplaceSettingsController < Spree::Admin::BaseController
2
+
3
+ def edit
4
+ @config = Spree::MarketplaceConfiguration.new
5
+ end
6
+
7
+ def update
8
+ config = Spree::MarketplaceConfiguration.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.marketplace_settings.update.success')
16
+ redirect_to spree.edit_admin_marketplace_settings_path
17
+ end
18
+
19
+ end
@@ -0,0 +1,24 @@
1
+ class Spree::Admin::SupplierBankAccountsController < Spree::Admin::ResourceController
2
+
3
+ before_filter :load_supplier
4
+ create.before :set_supplier
5
+
6
+ def new
7
+ @object = @supplier.bank_accounts.build
8
+ end
9
+
10
+ private
11
+
12
+ def load_supplier
13
+ @supplier = Spree::Supplier.friendly.find(params[:supplier_id])
14
+ end
15
+
16
+ def location_after_save
17
+ spree.edit_admin_supplier_path(@supplier)
18
+ end
19
+
20
+ def set_supplier
21
+ @object.supplier = @supplier
22
+ end
23
+
24
+ end
@@ -0,0 +1,67 @@
1
+ class Spree::SuppliersController < Spree::StoreController
2
+
3
+ before_filter :check_if_supplier, only: [:create, :new]
4
+ # ssl_required
5
+
6
+ def index
7
+ @suppliers = Spree::Supplier.all
8
+ end
9
+
10
+ def show
11
+ @supplier = Spree::Supplier.find(params[:id])
12
+ end
13
+
14
+ def create
15
+ authorize! :create, Spree::Supplier
16
+
17
+ @supplier = Spree::Supplier.new(supplier_params)
18
+
19
+ # Dont sign in as the newly created user if users already signed in.
20
+ unless spree_current_user
21
+ # Find or create user for email.
22
+ if @user = Spree.user_class.find_by_email(params[:supplier][:email])
23
+ unless @user.valid_password?(params[:supplier][:password])
24
+ flash[:error] = Spree.t('supplier_registration.create.invalid_password')
25
+ render :new and return
26
+ end
27
+ else
28
+ @user = Spree.user_class.new(email: params[:supplier][:email], password: params[:supplier].delete(:password), password_confirmation: params[:supplier].delete(:password_confirmation))
29
+ @user.save!
30
+ session[:spree_user_signup] = true
31
+ end
32
+ sign_in(Spree.user_class.to_s.underscore.gsub('/', '_').to_sym, @user)
33
+ associate_user
34
+ end
35
+
36
+ # Now create supplier.
37
+
38
+ @supplier.email = spree_current_user.email if spree_current_user
39
+
40
+ if @supplier.save
41
+ flash[:success] = Spree.t('supplier_registration.create.success')
42
+ redirect_to spree.admin_products_path
43
+ else
44
+ render :new
45
+ end
46
+ end
47
+
48
+ def new
49
+ authorize! :create, Spree::Supplier
50
+ @supplier = Spree::Supplier.new
51
+ @supplier.address = Spree::Address.default
52
+ end
53
+
54
+ private
55
+
56
+ def check_if_supplier
57
+ if spree_current_user and spree_current_user.supplier?
58
+ flash[:error] = Spree.t('supplier_registration.already_signed_up')
59
+ redirect_to spree.admin_products_path and return
60
+ end
61
+ end
62
+
63
+ def supplier_params
64
+ params.require(:supplier).permit(:first_name, :name, :last_name, :tax_id, :profile_picture)
65
+ end
66
+
67
+ end
@@ -0,0 +1,14 @@
1
+ module Spree
2
+ class MarketplaceAbility
3
+ include CanCan::Ability
4
+
5
+ def initialize(user)
6
+ user ||= Spree.user_class.new
7
+
8
+ if user.supplier
9
+ can [:admin, :manage], Spree::SupplierBankAccount, supplier_id: user.supplier_id
10
+ can :create, Spree::SupplierBankAccount
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ module Spree
2
+ class MarketplaceConfiguration < Preferences::Configuration
3
+
4
+ # Allow users to signup as a supplier.
5
+ preference :allow_signup, :boolean, default: false
6
+
7
+ # Sets Stripe api configuration.
8
+ preference :stripe_publishable_key, :string, default: -> {
9
+ if ActiveRecord::Base.connection.table_exists?(:spree_payment_methods)
10
+ # If you are using Stripe as a credit card processor we automatically lookup your api key to use for payments.
11
+ Spree::PaymentMethod.where(type: 'Spree::Gateway::StripeGateway').first.try(:preferred_publishable_key)
12
+ else
13
+ nil
14
+ end
15
+ }.call
16
+
17
+ preference :stripe_secret_key, :string, default: -> {
18
+ if ActiveRecord::Base.connection.table_exists?(:spree_payment_methods)
19
+ # If you are using Stripe as a credit card processor we automatically lookup your api key to use for payments.
20
+ Spree::PaymentMethod.where(type: 'Spree::Gateway::StripeGateway').first.try(:preferred_secret_key)
21
+ else
22
+ nil
23
+ end
24
+ }.call
25
+
26
+ end
27
+ end