solidus_virtual_gift_card 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/app/assets/javascripts/spree/backend/solidus_virtual_gift_card.coffee +6 -6
  4. data/app/assets/stylesheets/spree/backend/solidus_virtual_gift_card.css +4 -0
  5. data/app/controllers/spree/admin/gift_cards_controller.rb +32 -12
  6. data/app/mailers/spree/gift_card_mailer.rb +2 -1
  7. data/app/models/concerns/spree/gift_cards/line_item_concerns.rb +6 -1
  8. data/app/models/concerns/spree/gift_cards/order_concerns.rb +15 -9
  9. data/app/models/concerns/spree/gift_cards/order_contents_concerns.rb +84 -0
  10. data/app/models/spree/order_contents_decorator.rb +1 -0
  11. data/app/models/spree/virtual_gift_card.rb +47 -10
  12. data/app/overrides/admin_gift_card_order_confirmation.rb +6 -0
  13. data/app/overrides/admin_item_view_gift_card_codes.rb +9 -2
  14. data/app/views/spree/admin/gift_cards/_lookup_form.html.erb +31 -6
  15. data/app/views/spree/admin/gift_cards/edit.html.erb +81 -0
  16. data/app/views/spree/admin/gift_cards/index.html.erb +39 -0
  17. data/app/views/spree/admin/gift_cards/show.html.erb +0 -32
  18. data/app/views/spree/admin/orders/_cart_gift_card_details.html.erb +3 -0
  19. data/app/views/spree/admin/orders/_confirmation_gift_card_details.html.erb +50 -0
  20. data/app/views/spree/admin/orders/_gift_card_details.html.erb +2 -0
  21. data/app/views/spree/admin/orders/_shipments_gift_card_details.html.erb +3 -0
  22. data/bin/rails +1 -1
  23. data/config/initializers/line_item_controller_gift_card_details.rb +4 -0
  24. data/config/initializers/ransack.rb +7 -0
  25. data/config/locales/en.yml +3 -0
  26. data/config/routes.rb +9 -1
  27. data/db/migrate/20151013172931_add_recipient_fields_to_virtual_gift_card.rb +8 -0
  28. data/db/migrate/20151013210615_add_active_flag_to_virtual_gift_card.rb +5 -0
  29. data/db/migrate/20151013214647_set_redeemable_true_on_virtual_gift_cards.rb +11 -0
  30. data/db/migrate/20151019190731_add_email_send_time_to_virtual_gift_card.rb +7 -0
  31. data/lib/spree_virtual_gift_card/factories.rb +11 -2
  32. data/lib/tasks/send_gift_card_emails.rake +8 -0
  33. data/solidus_virtual_gift_card.gemspec +1 -1
  34. data/spec/controllers/spree/admin/gift_cards_controller_spec.rb +1 -33
  35. data/spec/controllers/spree/api/gift_cards_controller_spec.rb +1 -1
  36. data/spec/features/admin/gift_cards_spec.rb +74 -0
  37. data/spec/lib/tasks/send_gift_card_emails_spec.rb +60 -0
  38. data/spec/models/spree/line_item_spec.rb +21 -0
  39. data/spec/models/spree/order_contents_spec.rb +270 -0
  40. data/spec/models/spree/order_spec.rb +34 -57
  41. data/spec/models/spree/virtual_gift_card_spec.rb +54 -23
  42. data/spec/spec_helper.rb +1 -0
  43. metadata +23 -3
  44. data/app/views/spree/admin/orders/_gift_card_redemption_codes.html.erb +0 -3
