spree_loyalty_points 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/LICENSE +26 -0
  2. data/README.md +68 -0
  3. data/app/assets/javascripts/admin/spree_loyalty_points.js +83 -0
  4. data/app/assets/javascripts/store/spree_loyalty_points.js +1 -0
  5. data/app/assets/stylesheets/admin/spree_loyalty_points.css +3 -0
  6. data/app/assets/stylesheets/store/spree_loyalty_points.css +13 -0
  7. data/app/controllers/spree/admin/general_settings_controller_decorator.rb +17 -0
  8. data/app/controllers/spree/admin/loyalty_points_transactions_controller.rb +80 -0
  9. data/app/controllers/spree/admin/resource_controller_decorator.rb +21 -0
  10. data/app/controllers/spree/admin/return_authorizations_controller_decorator.rb +11 -0
  11. data/app/controllers/spree/checkout_controller_decorator.rb +17 -0
  12. data/app/controllers/spree/loyalty_points_controller.rb +9 -0
  13. data/app/models/concerns/spree/loyalty_points.rb +22 -0
  14. data/app/models/concerns/spree/order/loyalty_points.rb +55 -0
  15. data/app/models/concerns/spree/payment/loyalty_points.rb +39 -0
  16. data/app/models/concerns/spree/transactions_total_validation.rb +25 -0
  17. data/app/models/spree/app_configuration_decorator.rb +8 -0
  18. data/app/models/spree/loyalty_points_credit_transaction.rb +18 -0
  19. data/app/models/spree/loyalty_points_debit_transaction.rb +18 -0
  20. data/app/models/spree/loyalty_points_transaction.rb +45 -0
  21. data/app/models/spree/order_decorator.rb +18 -0
  22. data/app/models/spree/payment_decorator.rb +34 -0
  23. data/app/models/spree/payment_method/loyalty_points.rb +27 -0
  24. data/app/models/spree/payment_method_decorator.rb +7 -0
  25. data/app/models/spree/return_authorization_decorator.rb +23 -0
  26. data/app/models/spree/user_decorator.rb +20 -0
  27. data/app/overrides/add_condition_to_amount_on_return_authorization_page.rb +8 -0
  28. data/app/overrides/add_loyalty_points_balance_to_account_page.rb +9 -0
  29. data/app/overrides/add_loyalty_points_debiting_to_return_authorization_page.rb +28 -0
  30. data/app/overrides/add_loyalty_points_preferences_to_general_settings_page.rb +18 -0
  31. data/app/overrides/add_loyalty_points_to_admin_user_show_page.rb +15 -0
  32. data/app/overrides/add_loyalty_points_to_cart_page.rb +8 -0
  33. data/app/overrides/add_loyalty_points_to_order_checkout_page.rb +16 -0
  34. data/app/overrides/add_loyalty_points_to_return_authorization_index_page.rb +13 -0
  35. data/app/overrides/add_loyalty_points_transaction_table_to_return_authorization_form.rb +6 -0
  36. data/app/views/spree/admin/loyalty_points_transactions/index.html.erb +16 -0
  37. data/app/views/spree/admin/loyalty_points_transactions/new.html.erb +62 -0
  38. data/app/views/spree/admin/payments/source_forms/_loyaltypoints.html.erb +0 -0
  39. data/app/views/spree/admin/payments/source_views/_loyaltypoints.html.erb +0 -0
  40. data/app/views/spree/checkout/payment/_loyaltypoints.html.erb +8 -0
  41. data/app/views/spree/loyalty_points/_transaction_table.html.erb +44 -0
  42. data/app/views/spree/loyalty_points/index.html.erb +4 -0
  43. data/config/locales/en.yml +18 -0
  44. data/config/routes.rb +14 -0
  45. data/db/migrate/20140116090042_add_loyalty_points_balance_to_spree_user.rb +5 -0
  46. data/db/migrate/20140116110437_create_loyalty_points_transactions.rb +10 -0
  47. data/db/migrate/20140117062720_add_timestamps_to_loyalty_points_transaction.rb +7 -0
  48. data/db/migrate/20140117065314_add_fields_to_spree_loyalty_points_transaction.rb +7 -0
  49. data/db/migrate/20140122084005_add_comment_to_spree_loyalty_points_transaction.rb +5 -0
  50. data/db/migrate/20140123092709_add_paid_at_to_spree_order.rb +5 -0
  51. data/db/migrate/20140123120355_add_loyalty_points_to_spree_return_authorization.rb +6 -0
  52. data/db/migrate/20140124121728_add_loyalty_points_awarded_to_spree_order.rb +5 -0
  53. data/db/migrate/20140130131957_rename_fields_in_spree_loyalty_points_transaction.rb +6 -0
  54. data/db/migrate/20140131072702_remove_loyalty_points_awarded_from_spree_order.rb +5 -0
  55. data/db/migrate/20140203063433_add_indexing_to_spree_loyalty_points_transaction.rb +7 -0
  56. data/db/migrate/20140205111553_add_transaction_id_to_spree_loyalty_points_transactions.rb +5 -0
  57. data/db/migrate/20140207055836_add_lock_version_to_spree_user.rb +5 -0
  58. data/lib/generators/spree_loyalty_points/install/install_generator.rb +31 -0
  59. data/lib/spree_loyalty_points/engine.rb +26 -0
  60. data/lib/spree_loyalty_points/factories.rb +75 -0
  61. data/lib/spree_loyalty_points.rb +2 -0
  62. data/lib/tasks/loyalty_points/award.rake +10 -0
  63. metadata +124 -0
