spree_size_chart 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +14 -0
- data/Gemfile +9 -0
- data/LICENSE +26 -0
- data/README.md +77 -0
- data/Rakefile +29 -0
- data/Versionfile +11 -0
- data/app/assets/javascripts/admin/spree_size_chart.js +1 -0
- data/app/assets/javascripts/spree/admin/size_charts.js +2 -0
- data/app/assets/javascripts/spree/admin/size_types.js +2 -0
- data/app/assets/javascripts/store/spree_size_chart.js +1 -0
- data/app/assets/stylesheets/admin/spree_size_chart.css +3 -0
- data/app/assets/stylesheets/spree/admin/size_charts.css.scss +3 -0
- data/app/assets/stylesheets/spree/admin/size_types.css.scss +3 -0
- data/app/assets/stylesheets/store/spree_size_chart.css +16 -0
- data/app/controllers/spree/admin/size_charts_controller.rb +24 -0
- data/app/controllers/spree/admin/size_types_controller.rb +12 -0
- data/app/helpers/spree/admin/size_charts_helper.rb +2 -0
- data/app/helpers/spree/admin/size_types_helper.rb +2 -0
- data/app/models/spree.rb +5 -0
- data/app/models/spree/product_decorator.rb +3 -0
- data/app/models/spree/size_chart.rb +72 -0
- data/app/models/spree/size_type.rb +11 -0
- data/app/models/spree/size_value.rb +7 -0
- data/app/overrides/add_product_tab.rb +6 -0
- data/app/overrides/add_to_show_product.rb +4 -0
- data/app/overrides/admin_configuration.rb +18 -0
- data/app/views/spree/admin/size_charts/_form.html.erb +28 -0
- data/app/views/spree/admin/size_charts/edit.html.erb +24 -0
- data/app/views/spree/admin/size_types/_form.html.erb +4 -0
- data/app/views/spree/admin/size_types/edit.html.erb +10 -0
- data/app/views/spree/admin/size_types/index.html.erb +30 -0
- data/app/views/spree/admin/size_types/new.html.erb +10 -0
- data/app/views/spree/shared/_size_chart.html.erb +31 -0
- data/config/locales/en.yml +6 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20120416191149_create_spree_size_charts.rb +11 -0
- data/db/migrate/20120416191216_create_spree_size_types.rb +15 -0
- data/db/migrate/20120416191257_create_spree_size_values.rb +12 -0
- data/db/migrate/20120421093828_add_unit_to_spree_size_charts.rb +5 -0
- data/lib/generators/spree_size_chart/install/install_generator.rb +29 -0
- data/lib/spree_size_chart.rb +2 -0
- data/lib/spree_size_chart/engine.rb +20 -0
- data/lib/spree_size_chart/version.rb +3 -0
- data/script/rails +5 -0
- data/spec/controllers/spree/admin/size_charts_controller_spec.rb +5 -0
- data/spec/controllers/spree/admin/size_types_controller_spec.rb +5 -0
- data/spec/factories.rb +15 -0
- data/spec/helpers/spree/admin/size_charts_helper_spec.rb +15 -0
- data/spec/helpers/spree/admin/size_types_helper_spec.rb +15 -0
- data/spec/models/spree/size_chart_spec.rb +78 -0
- data/spec/models/spree/size_type_spec.rb +5 -0
- data/spec/models/spree/size_value_spec.rb +5 -0
- data/spec/requests/spree_size_chart_spec.rb +69 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/shared_connection.rb +12 -0
- data/spec/support/url_helpers.rb +7 -0
- data/spree_size_chart.gemspec +32 -0
- 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,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"> </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 %>
|
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 %>
|
data/config/routes.rb
ADDED
@@ -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,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,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
|
data/script/rails
ADDED
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,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
|