@@ -0,0 +1,81 @@
1
+ <script async='true'>GiftCards.setAdminDatepicker()</script>
2
+
3
+ <% content_for :page_title do %>
4
+ <%= Spree.t("admin.gift_cards.editing_gift_card") %>
5
+ <% end %>
6
+
7
+ <%= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => '' } %>
8
+
9
+ <%= form_for @gift_card, url: admin_order_gift_card_path(@order, @gift_card) do |f| %>
10
+ <fieldset>
11
+ <legend align="center"><%= Spree.t("admin.gift_cards.gift_card_details") %></legend>
12
+ <div class="row">
13
+ <label>Amount:</label>
14
+ <%= @gift_card.formatted_amount %>
15
+ </div>
16
+
17
+ <div class="row">
18
+ <label>Redemption Code:</label>
19
+ <%= @gift_card.redemption_code %>
20
+ </div>
21
+
22
+ <div class="row">
23
+ <div class="alpha twelve columns">
24
+ <%= f.field_container :recipient_name do %>
25
+ <%= f.label :recipient_name, Spree.t('admin.gift_cards.recipient_name') %> <br />
26
+ <%= f.text_field :recipient_name, class: 'fullwidth' %>
27
+ <% end %>
28
+ </div>
29
+ </div>
30
+
31
+ <div class="row">
32
+ <div class="alpha twelve columns">
33
+ <%= f.field_container :recipient_email do %>
34
+ <%= f.label :recipient_email, Spree.t('admin.gift_cards.recipient_email') %> <br />
35
+ <%= f.text_field :recipient_email, class: 'fullwidth' %>
36
+ <% end %>
37
+ </div>
38
+ </div>
39
+
40
+ <div class="row">
41
+ <div class="alpha twelve columns">
42
+ <%= f.field_container :purchaser_name do %>
43
+ <%= f.label :purchaser_name, Spree.t('admin.gift_cards.purchaser_name') %> <br />
44
+ <%= f.text_field :purchaser_name, class: 'fullwidth' %>
45
+ <% end %>
46
+ </div>
47
+ </div>
48
+
49
+ <div class="row">
50
+ <div class="alpha twelve columns">
51
+ <%= f.field_container :gift_message do %>
52
+ <%= f.label :gift_message, Spree.t('admin.gift_cards.gift_message') %> <br />
53
+ <%= f.text_area :gift_message, class: 'fullwidth', maxlength: '140' %>
54
+ <% end %>
55
+ </div>
56
+ </div>
57
+
58
+ <div class="row">
59
+ <div class="alpha twelve columns">
60
+ <% if @gift_card.sent_at %>
61
+ <div class="last-email-sent">
62
+ Email last sent at: <%= @gift_card.formatted_sent_at %>
63
+ </div>
64
+ <% else %>
65
+ <%= f.field_container :send_email_at do %>
66
+ <%= f.label :send_email_at, Spree.t('admin.gift_cards.send_email_at') %> <br />
67
+ <%= f.text_field :send_email_at, :class => 'datepicker datepicker-from giftcard-datepicker' %>
68
+ <% end %>
69
+ <% end %>
70
+ </div>
71
+ </div>
72
+
73
+ <%= render :partial => 'spree/admin/shared/edit_resource_links', locals: { collection_url: edit_admin_order_path(@order) } %>
74
+ </fieldset>
75
+
76
+ <div class="form-buttons filter-actions actions" data-hook="buttons">
77
+ <% if @order.completed? %>
78
+ <%= button_link_to "Send email now", send_email_admin_order_gift_card_path(@order, @gift_card), :icon => 'email', :data => { :confirm => "Any changes that have not been updated will not send" } %>
79
+ <% end %>
80
+ </div>
81
+ <% end %>
@@ -1 +1,40 @@
1
1
  <%= render partial: 'lookup_form' %>
