piggybak 0.3.0 → 0.3.1
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/README.md +4 -74
- data/VERSION +1 -1
- data/app/assets/javascripts/piggybak.js +7 -2
- data/app/assets/javascripts/piggybak.states.js +4 -1
- data/app/controllers/piggybak/orders_controller.rb +11 -22
- data/app/helpers/piggybak_helper.rb +5 -0
- data/app/models/piggybak/address.rb +5 -1
- data/app/models/piggybak/order.rb +27 -7
- data/app/models/piggybak/payment.rb +3 -2
- data/app/views/piggybak/orders/_google_analytics.html.erb +23 -0
- data/app/views/piggybak/orders/show.html.erb +5 -0
- data/app/views/rails_admin/main/_form_nested_no_destroy.html.haml +10 -2
- data/db/migrate/20120111195534_drop_cc_fields.rb +11 -0
- data/piggybak.gemspec +4 -2
- metadata +5 -3
data/README.md
CHANGED
@@ -11,28 +11,6 @@ Modular / mountable ecommerce gem. Features:
|
|
11
11
|
|
12
12
|
* Fully defined backend RailsAdmin interface for adding orders on the backend
|
13
13
|
|
14
|
-
This engine explicitly excludes:
|
15
|
-
|
16
|
-
* SSL configuration (to be handled in your parent application)
|
17
|
-
|
18
|
-
* Redirects on login / logout (see recipe below)
|
19
|
-
|
20
|
-
* Coupons and Gift cerficates (May be added later)
|
21
|
-
|
22
|
-
* Per unit inventory tracking
|
23
|
-
|
24
|
-
* Downloadable products
|
25
|
-
|
26
|
-
This engine is highly dependent on:
|
27
|
-
|
28
|
-
* Rails 3.1 (Assets, Engines)
|
29
|
-
|
30
|
-
* RailsAdmin (Admin UI)
|
31
|
-
|
32
|
-
* Devise (User Authentication)
|
33
|
-
|
34
|
-
* CanCan (User Authorization)
|
35
|
-
|
36
14
|
Installation
|
37
15
|
========
|
38
16
|
|
@@ -52,62 +30,14 @@ Installation
|
|
52
30
|
|
53
31
|
mount Piggybak::Engine => '/checkout', :as => 'piggybak'" to config/routes
|
54
32
|
|
55
|
-
|
33
|
+
More Details
|
56
34
|
========
|
57
35
|
|
58
|
-
|
59
|
-
* Add acts_as_orderer to user model (or model that devise hooks into as authenticated user)
|
60
|
-
* Add <%= cart_form(@some_item) %> to view to display cart form
|
61
|
-
* Add <%= cart_link %> to display link to cart
|
62
|
-
* Add <%= orders_link %> to display link to user orders
|
63
|
-
|
64
|
-
Recipes
|
65
|
-
========
|
66
|
-
|
67
|
-
* Redirect after login / logout
|
68
|
-
|
69
|
-
before_filter :set_last_page
|
70
|
-
def set_last_page
|
71
|
-
if !request.xhr? && !request.url.match(/users\/sign_in/) && !request.url.match(/users\/sign_out/)
|
72
|
-
session[:return_to] = request.url
|
73
|
-
end
|
74
|
-
end
|
75
|
-
def after_sign_in_path_for(resource_or_scope)
|
76
|
-
session[:return_to] || root_url
|
77
|
-
end
|
78
|
-
def after_sign_out_path_for(resource_or_scope)
|
79
|
-
session[:return_to] || root_url
|
80
|
-
end
|
81
|
-
|
82
|
-
* Cancan access control
|
83
|
-
|
84
|
-
class Ability
|
85
|
-
include CanCan::Ability
|
86
|
-
def initialize(user)
|
87
|
-
if user && user.roles.include?(Role.find_by_name("admin"))
|
88
|
-
can :access, :rails_admin
|
89
|
-
can :manage, [ #Insert your app models here
|
90
|
-
::Piggybak::Variant,
|
91
|
-
::Piggybak::ShippingMethod,
|
92
|
-
::Piggybak::PaymentMethod,
|
93
|
-
::Piggybak::TaxMethod,
|
94
|
-
::Piggybak::State,
|
95
|
-
::Piggybak::Country]
|
96
|
-
can [:download, :email, :read, :create, :update, :history, :export], ::Piggybak::Order
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
TODOs
|
103
|
-
========
|
36
|
+
Visit the project website [here][project-website] to see more documentation and view a demo.
|
104
37
|
|
105
|
-
|
106
|
-
* Test: Add unit testing
|
107
|
-
* Feature: Add API to call Refund if profiles only
|
108
|
-
* Feature: Add helper for Google Analytics order tagging
|
38
|
+
[project-website]: http://www.piggybak.org/
|
109
39
|
|
110
40
|
Copyright
|
111
41
|
========
|
112
42
|
|
113
|
-
Copyright (c) 2011 Steph Skardal. See LICENSE.txt for further details.
|
43
|
+
Copyright (c) 2011 End Point & Steph Skardal. See LICENSE.txt for further details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
@@ -2,7 +2,9 @@ var tax_total = 0;
|
|
2
2
|
|
3
3
|
$(function() {
|
4
4
|
piggybak.initialize_listeners();
|
5
|
-
piggybak.update_shipping_options($('#piggybak_order_shipping_address_attributes_state_id'))
|
5
|
+
piggybak.update_shipping_options($('#piggybak_order_shipping_address_attributes_state_id'), function() {
|
6
|
+
$('#piggybak_order_shipments_attributes_0_shipping_method_id').val(previous_shipping);
|
7
|
+
});
|
6
8
|
piggybak.update_tax();
|
7
9
|
});
|
8
10
|
|
@@ -35,7 +37,7 @@ var piggybak = {
|
|
35
37
|
$('#piggybak_order_shipping_address_attributes_state_id').val(state);
|
36
38
|
});
|
37
39
|
},
|
38
|
-
update_shipping_options: function(field) {
|
40
|
+
update_shipping_options: function(field, block) {
|
39
41
|
var shipping_field = $('#piggybak_order_shipments_attributes_0_shipping_method_id');
|
40
42
|
shipping_field.hide();
|
41
43
|
var shipping_data = {};
|
@@ -56,6 +58,9 @@ var piggybak = {
|
|
56
58
|
});
|
57
59
|
shipping_field.show();
|
58
60
|
piggybak.update_totals();
|
61
|
+
if(block) {
|
62
|
+
block();
|
63
|
+
}
|
59
64
|
}
|
60
65
|
});
|
61
66
|
},
|
@@ -41,7 +41,10 @@ var piggybak_states = {
|
|
41
41
|
new_field = $('<input>');
|
42
42
|
}
|
43
43
|
var old_field = $('#piggybak_order_' + type + '_address_attributes_state_id');
|
44
|
-
new_field.attr('name', old_field.attr('name')).attr('id', old_field.attr('id'))
|
44
|
+
new_field.attr('name', old_field.attr('name')).attr('id', old_field.attr('id'));
|
45
|
+
if(old_field.prop('tagName') == new_field.prop('tagName')) {
|
46
|
+
new_field.val(old_field.val());
|
47
|
+
}
|
45
48
|
old_field.replaceWith(new_field);
|
46
49
|
|
47
50
|
if(block) {
|
@@ -6,30 +6,19 @@ module Piggybak
|
|
6
6
|
@cart = Piggybak::Cart.new(request.cookies["cart"])
|
7
7
|
@order = Piggybak::Order.new
|
8
8
|
|
9
|
-
|
10
|
-
@order.user = current_user
|
11
|
-
@order.email = current_user.email
|
12
|
-
end
|
13
|
-
|
14
|
-
@order.billing_address ||= Piggybak::Address.new
|
15
|
-
@order.shipping_address ||= Piggybak::Address.new
|
16
|
-
|
17
|
-
@order.shipments ||= [Piggybak::Shipment.new]
|
18
|
-
|
19
|
-
@order.payments ||= [Piggybak::Payment.new]
|
9
|
+
@order.initialize_user(current_user)
|
20
10
|
end
|
21
11
|
|
22
12
|
def submit
|
23
13
|
response.headers['Cache-Control'] = 'no-cache'
|
14
|
+
@cart = Piggybak::Cart.new(request.cookies["cart"])
|
24
15
|
|
25
16
|
begin
|
26
17
|
ActiveRecord::Base.transaction do
|
27
18
|
@order = Piggybak::Order.new(params[:piggybak_order])
|
28
|
-
@order.
|
29
|
-
@order.payments.first.payment_method_id = Piggybak::PaymentMethod.find_by_active(true).id
|
19
|
+
@order.initialize_user(current_user)
|
30
20
|
|
31
|
-
|
32
|
-
@order.add_line_items(cart)
|
21
|
+
@order.add_line_items(@cart)
|
33
22
|
|
34
23
|
if @order.save
|
35
24
|
Piggybak::Notifier.order_notification(@order)
|
@@ -42,15 +31,10 @@ module Piggybak
|
|
42
31
|
end
|
43
32
|
end
|
44
33
|
rescue Exception => e
|
45
|
-
@
|
46
|
-
|
47
|
-
if current_user
|
48
|
-
@order.user = current_user
|
49
|
-
@order.email = current_user.email
|
34
|
+
if @order.errors.empty?
|
35
|
+
@order.errors.add "", "Your order could not go through. Please try again."
|
50
36
|
end
|
51
37
|
|
52
|
-
@user = current_user
|
53
|
-
|
54
38
|
render "piggybak/orders/show"
|
55
39
|
end
|
56
40
|
end
|
@@ -58,6 +42,11 @@ module Piggybak
|
|
58
42
|
def receipt
|
59
43
|
response.headers['Cache-Control'] = 'no-cache'
|
60
44
|
|
45
|
+
if !session.has_key?(:last_order)
|
46
|
+
redirect_to root_url
|
47
|
+
return
|
48
|
+
end
|
49
|
+
|
61
50
|
@order = Piggybak::Order.find(session[:last_order])
|
62
51
|
end
|
63
52
|
|
@@ -14,4 +14,9 @@ module PiggybakHelper
|
|
14
14
|
link_to text, piggybak.orders_list_url
|
15
15
|
end
|
16
16
|
end
|
17
|
+
def piggybak_track_order(store_name)
|
18
|
+
if params[:controller] == "piggybak/orders" && params[:action] == "receipt" && session.has_key?(:last_order)
|
19
|
+
render "piggybak/orders/google_analytics", :order => @order, :store_name => store_name
|
20
|
+
end
|
21
|
+
end
|
17
22
|
end
|
@@ -23,10 +23,14 @@ module Piggybak
|
|
23
23
|
if self.address2 && self.address2 != ''
|
24
24
|
address += "#{self.address2}<br />"
|
25
25
|
end
|
26
|
-
address += "#{self.city}, #{self.
|
26
|
+
address += "#{self.city}, #{self.state_display} #{self.zip}<br />"
|
27
27
|
address += "#{self.country.name}"
|
28
28
|
address
|
29
29
|
end
|
30
30
|
alias :display :admin_label
|
31
|
+
|
32
|
+
def state_display
|
33
|
+
self.state ? self.state.name : self.state_id
|
34
|
+
end
|
31
35
|
end
|
32
36
|
end
|
@@ -23,10 +23,28 @@ module Piggybak
|
|
23
23
|
validates_presence_of :tax_charge
|
24
24
|
validates_presence_of :created_at
|
25
25
|
|
26
|
+
after_initialize :initialize_nested
|
26
27
|
before_validation :set_defaults
|
27
28
|
after_validation :update_totals
|
28
29
|
before_save :process_payments, :update_status
|
29
30
|
|
31
|
+
def initialize_nested
|
32
|
+
self.billing_address ||= Piggybak::Address.new
|
33
|
+
self.shipping_address ||= Piggybak::Address.new
|
34
|
+
self.shipments ||= [Piggybak::Shipment.new]
|
35
|
+
self.payments ||= [Piggybak::Payment.new]
|
36
|
+
if self.payments.any?
|
37
|
+
self.payments.first.payment_method_id = Piggybak::PaymentMethod.find_by_active(true).id
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize_user(user)
|
42
|
+
if user
|
43
|
+
self.user = user
|
44
|
+
self.email = user.email
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
30
48
|
def process_payments
|
31
49
|
has_errors = false
|
32
50
|
self.payments.each do |payment|
|
@@ -63,7 +81,11 @@ module Piggybak
|
|
63
81
|
self.tax_charge = 0
|
64
82
|
|
65
83
|
self.line_items.each do |line_item|
|
66
|
-
|
84
|
+
if line_item.variant
|
85
|
+
line_item.total = line_item.variant.price * line_item.quantity
|
86
|
+
else
|
87
|
+
line_item.total = 0
|
88
|
+
end
|
67
89
|
end
|
68
90
|
end
|
69
91
|
|
@@ -71,14 +93,14 @@ module Piggybak
|
|
71
93
|
self.total = 0
|
72
94
|
|
73
95
|
self.line_items.each do |line_item|
|
74
|
-
self.total += line_item.total
|
96
|
+
self.total += line_item.total
|
75
97
|
end
|
76
98
|
|
77
99
|
self.tax_charge = TaxMethod.calculate_tax(self)
|
78
100
|
self.total += self.tax_charge
|
79
101
|
|
80
102
|
shipments.each do |shipment|
|
81
|
-
if shipment.new_record?
|
103
|
+
if shipment.new_record? && shipment.shipping_method
|
82
104
|
calculator = shipment.shipping_method.klass.constantize
|
83
105
|
shipment.total = calculator.rate(shipment.shipping_method, self)
|
84
106
|
end
|
@@ -90,8 +112,6 @@ module Piggybak
|
|
90
112
|
self.total -= credit.total
|
91
113
|
end
|
92
114
|
|
93
|
-
self.total = self.total.to_c
|
94
|
-
|
95
115
|
self.total_due = self.total
|
96
116
|
payments.each do |payment|
|
97
117
|
if payment.status == "paid"
|
@@ -110,7 +130,7 @@ module Piggybak
|
|
110
130
|
else
|
111
131
|
if self.total == 0.00
|
112
132
|
self.status = "new"
|
113
|
-
elsif self.shipments.all? { |s| s.status == "shipped" }
|
133
|
+
elsif self.shipments.any? && self.shipments.all? { |s| s.status == "shipped" }
|
114
134
|
self.status = "shipped"
|
115
135
|
else
|
116
136
|
self.status = "paid"
|
@@ -126,7 +146,7 @@ module Piggybak
|
|
126
146
|
{
|
127
147
|
:address1 => self.billing_address.address1,
|
128
148
|
:city => self.billing_address.city,
|
129
|
-
:state => self.billing_address.
|
149
|
+
:state => self.billing_address.state_display,
|
130
150
|
:zip => self.billing_address.zip,
|
131
151
|
:country => "US"
|
132
152
|
}
|
@@ -9,6 +9,9 @@ module Piggybak
|
|
9
9
|
validates_presence_of :month
|
10
10
|
validates_presence_of :year
|
11
11
|
|
12
|
+
attr_accessor :number
|
13
|
+
attr_accessor :verification_value
|
14
|
+
|
12
15
|
def status_enum
|
13
16
|
["paid", "refunded"]
|
14
17
|
end
|
@@ -40,8 +43,6 @@ module Piggybak
|
|
40
43
|
gateway_response = gateway.authorize(self.order.total_due*100, credit_card, :address => self.order.avs_address)
|
41
44
|
if gateway_response.success?
|
42
45
|
self.attributes = { :total => self.order.total_due,
|
43
|
-
:number => 'hidden',
|
44
|
-
:verification_value => 'hidden',
|
45
46
|
:transaction_id => payment_gateway.transaction_id(gateway_response) }
|
46
47
|
gateway.capture(1000, gateway_response.authorization)
|
47
48
|
return true
|
@@ -0,0 +1,23 @@
|
|
1
|
+
var _gaq = _gaq || [];
|
2
|
+
_gaq.push(['_addTrans',
|
3
|
+
'<%= @order.id %>',
|
4
|
+
'<%= store_name %>',
|
5
|
+
'<%= @order.total %>',
|
6
|
+
'<%= @order.tax_charge %>',
|
7
|
+
'<%= @order.shipments.first.total %>',
|
8
|
+
'<%= @order.billing_address.city %>',
|
9
|
+
'<%= @order.billing_address.state_display %>',
|
10
|
+
'<%= @order.billing_address.country.name %>'
|
11
|
+
]);
|
12
|
+
|
13
|
+
<% @order.line_items.each do |line_item| -%>
|
14
|
+
_gaq.push(['_addItem',
|
15
|
+
'<%= @order.id %>',
|
16
|
+
'<%= line_item.variant.sku %>',
|
17
|
+
'<%= line_item.variant.description %>',
|
18
|
+
'', // category or variation
|
19
|
+
'<%= line_item.variant.price %>', //unit price
|
20
|
+
'<%= line_item.quantity %>'
|
21
|
+
]);
|
22
|
+
<% end -%>
|
23
|
+
_gaq.push(['_trackTrans']); //submits transaction to the Analytics servers
|
@@ -114,4 +114,9 @@
|
|
114
114
|
var shipping_lookup = "<%= piggybak.orders_shipping_url %>";
|
115
115
|
var tax_lookup = "<%= piggybak.orders_tax_url %>";
|
116
116
|
var geodata_lookup = "<%= piggybak.orders_geodata_url %>";
|
117
|
+
<% if params.has_key?(:piggybak_order) && params[:piggybak_order].has_key?(:shipments_attributes) -%>
|
118
|
+
var previous_shipping = <%= params[:piggybak_order][:shipments_attributes]["0"][:shipping_method_id] %>;
|
119
|
+
<% else -%>
|
120
|
+
var previous_shipping = "";
|
121
|
+
<% end -%>
|
117
122
|
</script>
|
@@ -1,7 +1,15 @@
|
|
1
1
|
= form.fields_for field.name do |nested_form|
|
2
2
|
%blockquote
|
3
3
|
- if nested_form.object.new_record?
|
4
|
-
= nested_form.link_to_remove "cancel", :class => 'label notice'
|
4
|
+
= nested_form.link_to_remove "cancel", :class => 'label notice', :id => "payments_cancel"
|
5
5
|
= nested_form.generate({:action => :create, :model_config => field.associated_model_config, :nested_in => field.name })
|
6
6
|
%hr
|
7
|
-
= form.link_to_add t("admin.index.add_new"), field.name, :class => 'label notice'
|
7
|
+
= form.link_to_add t("admin.index.add_new"), field.name, :class => 'label notice', :id => "payments_add"
|
8
|
+
|
9
|
+
:javascript
|
10
|
+
$('#payments_add').live('click', function() {
|
11
|
+
$(this).hide();
|
12
|
+
});
|
13
|
+
$('#payments_cancel').live('click', function() {
|
14
|
+
$('#payments_add').show();
|
15
|
+
});
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class DropCcFields < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
remove_column :payments, :number
|
4
|
+
remove_column :payments, :verification_value
|
5
|
+
end
|
6
|
+
|
7
|
+
def down
|
8
|
+
add_column :payments, :number, :string
|
9
|
+
add_column :payments, :verification_value, :string
|
10
|
+
end
|
11
|
+
end
|
data/piggybak.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "piggybak"
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Steph Skardal", "Brian Buchalter"]
|
12
|
-
s.date = "2012-01-
|
12
|
+
s.date = "2012-01-11"
|
13
13
|
s.description = "Mountable ecommerce"
|
14
14
|
s.email = "steph@endpoint.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -59,6 +59,7 @@ Gem::Specification.new do |s|
|
|
59
59
|
"app/views/piggybak/notifier/order_notification.text.erb",
|
60
60
|
"app/views/piggybak/orders/_address_form.html.erb",
|
61
61
|
"app/views/piggybak/orders/_details.html.erb",
|
62
|
+
"app/views/piggybak/orders/_google_analytics.html.erb",
|
62
63
|
"app/views/piggybak/orders/download.text.erb",
|
63
64
|
"app/views/piggybak/orders/list.html.erb",
|
64
65
|
"app/views/piggybak/orders/no_access.text.erb",
|
@@ -87,6 +88,7 @@ Gem::Specification.new do |s|
|
|
87
88
|
"db/migrate/20120104020930_populate_countries_and_states.rb",
|
88
89
|
"db/migrate/20120106010412_create_credits.rb",
|
89
90
|
"db/migrate/20120107135459_add_active_to_countries.rb",
|
91
|
+
"db/migrate/20120111195534_drop_cc_fields.rb",
|
90
92
|
"lib/acts_as_orderer/base.rb",
|
91
93
|
"lib/acts_as_variant/base.rb",
|
92
94
|
"lib/currency.rb",
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: piggybak
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.3.
|
5
|
+
version: 0.3.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Steph Skardal
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2012-01-
|
14
|
+
date: 2012-01-11 00:00:00 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: countries
|
@@ -153,6 +153,7 @@ files:
|
|
153
153
|
- app/views/piggybak/notifier/order_notification.text.erb
|
154
154
|
- app/views/piggybak/orders/_address_form.html.erb
|
155
155
|
- app/views/piggybak/orders/_details.html.erb
|
156
|
+
- app/views/piggybak/orders/_google_analytics.html.erb
|
156
157
|
- app/views/piggybak/orders/download.text.erb
|
157
158
|
- app/views/piggybak/orders/list.html.erb
|
158
159
|
- app/views/piggybak/orders/no_access.text.erb
|
@@ -181,6 +182,7 @@ files:
|
|
181
182
|
- db/migrate/20120104020930_populate_countries_and_states.rb
|
182
183
|
- db/migrate/20120106010412_create_credits.rb
|
183
184
|
- db/migrate/20120107135459_add_active_to_countries.rb
|
185
|
+
- db/migrate/20120111195534_drop_cc_fields.rb
|
184
186
|
- lib/acts_as_orderer/base.rb
|
185
187
|
- lib/acts_as_variant/base.rb
|
186
188
|
- lib/currency.rb
|
@@ -200,7 +202,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
200
202
|
requirements:
|
201
203
|
- - ">="
|
202
204
|
- !ruby/object:Gem::Version
|
203
|
-
hash:
|
205
|
+
hash: 379901271419735142
|
204
206
|
segments:
|
205
207
|
- 0
|
206
208
|
version: "0"
|