spree_wishlist 1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +4 -0
  3. data/.travis.yml +14 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE +23 -0
  6. data/README.md +31 -0
  7. data/Rakefile +19 -0
  8. data/Versionfile +4 -0
  9. data/app/assets/javascripts/store/spree_wishlist.js +21 -0
  10. data/app/assets/stylesheets/store/spree_wishlist.css +2 -0
  11. data/app/controllers/spree/wished_products_controller.rb +37 -0
  12. data/app/controllers/spree/wishlists_controller.rb +48 -0
  13. data/app/models/spree/user_decorator.rb +11 -0
  14. data/app/models/spree/wished_product.rb +4 -0
  15. data/app/models/spree/wishlist.rb +40 -0
  16. data/app/overrides/add_wish_to_cart_form.rb +5 -0
  17. data/app/overrides/add_wishlists_to_account_my_orders.rb +5 -0
  18. data/app/views/spree/products/_wishlist_form.html.erb +10 -0
  19. data/app/views/spree/users/_wishlists.html.erb +8 -0
  20. data/app/views/spree/wishlists/_accessibility.html.erb +4 -0
  21. data/app/views/spree/wishlists/_mail_to_friend.html.erb +14 -0
  22. data/app/views/spree/wishlists/edit.html.erb +7 -0
  23. data/app/views/spree/wishlists/new.html.erb +6 -0
  24. data/app/views/spree/wishlists/show.html.erb +84 -0
  25. data/app/views/spree/wishlists/update.js.erb +0 -0
  26. data/config/locales/de.yml +26 -0
  27. data/config/locales/en.yml +26 -0
  28. data/config/locales/ru.yml +27 -0
  29. data/config/routes.rb +5 -0
  30. data/config/spree_permissions.yml +25 -0
  31. data/db/migrate/20091020182940_create_wishlists.rb +17 -0
  32. data/db/migrate/20091020183520_create_wished_products.rb +15 -0
  33. data/db/migrate/20111130204731_prefix_wishlist_tables_with_spree.rb +6 -0
  34. data/db/seeds.rb +2 -0
  35. data/lib/generators/spree_wishlist/install/install_generator.rb +27 -0
  36. data/lib/spree_wishlist.rb +3 -0
  37. data/lib/spree_wishlist/engine.rb +20 -0
  38. data/lib/wishlist_ability.rb +35 -0
  39. data/spec/controllers/spree/wished_products_controller_spec.rb +10 -0
  40. data/spec/controllers/spree/wishlists_controller_spec.rb +10 -0
  41. data/spec/lib/wishlist_ability_spec.rb +97 -0
  42. data/spec/models/spree/wished_product_spec.rb +11 -0
  43. data/spec/models/spree/wishlist_spec.rb +75 -0
  44. data/spec/spec_helper.rb +19 -0
  45. data/spree_wishlist.gemspec +25 -0
  46. metadata +151 -0