2
+ <%= paginate @gift_cards %>
3
+ <% if @gift_cards.any? %>
4
+ <table class="index">
5
+ <thead>
6
+ <tr>
7
+ <th class="align-center">Redemption Code</th>
8
+ <th class="align-center">Amount</th>
9
+ <th class="align-center">Purchased by</th>
10
+ <th class="align-center">Purchased at</th>
11
+ <th class="align-center">Recipient Email</th>
12
+ <th class="align-center">Date Sent</th>
13
+ <th class="align-center">Redeemed by</th>
14
+ <th class="align-center">Redeemed at</th>
15
+ </tr>
16
+ </thead>
17
+
18
+ <tbody>
19
+ <% @gift_cards.each do |gift_card| %>
20
+ <tr>
21
+ <td class="align-center"><%= gift_card.formatted_redemption_code %></td>
22
+ <td class="align-center"><%= number_to_currency(gift_card.amount) %></td>
23
+ <td class="align-center"><%= link_to "#{gift_card.purchaser.email}", edit_admin_user_path(gift_card.purchaser) %></td>
24
+ <td class="align-center"><%= gift_card.formatted_created_at %></td>
25
+ <td class="align-center"><%= gift_card.recipient_email %></td>
26
+ <td class="align-center"><%= gift_card.formatted_sent_at || gift_card.formatted_send_email_at %></td>
27
+ <% if gift_card.redeemed? %>
28
+ <td class="align-center"><%= link_to "#{gift_card.redeemer.email}", edit_admin_user_path(gift_card.redeemer) %></td>
29
+ <td class="align-center"><%= gift_card.formatted_redeemed_at %></td>
30
+ <% else %>
31
+ <td class="align-center"></td>
32
+ <td class="align-center"></td>
33
+ <% end %>
34
+ </tr>
35
+ <% end %>
36
+ </tbody>
37
+ </table>
38
+ <% end %>
39
+
40
+ <%= paginate @gift_cards %>
@@ -1,32 +0,0 @@
1
- <%= render partial: 'spree/admin/shared/sub_menu' %>
2
- <%= render partial: 'lookup_form' %>
3
-
4
- <table class="index">
5
- <thead>
6
- <tr>
7
- <th class="align-center">Redemption Code</th>
8
- <th class="align-center">Amount</th>
9
- <th class="align-center">Purchased by</th>
10
- <th class="align-center">Purchased at</th>
11
- <th class="align-center">Redeemed by</th>
12
- <th class="align-center">Redeemed at</th>
13
- </tr>
14
- </thead>
15
- <tbody>
16
- <% @gift_cards.each do |gift_card| %>
17
- <tr>
18
- <td class="align-center"><%= gift_card.formatted_redemption_code %></td>
19
- <td class="align-center"><%= number_to_currency(gift_card.amount) %></td>
20
- <td class="align-center"><%= link_to "#{gift_card.purchaser.email}", edit_admin_user_path(gift_card.purchaser) %></td>
21
- <td class="align-center"><%= gift_card.created_at.localtime.strftime("%F %I:%M%p") %></td>
22
- <% if gift_card.redeemed? %>
23
- <td class="align-center"><%= link_to "#{gift_card.redeemer.email}", edit_admin_user_path(gift_card.redeemer) %></td>
24
- <td class="align-center"><%= gift_card.redeemed_at.localtime.strftime("%F %I:%M%p") %></td>
25
- <% else %>
26
- <td class="align-center"></td>
27
- <td class="align-center"></td>
28
- <% end %>
29
- </tr>
30
- <% end %>
31
- </tbody>
32
- </table>
@@ -0,0 +1,3 @@
1
+ <% item.gift_cards.each do |gift_card| %>
2
+ <%= render partial: "gift_card_details", locals: { gift_card: gift_card } %>
3
+ <% end %>
@@ -0,0 +1,50 @@
1
+ <fieldset class="no-border-bottom">
2
+ <legend align="center" data-hook="gift-card">
3
+ <%= Spree.t(:gift_cards_details) %>
4
+ </legend>
5
+ </fieldset>
6
+
7
+ <table>
8
+ <colgroup>
9
+ <col style="width: 15%;" />
10
+ <col style="width: 15%;" />
11
+ <col style="width: 15%;" />
12
+ <col style="width: 30%;" />
13
+ <col style="width: 10%;" />
14
+ <col style="width: 15%;" />
15
+ </colgroup>
16
+
17
+ <thead>
18
+ <th><%= Spree.t(:recipient_email) %></th>
19
+ <th><%= Spree.t(:recipient_name) %></th>
20
+ <th><%= Spree.t(:purchaser_name) %></th>
21
+ <th><%= Spree.t(:gift_message) %></th>
22
+ <th><%= Spree.t(:send_email_at) %></th>
23
+ </thead>
24
+
25
+
26
+ <tbody>
27
+ <% @order.line_items.flat_map(&:gift_cards).each do |gift_card| %>
28
+ <tr>
29
+ <td>
30
+ <%= gift_card.recipient_email || "n/a" %>
31
+ </td>
32
+ <td>
33
+ <%= gift_card.recipient_name || "n/a" %>
34
+ </td>
35
+ <td>
36
+ <%= gift_card.purchaser_name || "n/a" %>
37
+ </td>
38
+ <td>
39
+ <%= gift_card.gift_message || "n/a" %>
40
+ </td>
41
+ <td>
42
+ <%= gift_card.formatted_send_email_at || "Immediately" %>
43
+ </td>
44
+ <td class="actions">
45
+ <%= link_to '', edit_admin_order_gift_card_path(@order, gift_card), :class => 'fa fa-edit no-text with-tip', :title => Spree.t('actions.edit') %>
46
+ </td>
47
+ </tr>
48
+ <% end %>
49
+ </tbody>
50
+ </table>
@@ -0,0 +1,2 @@
1
+ <br><strong><%= Spree.t('admin.gift_cards.redemption_code') %>:</strong> <%= gift_card.redemption_code %>
2
+ <br><%= link_to '(Edit Details)', edit_admin_order_gift_card_path(@order, gift_card), class: 'edit-gift-card-details' %>
@@ -0,0 +1,3 @@
1
+ <% item.line_item.gift_cards.each do |gift_card| %>
2
+ <%= render partial: "gift_card_details", locals: { gift_card: gift_card } %>
3
+ <% end %>
data/bin/rails CHANGED
@@ -1,7 +1,7 @@
1
1
  # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
2
2
 
3
3
  ENGINE_ROOT = File.expand_path('../..', __FILE__)
4
- ENGINE_PATH = File.expand_path('../../lib/spree_store_credits/engine', __FILE__)
4
+ ENGINE_PATH = File.expand_path('../../lib/spree_virtual_gift_card/engine', __FILE__)
5
5
 
6
6
  require 'rails/all'
7
7
  require 'rails/engine/commands'
@@ -0,0 +1,4 @@
1
+ Rails.application.config.to_prepare do
2
+ Spree::Api::LineItemsController.line_item_options += [gift_card_details: [:recipient_name, :recipient_email, :gift_message, :purchaser_name, :send_email_at]]
3
+ Spree::Order.line_item_comparison_hooks.add('gift_card_match')
4
+ end
@@ -0,0 +1,7 @@
1
+ Ransack.configure do |config|
2
+ config.add_predicate 'is',
3
+ arel_predicate: 'eq',
4
+ formatter: proc { |v| v.to_date },
5
+ validator: proc { |v| v.present? },
6
+ type: :string
7
+ end
@@ -3,8 +3,11 @@ en:
3
3
  spree:
4
4
  admin:
5
5
  gift_cards:
6
+ editing_gift_card: "Editing Gift Card"
6
7
  gift_card: "Gift Card"
8
+ gift_card_details: "Gift Card Details"
7
9
  gift_card_originator: "Gift Card - Order #%{order_number}"
10
+ gift_card_updated: "Gift card updated!"
8
11
  redeem: "Redeem"
9
12
  redeem_gift_card: "Redeem Gift Card"
10
13
  redeemed_gift_card: "Redeemed Gift Card"
data/config/routes.rb CHANGED
@@ -8,7 +8,15 @@ Spree::Core::Engine.routes.draw do
8
8
  end
9
9
  end
10
10
  collection do
11
- resources :gift_cards, only: [:index, :show]
11
+ resources :gift_cards, only: [:index]
12
+ end
13
+ end
14
+
15
+ resources :orders, only: [] do
16
+ resources :gift_cards, only: [:edit, :update] do
17
+ member do
18
+ get :send_email
19
+ end
12
20
  end
13
21
  end
14
22
  end