@@ -0,0 +1,27 @@
1
+ module Spree
2
+ class PaymentMethod::LoyaltyPoints < PaymentMethod
3
+ def actions
4
+ %w{capture void}
5
+ end
6
+
7
+ def can_void?(payment)
8
+ payment.state != 'void'
9
+ end
10
+
11
+ def can_capture?(payment)
12
+ ['checkout', 'pending'].include?(payment.state)
13
+ end
14
+
15
+ def capture(payment, source, gateway)
16
+ ActiveMerchant::Billing::Response.new(true, "", {}, {})
17
+ end
18
+
19
+ def void(source, gateway)
20
+ ActiveMerchant::Billing::Response.new(true, "", {}, {})
21
+ end
22
+
23
+ def source_required?
24
+ false
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ Spree::PaymentMethod.class_eval do
2
+
3
+ def self.loyalty_points_id_included?(method_ids)
4
+ where(type: 'Spree::PaymentMethod::LoyaltyPoints').where(id: method_ids).size != 0
5
+ end
6
+
7
+ end
@@ -0,0 +1,23 @@
1
+ Spree::ReturnAuthorization.class_eval do
2
+ include Spree::TransactionsTotalValidation
3
+ validate :transactions_total_range, if: -> { order.present? && order.loyalty_points_transactions.present? }
4
+
5
+ def update_loyalty_points
6
+ if loyalty_points_transaction_type == "Debit"
7
+ loyalty_points_debit_quantity = [order.user.loyalty_points_balance, order.loyalty_points_for(order.item_total), loyalty_points].min
8
+ order.create_debit_transaction(loyalty_points_debit_quantity)
9
+ else
10
+ loyalty_points_credit_quantity = [order.loyalty_points_for(order.total), loyalty_points].min
11
+ order.create_credit_transaction(loyalty_points_credit_quantity)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def transactions_total_range
18
+ validate_transactions_total_range(loyalty_points_transaction_type, order)
19
+ end
20
+
21
+ end
22
+
23
+ Spree::ReturnAuthorization.state_machine.after_transition :to => :received, :do => :update_loyalty_points
@@ -0,0 +1,20 @@
1
+ Spree::User.class_eval do
2
+ validates :loyalty_points_balance, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
3
+
4
+ has_many :loyalty_points_transactions
5
+ has_many :loyalty_points_debit_transactions
6
+ has_many :loyalty_points_credit_transactions
7
+
8
+ def loyalty_points_balance_sufficient?
9
+ loyalty_points_balance >= Spree::Config.loyalty_points_redeeming_balance
10
+ end
11
+
12
+ def has_sufficient_loyalty_points?(order)
13
+ loyalty_points_equivalent_currency >= order.total
14
+ end
15
+
16
+ def loyalty_points_equivalent_currency
17
+ loyalty_points_balance * Spree::Config.loyalty_points_conversion_rate
18
+ end
19
+
20
+ end
@@ -0,0 +1,8 @@
1
+ Deface::Override.new(:virtual_path => 'spree/admin/return_authorizations/_form',
2
+ :name => 'surround_amount_with_condition_in_return_authorization_form',
3
+ :surround => "erb[loud]:contains('field_container :amount')",
4
+ :text => "
5
+ <% if !@return_authorization.order.loyalty_points_used? %>
6
+ <%= render_original %>
7
+ <% end %>
8
+ ")
@@ -0,0 +1,9 @@
1
+ Deface::Override.new(:virtual_path => 'spree/users/show',
2
+ :name => 'add_loyalty_points_balance_to_account_page',
3
+ :insert_after => "#user-info",
4
+ :text => "
5
+ <dl id='loyalty-points-info'>
6
+ <dt><%= Spree.t(:loyalty_points_balance) %></dt>
7
+ <dd><%= @user.loyalty_points_balance %> (<%= link_to Spree.t(:details), spree.loyalty_points_path %>)</dd>
8
+ </dl>
9
+ ")
@@ -0,0 +1,28 @@
1
+ Deface::Override.new(:virtual_path => 'spree/admin/return_authorizations/_form',
2
+ :name => 'add_loyalty_points_to_return_authorization_page',
3
+ :insert_before => "erb[loud]:contains('field_container :reason')",
4
+ :text => "
5
+ <% if !@order.loyalty_points_used? && @order.eligible_for_loyalty_points?(@order.item_total) %>
6
+ <%= f.field_container :loyalty_points do %>
7
+ <%= label :loyalty_points, Spree.t(:loyalty_points_debit) %> <span class='required'>*</span><br />
8
+ <% if @return_authorization.received? %>
9
+ <%= @return_authorization.loyalty_points %> points Debited <br />
10
+ <% else %>
11
+ <%= f.text_field :loyalty_points, {:style => 'width:80px;'} %>
12
+ <%= f.hidden_field :loyalty_points_transaction_type, { value: :Debit } %>
13
+ <br /> User's Loyalty Points Balance: <%= @order.user.loyalty_points_balance %> <br /> Net Loyalty Points Credited for this Order: <%= @order.loyalty_points_total %>
14
+ <% end %>
15
+ <% end %>
16
+ <% elsif @order.loyalty_points_used? %>
17
+ <%= f.field_container :loyalty_points do %>
18
+ <br /><%= label :loyalty_points, Spree.t(:loyalty_points_credit) %> <span class='required'>*</span><br />
19
+ <% if @return_authorization.received? %>
20
+ <%= @return_authorization.loyalty_points %> points Credited <br />
21
+ <% else %>
22
+ <%= f.text_field :loyalty_points, {:style => 'width:80px;'} %>
23
+ <%= f.hidden_field :loyalty_points_transaction_type, { value: :Credit } %>
24
+ <br /> User's Loyalty Points Balance: <%= @order.user.loyalty_points_balance %> <br /> Net Loyalty Points Debited for this Order: <%= -@order.loyalty_points_total %>
25
+ <% end %>
26
+ <% end %>
27
+ <% end %>
28
+ ")
@@ -0,0 +1,18 @@
1
+ Deface::Override.new(:virtual_path => 'spree/admin/general_settings/edit',
2
+ :name => 'add_loyalty_points_preferences_to_general_settings_page',
3
+ :insert_before => "div.row",
4
+ :text => "
5
+ <div class='row'>
6
+ <fieldset class='loyalty-points no-border-bottom'>
7
+ <legend align='center'><%= Spree.t(:loyalty_points_settings)%></legend>
8
+ <% @preferences_loyalty_points.each do |key, value|
9
+ type = Spree::Config.preference_type(key) %>
10
+ <div class='field'>
11
+ <%= label_tag(key, Spree.t(key)) + tag(:br) if type != :boolean %>
12
+ <%= preference_field_tag(key, Spree::Config[key], :type => type) %>
13
+ <p><%= value[0] %></p>
14
+ </div>
15
+ <% end %>
16
+ </fieldset>
17
+ </div>
18
+ ")
@@ -0,0 +1,15 @@
1
+ Deface::Override.new(:virtual_path => 'spree/admin/users/show',
2
+ :name => 'add_loyalty_points_to_admin_user_show_page',
3
+ :insert_after => "tr[data-hook='roles']",
4
+ :text => "
5
+ <tr data-hook='loyalty-points'>
6
+ <th><%= Spree.t(:loyalty_points_balance) %></th>
7
+ <td>
8
+ <% if @user.loyalty_points_balance.present? %>
9
+ <%= link_to @user.loyalty_points_balance, spree.admin_user_loyalty_points_path(@user) %>
10
+ <% else %>
11
+ <%= 'No loyalty points yet' %>
12
+ <% end %>
13
+ </td>
14
+ </tr>
15
+ ")
@@ -0,0 +1,8 @@
1
+ Deface::Override.new(:virtual_path => 'spree/orders/edit',
2
+ :name => 'add_loyalty_points_to_cart_page',
3
+ :insert_after => "#subtotal h5",
4
+ :text => "
5
+ <% if @order.loyalty_points_for(@order.item_total) > 0 %>
6
+ <h5><%= Spree.t(:loyalty_points_earnable, :quantity => \"<span class='order-total'> \#{@order.loyalty_points_for(@order.item_total)}</span>\").html_safe %></h5>
7
+ <% end %>
8
+ ")
@@ -0,0 +1,16 @@
1
+ Deface::Override.new(:virtual_path => 'spree/shared/_order_details',
2
+ :name => 'add_loyalty_points_to_order_checkout_page',
3
+ :insert_after => "#order-charges",
4
+ :text => "
5
+ <tfoot id='loyalty_points'>
6
+ <tr id='loyalty-points-row'>
7
+ <% if @order.loyalty_points_awarded? %>
8
+ <td></td>
9
+ <td colspan='4' class='total'><span><%= @order.loyalty_points_for(@order.item_total) %></span> <b><%= Spree.t(:loyalty_points) %> have been credited to your account.</b></td>
10
+ <% else %>
11
+ <td></td>
12
+ <td colspan='4' class='total'><span><%= @order.loyalty_points_for(@order.item_total) %></span> <b><%= Spree.t(:loyalty_points) %> will be credited to your account soon.</b></td>
13
+ <% end %>
14
+ </tr>
15
+ </tfoot>
16
+ ")
@@ -0,0 +1,13 @@
1
+ Deface::Override.new(:virtual_path => 'spree/admin/return_authorizations/index',
2
+ :name => 'add_loyalty_points_to_return_authorization_index_page_head',
3
+ :insert_after => "thead[data-hook='rma_header'] th:contains('amount')",
4
+ :text => "
5
+ <th><%= Spree.t(:loyalty_points) %></th>
6
+ ")
7
+
8
+ Deface::Override.new(:virtual_path => 'spree/admin/return_authorizations/index',
9
+ :name => 'add_loyalty_points_to_return_authorization_index_page_row',
10
+ :insert_after => "tr[data-hook='rma_row'] td:contains('display_amount')",
11
+ :text => "
12
+ <td><%= return_authorization.loyalty_points %> pts <%= return_authorization.loyalty_points_transaction_type %></td>
13
+ ")
@@ -0,0 +1,6 @@
1
+ Deface::Override.new(:virtual_path => 'spree/admin/return_authorizations/_form',
2
+ :name => 'add_loyalty_points_transaction_table_to_return_authorization_form',
3
+ :insert_after => "div[data-hook='admin_return_authorization_form_fields']",
4
+ :text => "
5
+ <%= render partial: 'spree/loyalty_points/transaction_table' %>
6
+ ")
@@ -0,0 +1,16 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:loyalty_points) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <li>
7
+ <%= button_link_to Spree.t(:back_to_user_profile), :back, :icon => 'icon-arrow-left', :id => 'admin_user_link' %>
8
+ </li>
9
+ <li>
10
+ <%= button_link_to Spree.t(:update_loyalty_points), new_admin_user_loyalty_point_path(@user), :icon => 'icon-plus', :id => 'admin_user_new_loyalty_point_link' %>
11
+ </li>
12
+ <% end %>
13
+
14
+ <p>Current Balance: <%= @user.loyalty_points_balance %></p>
15
+ <%= render partial: 'spree/loyalty_points/transaction_table' %>
16
+ <br />
@@ -0,0 +1,62 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:loyalty_points) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <li><%= button_link_to Spree.t(:back_to_users_list), admin_users_path, :icon => 'icon-arrow-left' %></li>
7
+ <% end %>
8
+
9
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @loyalty_points_transaction.user } %>
10
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @loyalty_points_transaction } %>
11
+
12
+ <div id='loyalty-points-order-transactions'></div>
13
+
14
+ <%= form_for @loyalty_points_transaction, as: :loyalty_points_transaction, url: admin_user_loyalty_points_path(@user) do |f| %>
15
+ <fieldset data-hook="update_loyalty_points">
16
+
17
+ <legend align="center"><%= Spree.t(:update_loyalty_points) %></legend>
18
+
19
+ <div data-hook="update_loyalty_points_attrs" class="row">
20
+
21
+ <div class="four columns">
22
+ <%= f.field_container :loyalty_points do %>
23
+ <%= f.label :loyalty_points, Spree.t(:loyalty_points) %> <span class="required">*</span><br />
24
+ <%= f.text_field :loyalty_points, :class => 'fullwidth title' %>
25
+ <%= f.error_message_on :loyalty_points %>
26
+ <% end %>
27
+ </div>
28
+
29
+ <div class="field four columns">
30
+ <%= f.label :type, Spree.t(:transaction_type) %> <span class="required">*</span><br />
31
+ <%= f.select :type, options_for_select(Spree::LoyaltyPointsTransaction::CLASS_TO_TRANSACTION_TYPE.invert), {}, :class => 'select2 fullwidth' %>
32
+ <%= f.error_message_on :type %>
33
+ </div>
34
+
35
+ <div class="field four columns">
36
+ <%= label_tag nil, Spree.t(:order) %>
37
+ <%= f.select :source_id, @user.orders.collect {|o| [o.number, o.id]}, {:include_blank => true}, :class => 'select2 fullwidth', :"data-transactions-link" => admin_user_loyalty_points_path(@user) %>
38
+ <%= f.hidden_field :source_type, { :value => 'Spree::Order' } %>
39
+ </div>
40
+
41
+ </div>
42
+
43
+ <div data-hook="comment_row" class="row">
44
+
45
+ <div class="four columns">
46
+ <%= f.field_container :comment do %>
47
+ <%= f.label :comment, Spree.t(:comment) %> <span class="required">*</span><br />
48
+ <%= f.text_area :comment, :class => 'fullwidth' %>
49
+ <%= f.error_message_on :comment %>
50
+ <% end %>
51
+ </div>
52
+
53
+ </div>
54
+
55
+ <div class="form-buttons filter-actions actions" data-hook="buttons">
56
+ <%= button Spree.t('actions.update'), 'icon-ok' %>
57
+ <span class="or"><%= Spree.t(:or) %></span>
58
+ <%= link_to_with_icon 'icon-remove', Spree.t('actions.cancel'), admin_users_path, :class => 'button' %>
59
+ </div>
60
+
61
+ </fieldset>
62
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <%- lp_balance = spree_current_user.loyalty_points_balance %>
2
+ <%- equivalent_currency_balance = spree_current_user.loyalty_points_equivalent_currency %>
3
+ Loyalty Points Balance: <%= lp_balance %><%= "($" + equivalent_currency_balance.to_s + ")" %>
4
+ <%- lp_needed = @order.loyalty_points_for(@order.total, 'redeem') %>
5
+ <br/>Loyalty Points Needed: <%= lp_needed %>
6
+ <% if lp_needed > lp_balance %>
7
+ <br/><b>Insufficient Balance!</b>
8
+ <% end %>
@@ -0,0 +1,44 @@
1
+ <%= paginate @loyalty_points_transactions %>
2
+
3
+ <% if @loyalty_points_transactions.present? %>
4
+ <table class="loyalty-points-summary">
5
+ <thead>
6
+ <tr>
7
+ <th class="loyalty-points-date"><%= Spree.t(:date) %></th>
8
+ <th class="loyalty-points-source"><%= Spree.t(:source) %></th>
9
+ <th class="loyalty-points-source-id"><%= Spree.t(:source_reference) %></th>
10
+ <th class="loyalty-points-comment"><%= Spree.t(:comment) %></th>
11
+ <th class="loyalty-points-type"><%= Spree.t(:transaction_type) %></th>
12
+ <th class="loyalty-points"><%= Spree.t(:loyalty_points) %></th>
13
+ <th class="loyalty-points-balance"><%= Spree.t(:updated_balance) %></th>
14
+ </tr>
15
+ </thead>
16
+ <tbody>
17
+ <% @loyalty_points_transactions.each do |loyalty_point_transaction| %>
18
+ <tr class="<%= cycle('even', 'odd') %>">
19
+ <td class="loyalty-points-date"><%= pretty_time(loyalty_point_transaction.updated_at) %></td>
20
+ <% if loyalty_point_transaction.source.present? %>
21
+ <% transaction_source = loyalty_point_transaction.source_type.gsub('Spree::','') -%>
22
+ <td class="loyalty-points-source"><%= transaction_source %></td>
23
+ <% if transaction_source == "Order" %>
24
+ <td class="loyalty-points-source-id"><%= link_to loyalty_point_transaction.source.number, order_path(loyalty_point_transaction.source) %></td>
25
+ <% else %>
26
+ <td class="loyalty-points-source-id"><%= loyalty_point_transaction.source_id %></td>
27
+ <% end %>
28
+ <% else %>
29
+ <td class="loyalty-points-source"></td>
30
+ <td class="loyalty-points-source-id"></td>
31
+ <% end %>
32
+ <td class="loyalty-points-comment"><%= loyalty_point_transaction.comment %></td>
33
+ <td class="loyalty-points-type"><%= loyalty_point_transaction.transaction_type %></td>
34
+ <td class="loyalty-points"><%= loyalty_point_transaction.loyalty_points %></td>
35
+ <td class="loyalty-points-balance"><%= loyalty_point_transaction.balance %></td>
36
+ </tr>
37
+ <% end %>
38
+ </tbody>
39
+ </table>
40
+ <% else %>
41
+ <p><%= Spree.t(:you_have_not_earned_any_loyalty_points_yet) %></p>
42
+ <% end %>
43
+
44
+ <%= paginate @loyalty_points_transactions %>
@@ -0,0 +1,4 @@
1
+ <h3><%= Spree.t(:loyalty_points) %></h3>
2
+ <p>Current Balance: <%= spree_current_user.loyalty_points_balance %></p>
3
+ <%= render partial: 'spree/loyalty_points/transaction_table' %>
4
+ <br />
@@ -0,0 +1,18 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ spree:
6
+ loyalty_points_balance: Loyalty Points Balance
7
+ loyalty_points: Loyalty Points
8
+ loyalty_points_debit: Loyalty Points To Be Deducted Against this Return
9
+ loyalty_points_credit: Loyalty Points To Be Awarded Against this Return
10
+ details: Details
11
+ min_amount_required_to_get_loyalty_points: "Minimum amount to be spent per order(item total, excluding shipping and any other charges) to award loyalty points."
12
+ loyalty_points_awarding_unit: "Number of Loyalty Points to be awarded per Unit Amount Spent"
13
+ loyalty_points_redeeming_balance: Minimum Loyalty Points Balance Required for Redeeming
14
+ loyalty_points_conversion_rate: "Loyalty point to amount conversion rate"
15
+ loyalty_points_award_period: Time(in hours) after payment to award loyalty points
16
+ back_to_user_profile: Back to User Profile
17
+ update_loyalty_points: Update Loyalty Points
18
+ loyalty_points_earnable: "%{quantity} Loyalty Points Will Be Awarded for this Order"
data/config/routes.rb ADDED
@@ -0,0 +1,14 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ # Add your extension routes here
3
+
4
+ resources :loyalty_points, only: [:index]
5
+
6
+ namespace :admin do
7
+ resources :users do
8
+ resources :loyalty_points, only: [:index, :new, :create], controller: 'loyalty_points_transactions' do
9
+ get 'order_transactions/:order_id', action: :order_transactions, on: :collection
10
+ end
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,5 @@
1
+ class AddLoyaltyPointsBalanceToSpreeUser < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_users, :loyalty_points_balance, :integer, default: 0, null: false
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ class CreateLoyaltyPointsTransactions < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_loyalty_points_transactions do |t|
4
+ t.integer :loyalty_points
5
+ t.string :transaction_type
6
+ t.integer :user_id, :null => false
7
+ t.integer :order_id
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ class AddTimestampsToLoyaltyPointsTransaction < ActiveRecord::Migration
2
+ def change
3
+ change_table :spree_loyalty_points_transactions do |t|
4
+ t.timestamps
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ class AddFieldsToSpreeLoyaltyPointsTransaction < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_loyalty_points_transactions, :source_type, :string
4
+ rename_column :spree_loyalty_points_transactions, :order_id, :source_id
5
+ add_column :spree_loyalty_points_transactions, :updated_balance, :integer, default: 0, null: false
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class AddCommentToSpreeLoyaltyPointsTransaction < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_loyalty_points_transactions, :comment, :string
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddPaidAtToSpreeOrder < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_orders, :paid_at, :datetime
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class AddLoyaltyPointsToSpreeReturnAuthorization < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_return_authorizations, :loyalty_points, :integer, default: 0, null: false
4
+ add_column :spree_return_authorizations, :loyalty_points_transaction_type, :string
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddLoyaltyPointsAwardedToSpreeOrder < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_orders, :loyalty_points_awarded, :boolean, default: false, null: false
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class RenameFieldsInSpreeLoyaltyPointsTransaction < ActiveRecord::Migration
2
+ def change
3
+ rename_column :spree_loyalty_points_transactions, :updated_balance, :balance
4
+ rename_column :spree_loyalty_points_transactions, :transaction_type, :type
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class RemoveLoyaltyPointsAwardedFromSpreeOrder < ActiveRecord::Migration
2
+ def change
3
+ remove_column :spree_orders, :loyalty_points_awarded, :boolean, default: false, null: false
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class AddIndexingToSpreeLoyaltyPointsTransaction < ActiveRecord::Migration
2
+ def change
3
+ add_index :spree_loyalty_points_transactions, [:source_type, :source_id], name: 'by_source'
4
+ add_index :spree_loyalty_points_transactions, :user_id
5
+ add_index :spree_loyalty_points_transactions, :type
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class AddTransactionIdToSpreeLoyaltyPointsTransactions < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_loyalty_points_transactions, :transaction_id, :string
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddLockVersionToSpreeUser < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_users, :lock_version, :integer, default: 0, null: false
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ module SpreeLoyaltyPoints
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ class_option :auto_run_migrations, :type => :boolean, :default => false
6
+
7
+ def add_javascripts
8
+ append_file 'app/assets/javascripts/store/all.js', "//= require store/spree_loyalty_points\n"
9
+ append_file 'app/assets/javascripts/admin/all.js', "//= require admin/spree_loyalty_points\n"
10
+ end
11
+
12
+ def add_stylesheets
13
+ inject_into_file 'app/assets/stylesheets/store/all.css', " *= require store/spree_loyalty_points\n", :before => /\*\//, :verbose => true
14
+ inject_into_file 'app/assets/stylesheets/admin/all.css', " *= require admin/spree_loyalty_points\n", :before => /\*\//, :verbose => true
15
+ end
16
+
17
+ def add_migrations
18
+ run 'bundle exec rake railties:install:migrations FROM=spree_loyalty_points'
19
+ end
20
+
21
+ def run_migrations
22
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
23
+ if run_migrations
24
+ run 'bundle exec rake db:migrate'
25
+ else
26
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ module SpreeLoyaltyPoints
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'spree_loyalty_points'
6
+
7
+ config.autoload_paths += %W(#{config.root}/lib)
8
+
9
+ # use rspec for tests
10
+ config.generators do |g|
11
+ g.test_framework :rspec
12
+ end
13
+
14
+ def self.activate
15
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
16
+ Rails.configuration.cache_classes ? require(c) : load(c)
17
+ end
18
+ end
19
+
20
+ initializer "spree.register.payment_methods" do |app|
21
+ app.config.spree.payment_methods << Spree::PaymentMethod::LoyaltyPoints
22
+ end
23
+
24
+ config.to_prepare &method(:activate).to_proc
25
+ end
26
+ end
@@ -0,0 +1,75 @@
1
+ FactoryGirl.define do
2
+ # Define your Spree extensions Factories within this file to enable applications, and other extensions to use and override them.
3
+ #
4
+ # Example adding this to your spec_helper will load these Factories for use:
5
+ # require 'spree_loyalty_points/factories'
6
+
7
+ factory :loyalty_points_transaction, :class => Spree::LoyaltyPointsTransaction do
8
+ loyalty_points { (10..99).to_a.sample }
9
+ balance { (100..999).to_a.sample }
10
+ comment { Faker::Lorem.words(3).join(' ') }
11
+ type "Spree::LoyaltyPointsCreditTransaction"
12
+
13
+ association :user, factory: :user_with_loyalty_points
14
+
15
+ factory :loyalty_points_credit_transaction, :class => Spree::LoyaltyPointsCreditTransaction do
16
+ type "Spree::LoyaltyPointsCreditTransaction"
17
+ end
18
+
19
+ factory :loyalty_points_debit_transaction, :class => Spree::LoyaltyPointsDebitTransaction do
20
+ type "Spree::LoyaltyPointsDebitTransaction"
21
+ end
22
+
23
+ end
24
+
25
+ factory :user_with_loyalty_points, parent: :user do
26
+ loyalty_points_balance { (100..999).to_a.sample }
27
+
28
+ ignore do
29
+ transactions_count 5
30
+ end
31
+
32
+ after(:create) do |user, evaluator|
33
+ create_list(:loyalty_points_transaction, evaluator.transactions_count, user: user)
34
+ end
35
+ end
36
+
37
+ factory :order_with_loyalty_points, parent: :order do
38
+
39
+ association :user, factory: :user_with_loyalty_points
40
+
41
+ ignore do
42
+ transactions_count 5
43
+ end
44
+
45
+ after(:create) do |order, evaluator|
46
+ create_list(:loyalty_points_transaction, evaluator.transactions_count, source: order)
47
+ end
48
+
49
+ factory :shipped_order_with_loyalty_points do
50
+ ignore do
51
+ shipments_count 5
52
+ end
53
+
54
+ after(:create) do |order, evaluator|
55
+ create_list(:shipment, evaluator.shipments_count, order: order, state: "shipped")
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ factory :payment_with_loyalty_points, parent: :payment do
62
+
63
+ association :order, factory: :order_with_loyalty_points
64
+
65
+ end
66
+
67
+ factory :return_authorization_with_loyalty_points, parent: :return_authorization do
68
+ loyalty_points { (50..99).to_a.sample }
69
+ loyalty_points_transaction_type "Debit"
70
+
71
+ association :order, factory: :shipped_order_with_loyalty_points
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,2 @@
1
+ require 'spree_core'
2
+ require 'spree_loyalty_points/engine'