@@ -0,0 +1,4 @@
1
+ spec/dummy
2
+ spec/test_app
3
+ Gemfile.lock
4
+ *.swp
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ mtime
@@ -0,0 +1,14 @@
1
+ before_script:
2
+ - "bundle exec rake test_app"
3
+ script: "DISPLAY=:99.0 bundle exec rspec spec"
4
+ notifications:
5
+ email:
6
+ - jdyer@spreecommerce.com
7
+ irc: "irc.freenode.org#spree"
8
+ branches:
9
+ only:
10
+ - master
11
+ rvm:
12
+ - 1.8.7
13
+ - 1.9.3
14
+ - ree
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :test do
4
+ gem 'faker'
5
+ end
6
+
7
+ # Specify your dependencies in spree_wishlist.gemspec
8
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Redistribution and use in source and binary forms, with or without modification,
2
+ are permitted provided that the following conditions are met:
3
+
4
+ * Redistributions of source code must retain the above copyright notice,
5
+ this list of conditions and the following disclaimer.
6
+ * Redistributions in binary form must reproduce the above copyright notice,
7
+ this list of conditions and the following disclaimer in the documentation
8
+ and/or other materials provided with the distribution.
9
+ * Neither the name of the Rails Dog LLC nor the names of its
10
+ contributors may be used to endorse or promote products derived from this
11
+ software without specific prior written permission.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,31 @@
1
+ # Spree Wishlist extension
2
+
3
+ [![Build
4
+ Status](https://secure.travis-ci.org/spree/spree_wishlist.png)](http://travis-ci.org/spree/spree_wishlist)
5
+
6
+ The Spree Wishlist extension enables multiple wishlists per user, as well as managing those
7
+ as public (sharable) and private. It also includes the ability to notify a friend via email
8
+ of a recommended product.
9
+
10
+ ## Installation
11
+
12
+ 1. Add the following to your Gemfile
13
+
14
+ <pre>
15
+ gem 'spree_wishlist', '~> 1.3'
16
+ gem 'spree_email_to_friend'
17
+ </pre>
18
+
19
+ 2. Run `bundle install`
20
+
21
+ 3. To setup the asset pipeline includes and copy migrations run: `rails g spree_wishlist:install`
22
+
23
+ ## Development
24
+
25
+ * Fork the repo
26
+ * clone your repo
27
+ * Run `bundle`
28
+ * Run `bundle exec rake test_app` to create the test application in `spec/test_app`.
29
+ * Make your changes.
30
+ * Ensure specs pass by running `bundle exec rake`
31
+ * Submit your pull request
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+ Bundler.setup
6
+
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new
9
+
10
+ require 'spree/core/testing_support/common_rake'
11
+
12
+ desc "Default Task"
13
+ task :default => [:spec]
14
+
15
+ desc "Generates a dummy app for testing"
16
+ task :test_app do
17
+ ENV['LIB_NAME'] = 'spree_wishlist'
18
+ Rake::Task['common:test_app'].invoke
19
+ end
@@ -0,0 +1,4 @@
1
+ "1.0.x" => { :version => "1.3", :tag => "v1.3" }
2
+ "0.70.x" => { :ref => "0400d9e7c85f4ad637ac", :version => "1.2" }
3
+ "0.60.x" => { :ref => "5172de86dd46905e6d60288584b567155055675e", :version => "1.1" }
4
+ "0.50.x" => { :ref => "5172de86dd46905e6d60288584b567155055675e", :version => "1.1" }
@@ -0,0 +1,21 @@
1
+ $(function() {
2
+
3
+ $("#new_spree_wished_product").submit(function() {
4
+ selected_variant_id = $("#product-variants input[type=radio]:checked").val();
5
+ if (selected_variant_id)
6
+ {
7
+ $("#wished_product_variant_id").val(selected_variant_id);
8
+ }
9
+ });
10
+
11
+
12
+ $("form#change_wishlist_accessibility").submit(function() {
13
+ $.post($(this).attr("action"), $(this).serialize(), null, "script");
14
+ return false;
15
+ });
16
+
17
+ $("form#change_wishlist_accessibility input[type=radio]").click(function() {
18
+ $(this).parent().submit();
19
+ });
20
+
21
+ });
@@ -0,0 +1,2 @@
1
+ #wishlist-form {margin-top: 5px;}
2
+ #wishlist_header h1, #wishlist_header div { float: left; width: 30%; }
@@ -0,0 +1,37 @@
1
+ class Spree::WishedProductsController < Spree::BaseController
2
+ respond_to :html
3
+
4
+ def create
5
+ @wished_product = Spree::WishedProduct.new(params[:wished_product])
6
+ @wishlist = current_user.wishlist
7
+
8
+ if @wishlist.include? params[:wished_product][:variant_id]
9
+ @wished_product = @wishlist.wished_products.detect {|wp| wp.variant_id == params[:wished_product][:variant_id].to_i }
10
+ else
11
+ @wished_product.wishlist = current_user.wishlist
12
+ @wished_product.save
13
+ end
14
+
15
+ respond_with(@wished_product) do |format|
16
+ format.html { redirect_to wishlist_url(@wishlist) }
17
+ end
18
+ end
19
+
20
+ def update
21
+ @wished_product = Spree::WishedProduct.find(params[:id])
22
+ @wished_product.update_attributes(params[:wished_product])
23
+
24
+ respond_with(@wished_product) do |format|
25
+ format.html { redirect_to wishlist_url(@wished_product.wishlist) }
26
+ end
27
+ end
28
+
29
+ def destroy
30
+ @wished_product = Spree::WishedProduct.find(params[:id])
31
+ @wished_product.destroy
32
+
33
+ respond_with(@wished_product) do |format|
34
+ format.html { redirect_to wishlist_url(@wished_product.wishlist) }
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,48 @@
1
+ class Spree::WishlistsController < Spree::BaseController
2
+ helper 'spree/products'
3
+
4
+ respond_to :html
5
+ respond_to :js, :only => [:update]
6
+
7
+ def new
8
+ @wishlist = Spree::Wishlist.new
9
+
10
+ respond_with(@wishlist)
11
+ end
12
+
13
+ def edit
14
+ @wishlist = Spree::Wishlist.find_by_access_hash(params[:id])
15
+
16
+ respond_with(@wishlist)
17
+ end
18
+
19
+ def update
20
+ @wishlist = Spree::Wishlist.find_by_access_hash(params[:id])
21
+ @wishlist.update_attributes(params[:wishlist])
22
+
23
+ respond_with(@wishlist)
24
+ end
25
+
26
+ def show
27
+ @wishlist = Spree::Wishlist.find_by_access_hash(params[:id])
28
+
29
+ respond_with(@wishlist)
30
+ end
31
+
32
+ def create
33
+ @wishlist = Spree::Wishlist.new(params[:wishlist])
34
+ @wishlist.user = current_user
35
+
36
+ @wishlist.save
37
+ respond_with(@wishlist)
38
+ end
39
+
40
+ def destroy
41
+ @wishlist = Spree::Wishlist.find_by_access_hash(params[:id])
42
+ @wishlist.destroy
43
+ respond_with(@wishlist )do |format|
44
+ format.html { redirect_to account_path }
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,11 @@
1
+ Spree::User.class_eval do
2
+ has_many :wishlists
3
+
4
+ def wishlist
5
+ default_wishlist = self.wishlists.first(:conditions => ["is_default = ?", true])
6
+ default_wishlist ||= self.wishlists.first
7
+ default_wishlist ||= self.wishlists.create(:name => I18n.t(:default_wishlist_name, :default => "My wishlist"), :is_default => true)
8
+ default_wishlist.update_attribute(:is_default, true) unless default_wishlist.is_default?
9
+ default_wishlist
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ class Spree::WishedProduct < ActiveRecord::Base
2
+ belongs_to :variant
3
+ belongs_to :wishlist
4
+ end
@@ -0,0 +1,40 @@
1
+ class Spree::Wishlist < ActiveRecord::Base
2
+ belongs_to :user
3
+ has_many :wished_products
4
+ before_create :set_access_hash
5
+
6
+ validates :name, :presence => true
7
+
8
+ def include?(variant_id)
9
+ self.wished_products.map(&:variant_id).include? variant_id.to_i
10
+ end
11
+
12
+ def to_param
13
+ self.access_hash
14
+ end
15
+
16
+ def self.get_by_param(param)
17
+ Spree::Wishlist.find_by_access_hash(param)
18
+ end
19
+
20
+ def can_be_read_by?(user)
21
+ !self.is_private? || user == self.user
22
+ end
23
+
24
+ def is_default=(value)
25
+ self['is_default'] = value
26
+ if self.is_default?
27
+ Spree::Wishlist.update_all({:is_default => false}, ["id != ? AND is_default = ? AND user_id = ?", self.id, true, self.user_id])
28
+ end
29
+ end
30
+
31
+ def is_public?
32
+ !self.is_private?
33
+ end
34
+
35
+ private
36
+
37
+ def set_access_hash
38
+ self.access_hash = Digest::SHA1.hexdigest("--#{user_id}--#{user.password_salt}--#{Time.now}--")
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/products/show",
2
+ :name => "add_wish_to_cart_form",
3
+ :insert_bottom => "[data-hook='cart_form']",
4
+ :partial => "spree/products/wishlist_form",
5
+ :disabled => false)
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/users/show",
2
+ :name => "add_wishlists_to_account_my_orders",
3
+ :insert_after => "[data-hook='account_my_orders']",
4
+ :partial => "spree/users/wishlists",
5
+ :disabled => false)
@@ -0,0 +1,10 @@
1
+ <% if current_user %>
2
+ <div id="wishlist-form">
3
+ <%= form_for Spree::WishedProduct.new do |f| %>
4
+ <%= f.hidden_field :variant_id, :value => @product.master.id %>
5
+ <button type="submit" class="large primary">
6
+ <%= t(:add_to_wishlist) %>
7
+ </button>
8
+ <% end %>
9
+ </div>
10
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <h3><%= t(:my_wishlists) %></h3>
2
+ <ul>
3
+ <% @user.wishlists.each do |wl| %>
4
+ <% if !wl.is_private? || @user == current_user %>
5
+ <li><%= link_to wl.name, wl %></li>
6
+ <% end -%>
7
+ <% end -%>
8
+ </ul>
@@ -0,0 +1,4 @@
1
+ <%= form_for @wishlist, :html => {:class => 'ajax_form', :id => 'change_wishlist_accessibility'} do |f| %>
2
+ <%= f.radio_button :is_private, true %>&nbsp;<%= t(:private) %>
3
+ <%= f.radio_button :is_private, false %>&nbsp;<%= t(:public) %>
4
+ <% end -%>
@@ -0,0 +1,14 @@
1
+ <%= mail.recipient_name %>,
2
+
3
+ Please, take a look to my wishlist:
4
+
5
+ * <%= wishlist.name %>
6
+
7
+ <% unless mail.message.blank? -%>
8
+ <%= mail.message %>
9
+ <% end -%>
10
+
11
+ <%= mail.sender_name %>
12
+
13
+ Click the link below to view the <%= wishlist.name %> page.
14
+ <%= wishlist_url(wishlist) %>
@@ -0,0 +1,7 @@
1
+ <h1 class="row"><%= t(:editing_wishlist) %></h1>
2
+ <%= form_for @wishlist do |f| %>
3
+ <p><%= f.label :name, t(:name) %>:&nbsp;<%= f.text_field :name %></p>
4
+ <p><%= f.check_box :is_private %>&nbsp;<%= f.label :is_private, t(:is_private) %></p>
5
+ <p><%= f.check_box :is_default %>&nbsp;<%= f.label :is_default, t(:is_default) %></p>
6
+ <%= f.submit t(:update) %> <%= t(:or) %> <%= link_to t(:delete_wishlist), @wishlist, :method => :delete, :confirm => t(:are_you_sure_wishlist), :class => "button" %>
7
+ <% end -%>
@@ -0,0 +1,6 @@
1
+ <h1><%= t(:creating_wishlist) %></h1>
2
+ <%= form_for @wishlist do |f| %>
3
+ <p><%= f.label :name, t(:name) %>:&nbsp;<%= f.text_field :name %></p>
4
+ <p><%= f.check_box :is_private %>&nbsp;<%= f.label :is_private, t(:is_private) %></p>
5
+ <%= f.submit t(:create) %>
6
+ <% end -%>
@@ -0,0 +1,84 @@
1
+ <div id="wishlist_header" class="row">
2
+ <h1><%= @wishlist.name %></h1>
3
+ <% if @wishlist.user == current_user %>
4
+ <div id="manage_wishlist_links">
5
+ <%= link_to t(:edit_wishlist), edit_wishlist_path(@wishlist), :class => 'button' %>
6
+ </div>
7
+ <div><%= render :partial => 'accessibility' %></div>
8
+ <% end -%>
9
+ </div>
10
+ <table id="wishlist">
11
+ <thead>
12
+ <tr>
13
+ <% if @wishlist.user == current_user %>
14
+ <th><%= t(:wishlist_actions) %></th>
15
+ <% end -%>
16
+ <th><%= t(:item_view) %></th>
17
+ <th><%= t(:item_description) %></th>
18
+ <th><%= t(:availability) %></th>
19
+ <th><%= t(:date_added) %></th>
20
+ <th><%= t(:price) %></th>
21
+ </tr>
22
+ </thead>
23
+ <tbody id="line_items">
24
+ <% if @wishlist.wished_products.size > 0 %>
25
+ <% @wishlist.wished_products.each do |wish|
26
+ variant = wish.variant
27
+ product = variant.product %>
28
+ <tr class="<%= cycle('', 'alt') %>">
29
+ <% if @wishlist.user == current_user %>
30
+ <td>
31
+ <p><%= link_to t(:remove_from_wishlist), wish, :method => :delete, :class => 'button' %></p>
32
+ <%= form_for :order, :url => populate_orders_url do |f| %>
33
+ <%= hidden_field_tag "variants[#{variant.id}]", 1, :size => 3 %>
34
+ <%= link_to t(:add_to_cart), '#', :onclick => "$(this).parent().submit(); return false;", :class => "button" %>
35
+ <% end %>
36
+ <% if current_user.wishlists.count > 1 %>
37
+ <%= t(:move_to_another_wishlist) %>:
38
+ <%= form_for wish do |f| %>
39
+ <%= f.select :wishlist_id, current_user.wishlists.map{|wl| [wl.name, wl.id]} %>
40
+ <%= f.submit t(:move) %>
41
+ <% end %>
42
+ <% end %>
43
+ <br />
44
+ </td>
45
+ <% end -%>
46
+ <td>
47
+ <% if variant.images.length == 0 %>
48
+ <%= small_image(variant.product) %>
49
+ <% else %>
50
+ <%= image_tag variant.images.first.attachment.url(:small) %>
51
+ <% end %>
52
+ </td>
53
+ <td>
54
+ <h4><%= link_to product.name, product %></h4>
55
+ <p><%= variant_options variant %></p>
56
+ <%= truncate(product.description, :length => 100, :omission => "...") %>
57
+ </td>
58
+ <td>
59
+ <%= variant.in_stock? ? t(:in_stock) : t(:out_of_stock) %>
60
+ </td>
61
+ <td>
62
+ <%= wish.created_at.strftime "%m/%d/%Y" %>
63
+ </td>
64
+ <td>
65
+ <%= number_to_currency(variant.price) %>
66
+ </td>
67
+ </tr>
68
+ <% end -%>
69
+ <% else -%>
70
+ <tr>
71
+ <td colspan="6"><%= t(:your_wishlist_is_empty) %></td>
72
+ </tr>
73
+ <% end -%>
74
+ </tbody>
75
+ </table>
76
+ <div class="footer_links" data-hook="wishlist_footer_links">
77
+ <% if @wishlist.user == current_user %>
78
+ <%= link_to t(:create_new_wishlist), new_wishlist_path, :class => "button" %>
79
+ <% end -%>
80
+ <%= link_to t(:continue_shopping), products_path, :class => "button" %>
81
+ <% if respond_to?(:email_to_friend_url) %>
82
+ <%= link_to t('email_to_friend.send_to_friend'), email_to_friend_url('wishlist', @wishlist), :class => "button" %>
83
+ <% end %>
84
+ </div>
@@ -0,0 +1,26 @@
1
+ de:
2
+ add_to_wishlist: "Für die Wunschliste"
3
+ are_you_sure_wishlist: "Sind sie sicher, dass sie diese Wunschliste löschen wollen?"
4
+ availability: "Verfügbarkeit"
5
+ create_new_wishlist: "Neue Wunschliste erstellen"
6
+ creating_wishlist: "Wunschliste erstellen"
7
+ date_added: "Hinzugefügt am"
8
+ delete_wishlist: "Wunschliste löschen"
9
+ edit_wishlist: "Wunschliste ändern"
10
+ editing_wishlist: "Ändere Wunschliste"
11
+ in_stock: "Verfügbar"
12
+ is_default: "ist voreingstellt"
13
+ is_private: "ist privat"
14
+ item_view: "Bild"
15
+ move: "Verschieben"
16
+ move_to_another_wishlist: "Verschiebe in"
17
+ my_wishlists: "Meine Wuschlisten"
18
+ private_wishlist: "Private Wunschlisten"
19
+ private: "Privat"
20
+ public_wishlist: "Öffentliche Wunschlisten"
21
+ public: "Öffentlich"
22
+ remove_from_wishlist: "Von Wunschliste entfernen"
23
+ wishlist_actions: ""
24
+ your_wishlist_is_empty: "Deine Wunschliste ist leer"
25
+ update_quantity: "Ändere Menge"
26
+ item_added_to_wishlist: "Artikel wurde zur Wunschliste hinzugefügt"
@@ -0,0 +1,26 @@
1
+ en:
2
+ add_to_wishlist: "Add to wishlist"
3
+ are_you_sure_wishlist: "Are you sure that you want to delete this wishlist?"
4
+ availability: "Availability"
5
+ create_new_wishlist: "Create new wishlist"
6
+ creating_wishlist: "Creating wishlist"
7
+ date_added: "Date added"
8
+ delete_wishlist: "Delete wishlist"
9
+ edit_wishlist: "Edit wishlist"
10
+ editing_wishlist: "Editing wishlist"
11
+ in_stock: "In stock"
12
+ is_default: "is default"
13
+ is_private: "is private"
14
+ item_view: "View"
15
+ move: "Move"
16
+ move_to_another_wishlist: "Move to another wishlist"
17
+ my_wishlists: "My wishlists"
18
+ private_wishlist: "Private wishlist"
19
+ private: "Private"
20
+ public_wishlist: "Public wishlist"
21
+ public: "Public"
22
+ remove_from_wishlist: "Remove from wishlist"
23
+ wishlist_actions: "Actions"
24
+ your_wishlist_is_empty: "Your wishlist is empty"
25
+ update_quantity: "Update quantity"
26
+ item_added_to_wishlist: "Item added to wishlist"
@@ -0,0 +1,27 @@
1
+ ru:
2
+ add_to_wishlist: "Добавить в список желаний"
3
+ are_you_sure_wishlist: "Вы уверены, что хотите удалить этот список желаний?"
4
+ availability: "Доступность"
5
+ create_new_wishlist: "Создать ещё один"
6
+ creating_wishlist: "Создание списка желаний"
7
+ date_added: "Дата добавления"
8
+ delete_wishlist: "Удалить"
9
+ edit_wishlist: "Редактировать"
10
+ editing_wishlist: "Редактирование списка желаний"
11
+ in_stock: "Есть в наличии"
12
+ is_default: "по умолчанию"
13
+ is_private: "приватный"
14
+ item_view: "Миниатюра"
15
+ move: "Переместить"
16
+ move_to_another_wishlist: "Переместить в другой список"
17
+ my_wishlists: "Мои списки желаний"
18
+ private_wishlist: "Личный список желаний"
19
+ private: "Приватный"
20
+ public_wishlist: "Публичный список желаний"
21
+ public: "Публичный"
22
+ remove_from_wishlist: "Убрать из списка"
23
+ wishlist_actions: "Действия"
24
+ your_wishlist_is_empty: "Ваш список желаний пуст"
25
+ update_quantity: "Update quantity"
26
+ item_added_to_wishlist: "Item added to wishlist"
27
+ default_wishlist_name: "Мой список желаний"
@@ -0,0 +1,5 @@
1
+ Spree::Core::Engine.routes.append do
2
+ resources :wishlists
3
+ resources :wished_products, :only => [:create, :update, :destroy]
4
+ match '/wishlist' => "wishlists#show", :as => "default_wishlist"
5
+ end
@@ -0,0 +1,25 @@
1
+ 'WishlistsController':
2
+ permission1:
3
+ roles : [admin]
4
+ options :
5
+ for : [show]
6
+ unless : "can_read?"
7
+ permission2:
8
+ roles : [user]
9
+ options :
10
+ for : [new, create]
11
+ permission3:
12
+ roles : [admin]
13
+ options :
14
+ except : [show, new, create]
15
+ unless : "current_user and current_user.id == object.user_id"
16
+ 'WishedProductsController':
17
+ permission1:
18
+ roles : [user]
19
+ options :
20
+ for : [index, create]
21
+ permission2:
22
+ roles : [admin]
23
+ options :
24
+ for : [update, destroy]
25
+ unless : "current_user and current_user.id == object.wishlist.user_id"
@@ -0,0 +1,17 @@
1
+ class CreateWishlists < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :wishlists do |t|
4
+ t.references :user
5
+ t.string :name
6
+ t.string :access_hash
7
+ t.boolean :is_private, :default => true, :null => false
8
+ t.boolean :is_default, :default => false, :null => false
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ drop_table :wishlists
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ class CreateWishedProducts < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :wished_products do |t|
4
+ t.references :variant
5
+ t.references :wishlist
6
+ t.text :remark
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :wished_products
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ class PrefixWishlistTablesWithSpree < ActiveRecord::Migration
2
+ def change
3
+ rename_table :wishlists, :spree_wishlists
4
+ rename_table :wished_products, :spree_wished_products
5
+ end
6
+ end
@@ -0,0 +1,2 @@
1
+ # Use this file to load your own seed data from extensions.
2
+ # See the db/seeds.rb file in the Spree core for some ideas on what you can do here.
@@ -0,0 +1,27 @@
1
+ module SpreeWishlist
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ def add_javascripts
6
+ append_file "app/assets/javascripts/store/all.js", "//= require store/spree_wishlist\n"
7
+ end
8
+
9
+ def add_stylesheets
10
+ inject_into_file "app/assets/stylesheets/store/all.css", " *= require store/spree_wishlist\n", :before => /\*\//, :verbose => true
11
+ end
12
+
13
+ def add_migrations
14
+ run 'rake railties:install:migrations FROM=spree_wishlist'
15
+ end
16
+
17
+ def run_migrations
18
+ res = ask "Would you like to run the migrations now? [Y/n]"
19
+ if res == "" || res.downcase == "y"
20
+ run 'rake db:migrate'
21
+ else
22
+ puts "Skiping rake db:migrate, don't forget to run it!"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ require 'spree_core'
2
+ require 'spree_auth'
3
+ require 'spree_wishlist/engine'
@@ -0,0 +1,20 @@
1
+ module SpreeWishlist
2
+ class Engine < Rails::Engine
3
+ engine_name 'spree_wishlist'
4
+
5
+ config.autoload_paths += %W(#{config.root}/lib)
6
+
7
+ def self.activate
8
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/**/*_decorator*.rb")) do |c|
9
+ Rails.application.config.cache_classes ? require(c) : load(c)
10
+ end
11
+
12
+ #Dir.glob(File.join(File.dirname(__FILE__), "../app/overrides/**/*.rb")) do |c|
13
+ # Rails.application.config.cache_classes ? require(c) : load(c)
14
+ #end
15
+ Spree::Ability.register_ability(WishlistAbility)
16
+ end
17
+
18
+ config.to_prepare &method(:activate).to_proc
19
+ end
20
+ end
@@ -0,0 +1,35 @@
1
+ class WishlistAbility
2
+
3
+ # Stuff like class AbilityDecorator goes here.
4
+
5
+ include CanCan::Ability
6
+
7
+ def initialize(user)
8
+ # Anyone can create a wishlist
9
+ can :index, Spree::Wishlist do
10
+ !user.new_record?
11
+ end
12
+
13
+ can :create, Spree::Wishlist
14
+ # You can your own wishlists, and everyone cas see public ones
15
+ can :read, Spree::Wishlist do |wishlist|
16
+ wishlist.user == user || wishlist.is_public?
17
+ end
18
+ # You can only change your own wishlist
19
+ can [:read, :move, :update, :edit, :destroy], Spree::Wishlist do |wishlist|
20
+ wishlist.user == user
21
+ end
22
+
23
+ can :create, Spree::WishedProduct do |wished_product|
24
+ !user.new_record?
25
+ end
26
+
27
+ can :read, Spree::WishedProduct do |wished_product|
28
+ wished_product.wishlist.user == user || wished_product.wishlist.is_public?
29
+ end
30
+ can [:index, :update, :destroy], Spree::WishedProduct do |wished_product|
31
+ wished_product.wishlist.user == user
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Spree::WishedProductsController do
4
+
5
+ #Delete this example and add some real ones
6
+ it "should use Spree::WishedProductsController" do
7
+ controller.should be_an_instance_of(Spree::WishedProductsController)
8
+ end
9
+
10
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Spree::WishlistsController do
4
+
5
+ #Delete this example and add some real ones
6
+ it "should use Spree::WishlistsController" do
7
+ controller.should be_an_instance_of(Spree::WishlistsController)
8
+ end
9
+
10
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+ require 'cancan/matchers'
3
+
4
+ describe WishlistAbility do
5
+
6
+ let(:user) { Factory(:user) }
7
+ let(:ability) { WishlistAbility.new(Factory(:user)) }
8
+ let(:token) { nil }
9
+
10
+ TOKEN = "token123"
11
+
12
+ shared_examples_for "allow CRUD" do
13
+ it "should allow create" do
14
+ ability.should be_able_to(:create, resource, token)
15
+ end
16
+ it "should allow read" do
17
+ ability.should be_able_to(:read, resource, token)
18
+ end
19
+ it "should allow update" do
20
+ ability.should be_able_to(:update, resource, token)
21
+ end
22
+ it "should allow destroy" do
23
+ ability.should be_able_to(:destroy, resource, token)
24
+ end
25
+ end
26
+
27
+ shared_examples_for "access denied" do
28
+ it "should not allow read" do
29
+ ability.should_not be_able_to(:read, resource)
30
+ end
31
+ it "should not allow create" do
32
+ ability.should_not be_able_to(:create, resource)
33
+ end
34
+ it "should not allow update" do
35
+ ability.should_not be_able_to(:update, resource)
36
+ end
37
+ end
38
+
39
+ shared_examples_for "no index allowed" do
40
+ it "should not allow index" do
41
+ ability.should_not be_able_to(:index, resource)
42
+ end
43
+ end
44
+
45
+ shared_examples_for "create only" do
46
+ it "should allow create" do
47
+ ability.should be_able_to(:create, resource)
48
+ end
49
+ it "should not allow read" do
50
+ ability.should_not be_able_to(:read, resource)
51
+ end
52
+ it "should not allow update" do
53
+ ability.should_not be_able_to(:update, resource)
54
+ end
55
+ it "should not allow index" do
56
+ ability.should_not be_able_to(:index, resource)
57
+ end
58
+ end
59
+
60
+ shared_examples_for "read only" do
61
+ it "should not allow create" do
62
+ ability.should_not be_able_to(:create, resource)
63
+ end
64
+ it "should allow read" do
65
+ ability.should be_able_to(:read, resource)
66
+ end
67
+ it "should not allow update" do
68
+ ability.should_not be_able_to(:update, resource)
69
+ end
70
+ it "should allow index" do
71
+ ability.should be_able_to(:index, resource)
72
+ end
73
+ end
74
+
75
+ #context "for Wishedproduct" do
76
+ #end
77
+
78
+ #context "for Wishlist" do
79
+ #context "private" do
80
+ #let(:resource) { Spree::Wishlist.new(:is_private => true) }
81
+ #pending
82
+ #end
83
+
84
+ #context "public" do
85
+ #let(:resource) { Spree::Wishlist.new(:is_private => false) }
86
+ #context "requested by same user" do
87
+ #before { resource.user = user }
88
+ #pending
89
+ #it_should_behave_like "allow CRUD"
90
+ #end
91
+ #context "requested by other user" do
92
+ #pending
93
+ #end
94
+
95
+ #end
96
+ #end
97
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Spree::WishedProduct do
4
+ before(:each) do
5
+ @wished_product = Spree::WishedProduct.new
6
+ end
7
+
8
+ it "should be valid" do
9
+ @wished_product.should be_valid
10
+ end
11
+ end
@@ -0,0 +1,75 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Spree::Wishlist do
4
+ before(:each) do
5
+ @user = Factory(:user)
6
+ @wishlist = Spree::Wishlist.new(:user => @user, :name => "My Wishlist")
7
+ end
8
+
9
+ context "creating a new wishlist" do
10
+ it "is valid with valid attributes" do
11
+ @wishlist.should be_valid
12
+ end
13
+
14
+ it "is not valid without a name" do
15
+ @wishlist.name = nil
16
+ @wishlist.should_not be_valid
17
+ end
18
+ end
19
+
20
+ context "#include?" do
21
+ before(:each) do
22
+ @variant = Factory(:variant)
23
+ wished_product = Spree::WishedProduct.new(:variant => @variant)
24
+ @wishlist.wished_products << wished_product
25
+ @wishlist.save
26
+ end
27
+
28
+ it "should be true if the wishlist includes the specified variant" do
29
+ @wishlist.include?(@variant.id).should be_true
30
+ end
31
+ end
32
+
33
+ context "#to_param" do
34
+ it "should return the wishlist's access_hash" do
35
+ @wishlist.to_param.should == @wishlist.access_hash
36
+ end
37
+ end
38
+
39
+ context "#can_be_read_by?" do
40
+ context "when the wishlist is private" do
41
+ before(:each) do
42
+ @wishlist.is_private = true
43
+ end
44
+
45
+ it "is true when the user owns the wishlist" do
46
+ @wishlist.can_be_read_by?(@user).should be_true
47
+ end
48
+
49
+ it "is false when the user does not own the wishlist" do
50
+ other_user = Factory(:user)
51
+ @wishlist.can_be_read_by?(other_user).should be_false
52
+ end
53
+ end
54
+
55
+ context "when the wishlist is public" do
56
+ it "is true for any user" do
57
+ @wishlist.is_private = false
58
+ other_user = Factory(:user)
59
+ @wishlist.can_be_read_by?(other_user).should be_true
60
+ end
61
+ end
62
+ end
63
+
64
+ context "#is_public?" do
65
+ it "is true when the wishlist is public" do
66
+ @wishlist.is_private = false
67
+ @wishlist.is_public?.should be_true
68
+ end
69
+
70
+ it "is false when the wishlist is private" do
71
+ @wishlist.is_private = true
72
+ @wishlist.is_public?.should_not be_true
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,19 @@
1
+ # Configure Rails Environment
2
+ ENV["RAILS_ENV"] = "test"
3
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
4
+ require 'rspec/rails'
5
+
6
+ # Requires supporting ruby files with custom matchers and macros, etc,
7
+ # in spec/support/ and its subdirectories.
8
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
9
+
10
+ # Requires factories defined in spree_core
11
+ require 'spree/core/testing_support/factories'
12
+
13
+ RSpec.configure do |config|
14
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
15
+ # examples within a transaction, remove the following line or assign false
16
+ # instead of true.
17
+ config.use_transactional_fixtures = true
18
+ end
19
+
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ Gem::Specification.new do |s|
4
+ s.platform = Gem::Platform::RUBY
5
+ s.name = 'spree_wishlist'
6
+ s.version = '1.3'
7
+ s.summary = 'Add wishlists to Spree'
8
+ s.homepage = 'https://github.com/spree/spree_wishlist'
9
+ s.required_ruby_version = '>= 1.8.7'
10
+
11
+ s.author = 'John Dyer'
12
+ s.required_ruby_version = '>= 1.8.7'
13
+ s.rubygems_version = '1.3.6'
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency 'spree_core', '>= 1.0.0'
20
+ s.add_dependency 'spree_auth', '>= 1.0.0'
21
+
22
+ s.add_development_dependency 'factory_girl'
23
+ s.add_development_dependency 'rspec-rails', '~> 2.8.0.rc1'
24
+ s.add_development_dependency 'sqlite3'
25
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_wishlist
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.3'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John Dyer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: spree_core
16
+ requirement: &70114287756500 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70114287756500
25
+ - !ruby/object:Gem::Dependency
26
+ name: spree_auth
27
+ requirement: &70114287755900 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70114287755900
36
+ - !ruby/object:Gem::Dependency
37
+ name: factory_girl
38
+ requirement: &70114287755480 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70114287755480
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec-rails
49
+ requirement: &70114287770860 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.8.0.rc1
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70114287770860
58
+ - !ruby/object:Gem::Dependency
59
+ name: sqlite3
60
+ requirement: &70114287770100 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70114287770100
69
+ description:
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - .gitignore
76
+ - .rspec
77
+ - .travis.yml
78
+ - Gemfile
79
+ - LICENSE
80
+ - README.md
81
+ - Rakefile
82
+ - Versionfile
83
+ - app/assets/javascripts/store/spree_wishlist.js
84
+ - app/assets/stylesheets/store/spree_wishlist.css
85
+ - app/controllers/spree/wished_products_controller.rb
86
+ - app/controllers/spree/wishlists_controller.rb
87
+ - app/models/spree/user_decorator.rb
88
+ - app/models/spree/wished_product.rb
89
+ - app/models/spree/wishlist.rb
90
+ - app/overrides/add_wish_to_cart_form.rb
91
+ - app/overrides/add_wishlists_to_account_my_orders.rb
92
+ - app/views/spree/products/_wishlist_form.html.erb
93
+ - app/views/spree/users/_wishlists.html.erb
94
+ - app/views/spree/wishlists/_accessibility.html.erb
95
+ - app/views/spree/wishlists/_mail_to_friend.html.erb
96
+ - app/views/spree/wishlists/edit.html.erb
97
+ - app/views/spree/wishlists/new.html.erb
98
+ - app/views/spree/wishlists/show.html.erb
99
+ - app/views/spree/wishlists/update.js.erb
100
+ - config/locales/de.yml
101
+ - config/locales/en.yml
102
+ - config/locales/ru.yml
103
+ - config/routes.rb
104
+ - config/spree_permissions.yml
105
+ - db/migrate/20091020182940_create_wishlists.rb
106
+ - db/migrate/20091020183520_create_wished_products.rb
107
+ - db/migrate/20111130204731_prefix_wishlist_tables_with_spree.rb
108
+ - db/seeds.rb
109
+ - lib/generators/spree_wishlist/install/install_generator.rb
110
+ - lib/spree_wishlist.rb
111
+ - lib/spree_wishlist/engine.rb
112
+ - lib/wishlist_ability.rb
113
+ - spec/controllers/spree/wished_products_controller_spec.rb
114
+ - spec/controllers/spree/wishlists_controller_spec.rb
115
+ - spec/lib/wishlist_ability_spec.rb
116
+ - spec/models/spree/wished_product_spec.rb
117
+ - spec/models/spree/wishlist_spec.rb
118
+ - spec/spec_helper.rb
119
+ - spree_wishlist.gemspec
120
+ homepage: https://github.com/spree/spree_wishlist
121
+ licenses: []
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: 1.8.7
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ! '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 1.8.15
141
+ signing_key:
142
+ specification_version: 3
143
+ summary: Add wishlists to Spree
144
+ test_files:
145
+ - spec/controllers/spree/wished_products_controller_spec.rb
146
+ - spec/controllers/spree/wishlists_controller_spec.rb
147
+ - spec/lib/wishlist_ability_spec.rb
148
+ - spec/models/spree/wished_product_spec.rb
149
+ - spec/models/spree/wishlist_spec.rb
150
+ - spec/spec_helper.rb
151
+ has_rdoc: