spree_reffiliate 2.3.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 (55) hide show
  1. checksums.yaml +7 -0
  2. data/ .travis.yml +3 -0
  3. data/.gitignore +14 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +9 -0
  6. data/LICENSE +26 -0
  7. data/README.md +121 -0
  8. data/Rakefile +21 -0
  9. data/app/controllers/spree/admin/affiliates_controller.rb +23 -0
  10. data/app/controllers/spree/reffiliate_controller.rb +22 -0
  11. data/app/controllers/spree/user_controller_decorator.rb +6 -0
  12. data/app/models/spree/affiliate.rb +39 -0
  13. data/app/models/spree/promotion/rules/affiliated_promotion_rule.rb +37 -0
  14. data/app/models/spree/promotion/rules/referred_promotion_rule.rb +15 -0
  15. data/app/models/spree/referral.rb +40 -0
  16. data/app/models/spree/referred_record.rb +9 -0
  17. data/app/models/spree/user_decorator.rb +41 -0
  18. data/app/overrides/spree/admin/shared/_configuration_menu.rb +6 -0
  19. data/app/overrides/spree/admin/users/edit.rb +50 -0
  20. data/app/overrides/spree/admin/users/index.rb +18 -0
  21. data/app/overrides/spree/users/show.rb +12 -0
  22. data/app/views/spree/admin/affiliates/_form.html.erb +45 -0
  23. data/app/views/spree/admin/affiliates/edit.html.erb +76 -0
  24. data/app/views/spree/admin/affiliates/index.html.erb +55 -0
  25. data/app/views/spree/admin/affiliates/new.html.erb +23 -0
  26. data/app/views/spree/admin/promotions/rules/_affiliated_promotion_rule.erb +6 -0
  27. data/app/views/spree/admin/promotions/rules/_referred_promotion_rule.html.erb +0 -0
  28. data/bin/rails +7 -0
  29. data/config/initializers/spree.rb +6 -0
  30. data/config/locales/en.yml +10 -0
  31. data/config/routes.rb +8 -0
  32. data/db/migrate/20140907041850_create_spree_referrals.rb +8 -0
  33. data/db/migrate/20140907042024_create_spree_affiliates.rb +9 -0
  34. data/db/migrate/20140907042102_create_spree_referred_records.rb +9 -0
  35. data/db/migrate/20140907062121_add_index_to_spree_referrals.rb +5 -0
  36. data/db/migrate/20140907062422_add_index_to_spree_referred_record.rb +5 -0
  37. data/db/migrate/20140912003727_create_spree_promotion_rules_affiliates.rb +10 -0
  38. data/db/migrate/20140913042034_add_layout_to_spree_affiliate.rb +5 -0
  39. data/lib/generators/spree_reffiliate/install/install_generator.rb +21 -0
  40. data/lib/spree_reffiliate/engine.rb +20 -0
  41. data/lib/spree_reffiliate/factories.rb +12 -0
  42. data/lib/spree_reffiliate.rb +2 -0
  43. data/lib/tasks/spree_reffiliate.rake +10 -0
  44. data/spec/assets/spree/affiliates/corona.html.erb +1 -0
  45. data/spec/controllers/spree/reffiliate_controller_spec.rb +56 -0
  46. data/spec/controllers/spree/user_controller_spec.rb +20 -0
  47. data/spec/models/spree/affiliate_spec.rb +33 -0
  48. data/spec/models/spree/promotion/rules/affiliated_promotion_rule_spec.rb +46 -0
  49. data/spec/models/spree/promotion/rules/referred_promotion_rule_spec.rb +20 -0
  50. data/spec/models/spree/referral_spec.rb +41 -0
  51. data/spec/models/spree/referred_record_spec.rb +29 -0
  52. data/spec/models/spree/user_spec.rb +52 -0
  53. data/spec/spec_helper.rb +93 -0
  54. data/spree_reffiliate.gemspec +31 -0
  55. metadata +261 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 77a9b01c5eb8422a610145b80f1d11435a6771f1
4
+ data.tar.gz: 1d594af8533cb3147f70467b4f05b0ccba940886
5
+ SHA512:
6
+ metadata.gz: 7da5e58657f86c5304f78017afcd1607762a5b2ebc4f966c7b6d924488b511f389f9e422f7934d71f34af94b036eb55219fd5262237111f2ab35bd044a975164
7
+ data.tar.gz: 8e4953bcb70cf171baf418d5e4479875e343b167c814a2dcf7e6b498bd372504db964ced8598558e1dec7c106e962ac17307741886a73226a14d9c9a87bb9aee
data/ .travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ addons:
2
+ code_climate:
3
+ repo_token: dcc9b789b5067ef1437fffe22754df1ffefa75f86566c5d1ba88fbfdd393c720
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ \#*
2
+ *~
3
+ .#*
4
+ .DS_Store
5
+ .idea
6
+ .project
7
+ .sass-cache
8
+ coverage
9
+ Gemfile.lock
10
+ tmp
11
+ nbproject
12
+ pkg
13
+ *.swp
14
+ spec/dummy
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'spree', github: 'spree/spree', branch: '2-3-stable'
4
+ # Provides basic authentication functionality for testing parts of your engine
5
+ gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '2-3-stable'
6
+
7
+ gem "codeclimate-test-reporter", group: :test, require: nil
8
+
9
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2014 [name of plugin creator]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,121 @@
1
+ Spree Reffiliate
2
+ ================
3
+ [![Codeship Status for kinduff/spree_reffiliate](https://codeship.com/projects/ab504f70-4b22-0132-8f9f-22e1dbe6882e/status)](https://codeship.com/projects/46636)
4
+ [![Build Status](https://travis-ci.org/kinduff/spree_reffiliate.svg?branch=master)](https://travis-ci.org/kinduff/spree_reffiliate)
5
+ [![Code Climate](https://codeclimate.com/github/kinduff/spree_reffiliate/badges/gpa.svg)](https://codeclimate.com/github/kinduff/spree_reffiliate)
6
+ [![Test Coverage](https://codeclimate.com/github/kinduff/spree_reffiliate/badges/coverage.svg)](https://codeclimate.com/github/kinduff/spree_reffiliate)
7
+
8
+ Spree Reffiliate is a [Spree] Extension that adds the referral and affiliate features to your Spree Store. Users are going to be able to share a unique hyperlink with their friends to gain benefits and you'll be able to create affiliate campaigns through the Spree Administrator and configure it to your needs.
9
+
10
+ ### Referrals
11
+ + User can share a unique URL
12
+ + User can signup as a referred user
13
+ + Referred user can have promotions
14
+ + Admin is able to see referred users and orders from user
15
+
16
+ ### Affiliates
17
+ + Admin is able to create an affiliate with a custom path
18
+ + Customize the affiliate view with a partial
19
+ + Users are going to be able to signup as an affiliated user
20
+ + Affiliated user can have individual promotions
21
+ + Admin is able to see affiliated users and orders from affiliate
22
+
23
+ ![Spree Reffiliate](https://cloud.githubusercontent.com/assets/1270156/4210980/11c6ba84-387f-11e4-8f3d-4eb7f45f9004.png)
24
+
25
+ ## Installation
26
+
27
+ Add spree_reffiliate to your Gemfile:
28
+
29
+ ```ruby
30
+ gem 'spree_reffiliate', github: 'kinduff/spree_reffiliate'
31
+ ```
32
+
33
+ Bundle your dependencies and run the installation generator:
34
+
35
+ ```shell
36
+ bundle
37
+ bundle exec rails g spree_reffiliate:install
38
+ ```
39
+
40
+ ### Existing Users
41
+ If you already have users within your database, you'll need to run the following command to generate the referral registry for your users:
42
+
43
+ ```shell
44
+ bundle exec rake reffiliate:generate
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ Referral path is `/r/:code` and Affiliate path (assigned in the admin) is `/a/:path`
50
+
51
+ Once installed, you'll be able to access the following methods.
52
+
53
+ #### Spree::User
54
+ + referred_by => user record
55
+ + referral_count => user count
56
+ + referred? => boolean
57
+ + affiliate? => boolean
58
+ + affiliate => affiliate record
59
+ + referral => referral record
60
+
61
+ #### Spree::Referral
62
+ + code => referral code
63
+ + referred_users => array of users
64
+ + referred_orders => array of orders
65
+ + referred_count => user count
66
+ + referral_activated_users => users with completed orders
67
+
68
+ #### Spree::Affiliates
69
+ + referred_users => array of users
70
+ + referred_orders => array of orders
71
+ + referred_count => user count
72
+
73
+ ### Spree Admin
74
+
75
+ #### Users
76
+ ![User Listing](https://cloud.githubusercontent.com/assets/1270156/4210981/11cd353a-387f-11e4-826d-07b272bb249a.png)
77
+
78
+ #### Affiliates
79
+ ![Referral Listing](https://cloud.githubusercontent.com/assets/1270156/4210982/11e9966c-387f-11e4-9a27-fca70c7a706d.png)
80
+
81
+ #### Promotion Rules
82
+
83
+ **Important**: in both referrals and affiliates, do **not** fill in the promotion code for the promotion itself to be applied automatically to the user's order. If you add a promotion code, the user will need to apply the for promotion manually.
84
+
85
+ ##### For referrals
86
+
87
+ ![Referral Rules](https://cloud.githubusercontent.com/assets/1270156/4244240/ec3dac8c-3a1d-11e4-8c6d-42c9f9b31e5f.png)
88
+
89
+ ##### For affiliates
90
+
91
+ ![Affiliate Rules](https://cloud.githubusercontent.com/assets/1270156/4244241/ec3e156e-3a1d-11e4-972a-5d61ebf0f053.png)
92
+
93
+ ### User account
94
+ ![User account](https://cloud.githubusercontent.com/assets/1270156/4210983/11e9b9a8-387f-11e4-8733-182bdebc449c.png)
95
+
96
+ ## Testing
97
+
98
+ First bundle your dependencies, then run `rake`. `rake` will default to building the dummy app if it does not exist, then it will run specs. The dummy app can be regenerated by using `rake test_app`.
99
+
100
+ ```shell
101
+ bundle
102
+ bundle exec rake
103
+ ```
104
+
105
+ When testing your applications integration with this extension you may use it's factories.
106
+ Simply add this require statement to your spec_helper:
107
+
108
+ ```ruby
109
+ require 'spree_reffiliate/factories'
110
+ ```
111
+
112
+ ## ToDo
113
+ + Add missing documentation
114
+ + Add 2-2-stable and 2-1-stable support (or at least test them)
115
+ + Improve affiliates admin
116
+ + Improve User and Orders listing at user admin
117
+ + Add option or helper to show referral code to the user
118
+
119
+ Copyright (c) 2014 Alejandro AR, released under the New BSD License
120
+
121
+ [Spree]: http://spreecommerce.com/
data/Rakefile ADDED
@@ -0,0 +1,21 @@
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 do
10
+ if Dir["spec/dummy"].empty?
11
+ Rake::Task[:test_app].invoke
12
+ Dir.chdir("../../")
13
+ end
14
+ Rake::Task[:spec].invoke
15
+ end
16
+
17
+ desc 'Generates a dummy app for testing'
18
+ task :test_app do
19
+ ENV['LIB_NAME'] = 'spree_reffiliate'
20
+ Rake::Task['extension:test_app'].invoke
21
+ end
@@ -0,0 +1,23 @@
1
+ module Spree
2
+ module Admin
3
+ class AffiliatesController < Spree::Admin::ResourceController
4
+ helper_method :affiliate_partial_exists?
5
+ before_filter :layout_options, only: [:new, :edit]
6
+
7
+ def index
8
+ @affiliates = Affiliate.all.page(params[:page]).per(Spree::Config[:admin_products_per_page])
9
+ end
10
+
11
+ protected
12
+
13
+ def affiliate_partial_exists? partial
14
+ return false if partial.blank?
15
+ Affiliate.lookup_for_partial lookup_context, partial
16
+ end
17
+
18
+ def layout_options
19
+ @layout_options = Spree::Affiliate.layout_options
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ module Spree
2
+ class ReffiliateController < Spree::StoreController
3
+ def referral
4
+ session[:referral] = params[:code]
5
+ redirect_to root_path
6
+ end
7
+ def affiliate
8
+ session[:affiliate] = params[:path]
9
+ affiliate = Spree::Affiliate.find_by(:path => params[:path])
10
+ if affiliate.nil? or affiliate.partial.blank? or !partial_exists affiliate.partial
11
+ redirect_to(root_path)
12
+ elsif partial_exists affiliate.partial
13
+ render "spree/affiliates/#{affiliate.partial}", :layout => affiliate.get_layout
14
+ end
15
+ end
16
+
17
+ private
18
+ def partial_exists partial
19
+ Affiliate.lookup_for_partial lookup_context, partial
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ Spree::UserRegistrationsController.class_eval do
2
+ before_filter :check_referral_and_affiliate, :only => :create
3
+ def check_referral_and_affiliate
4
+ params[:spree_user].merge!(:referral_code => session[:referral], :affiliate_code => session[:affiliate])
5
+ end
6
+ end
@@ -0,0 +1,39 @@
1
+ module Spree
2
+ class Affiliate < Spree::Base
3
+ has_many :referred_records
4
+
5
+ validates_presence_of :name, :path
6
+
7
+ def referred_users
8
+ referred_records.includes(:user).collect(&:user).compact
9
+ end
10
+
11
+ def referred_orders
12
+ referred_records.includes({:user => :orders}).collect{|u| u.user.orders }.flatten.compact
13
+ end
14
+
15
+ def referred_count
16
+ referred_records.count
17
+ end
18
+
19
+ def get_layout
20
+ return false if layout == 'false'
21
+ layout
22
+ end
23
+
24
+ private
25
+
26
+ def self.layout_options
27
+ [
28
+ ["No Layout", "false"],
29
+ ["Spree Application Layout", 'spree/layouts/spree_application'],
30
+ ["Custom Layout Path", nil]
31
+ ]
32
+ end
33
+
34
+ def self.lookup_for_partial lookup_context, partial
35
+ lookup_context.template_exists?(partial, ["spree/affiliates"], false)
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ module Spree
2
+ class Promotion
3
+ module Rules
4
+ class AffiliatedPromotionRule < Spree::PromotionRule
5
+ belongs_to :affiliate, :class_name => '::Spree::Affiliate'
6
+ has_and_belongs_to_many :affiliates, :class_name => '::Spree::Affiliate',
7
+ :join_table => 'spree_affiliates_promotion_rules', :foreign_key => 'promotion_rule_id',
8
+ :association_foreign_key => 'affiliate_id'
9
+
10
+ def eligible?(order, options = {})
11
+ return true if order.user and order.user.affiliate? and affiliates.collect(&:id).include?(order.user.affiliate.id)
12
+ false
13
+ end
14
+
15
+ def applicable?(promotable)
16
+ promotable.is_a?(Spree::Order)
17
+ end
18
+
19
+ def affiliate_ids_string
20
+ affiliate_ids.join(',')
21
+ end
22
+
23
+ def affiliate_ids_string=(s)
24
+ self.affiliate_ids = s.to_s.split(',').map(&:strip)
25
+ end
26
+
27
+ def affiliate_list
28
+ affiliate_ids
29
+ end
30
+
31
+ def affiliate_list=(a)
32
+ self.affiliate_ids = a
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ class Promotion
3
+ module Rules
4
+ class ReferredPromotionRule < Spree::PromotionRule
5
+ def eligible?(order, options = {})
6
+ return true if order.user and order.user.referred?
7
+ false
8
+ end
9
+ def applicable?(promotable)
10
+ promotable.is_a?(Spree::Order)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ module Spree
2
+ class Referral < Spree::Base
3
+ belongs_to :user, class_name: Spree.user_class.to_s
4
+ has_many :referred_records
5
+
6
+ validates_presence_of :user_id, :code
7
+
8
+ before_validation :attach_code, on: :create
9
+
10
+ def referred_users
11
+ referred_records.includes(:user).collect(&:user).compact
12
+ end
13
+
14
+ def referred_orders
15
+ referred_records_with_user_orders.collect{|u| u.user.orders }.flatten.compact
16
+ end
17
+
18
+ def referral_activated_users
19
+ referred_records_with_user_orders.select{|u| post_referral_order?(u) }.collect(&:user)
20
+ end
21
+
22
+ protected
23
+ def attach_code
24
+ self.code = loop do
25
+ code = (0...8).map { (65 + rand(26)).chr }.join
26
+ break code unless Referral.exists?(code: code)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def referred_records_with_user_orders
33
+ referred_records.includes({:user => :orders})
34
+ end
35
+
36
+ def post_referral_order?(referred_record)
37
+ referred_record.user.orders.where('completed_at > ?', self.user.created_at).any?
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ module Spree
2
+ class ReferredRecord < Spree::Base
3
+ belongs_to :referral
4
+ belongs_to :user, class_name: Spree.user_class.to_s
5
+ belongs_to :affiliate
6
+
7
+ validates_presence_of :user
8
+ end
9
+ end
@@ -0,0 +1,41 @@
1
+ module Spree
2
+ Spree.user_class.class_eval do
3
+ has_one :referral
4
+ has_one :referred_record
5
+ has_one :affiliate, through: :referred_record, foreign_key: :affiliate_id
6
+ has_one :affiliate_record, class_name: ReferredRecord
7
+
8
+ attr_accessor :referral_code, :affiliate_code
9
+
10
+ after_create :create_referral
11
+ after_create :referral_affiliate_check
12
+
13
+ def referred_by
14
+ referred_record.try(:referral).try(:user)
15
+ end
16
+
17
+ def referred_count
18
+ referral.referred_records.count
19
+ end
20
+
21
+ def referred?
22
+ !referred_record.try(:referral).try(:user).nil?
23
+ end
24
+
25
+ def affiliate?
26
+ !affiliate.nil?
27
+ end
28
+
29
+ private
30
+ def referral_affiliate_check
31
+ if !self.referral_code.nil?
32
+ referred = Referral.find_by(code: referral_code)
33
+ elsif !self.affiliate_code.nil?
34
+ referred = Affiliate.find_by(path: affiliate_code)
35
+ end
36
+ if referred
37
+ referred.referred_records.create(user: self)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,6 @@
1
+ Deface::Override.new(
2
+ :virtual_path => "spree/admin/shared/_configuration_menu",
3
+ :name => "admin_content_admin_configuration_menu_parser",
4
+ :insert_bottom => "[data-hook='admin_configurations_sidebar_menu']",
5
+ :text => "<%= configurations_sidebar_menu_item Spree.t(:affiliates), admin_affiliates_path %>"
6
+ )
@@ -0,0 +1,50 @@
1
+ Deface::Override.new(
2
+ :virtual_path => "spree/admin/users/edit",
3
+ :name => "referral_fieldset",
4
+ :insert_after => "[data-hook='admin_user_api_key']"
5
+ ) do
6
+ <<-CODE.chomp
7
+ <fieldset>
8
+ <legend>Referral Information</legend>
9
+ <table>
10
+ <tr>
11
+ <th>Referred by</th>
12
+ <td>
13
+ <% if @user.referred? %>
14
+ <%= link_to(@user.referred_by.email, edit_admin_user_url(@user.referred_by)) %>
15
+ <% elsif @user.affiliate? %>
16
+ <%= link_to(@user.affiliate.name, edit_admin_affiliate_url(@user.affiliate)) %>
17
+ <% else %>
18
+ Organic
19
+ <% end %>
20
+ </td>
21
+ </tr>
22
+ <th>Referral code</th>
23
+ <td><%= @user.referral.code %></td>
24
+ <tr>
25
+ </tr>
26
+ <th>Referred orders</th>
27
+ <td>
28
+ <%= "No referred orders yet." if @user.referral.referred_orders.count == 0 %>
29
+ <ol style="margin-left: 20px;">
30
+ <% @user.referral.referred_orders.each do |order| %>
31
+ <li><%= link_to order.number, edit_admin_order_path(order) %></li>
32
+ <% end %>
33
+ <ol>
34
+ </td>
35
+ <tr>
36
+ <tr>
37
+ <th>Users referred</th>
38
+ <td>
39
+ <%= "No referred users yet." if @user.referred_count == 0 %>
40
+ <ol style="margin-left: 20px;">
41
+ <% @user.referral.referred_users.each do |user| %>
42
+ <li><%= link_to user.email, edit_admin_user_url(user) %></li>
43
+ <% end %>
44
+ </ol>
45
+ </td>
46
+ <tr>
47
+ </tr>
48
+ </fieldset>
49
+ CODE
50
+ end
@@ -0,0 +1,18 @@
1
+ Deface::Override.new(
2
+ :virtual_path => "spree/admin/users/index",
3
+ :name => "referral_code_header",
4
+ :insert_before => "[data-hook='admin_users_index_headers'] th:nth-child(2)",
5
+ :text => "<th class='align-center'>Referrals</th>"
6
+ )
7
+ Deface::Override.new(
8
+ :virtual_path => "spree/admin/users/index",
9
+ :name => "referral_code",
10
+ :insert_before => "[data-hook='admin_users_index_rows'] td:nth-child(2)",
11
+ :text => "<td class='align-center'><%= user.referred_count %></td>"
12
+ )
13
+ Deface::Override.new(
14
+ :virtual_path => "spree/admin/users/index",
15
+ :name => "column_withds",
16
+ :replace => "#listing_users > colgroup",
17
+ :text => "<col style='width: 75%'><col style='width: 10%'><col style='width: 15%'>"
18
+ )
@@ -0,0 +1,12 @@
1
+ Deface::Override.new(
2
+ :virtual_path => "spree/users/show",
3
+ :name => "user_info",
4
+ :insert_after => "[data-hook='account_summary'] #user-info dd:first"
5
+ ) do
6
+ <<-CODE.chomp
7
+ <dt>Referral URL</dt>
8
+ <dd><input type='text' value='<%= referral_url(@user.referral.code) %>' onClick='this.select();' /></dd>
9
+ <dt>Referred Users</dt>
10
+ <dd><%= @user.referred_count%></dd>
11
+ CODE
12
+ end
@@ -0,0 +1,45 @@
1
+ <div data-hook="admin_user_form_fields" class="row">
2
+ <div class="alpha six columns">
3
+ <%= f.field_container :name do %>
4
+ <%= f.label :name, Spree.t(:name) %>
5
+ <%= f.text_field :name, class: 'fullwidth' %>
6
+ <%= error_message_on :user, :name %>
7
+ <% end %>
8
+ <%= f.field_container :partial do %>
9
+ <%= f.label :partial, Spree.t(:partial) + " (leave blank if no partial) " %>
10
+ <p>app/views/spree/affiliates/<%= f.text_field :partial %></p>
11
+ <%= f.error_message_on :partial %>
12
+ <% end %>
13
+ </div>
14
+
15
+ <div class="omega six columns">
16
+ <%= f.field_container :path do %>
17
+ <%= f.label :path, Spree.t(:path) %>
18
+ <%= f.text_field :path, class: 'fullwidth' %>
19
+ <%= f.error_message_on :path %>
20
+ <% end %>
21
+ <%= f.field_container :path do %>
22
+ <%= f.label :layout, Spree.t(:layout) %>
23
+ <%= select_tag 'fake_layout', options_for_select(@layout_options, selected: @affiliate.layout), class: "fullwidth #{'other' unless @layout_options.flatten.include?(@affiliate.layout)}" %>
24
+ <%= f.text_field :layout, value: @affiliate.layout.nil? ? @layout_options.first : @affiliate.layout, class: 'fullwidth' %>
25
+ <script>
26
+ var fake_layout = $("#fake_layout"),
27
+ affiliate_layout = $("#affiliate_layout");
28
+ fake_layout.on("change", function(){
29
+ affiliate_layout.hide();
30
+ if ($(this).val() != '') {
31
+ affiliate_layout.val($(this).val());
32
+ } else {
33
+ affiliate_layout.val('layouts/application').show().focus();
34
+ }
35
+ });
36
+ if (!fake_layout.hasClass('other')) {
37
+ affiliate_layout.hide();
38
+ } else {
39
+ fake_layout.val('');
40
+ }
41
+ </script>
42
+ <%= f.error_message_on :layout %>
43
+ <% end %>
44
+ </div>
45
+ </div>
@@ -0,0 +1,76 @@
1
+ <% content_for :page_title do %>
2
+ <%= link_to "#{Spree.t(:editing_affiliate)} #{@affiliate.name}", edit_admin_affiliate_url(@affiliate) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <li>
7
+ <%= button_link_to Spree.t(:back_to_affiliates_list), spree.admin_affiliates_path, :icon => 'arrow-left' %>
8
+ </li>
9
+ <% end %>
10
+
11
+ <fieldset data-hook="admin_affiliate_edit_general_settings" class="alpha twelve columns">
12
+ <legend><%= Spree.t(:general_settings) %></legend>
13
+
14
+ <div data-hook="admin_affiliate_edit_form_header">
15
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @affiliate } %>
16
+ </div>
17
+
18
+ <div data-hook="admin_affiliate_edit_form">
19
+ <%= form_for [:admin, @affiliate], as: :affiliate, url: admin_affiliate_url(@affiliate), method: :put do |f| %>
20
+ <%= render :partial => 'form', :locals => { :f => f } %>
21
+
22
+ <div data-hook="admin_affiliate_edit_form_button">
23
+ <%= render :partial => 'spree/admin/shared/edit_resource_links', :locals => { :collection_url => admin_affiliates_url } %>
24
+ </div>
25
+ <% end %>
26
+ </div>
27
+ </fieldset>
28
+ <fieldset data-hook="admin_affiliate_edit_stats" class="alpha twelve columns">
29
+ <legend><%= Spree.t(:statistics) %></legend>
30
+ <table>
31
+ <tbody>
32
+ <tr>
33
+ <th>Affiliate hyperlink</th>
34
+ <td><%= text_field_tag nil, affiliate_url(@affiliate.path), onclick: 'this.select();' %></td>
35
+ </tr>
36
+ <tr>
37
+ <th>Partial Status</th>
38
+ <% if @affiliate.partial.blank? or !affiliate_partial_exists?(@affiliate.partial) %>
39
+ <td style="color: red">Not found</td>
40
+ <% elsif affiliate_partial_exists?(@affiliate.partial) %>
41
+ <td style="color: green">Found</td>
42
+ <% end %>
43
+ </tr>
44
+ <tr>
45
+ <th>Referred users count</th>
46
+ <td><%= @affiliate.referred_count %></td>
47
+ </tr>
48
+ <tr>
49
+ <th>Referred orders count</th>
50
+ <td><%= @affiliate.referred_orders.count %></td>
51
+ </tr>
52
+ <tr>
53
+ <th>Orders referred</th>
54
+ <td>
55
+ <%= "No referred orders" if @affiliate.referred_orders.count == 0 %>
56
+ <ol style="margin-left: 20px;">
57
+ <% @affiliate.referred_orders.each do |user| %>
58
+ <li><%= link_to user.email, edit_admin_user_url(user) %></li>
59
+ <% end %>
60
+ </ol>
61
+ </td>
62
+ <tr>
63
+ <tr>
64
+ <th>Users referred</th>
65
+ <td>
66
+ <%= "No referred users" if @affiliate.referred_count == 0 %>
67
+ <ol style="margin-left: 20px;">
68
+ <% @affiliate.referred_users.each do |user| %>
69
+ <li><%= link_to user.email, edit_admin_user_url(user) %></li>
70
+ <% end %>
71
+ </ol>
72
+ </td>
73
+ <tr>
74
+ </tbody>
75
+ </table>
76
+ </fieldset>