piggybak 0.5.5 → 0.6.0
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 +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
|
+
});
|