spree_size_chart 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/.gitignore +14 -0
  2. data/Gemfile +9 -0
  3. data/LICENSE +26 -0
  4. data/README.md +77 -0
  5. data/Rakefile +29 -0
  6. data/Versionfile +11 -0
  7. data/app/assets/javascripts/admin/spree_size_chart.js +1 -0
  8. data/app/assets/javascripts/spree/admin/size_charts.js +2 -0
  9. data/app/assets/javascripts/spree/admin/size_types.js +2 -0
  10. data/app/assets/javascripts/store/spree_size_chart.js +1 -0
  11. data/app/assets/stylesheets/admin/spree_size_chart.css +3 -0
  12. data/app/assets/stylesheets/spree/admin/size_charts.css.scss +3 -0
  13. data/app/assets/stylesheets/spree/admin/size_types.css.scss +3 -0
  14. data/app/assets/stylesheets/store/spree_size_chart.css +16 -0
  15. data/app/controllers/spree/admin/size_charts_controller.rb +24 -0
  16. data/app/controllers/spree/admin/size_types_controller.rb +12 -0
  17. data/app/helpers/spree/admin/size_charts_helper.rb +2 -0
  18. data/app/helpers/spree/admin/size_types_helper.rb +2 -0
  19. data/app/models/spree.rb +5 -0
  20. data/app/models/spree/product_decorator.rb +3 -0
  21. data/app/models/spree/size_chart.rb +72 -0
  22. data/app/models/spree/size_type.rb +11 -0
  23. data/app/models/spree/size_value.rb +7 -0
  24. data/app/overrides/add_product_tab.rb +6 -0
  25. data/app/overrides/add_to_show_product.rb +4 -0
  26. data/app/overrides/admin_configuration.rb +18 -0
  27. data/app/views/spree/admin/size_charts/_form.html.erb +28 -0
  28. data/app/views/spree/admin/size_charts/edit.html.erb +24 -0
  29. data/app/views/spree/admin/size_types/_form.html.erb +4 -0
  30. data/app/views/spree/admin/size_types/edit.html.erb +10 -0
  31. data/app/views/spree/admin/size_types/index.html.erb +30 -0
  32. data/app/views/spree/admin/size_types/new.html.erb +10 -0
  33. data/app/views/spree/shared/_size_chart.html.erb +31 -0
  34. data/config/locales/en.yml +6 -0
  35. data/config/routes.rb +9 -0
  36. data/db/migrate/20120416191149_create_spree_size_charts.rb +11 -0
  37. data/db/migrate/20120416191216_create_spree_size_types.rb +15 -0
  38. data/db/migrate/20120416191257_create_spree_size_values.rb +12 -0
  39. data/db/migrate/20120421093828_add_unit_to_spree_size_charts.rb +5 -0
  40. data/lib/generators/spree_size_chart/install/install_generator.rb +29 -0
  41. data/lib/spree_size_chart.rb +2 -0
  42. data/lib/spree_size_chart/engine.rb +20 -0
  43. data/lib/spree_size_chart/version.rb +3 -0
  44. data/script/rails +5 -0
  45. data/spec/controllers/spree/admin/size_charts_controller_spec.rb +5 -0
  46. data/spec/controllers/spree/admin/size_types_controller_spec.rb +5 -0
  47. data/spec/factories.rb +15 -0
  48. data/spec/helpers/spree/admin/size_charts_helper_spec.rb +15 -0
  49. data/spec/helpers/spree/admin/size_types_helper_spec.rb +15 -0
  50. data/spec/models/spree/size_chart_spec.rb +78 -0
  51. data/spec/models/spree/size_type_spec.rb +5 -0
  52. data/spec/models/spree/size_value_spec.rb +5 -0
  53. data/spec/requests/spree_size_chart_spec.rb +69 -0
  54. data/spec/spec_helper.rb +36 -0
  55. data/spec/support/shared_connection.rb +12 -0
  56. data/spec/support/url_helpers.rb +7 -0
  57. data/spree_size_chart.gemspec +32 -0
  58. metadata +215 -0
