piggybak 0.5.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +32 -25
- data/VERSION +1 -1
- data/app/assets/javascripts/piggybak.js +11 -1
- data/app/assets/javascripts/piggybak.states.js +6 -5
- data/app/controllers/piggybak/orders_controller.rb +14 -22
- data/app/models/piggybak/address.rb +4 -1
- data/app/models/piggybak/adjustment.rb +1 -25
- data/app/models/piggybak/cart.rb +18 -17
- data/app/models/piggybak/line_item.rb +106 -19
- data/app/models/piggybak/order.rb +94 -108
- data/app/models/piggybak/payment.rb +25 -27
- data/app/models/piggybak/payment_method.rb +3 -1
- data/app/models/piggybak/payment_method_value.rb +3 -1
- data/app/models/piggybak/{variant.rb → sellable.rb} +6 -4
- data/app/models/piggybak/shipment.rb +4 -10
- data/app/models/piggybak/shipping_calculator/flat_rate.rb +4 -0
- data/app/models/piggybak/shipping_calculator/free.rb +4 -0
- data/app/models/piggybak/shipping_calculator/range.rb +4 -0
- data/app/models/piggybak/shipping_method.rb +1 -1
- data/app/models/piggybak/tax_method.rb +1 -1
- data/app/views/piggybak/cart/_form.html.erb +7 -7
- data/app/views/piggybak/cart/_items.html.erb +14 -5
- data/app/views/piggybak/notifier/order_notification.text.erb +10 -2
- data/app/views/piggybak/orders/_details.html.erb +14 -5
- data/app/views/piggybak/orders/_google_analytics.html.erb +3 -3
- data/app/views/piggybak/orders/download.text.erb +6 -6
- data/app/views/piggybak/orders/submit.html.erb +55 -49
- data/app/views/rails_admin/main/_location_select.html.haml +3 -3
- data/app/views/rails_admin/main/_order_details.html.erb +12 -24
- data/app/views/rails_admin/main/_polymorphic_nested.html.haml +29 -0
- data/bin/piggybak +12 -0
- data/config/routes.rb +0 -2
- data/db/migrate/20121008160425_rename_variants_to_sellables.rb +11 -0
- data/db/migrate/20121008175144_line_item_rearchitecture.rb +96 -0
- data/lib/acts_as_sellable.rb +21 -0
- data/lib/formatted_changes.rb +2 -2
- data/lib/piggybak.rb +80 -126
- data/lib/piggybak/cli.rb +81 -0
- data/lib/piggybak/config.rb +21 -0
- data/piggybak.gemspec +10 -7
- data/spec/dummy_app/app/models/image.rb +1 -1
- data/spec/factories.rb +1 -1
- metadata +52 -49
- data/app/controllers/piggybak/payments_controller.rb +0 -14
- data/app/views/rails_admin/main/_order_notes.html.erb +0 -1
- data/app/views/rails_admin/main/_payment_refund.html.haml +0 -6
- data/lib/acts_as_variant.rb +0 -15
@@ -2,6 +2,10 @@ module Piggybak
|
|
2
2
|
class ShippingCalculator::Range
|
3
3
|
KEYS = ["cost", "upper", "lower"]
|
4
4
|
|
5
|
+
def self.description
|
6
|
+
"Cost per Range"
|
7
|
+
end
|
8
|
+
|
5
9
|
def self.available?(method, object)
|
6
10
|
low_end = method.metadata.detect { |m| m.key == "lower" }.value
|
7
11
|
high_end = method.metadata.detect { |m| m.key == "upper" }.value
|
@@ -1,14 +1,14 @@
|
|
1
|
-
<% if object.reflections.keys.include?(:
|
2
|
-
<% if object.
|
3
|
-
<% if object.
|
1
|
+
<% if object.reflections.keys.include?(:piggybak_sellable) -%>
|
2
|
+
<% if object.piggybak_sellable && object.piggybak_sellable.active -%>
|
3
|
+
<% if object.piggybak_sellable.quantity > 0 || object.piggybak_sellable.unlimited_inventory -%>
|
4
4
|
<%= form_tag piggybak.cart_add_url do -%>
|
5
|
-
<div id="
|
6
|
-
<span id="title"><%= object.
|
7
|
-
<span id="price"><%= number_to_currency object.
|
5
|
+
<div id="sellable_details">
|
6
|
+
<span id="title"><%= object.piggybak_sellable.description %></span>
|
7
|
+
<span id="price"><%= number_to_currency object.piggybak_sellable.price %></span>
|
8
8
|
</div>
|
9
9
|
<label>Quantity</label>
|
10
10
|
<%= text_field_tag :quantity, "1" %>
|
11
|
-
<%= hidden_field_tag :
|
11
|
+
<%= hidden_field_tag :sellable_id, object.piggybak_sellable.id %>
|
12
12
|
<%= submit_tag "Add to Cart", :id => "submit" %>
|
13
13
|
<% end -%>
|
14
14
|
<% else -%>
|
@@ -12,19 +12,19 @@
|
|
12
12
|
</tr>
|
13
13
|
<% @cart.items.each do |item| %>
|
14
14
|
<tr>
|
15
|
-
<td><%= item[:
|
16
|
-
<td><%= number_to_currency item[:
|
15
|
+
<td><%= item[:sellable].description %></td>
|
16
|
+
<td><%= number_to_currency item[:sellable].price %></td>
|
17
17
|
<td>
|
18
18
|
<% if page == "cart" -%>
|
19
|
-
<%= text_field_tag "quantity[#{item[:
|
19
|
+
<%= text_field_tag "quantity[#{item[:sellable].id}]", item[:quantity] %>
|
20
20
|
<% else -%>
|
21
21
|
<%= item[:quantity] %>
|
22
22
|
<% end -%>
|
23
23
|
</td>
|
24
|
-
<td><%= number_to_currency item[:quantity]*item[:
|
24
|
+
<td><%= number_to_currency item[:quantity]*item[:sellable].price %></td>
|
25
25
|
<% if page == "cart" -%>
|
26
26
|
<td>
|
27
|
-
<%= link_to "Remove", piggybak.remove_item_url(item[:
|
27
|
+
<%= link_to "Remove", piggybak.remove_item_url(item[:sellable].id), :method => :delete %>
|
28
28
|
</td>
|
29
29
|
<% end -%>
|
30
30
|
</tr>
|
@@ -48,6 +48,15 @@
|
|
48
48
|
<td>Shipping</td>
|
49
49
|
<td id="shipping_total"></td>
|
50
50
|
</tr>
|
51
|
+
<% Piggybak.config.line_item_types.each do |k, v| -%>
|
52
|
+
<% if v.has_key?(:display_in_cart) -%>
|
53
|
+
<tr id="<%= "#{k}_row" %>" style="display:none;">
|
54
|
+
<td colspan="<%= page == "cart" ? "3" : "2" %>"></td>
|
55
|
+
<td><%= v[:display_in_cart] %></td>
|
56
|
+
<td class="extra_totals" id="<%= k %>_total">$0.00</td>
|
57
|
+
</tr>
|
58
|
+
<% end -%>
|
59
|
+
<% end -%>
|
51
60
|
<tr>
|
52
61
|
<td colspan="<%= page == "cart" ? "3" : "2" %>"></td>
|
53
62
|
<td>Total</td>
|
@@ -2,8 +2,16 @@ Thanks for your order!
|
|
2
2
|
|
3
3
|
Items
|
4
4
|
|
5
|
-
<% @order.line_items.each do |line_item| %>
|
6
|
-
<%= line_item.
|
5
|
+
<% @order.line_items.sellables.each do |line_item| %>
|
6
|
+
<%= line_item.description %> x <%= line_item.quantity %> = <%= number_to_currency line_item.price %>
|
7
|
+
<% end -%>
|
8
|
+
|
9
|
+
<% @order.line_items.shipments.each do |line_item| %>
|
10
|
+
<%= line_item.description %> = <%= number_to_currency line_item.price %>
|
11
|
+
<% end -%>
|
12
|
+
|
13
|
+
<% @order.line_items.payments.each do |line_item| %>
|
14
|
+
<%= line_item.description %> = <%= number_to_currency line_item.price %>
|
7
15
|
<% end -%>
|
8
16
|
|
9
17
|
Total
|
@@ -5,12 +5,12 @@
|
|
5
5
|
<th>Quantity</th>
|
6
6
|
<th>Subtotal</th>
|
7
7
|
</tr>
|
8
|
-
<% order.line_items.each do |line_item| %>
|
8
|
+
<% order.line_items.sellables.each do |line_item| %>
|
9
9
|
<tr>
|
10
10
|
<td><%= line_item.description %></td>
|
11
|
-
<td><%= number_to_currency line_item.
|
11
|
+
<td><%= number_to_currency line_item.unit_price %></td>
|
12
12
|
<td><%= line_item.quantity %></td>
|
13
|
-
<td><%= number_to_currency line_item.
|
13
|
+
<td><%= number_to_currency line_item.price %></td>
|
14
14
|
</tr>
|
15
15
|
<% end -%>
|
16
16
|
<tr>
|
@@ -19,7 +19,7 @@
|
|
19
19
|
<tr>
|
20
20
|
<td colspan="2"></td>
|
21
21
|
<td>Subtotal</td>
|
22
|
-
<td><%= number_to_currency order.line_items.inject(0) { |subtotal, li| subtotal + li.
|
22
|
+
<td><%= number_to_currency order.line_items.sellables.inject(0) { |subtotal, li| subtotal + li.price } %></td>
|
23
23
|
</tr>
|
24
24
|
<tr>
|
25
25
|
<td colspan="2"></td>
|
@@ -29,8 +29,17 @@
|
|
29
29
|
<tr>
|
30
30
|
<td colspan="2"></td>
|
31
31
|
<td>Shipping</td>
|
32
|
-
<td><%= number_to_currency order.
|
32
|
+
<td><%= number_to_currency order.shipment_charge %></td>
|
33
|
+
</tr>
|
34
|
+
<% Piggybak.config.line_item_types.each do |k, v| -%>
|
35
|
+
<% if v.has_key?(:display_in_cart) && order.line_items.detect { |li| li.line_item_type == k.to_s } -%>
|
36
|
+
<tr>
|
37
|
+
<td colspan="2"></td>
|
38
|
+
<td><%= v[:display_in_cart] %></td>
|
39
|
+
<td class="extra_totals" id="<%= k %>_total"><%= number_to_currency order.line_items.detect { |li| li.line_item_type == k.to_s }.price %></td>
|
33
40
|
</tr>
|
41
|
+
<% end -%>
|
42
|
+
<% end -%>
|
34
43
|
<tr>
|
35
44
|
<td colspan="2"></td>
|
36
45
|
<td>Total</td>
|
@@ -4,16 +4,16 @@ _gaq.push(['_addTrans',
|
|
4
4
|
'<%= store_name %>',
|
5
5
|
'<%= @order.total %>',
|
6
6
|
'<%= @order.tax_charge %>',
|
7
|
-
'<%= @order.
|
7
|
+
'<%= @order.shipment_charge %>',
|
8
8
|
'<%= @order.billing_address.city %>',
|
9
9
|
'<%= @order.billing_address.state_display %>',
|
10
10
|
'<%= @order.billing_address.country.name %>'
|
11
11
|
]);
|
12
12
|
|
13
|
-
<% @order.line_items.each do |line_item| -%>
|
13
|
+
<% @order.line_items.sellables.each do |line_item| -%>
|
14
14
|
_gaq.push(['_addItem',
|
15
15
|
'<%= @order.id %>',
|
16
|
-
'<%= line_item.
|
16
|
+
'<%= line_item.sellable.try(:sku) %>',
|
17
17
|
'<%= line_item.description %>',
|
18
18
|
'', // category or variation
|
19
19
|
'<%= line_item.price %>', //unit price
|
@@ -3,16 +3,16 @@ Order: #<%= @order.id %>
|
|
3
3
|
Email: <%= @order.email %>
|
4
4
|
Phone: <%= @order.phone %>
|
5
5
|
|
6
|
-
<% @order.line_items.each do |line_item| %>
|
7
|
-
<%= line_item.quantity %> x <%= raw line_item.description %> (<%= number_to_currency line_item.
|
6
|
+
<% @order.line_items.sellables.each do |line_item| %>
|
7
|
+
<%= line_item.quantity %> x <%= raw line_item.description %> (<%= number_to_currency line_item.price %>)
|
8
8
|
<% end -%>
|
9
9
|
|
10
|
-
Subtotal: <%= number_to_currency @order.line_items.inject(0) { |subtotal, li| subtotal + li.
|
11
|
-
Shipping & Handling: <%= number_to_currency @order.shipments.inject(0) { |shipping, shipment| shipping + shipment.
|
10
|
+
Subtotal: <%= number_to_currency @order.line_items.sellables.inject(0) { |subtotal, li| subtotal + li.price } %>
|
11
|
+
Shipping & Handling: <%= number_to_currency @order.line_items.shipments.inject(0) { |shipping, shipment| shipping + shipment.price } %>
|
12
12
|
Tax: <%= number_to_currency @order.tax_charge %>
|
13
13
|
Total: <%= number_to_currency @order.total %>
|
14
|
-
Less Payment: <%= number_to_currency(@order.payments.inject(0) { |total, p| total + p.
|
15
|
-
Adjustments: <%= number_to_currency(@order.adjustments.inject(0) { |total, adj| total + adj.
|
14
|
+
Less Payment: <%= number_to_currency(@order.line_items.payments.inject(0) { |total, p| total + p.price if p.payment.status == "paid" }) %>
|
15
|
+
Adjustments: <%= number_to_currency(@order.line_items.adjustments.inject(0) { |total, adj| total + adj.price }) %>
|
16
16
|
Balance Due: <%= number_to_currency @order.total_due %>
|
17
17
|
|
18
18
|
Billing Information
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<% if @order.errors.any? -%>
|
7
7
|
<div id="checkout_error">
|
8
8
|
<b>You have errors with your submission:</b><br />
|
9
|
-
<%= raw @order.errors.full_messages.join("<br />") %>
|
9
|
+
<%= raw @order.errors.full_messages.collect { |b| b.gsub(/^Line items payment/, 'Payment').gsub(/^Line items shipment shipping/, 'Shipping') }.join("<br />") %>
|
10
10
|
</div>
|
11
11
|
<% end -%>
|
12
12
|
<div class="clear"></div>
|
@@ -50,59 +50,65 @@
|
|
50
50
|
<div id="add_details">
|
51
51
|
<div id="shipping">
|
52
52
|
<h3>Shipping Option</h3>
|
53
|
-
<%= f.fields_for :
|
54
|
-
|
55
|
-
<%=
|
56
|
-
|
57
|
-
|
58
|
-
<%=
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
53
|
+
<%= f.fields_for :line_items, @order.line_items.detect { |li| li.line_item_type == "shipment" } do |line_item_f| %>
|
54
|
+
<%= line_item_f.hidden_field :line_item_type, { :value => "shipment" } %>
|
55
|
+
<%= line_item_f.fields_for :shipment do |shipment| %>
|
56
|
+
<div class="item">
|
57
|
+
<%= shipment.label :shipping_method_id %>
|
58
|
+
<%= shipment.select :shipping_method_id, [] %>
|
59
|
+
<div id="shipping_spinner" style="display:none;">
|
60
|
+
<%= image_tag "ajax-loader.gif" %>
|
61
|
+
</div>
|
62
|
+
<div id="shipping_default" style="display:none;">
|
63
|
+
Please enter a shipping address.
|
64
|
+
</div>
|
65
|
+
<div id="shipping_empty" style="display:none;">
|
66
|
+
No shipping methods found.
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
<% end -%>
|
67
70
|
<% end -%>
|
68
71
|
</div>
|
69
72
|
<div id="payment">
|
70
73
|
<h3>Payment</h3>
|
71
|
-
<%= f.fields_for :
|
72
|
-
|
73
|
-
<%=
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
74
|
+
<%= f.fields_for :line_items, @order.line_items.detect { |li| li.line_item_type == "payment" } do |line_item_f| %>
|
75
|
+
<%= line_item_f.hidden_field :line_item_type, { :value => "payment" } %>
|
76
|
+
<%= line_item_f.fields_for :payment do |payment| %>
|
77
|
+
<div class="item">
|
78
|
+
<%= payment.label :number %>
|
79
|
+
<% if @order.errors.keys.include?("payments.number".to_sym) %>
|
80
|
+
<span class="field_with_errors">
|
81
|
+
<%= payment.text_field :number %>
|
82
|
+
</span>
|
83
|
+
<% else -%>
|
84
|
+
<%= payment.text_field :number %>
|
85
|
+
<% end -%>
|
86
|
+
</div>
|
87
|
+
|
88
|
+
<div class="item">
|
89
|
+
<%= payment.label :verification_value %>
|
90
|
+
<% if @order.errors.keys.include?("payments.verification_value".to_sym) %>
|
91
|
+
<span class="field_with_errors">
|
92
|
+
<%= payment.text_field :verification_value %>
|
93
|
+
</span>
|
94
|
+
<% else -%>
|
95
|
+
<%= payment.text_field :verification_value %>
|
96
|
+
<% end -%>
|
97
|
+
</div>
|
98
|
+
|
99
|
+
<div class="item">
|
100
|
+
<%= payment.label :month %>
|
101
|
+
<% if @order.errors.keys.include?("payments.verification_value".to_sym) %>
|
102
|
+
<span class="field_with_errors">
|
103
|
+
<%= payment.select :month, 1.upto(12).to_a %> /
|
104
|
+
<%= payment.select :year, Time.now.year.upto(Time.now.year + 10).to_a %>
|
105
|
+
</span>
|
106
|
+
<% else -%>
|
107
|
+
<%= payment.select :month, 1.upto(12).to_a %> /
|
108
|
+
<%= payment.select :year, Time.now.year.upto(Time.now.year + 10).to_a %>
|
109
|
+
<% end -%>
|
110
|
+
</div>
|
104
111
|
<% end -%>
|
105
|
-
</div>
|
106
112
|
<% end -%>
|
107
113
|
</div>
|
108
114
|
<div id="submit">
|
@@ -8,8 +8,8 @@
|
|
8
8
|
- else
|
9
9
|
= form.text_field "state_id"
|
10
10
|
|
11
|
-
- if type == "billing"
|
12
|
-
= javascript_include_tag "piggybak.states"
|
13
|
-
|
14
11
|
:javascript
|
15
12
|
var geodata_lookup = "#{piggybak.orders_geodata_url}";
|
13
|
+
|
14
|
+
- if type == "billing"
|
15
|
+
= javascript_include_tag "piggybak.states"
|
@@ -3,32 +3,32 @@ N/A
|
|
3
3
|
<% else -%>
|
4
4
|
<table cellpadding="5" cellspacing="0">
|
5
5
|
<tr>
|
6
|
-
<td width="150">Subtotal</td>
|
7
|
-
<td
|
6
|
+
<td width="150">Subtotal (Sellables)</td>
|
7
|
+
<td><%= number_to_currency form.object.subtotal %></td>
|
8
8
|
</tr>
|
9
9
|
<tr>
|
10
10
|
<td>Shipping</td>
|
11
|
-
<td
|
11
|
+
<td><%= number_to_currency form.object.shipment_charge %></td>
|
12
12
|
</tr>
|
13
13
|
<tr>
|
14
14
|
<td>Tax</td>
|
15
|
-
<td
|
15
|
+
<td><%= number_to_currency form.object.tax_charge %></td>
|
16
16
|
</tr>
|
17
17
|
<tr>
|
18
|
-
<td>
|
19
|
-
<td
|
18
|
+
<td>Adjustments</td>
|
19
|
+
<td><%= number_to_currency form.object.adjustment_charge %></td>
|
20
20
|
</tr>
|
21
21
|
<tr>
|
22
|
-
<td>
|
23
|
-
<td
|
22
|
+
<td>Total</td>
|
23
|
+
<td><%= number_to_currency form.object.total %></td>
|
24
24
|
</tr>
|
25
25
|
<tr>
|
26
|
-
<td>
|
27
|
-
<td
|
26
|
+
<td>Payments</td>
|
27
|
+
<td><%= number_to_currency form.object.payment_charge %></td>
|
28
28
|
</tr>
|
29
29
|
<tr>
|
30
30
|
<td>Balance Due</td>
|
31
|
-
<td
|
31
|
+
<td><%= number_to_currency form.object.total_due %></td>
|
32
32
|
</tr>
|
33
33
|
<tr>
|
34
34
|
<td>Created at</td>
|
@@ -42,23 +42,11 @@ N/A
|
|
42
42
|
<li><%= link_to "Send or Resend Email Confirmation", piggybak.email_order_url(form.object.id) %></li>
|
43
43
|
<li><%= link_to "View as Text", piggybak.download_order_url(form.object.id) %></li>
|
44
44
|
<% if form.object.total_due == 0.00 -%>
|
45
|
-
<li><%= link_to "Cancel Order", piggybak.cancel_order_url(form.object.id) %> (This does not
|
45
|
+
<li><%= link_to "Cancel Order", piggybak.cancel_order_url(form.object.id) %> (This does not refund payments.)</li>
|
46
46
|
<% end -%>
|
47
47
|
</ul>
|
48
48
|
</td>
|
49
49
|
</tr>
|
50
|
-
<% else -%>
|
51
|
-
<tr>
|
52
|
-
<td valign="top">Actions</td>
|
53
|
-
<td>
|
54
|
-
<ul>
|
55
|
-
<li>
|
56
|
-
<%= link_to "Restore Cancel Order", piggybak.restore_order_url(form.object.id) %>
|
57
|
-
(This marks order as un-cancelled.)
|
58
|
-
</li>
|
59
|
-
</ul>
|
60
|
-
</td>
|
61
|
-
</tr>
|
62
50
|
<% end -%>
|
63
51
|
</table>
|
64
52
|
<% end -%>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
- if form.object.new_record?
|
2
|
+
= form.select "line_item_type", Piggybak::LineItem.line_item_type_select, {}, :onchange => "toggle_line_item($(this));"
|
3
|
+
- else
|
4
|
+
= form.hidden_field "line_item_type"
|
5
|
+
= form.object.line_item_type
|
6
|
+
|
7
|
+
%script
|
8
|
+
var line_item_types=#{raw Piggybak.config.line_item_types.to_json};
|
9
|
+
var toggle_line_item = function(el) {
|
10
|
+
el.parent().parent().siblings('div').hide();
|
11
|
+
if(line_item_types[el.val()].fields === undefined) {
|
12
|
+
line_item_types[el.val()].fields = new Array();
|
13
|
+
}
|
14
|
+
$.each(line_item_types[el.val()].fields, function(a, b) {
|
15
|
+
el.parent().parent().siblings('.' + b + '_field').show();
|
16
|
+
if(line_item_types[el.val()].nested_attrs !== undefined) {
|
17
|
+
el.parent().parent().siblings('.' + b + '_field').find('> .controls,> .control-label').hide();
|
18
|
+
}
|
19
|
+
});
|
20
|
+
};
|
21
|
+
$.each($('.line_item_type_field select,.line_item_type_field input'), function(i, el) {
|
22
|
+
toggle_line_item($(el));
|
23
|
+
});
|
24
|
+
//Removing delete-ability of line_item_types that can't be destroyed
|
25
|
+
$.each($('.line_item_type_field input'), function(i, el) {
|
26
|
+
if(!line_item_types[$(el).val()].allow_destroy) {
|
27
|
+
$(el).parentsUntil('fieldset').parent().parent().find('.remove_nested_fields').remove();
|
28
|
+
}
|
29
|
+
});
|