@@ -0,0 +1,8 @@
1
+ class AddRecipientFieldsToVirtualGiftCard < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_virtual_gift_cards, :recipient_name, :string
4
+ add_column :spree_virtual_gift_cards, :recipient_email, :string
5
+ add_column :spree_virtual_gift_cards, :gift_message, :text
6
+ add_column :spree_virtual_gift_cards, :purchaser_name, :string
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ class AddActiveFlagToVirtualGiftCard < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_virtual_gift_cards, :redeemable, :boolean, default: false
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class SetRedeemableTrueOnVirtualGiftCards < ActiveRecord::Migration
2
+ def up
3
+ Spree::VirtualGiftCard.find_each do |gift_card|
4
+ gift_card.update_attributes!(redeemable: true)
5
+ end
6
+ end
7
+
8
+ def down
9
+ #noop
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ class AddEmailSendTimeToVirtualGiftCard < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_virtual_gift_cards, :send_email_at, :date
4
+ add_column :spree_virtual_gift_cards, :sent_at, :datetime
5
+ add_index :spree_virtual_gift_cards, :send_email_at
6
+ end
7
+ end
@@ -4,10 +4,19 @@ FactoryGirl.define do
4
4
  end
5
5
 
6
6
  factory :virtual_gift_card, class: Spree::VirtualGiftCard do
7
- association :purchaser, factory: :user
8
7
  association :line_item, factory: :line_item
9
-
10
8
  amount 25.0
11
9
  currency "USD"
10
+ recipient_name "Tom Riddle"
11
+ recipient_email "me@lordvoldemort.com"
12
+
13
+ factory :redeemable_virtual_gift_card do
14
+ association :purchaser, factory: :user
15
+ redeemable true
16
+
17
+ before(:create) do |gift_card, evaluator|
18
+ gift_card.redemption_code = gift_card.send(:generate_unique_redemption_code)
19
+ end
20
+ end
12
21
  end
13
22
  end
@@ -0,0 +1,8 @@
1
+ namespace :solidus_virtual_gift_card do
2
+ desc "Send todays gift card emails"
3
+ task :send_current_emails => :environment do
4
+ Spree::VirtualGiftCard.where(send_email_at: Date.today, sent_at: nil, redeemable: true).find_each do |gift_card|
5
+ gift_card.send_email
6
+ end
7
+ end
8
+ end
@@ -3,7 +3,7 @@
3
3
  Gem::Specification.new do |s|
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.name = "solidus_virtual_gift_card"
6
- s.version = "1.0.0"
6
+ s.version = "1.0.1"
7
7
  s.summary = "Virtual gift card for purchase, drops into the user's account as store credit"
8
8
  s.required_ruby_version = ">= 2.1"
9
9
 
@@ -14,38 +14,6 @@ describe Spree::Admin::GiftCardsController do
14
14
  end
15
15
  end
16
16
 
17
- describe 'GET show' do
18
- let(:gift_card) { create(:virtual_gift_card) }
19
- let(:redemption_code) { gift_card.redemption_code }
20
-
21
- subject { spree_get :show, id: redemption_code }
22
-
23
- context 'with a valid redemption code' do
24
- it 'loads the gift cards' do
25
- subject
26
- expect(assigns(:gift_cards)).to eq [gift_card]
27
- end
28
-
29
- it 'returns a 200 status code' do
30
- subject
31
- expect(response.code).to eq '200'
32
- end
33
- end
34
-
35
- context 'with an invalid redemption code' do
36
- let(:redemption_code) { "DOES-NOT-EXIST" }
37
-
38
- it "redirects to index" do
39
- expect(subject).to redirect_to spree.admin_gift_cards_path
40
- end
41
-
42
- it "sets the flash error" do
43
- subject
44
- expect(flash[:error]).to eq Spree.t('admin.gift_cards.errors.not_found')
45
- end
46
- end
47
- end
48
-
49
17
  describe 'GET lookup' do
50
18
  let(:user) { create :user }
51
19
  subject { spree_get :lookup, user_id: user.id }
@@ -58,7 +26,7 @@ describe Spree::Admin::GiftCardsController do
58
26
 
59
27
  describe 'POST redeem' do
60
28
  let(:user) { create :user }
61
- let(:gift_card) { create(:virtual_gift_card) }
29
+ let(:gift_card) { create(:redeemable_virtual_gift_card) }
62
30
  let(:redemption_code) { gift_card.redemption_code }
63
31
 
64
32
  subject { spree_post :redeem, user_id: user.id, gift_card: { redemption_code: redemption_code } }
@@ -6,7 +6,7 @@ describe Spree::Api::GiftCardsController do
6
6
  let!(:gc_category) { create(:store_credit_gift_card_category) }
7
7
 
8
8
  describe "POST redeem" do
9
- let(:gift_card) { create(:virtual_gift_card) }
9
+ let(:gift_card) { create(:redeemable_virtual_gift_card) }
10
10
 
11
11
  let(:parameters) do
12
12
  {
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Gift Cards', :type => :feature, :js => true do
4
+ stub_authorization!
5
+
6
+ let(:admin_user) { create(:admin_user) }
7
+
8
+ before do
9
+ allow_any_instance_of(Spree::Admin::BaseController).to receive(:spree_current_user).and_return(admin_user)
10
+ end
11
+
12
+ describe "edit gift card" do
13
+ let(:gift_card) { create(:redeemable_virtual_gift_card) }
14
+ let(:order) { gift_card.line_item.order }
15
+ let(:new_recipient_name) { "Heidi" }
16
+ let(:new_recipient_email) { "heidi@gmail.com" }
17
+ let(:new_purchaser_name) { "Neerali" }
18
+ let(:new_gift_message) { "Sweaters!" }
19
+
20
+ it "can edit recipient information and send email date" do
21
+ visit spree.cart_admin_order_path(order)
22
+
23
+ within ".line-item-name" do
24
+ click_link("Edit Details")
25
+ end
26
+
27
+ fill_in "virtual_gift_card_recipient_name", with: new_recipient_name
28
+ fill_in "virtual_gift_card_recipient_email", with: new_recipient_email
29
+ fill_in "virtual_gift_card_purchaser_name", with: new_purchaser_name
30
+ fill_in "virtual_gift_card_gift_message", with: new_gift_message
31
+ fill_in "virtual_gift_card_send_email_at", with: Date.tomorrow
32
+
33
+ # Just so the datepicker gets out of poltergeists way.
34
+ page.execute_script("$('#virtual_gift_card_send_email_at').datepicker('widget').hide();")
35
+
36
+ click_on 'Update'
37
+ expect(page).to have_content("Gift card updated!")
38
+ expect(gift_card.reload.recipient_name).to eq(new_recipient_name)
39
+ expect(gift_card.recipient_email).to eq(new_recipient_email)
40
+ expect(gift_card.purchaser_name).to eq(new_purchaser_name)
41
+ expect(gift_card.gift_message).to eq(new_gift_message)
42
+ end
43
+ end
44
+
45
+ describe "lookup a gift card" do
46
+ let(:gift_card) { create(:redeemable_virtual_gift_card,
47
+ recipient_name: "Daeva",
48
+ recipient_email: 'dog@example.com',
49
+ )
50
+ }
51
+ let(:other_gift_card) { create(:redeemable_virtual_gift_card)}
52
+ let(:order) { gift_card.line_item.order }
53
+
54
+ it "can lookup gift card by recipient email" do
55
+ visit spree.admin_gift_cards_path
56
+
57
+ fill_in "q[recipient_email_cont]", with: gift_card.recipient_email
58
+ click_on "Lookup Gift Card"
59
+
60
+ expect(page).to have_content(gift_card.purchaser.email)
61
+ expect(page).to_not have_content(other_gift_card.purchaser.email)
62
+ end
63
+
64
+ it "can lookup gift card by order number" do
65
+ visit spree.admin_gift_cards_path
66
+
67
+ fill_in "q[line_item_order_number_cont]", with: order.number
68
+ click_on "Lookup Gift Card"
69
+
70
+ expect(page).to have_content(gift_card.purchaser.email)
71
+ expect(page).to_not have_content(other_gift_card.purchaser.email)
72
+ end
73
+ end
74
+ end