@@ -0,0 +1,24 @@
1
+ <%= render :partial => 'spree/admin/shared/product_sub_menu' %>
2
+
3
+ <%= render :partial => 'spree/admin/shared/product_tabs', :locals => { :current => 'Size Chart' } %>
4
+
5
+ <h1><%= t(:edit_size_chart) %></h1>
6
+
7
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @size_chart } %>
8
+ <% size_type_ids = @size_chart.size_type_ids %>
9
+
10
+ <%= form_for @size_chart, :url => admin_product_size_chart_path(@product), :method => :put do |f| %>
11
+ <%= f.label :option_type_id, t(:option_type_id) %>
12
+ <%= f.select :option_type_id, Spree::OptionType.select("id, name").map {|opt| [opt.name, opt.id] }, { :include_blank => true } %>
13
+
14
+ <% Spree::SizeType.all.each do |type| %>
15
+ <label><%= type.name %>
16
+ <%= check_box_tag "size_chart[size_type_ids][]", type.id, size_type_ids.include?(type.id) %>
17
+ </label>
18
+ <% end %>
19
+
20
+ <%= f.select :unit, Spree::SizeChart::UNITS, :include_blank => true %>
21
+
22
+ <%= render :partial => 'form', :locals => { :form => f } %>
23
+ <%= render :partial => 'spree/admin/shared/new_resource_links' %>
24
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <%= form.field_container :name do %>
2
+ <%= form.label :name, t(:size_type_name) %>
3
+ <%= form.text_field :name %>
4
+ <% end %>
@@ -0,0 +1,10 @@
1
+ <%= render :partial => 'spree/admin/shared/configuration_menu' %>
2
+
3
+ <h1><%= t(:new_size_type) %></h1>
4
+
5
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @size_type } %>
6
+
7
+ <%= form_for [:admin, @size_type] do |type_form| %>
8
+ <%= render :partial => 'form', :locals => { :form => type_form } %>
9
+ <%= render :partial => 'spree/admin/shared/new_resource_links' %>
10
+ <% end %>
@@ -0,0 +1,30 @@
1
+ <%= render :partial => 'spree/admin/shared/configuration_menu' %>
2
+
3
+ <div class='toolbar'>
4
+ <ul class='actions'>
5
+ <li>
6
+ <%= button_link_to t("new_size_type"), new_object_url, :icon => 'add' %>
7
+ </li>
8
+ </ul>
9
+ <br class='clear' />
10
+ </div>
11
+
12
+ <h1><%= t("size_types") %></h1>
13
+
14
+ <table class="index">
15
+ <thead data-hook="admin_size_types_index_headers">
16
+ <th><%= t("size_type_name") %></th>
17
+ <th data-hook="admin_social_methods_index_header_actions">&nbsp;</th>
18
+ </thead>
19
+ <tbody>
20
+ <% @size_types.each do |size|%>
21
+ <tr id="<%= dom_id size %>" data-hook="admin_trackers_index_rows">
22
+ <td><%= size.name %></td>
23
+ <td>
24
+ <%= link_to_edit size %> &nbsp;
25
+ <%= link_to_delete size %>
26
+ </td>
27
+ </tr>
28
+ <% end %>
29
+ </tbody>
30
+ </table>
@@ -0,0 +1,10 @@
1
+ <%= render :partial => 'spree/admin/shared/configuration_menu' %>
2
+
3
+ <h1><%= t(:new_size_type) %></h1>
4
+
5
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @size_type } %>
6
+
7
+ <%= form_for [:admin, @size_type] do |type_form| %>
8
+ <%= render :partial => 'form', :locals => { :form => type_form } %>
9
+ <%= render :partial => 'spree/admin/shared/new_resource_links' %>
10
+ <% end %>
@@ -0,0 +1,31 @@
1
+ <% @size_chart = @product.size_chart %>
2
+ <% if @size_chart and !@size_chart.size_values.empty? %>
3
+ <div id="product-size-chart" data-hook="product_size_chart">
4
+ <table>
5
+ <% @i = 0 %>
6
+ <% @size_type_count = @size_chart.size_types.count %>
7
+ <thead>
8
+ <tr>
9
+ <th><%= @size_chart.option_type_with_unit -%></th>
10
+ <% @size_chart.size_types.each do |type| %>
11
+ <th><%= type.name -%></th>
12
+ <% end %>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <% @size_chart.find_size_values.each do |size_value| %>
17
+ <% if @i == 0 %>
18
+ <%= "<tr>".html_safe %>
19
+ <th><%= @size_chart.option_values.find(size_value.option_value_id).name -%></th>
20
+ <% end %>
21
+ <td>
22
+ <%= number_with_precision(size_value.value, :strip_insignificant_zeros => true, :locale => :en) %>
23
+ </td>
24
+ <%= "</tr>".html_safe if @i == @size_type_count - 1 %>
25
+ <% @i += 1 %>
26
+ <% @i = 0 if @i == @size_type_count %>
27
+ <% end %>
28
+ </tbody>
29
+ </table>
30
+ </div>
31
+ <% end %>
@@ -0,0 +1,6 @@
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
+ hello: "Hello world"
6
+ size_chart: Size Chart
data/config/routes.rb ADDED
@@ -0,0 +1,9 @@
1
+ Spree::Core::Engine.routes.append do
2
+ namespace :admin do
3
+ resources :products do
4
+ resource :size_chart
5
+ end
6
+
7
+ resources :size_types
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class CreateSpreeSizeCharts < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_size_charts do |t|
4
+ t.string :name
5
+ t.references :product
6
+ t.references :option_type
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ class CreateSpreeSizeTypes < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_size_types do |t|
4
+ t.string :name
5
+
6
+ t.timestamps
7
+ end
8
+
9
+ create_table :spree_size_charts_size_types do |t|
10
+ t.references :size_chart
11
+ t.references :size_type
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ class CreateSpreeSizeValues < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_size_values do |t|
4
+ t.decimal :value, :precision => 8, :scale => 2
5
+
6
+ t.references :option_value
7
+ t.references :size_type
8
+ t.references :size_chart
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ class AddUnitToSpreeSizeCharts < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_size_charts, :unit, :string
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+ module SpreeSizeChart
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_size_chart\n"
7
+ append_file "app/assets/javascripts/admin/all.js", "//= require admin/spree_size_chart\n"
8
+ end
9
+
10
+ def add_stylesheets
11
+ inject_into_file "app/assets/stylesheets/store/all.css", " *= require store/spree_size_chart\n", :before => /\*\//, :verbose => true
12
+ inject_into_file "app/assets/stylesheets/admin/all.css", " *= require admin/spree_size_chart\n", :before => /\*\//, :verbose => true
13
+ end
14
+
15
+ def add_migrations
16
+ run 'bundle exec rake railties:install:migrations FROM=spree_size_chart'
17
+ end
18
+
19
+ def run_migrations
20
+ res = ask "Would you like to run the migrations now? [Y/n]"
21
+ if res == "" || res.downcase == "y"
22
+ run 'bundle exec rake db:migrate'
23
+ else
24
+ puts "Skiping rake db:migrate, don't forget to run it!"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,2 @@
1
+ require 'spree_core'
2
+ require 'spree_size_chart/engine'
@@ -0,0 +1,20 @@
1
+ module SpreeSizeChart
2
+ class Engine < Rails::Engine
3
+ engine_name 'spree_size_chart'
4
+
5
+ config.autoload_paths += %W(#{config.root}/lib)
6
+
7
+ # use rspec for tests
8
+ config.generators do |g|
9
+ g.test_framework :rspec
10
+ end
11
+
12
+ def self.activate
13
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/**/*_decorator*.rb")) do |c|
14
+ Rails.configuration.cache_classes ? require(c) : load(c)
15
+ end
16
+ end
17
+
18
+ config.to_prepare &method(:activate).to_proc
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module SpreeSizeChart
2
+ VERSION = "1.0.0"
3
+ end
data/script/rails ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ ENGINE_PATH = File.expand_path('../..', __FILE__)
5
+ load File.expand_path('../../spec/dummy/script/rails', __FILE__)
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Admin::SizeChartsController do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Admin::SizeTypesController do
4
+
5
+ end
data/spec/factories.rb ADDED
@@ -0,0 +1,15 @@
1
+ Factory.define :size_type, :class => Spree::SizeType do |t|
2
+ t.name "Chest"
3
+ end
4
+
5
+ Factory.define :size_chart, :class => Spree::SizeChart do |t|
6
+ t.association(:product)
7
+ t.association(:option_type)
8
+ end
9
+
10
+ Factory.define :size_value, :class => Spree::SizeValue do |t|
11
+ t.value 74
12
+ t.association(:option_value)
13
+ t.association(:size_type)
14
+ t.association(:size_chart)
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ # Specs in this file have access to a helper object that includes
4
+ # the Spree::Admin::SizeChartsHelper. For example:
5
+ #
6
+ # describe Spree::Admin::SizeChartsHelper do
7
+ # describe "string concat" do
8
+ # it "concats two strings with spaces" do
9
+ # helper.concat_strings("this","that").should == "this that"
10
+ # end
11
+ # end
12
+ # end
13
+ describe Spree::Admin::SizeChartsHelper do
14
+ pending "add some examples to (or delete) #{__FILE__}"
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ # Specs in this file have access to a helper object that includes
4
+ # the Spree::Admin::SizeTypesHelper. For example:
5
+ #
6
+ # describe Spree::Admin::SizeTypesHelper do
7
+ # describe "string concat" do
8
+ # it "concats two strings with spaces" do
9
+ # helper.concat_strings("this","that").should == "this that"
10
+ # end
11
+ # end
12
+ # end
13
+ describe Spree::Admin::SizeTypesHelper do
14
+ pending "add some examples to (or delete) #{__FILE__}"
15
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::SizeChart do
4
+ before do
5
+ @option_type = Factory(:option_type, :name => "Size")
6
+ @option_value1 = Factory(:option_value, :name => "M", :option_type => @option_type)
7
+ @option_value2 = Factory(:option_value, :name => "L", :option_type => @option_type)
8
+ @option_value3 = Factory(:option_value, :name => "XL", :option_type => @option_type)
9
+
10
+ @product = Factory(:product)
11
+ @size_chart = Factory(:size_chart, :option_type => @option_type, :product => @product)
12
+ @size_chart.size_types << @size_type1 = Factory(:size_type, :name => "Chest")
13
+ @size_chart.size_types << @size_type2 = Factory(:size_type, :name => "Sleeves")
14
+ end
15
+
16
+ describe "#find_or_initialize_size_types" do
17
+
18
+ it "initialize all size_values when no existing records" do
19
+ @size_chart.find_or_initialize_size_values.count.should == 6
20
+ @size_chart.find_or_initialize_size_values.all?(&:new_record?).should be_true
21
+ end
22
+
23
+ it "finds existing record and initialize size value left" do
24
+ @size_value1 = Factory(:size_value, :option_value => @option_value1, :size_chart => @size_chart, :size_type => @size_type1)
25
+ @size_value2 = Factory(:size_value, :option_value => @option_value1, :size_chart => @size_chart, :size_type => @size_type2)
26
+
27
+ @size_chart.find_or_initialize_size_values.count.should == 6
28
+ @size_chart.find_or_initialize_size_values.all?(&:new_record?).should be_false
29
+ @size_chart.find_or_initialize_size_values.should include(@size_value1, @size_value2)
30
+ end
31
+
32
+ end
33
+
34
+ describe "#hash_size_values" do
35
+ before do
36
+ @size_value1 = Factory(:size_value, :option_value => @option_value1, :size_chart => @size_chart, :size_type => @size_type1)
37
+ @size_value2 = Factory(:size_value, :option_value => @option_value1, :size_chart => @size_chart, :size_type => @size_type2)
38
+ @size_value3 = Factory(:size_value, :option_value => @option_value3, :size_chart => @size_chart, :size_type => @size_type2)
39
+ end
40
+
41
+ it "returns hash with option_value_id as first key and size_type_id as second key" do
42
+ @size_chart.hash_size_values.should == {@option_value1.id => {@size_type1.id => @size_value1, @size_type2.id => @size_value2}, @option_value3.id => {@size_type2.id => @size_value3}}
43
+ end
44
+ end
45
+
46
+ describe "#find_size_values" do
47
+ before do
48
+ @variant = Factory(:variant, :product => @product)
49
+ @variant.option_values << @option_value3
50
+ @size_value3 = Factory(:size_value, :option_value => @option_value3, :size_chart => @size_chart, :size_type => @size_type2)
51
+ end
52
+
53
+ it "returns only if product variants has option_value" do
54
+ @size_chart.find_size_values.count.should == 1
55
+ @size_chart.find_size_values.first.should == @size_value3
56
+ end
57
+ end
58
+
59
+ describe "size_values_attributes=" do
60
+ before do
61
+ @size_value1 = Factory(:size_value, :option_value => @option_value1, :size_chart => @size_chart, :size_type => @size_type1)
62
+ @size_value2 = Factory(:size_value, :option_value => @option_value1, :size_chart => @size_chart, :size_type => @size_type2)
63
+ @size_value3 = Factory(:size_value, :option_value => @option_value3, :size_chart => @size_chart, :size_type => @size_type2)
64
+ end
65
+
66
+ it "should destroy existing record if value is blank" do
67
+ @size_chart.update_attributes :size_values_attributes => {"0"=>{"id" => @size_value1.id, "size_type_id"=> @size_type1.id, "option_value_id"=> @size_type1.id, "value"=>"" }, "1"=>{"id" => @size_value2.id, "size_type_id"=> @size_type2.id, "option_value_id"=> @option_value1.id, "value"=>"123" }}
68
+ @size_chart.size_values.count.should == 2
69
+ @size_chart.size_values.should =~ [@size_value2, @size_value3]
70
+ end
71
+
72
+ it "should destroy existing record if value is blank" do
73
+ @size_chart.update_attributes :size_values_attributes => {"0"=>{"size_type_id"=> @size_type1.id, "option_value_id"=> @option_value2.id, "value"=>"" }}
74
+ @size_chart.size_values.count.should == 3
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::SizeType do
4
+ pending "add some examples to (or delete) #{__FILE__}"
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::SizeValue do
4
+ pending "add some examples to (or delete) #{__FILE__}"
5
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ feature "spree size chart" do
4
+ before do
5
+ @option_type = Factory(:option_type, :name => "Size")
6
+ @option_value1 = Factory(:option_value, :name => "M", :option_type => @option_type)
7
+ @option_value2 = Factory(:option_value, :name => "L", :option_type => @option_type)
8
+ @option_value3 = Factory(:option_value, :name => "XL", :option_type => @option_type)
9
+ @size_type1 = Factory(:size_type, :name => "Chest")
10
+ @size_type2 = Factory(:size_type, :name => "Sleeves")
11
+ @product = Factory(:product)
12
+ end
13
+
14
+ def fill_size_chart
15
+ fill_in "size_chart_size_values_attributes_0_value", :with => 50
16
+ fill_in "size_chart_size_values_attributes_1_value", :with => 70
17
+
18
+ fill_in "size_chart_size_values_attributes_2_value", :with => 54
19
+ fill_in "size_chart_size_values_attributes_3_value", :with => 76
20
+
21
+ fill_in "size_chart_size_values_attributes_4_value", :with => 56
22
+ fill_in "size_chart_size_values_attributes_5_value", :with => 78
23
+ end
24
+
25
+ scenario "create size chart" do
26
+ visit spree.edit_admin_product_path(@product)
27
+ click_link "Size Chart"
28
+ select "Size", :from => "Option Type"
29
+ check "Chest"
30
+ check "Sleeves"
31
+ click_button "Create"
32
+
33
+ fill_size_chart
34
+ click_button "Create"
35
+
36
+ visit spree.product_path(@product)
37
+ page.should have_content "50"
38
+ page.should have_content "70"
39
+ end
40
+
41
+ scenario "update size chart" do
42
+ visit spree.edit_admin_product_path(@product)
43
+ click_link "Size Chart"
44
+ select "Size", :from => "Option Type"
45
+ check "Chest"
46
+ check "Sleeves"
47
+ click_button "Create"
48
+
49
+ fill_size_chart
50
+ click_button "Create"
51
+
52
+ fill_in "size_chart_size_values_attributes_0_value", :with => 52
53
+ uncheck "Sleeves"
54
+
55
+ click_button "Create"
56
+
57
+ visit spree.product_path(@product)
58
+ # should have chest size
59
+ page.should have_content "52"
60
+ page.should have_content "54"
61
+ page.should have_content "56"
62
+
63
+ # should not have sleeves size
64
+ page.should_not have_content "70"
65
+ page.should_not have_content "76"
66
+ page.should_not have_content "78"
67
+ end
68
+
69
+ end