piggybak_simple_variants 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/piggybak_simple_variants/piggybak_simple_variants-application.js +1 -0
- data/app/assets/javascripts/piggybak_simple_variants/piggybak_simple_variants.js +46 -0
- data/app/assets/stylesheets/piggybak_simple_variants/application.css +0 -0
- data/app/helpers/piggybak_simple_variants_helper.rb +17 -0
- data/app/models/piggybak_simple_variants/option.rb +9 -0
- data/app/models/piggybak_simple_variants/option_value.rb +14 -0
- data/app/models/piggybak_simple_variants/variant.rb +7 -0
- data/app/models/piggybak_simple_variants/variant_option.rb +6 -0
- data/app/views/piggybak_simple_variants/cart/_radio_buttons_form.html.erb +44 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20140511185627_create_piggybak_simple_variants_options.rb +9 -0
- data/db/migrate/20140511185729_create_piggybak_simple_variants_option_values.rb +10 -0
- data/db/migrate/20140511185906_create_piggybak_simple_variants_variants.rb +9 -0
- data/db/migrate/20140511193145_update_piggybak_sellables.rb +9 -0
- data/db/migrate/20140513200039_create_piggybak_simple_variants_variant_options.rb +15 -0
- data/lib/acts_as_sellable_with_simple_variants.rb +14 -0
- data/lib/piggybak_simple_variants.rb +5 -0
- data/lib/piggybak_simple_variants/engine.rb +118 -0
- data/lib/piggybak_simple_variants/version.rb +3 -0
- data/lib/tasks/piggybak_simple_variants_tasks.rake +4 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +54 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +83 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/fixtures/piggybak_simple_variants/option_configurations.yml +11 -0
- data/test/fixtures/piggybak_simple_variants/option_values.yml +11 -0
- data/test/fixtures/piggybak_simple_variants/options.yml +11 -0
- data/test/fixtures/piggybak_simple_variants/variants.yml +11 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/models/piggybak_simple_variants/option_configuration_test.rb +9 -0
- data/test/models/piggybak_simple_variants/option_test.rb +9 -0
- data/test/models/piggybak_simple_variants/option_value_test.rb +9 -0
- data/test/models/piggybak_simple_variants/variant_test.rb +9 -0
- data/test/piggybak_simple_variants_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- metadata +186 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'PiggybakSimpleVariants'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'lib'
|
28
|
+
t.libs << 'test'
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
task default: :test
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require piggybak_simple_variants/piggybak_simple_variants
|
@@ -0,0 +1,46 @@
|
|
1
|
+
var piggybak_simple_variants = {
|
2
|
+
refreshControls : function(data) {
|
3
|
+
if(data.all_selected) { // if all selected
|
4
|
+
var selected_key = data.selected.sort(function (a, b) { return a - b }).join('_');
|
5
|
+
console.log(selected_key);
|
6
|
+
if(simple_variant_map[selected_key]) {
|
7
|
+
$('.simple_variant_options form').show();
|
8
|
+
$('#sellable_id').val(simple_variant_map[selected_key].id);
|
9
|
+
$('#variant_price span').html(simple_variant_map[selected_key].price);
|
10
|
+
} else { // if variant not available
|
11
|
+
$('.simple_variant_options form').hide();
|
12
|
+
$('.unavailable').show();
|
13
|
+
}
|
14
|
+
} else { // if not all selected
|
15
|
+
$('.all_selected').show();
|
16
|
+
$('.simple_variant_options form').hide();
|
17
|
+
}
|
18
|
+
},
|
19
|
+
extractRadioButtonValues: function() {
|
20
|
+
var all_selected = true;
|
21
|
+
var selected = new Array();
|
22
|
+
$.each($('.option'), function(i, j) {
|
23
|
+
var option_id = $(j).attr('id');
|
24
|
+
if($('input[name=' + option_id + ']:checked').length) {
|
25
|
+
selected.push($('input[name=' + option_id + ']:checked').val());
|
26
|
+
} else {
|
27
|
+
all_selected = false;
|
28
|
+
}
|
29
|
+
});
|
30
|
+
return { all_selected: all_selected, selected: selected };
|
31
|
+
},
|
32
|
+
toggleVariantForm: function() {
|
33
|
+
$('.unavailable, .all_selected').hide();
|
34
|
+
var data;
|
35
|
+
data = piggybak_simple_variants.extractRadioButtonValues();
|
36
|
+
piggybak_simple_variants.refreshControls(data);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
$(function() {
|
41
|
+
$('.simple_variant_options input[type=radio]').click(function() { piggybak_simple_variants.toggleVariantForm(); });
|
42
|
+
if($('.simple_variant_options').size() > 0) {
|
43
|
+
piggybak_simple_variants.toggleVariantForm();
|
44
|
+
}
|
45
|
+
});
|
46
|
+
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module PiggybakSimpleVariantsHelper
|
2
|
+
def variant_cart_form(object, options = {:controls => 'radio_buttons'})
|
3
|
+
render "piggybak_simple_variants/cart/#{options[:controls]}_form", :object => object
|
4
|
+
end
|
5
|
+
|
6
|
+
def options_for_variant(variant)
|
7
|
+
PiggybakSimpleVariants::Option.select("DISTINCT piggybak_simple_variants_options.*").joins(:option_values => [:variant_options => :variant]).where("piggybak_simple_variants_variants.klass = '#{variant.klass}'")
|
8
|
+
end
|
9
|
+
|
10
|
+
def simple_variant_map(object)
|
11
|
+
map = {}
|
12
|
+
object.piggybak_sellable.each do |sellable|
|
13
|
+
map[sellable.variant.option_values.hash_ordered.map { |ov| ov.id }.join('_')] = { :id => sellable.id, :price => number_to_currency(sellable.price) }
|
14
|
+
end
|
15
|
+
map.to_json
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module PiggybakSimpleVariants
|
2
|
+
class Option < ActiveRecord::Base
|
3
|
+
has_many :option_values, -> { order(:position) }, :dependent => :destroy
|
4
|
+
|
5
|
+
default_scope { order('position ASC') }
|
6
|
+
|
7
|
+
accepts_nested_attributes_for :option_values, :allow_destroy => true
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module PiggybakSimpleVariants
|
2
|
+
class OptionValue < ActiveRecord::Base
|
3
|
+
has_many :variant_options
|
4
|
+
has_many :variants, through: :variant_options
|
5
|
+
belongs_to :option, :inverse_of => :option_values
|
6
|
+
|
7
|
+
def admin_label
|
8
|
+
"#{self.option.name}: #{self.name}"
|
9
|
+
end
|
10
|
+
|
11
|
+
scope :hash_ordered, -> { includes(:option).order("piggybak_simple_variants_options.position ASC, piggybak_simple_variants_option_values.position ASC") }
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
module PiggybakSimpleVariants
|
2
|
+
class Variant < ActiveRecord::Base
|
3
|
+
has_many :piggybak_sellables, class_name: "Piggybak::Sellable"
|
4
|
+
has_many :variant_options
|
5
|
+
has_many :option_values, through: :variant_options, class_name: "::PiggybakSimpleVariants::OptionValue"
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<div class="simple_variant_options">
|
2
|
+
<% if object.reflections.keys.include?(:piggybak_sellable) -%>
|
3
|
+
<% optionArray = Hash.new -%>
|
4
|
+
<% object.piggybak_sellable.each do |sellable| -%>
|
5
|
+
<% if sellable.active -%>
|
6
|
+
<% if sellable.quantity > 0 || sellable.unlimited_inventory -%>
|
7
|
+
<% sellable.variant.option_values.each do |option_value| -%>
|
8
|
+
<% if optionArray.empty? || optionArray[option_value.option].blank? -%>
|
9
|
+
<% optionArray[option_value.option] = [] -%>
|
10
|
+
<% optionArray[option_value.option] << option_value -%>
|
11
|
+
<% else -%>
|
12
|
+
<% if !optionArray[option_value.option].include? option_value -%>
|
13
|
+
<% optionArray[option_value.option] << option_value -%>
|
14
|
+
<% end -%>
|
15
|
+
<% end -%>
|
16
|
+
<% end -%>
|
17
|
+
<% end -%>
|
18
|
+
<% end -%>
|
19
|
+
<% end -%>
|
20
|
+
|
21
|
+
<script type="text/javascript">
|
22
|
+
var simple_variant_map = <%= raw simple_variant_map(object) %>;
|
23
|
+
</script>
|
24
|
+
|
25
|
+
<% optionArray.each do |option, option_values| -%>
|
26
|
+
<div class="option" id="option_<%= option.id %>">
|
27
|
+
<h4><%= option.name %></h4>
|
28
|
+
<% option_values.each do |option_value| -%>
|
29
|
+
<input type="radio" name="option_<%= option.id %>" value="<%= option_value.id %>" class="piggybak-cart-option" />
|
30
|
+
<%= option_value.name %><br />
|
31
|
+
<% end -%>
|
32
|
+
</div>
|
33
|
+
<% end -%>
|
34
|
+
<span class="all_selected">You must select an choice from each option.</span>
|
35
|
+
<span class="unavailable">This combination is not available.</span>
|
36
|
+
<%= form_tag piggybak.cart_add_url do -%>
|
37
|
+
<input type="hidden" id="sellable_id" name="sellable_id" />
|
38
|
+
<div id="variant_price">Price: <span></span></div>
|
39
|
+
<label for="quantity">Quantity</label>
|
40
|
+
<%= text_field_tag :quantity, 1 %>
|
41
|
+
<%= submit_tag "Add to Cart", :id => "submit" %>
|
42
|
+
<% end -%>
|
43
|
+
<% end -%>
|
44
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
class CreatePiggybakSimpleVariantsOptionValues < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :piggybak_simple_variants_option_values do |t|
|
4
|
+
t.integer :option_id, null: false
|
5
|
+
t.string :name, null: false
|
6
|
+
t.integer :position
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreatePiggybakSimpleVariantsVariantOptions < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
create_table :piggybak_simple_variants_variant_options do |t|
|
4
|
+
t.integer :variant_id, null: false
|
5
|
+
t.integer :option_value_id, null: false
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
add_index :piggybak_simple_variants_variant_options, :variant_id, :name => 'piggybak_sv_variant_options_option_value_id'
|
9
|
+
add_index :piggybak_simple_variants_variant_options, :option_value_id, :name => 'piggybak_sv_variant_options_option_value_id'
|
10
|
+
end
|
11
|
+
|
12
|
+
def down
|
13
|
+
drop_table :piggybak_simple_variants_variant_options
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Piggybak
|
2
|
+
module ActsAsSellableWithSimpleVariants
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def acts_as_sellable_with_simple_variants
|
7
|
+
has_many :piggybak_sellable, :as => "item", :class_name => "::Piggybak::Sellable", :inverse_of => :item
|
8
|
+
accepts_nested_attributes_for :piggybak_sellable, :allow_destroy => true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
::ActiveRecord::Base.send :include, Piggybak::ActsAsSellableWithSimpleVariants
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module PiggybakSimpleVariants
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace PiggybakSimpleVariants
|
4
|
+
|
5
|
+
config.to_prepare do
|
6
|
+
ApplicationController.class_eval do
|
7
|
+
helper :piggybak_simple_variants
|
8
|
+
end
|
9
|
+
RailsAdmin::ApplicationController.class_eval do
|
10
|
+
helper :piggybak_simple_variants
|
11
|
+
end
|
12
|
+
Piggybak::Sellable.class_eval do
|
13
|
+
belongs_to :variant, class_name: "PiggybakSimpleVariants::Variant"
|
14
|
+
def available?
|
15
|
+
if active && quantity > 0 || unlimited_inventory
|
16
|
+
true
|
17
|
+
else
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
config.before_initialize do
|
25
|
+
Piggybak.config do |config|
|
26
|
+
config.manage_classes += ["::PiggybakSimpleVariants::Option",
|
27
|
+
"::PiggybakSimpleVariants::Variant",
|
28
|
+
"::PiggybakSimpleVariants::VariantOption",
|
29
|
+
"::PiggybakSimpleVariants::OptionValue"]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
initializer "piggybak_simple_variants.assets.precompile" do |app|
|
34
|
+
app.config.assets.precompile += ['piggybak_simple_variants/piggybak_simple_variants-application.js']
|
35
|
+
end
|
36
|
+
|
37
|
+
# TODO: Figure out of we can have this only in to_prepare or here
|
38
|
+
initializer "piggybak_simple_variants.add_helper" do |app|
|
39
|
+
ApplicationController.class_eval do
|
40
|
+
helper :piggybak_simple_variants
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
initializer "piggybak.rails_admin_config" do |app|
|
45
|
+
RailsAdmin.config do |config|
|
46
|
+
config.model PiggybakSimpleVariants::OptionValue do
|
47
|
+
visible false
|
48
|
+
edit do
|
49
|
+
field :name
|
50
|
+
field :position
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
config.model PiggybakSimpleVariants::Option do
|
55
|
+
navigation_label "Extensions"
|
56
|
+
list do
|
57
|
+
field :name
|
58
|
+
field :position
|
59
|
+
field :option_values
|
60
|
+
end
|
61
|
+
edit do
|
62
|
+
field :name
|
63
|
+
field :position
|
64
|
+
field :option_values do
|
65
|
+
active true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
config.model PiggybakSimpleVariants::Variant do
|
71
|
+
label "Define variants"
|
72
|
+
show do
|
73
|
+
field :name do
|
74
|
+
visible true
|
75
|
+
end
|
76
|
+
field :klass
|
77
|
+
field :option_values do
|
78
|
+
visible true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
edit do
|
82
|
+
field :name do
|
83
|
+
active true
|
84
|
+
end
|
85
|
+
field :klass do
|
86
|
+
visible :true
|
87
|
+
help "Add the name of your class for this variant."
|
88
|
+
end
|
89
|
+
field :option_values do
|
90
|
+
visible true
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
config.model PiggybakSimpleVariants::VariantOption do
|
96
|
+
label "Options for variants"
|
97
|
+
visible false
|
98
|
+
end
|
99
|
+
|
100
|
+
config.model Piggybak::Sellable do
|
101
|
+
label "Sellable"
|
102
|
+
visible false
|
103
|
+
edit do
|
104
|
+
field :sku
|
105
|
+
field :description
|
106
|
+
field :price
|
107
|
+
field :active
|
108
|
+
field :quantity
|
109
|
+
field :unlimited_inventory do
|
110
|
+
help "If true, backorders on this variant will be allowed, regardless of quantity on hand."
|
111
|
+
end
|
112
|
+
field :variant
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|