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.
Files changed (47) hide show
  1. data/README.md +32 -25
  2. data/VERSION +1 -1
  3. data/app/assets/javascripts/piggybak.js +11 -1
  4. data/app/assets/javascripts/piggybak.states.js +6 -5
  5. data/app/controllers/piggybak/orders_controller.rb +14 -22
  6. data/app/models/piggybak/address.rb +4 -1
  7. data/app/models/piggybak/adjustment.rb +1 -25
  8. data/app/models/piggybak/cart.rb +18 -17
  9. data/app/models/piggybak/line_item.rb +106 -19
  10. data/app/models/piggybak/order.rb +94 -108
  11. data/app/models/piggybak/payment.rb +25 -27
  12. data/app/models/piggybak/payment_method.rb +3 -1
  13. data/app/models/piggybak/payment_method_value.rb +3 -1
  14. data/app/models/piggybak/{variant.rb → sellable.rb} +6 -4
  15. data/app/models/piggybak/shipment.rb +4 -10
  16. data/app/models/piggybak/shipping_calculator/flat_rate.rb +4 -0
  17. data/app/models/piggybak/shipping_calculator/free.rb +4 -0
  18. data/app/models/piggybak/shipping_calculator/range.rb +4 -0
  19. data/app/models/piggybak/shipping_method.rb +1 -1
  20. data/app/models/piggybak/tax_method.rb +1 -1
  21. data/app/views/piggybak/cart/_form.html.erb +7 -7
  22. data/app/views/piggybak/cart/_items.html.erb +14 -5
  23. data/app/views/piggybak/notifier/order_notification.text.erb +10 -2
  24. data/app/views/piggybak/orders/_details.html.erb +14 -5
  25. data/app/views/piggybak/orders/_google_analytics.html.erb +3 -3
  26. data/app/views/piggybak/orders/download.text.erb +6 -6
  27. data/app/views/piggybak/orders/submit.html.erb +55 -49
  28. data/app/views/rails_admin/main/_location_select.html.haml +3 -3
  29. data/app/views/rails_admin/main/_order_details.html.erb +12 -24
  30. data/app/views/rails_admin/main/_polymorphic_nested.html.haml +29 -0
  31. data/bin/piggybak +12 -0
  32. data/config/routes.rb +0 -2
  33. data/db/migrate/20121008160425_rename_variants_to_sellables.rb +11 -0
  34. data/db/migrate/20121008175144_line_item_rearchitecture.rb +96 -0
  35. data/lib/acts_as_sellable.rb +21 -0
  36. data/lib/formatted_changes.rb +2 -2
  37. data/lib/piggybak.rb +80 -126
  38. data/lib/piggybak/cli.rb +81 -0
  39. data/lib/piggybak/config.rb +21 -0
  40. data/piggybak.gemspec +10 -7
  41. data/spec/dummy_app/app/models/image.rb +1 -1
  42. data/spec/factories.rb +1 -1
  43. metadata +52 -49
  44. data/app/controllers/piggybak/payments_controller.rb +0 -14
  45. data/app/views/rails_admin/main/_order_notes.html.erb +0 -1
  46. data/app/views/rails_admin/main/_payment_refund.html.haml +0 -6
  47. data/lib/acts_as_variant.rb +0 -15
data/bin/piggybak ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'piggybak/cli'
7
+ rescue LoadError => e
8
+ warn 'Could not load "piggybak/cli"'
9
+ exit -1
10
+ end
11
+
12
+ Piggybak::CLI.start
data/config/routes.rb CHANGED
@@ -20,7 +20,5 @@ Piggybak::Engine.routes.draw do
20
20
  match "/admin/orders/:id/email" => "orders#email", :as => :email_order
21
21
  match "/admin/orders/:id/download" => "orders#download", :as => :download_order, :format => "txt"
22
22
  match "/admin/orders/:id/cancel" => "orders#cancel", :as => :cancel_order
23
- match "/admin/orders/:id/restore" => "orders#restore", :as => :restore_order
24
- match "/admin/payments/:id/refund" => "payments#refund", :as => :refund_payment
25
23
  end
26
24
  end
@@ -0,0 +1,11 @@
1
+ class RenameVariantsToSellables < ActiveRecord::Migration
2
+ def up
3
+ rename_table :variants, :sellables
4
+ rename_column :line_items, :variant_id, :sellable_id
5
+ end
6
+
7
+ def down
8
+ rename_table :sellables, :variants
9
+ rename_column :line_items, :sellable_id, :variant_id
10
+ end
11
+ end
@@ -0,0 +1,96 @@
1
+ class LineItemRearchitecture < ActiveRecord::Migration
2
+ def up
3
+ add_column :line_items, :line_item_type, :string, :null => false, :default => "sellable"
4
+ rename_column :line_items, :price, :unit_price
5
+ rename_column :line_items, :total, :price
6
+ change_column :line_items, :sellable_id, :integer, :null => true
7
+ add_column :line_items, :sort, :integer, :null => false, :default => 0
8
+ change_table(:line_items) do |t|
9
+ t.timestamps
10
+ end
11
+
12
+ add_column :shipments, :line_item_id, :integer
13
+ add_column :payments, :line_item_id, :integer
14
+
15
+ [Piggybak::Shipment, Piggybak::Payment, Piggybak::Adjustment].each do |klass|
16
+ klass.all.each do |item|
17
+ description = ''
18
+ if klass == Piggybak::Shipment
19
+ description = item.shipping_method.description
20
+ elsif klass == Piggybak::Payment
21
+ description = "Payment"
22
+ elsif klass == Piggybak::Adjustment
23
+ description = item.note || "Adjustment"
24
+ end
25
+ li = Piggybak::LineItem.new({ :line_item_type => klass.to_s.demodulize.downcase,
26
+ :price => 0.00,
27
+ :description => description,
28
+ :quantity => 1,
29
+ :order_id => item.order_id })
30
+ li.save
31
+
32
+ if [Piggybak::Shipment, Piggybak::Payment].include?(klass)
33
+ item.update_attribute(:line_item_id, li.id)
34
+ end
35
+
36
+ li.update_attribute(:price, item.total)
37
+ end
38
+ end
39
+
40
+ remove_column :shipments, :total
41
+ remove_column :payments, :total
42
+ remove_column :adjustments, :total
43
+ remove_column :shipments, :order_id
44
+ remove_column :payments, :order_id
45
+ remove_column :adjustments, :order_id
46
+
47
+ Piggybak::Order.all.each do |o|
48
+ next if o.attributes["tax_charge"] == 0.00
49
+ o.line_items << Piggybak::LineItem.new({ :line_item_type => "tax",
50
+ :price => o.attributes["tax_charge"],
51
+ :description => "Tax Charge",
52
+ :quantity => 1 })
53
+ end
54
+
55
+ remove_column :orders, :tax_charge
56
+ end
57
+
58
+ def down
59
+ add_column :shipments, :total, :decimal, :null => false, :default => 0.0
60
+ add_column :payments, :total, :decimal, :null => false, :default => 0.0
61
+ add_column :adjustments, :total, :decimal
62
+ add_column :shipments, :order_id, :integer, :null => false, :default => 0
63
+ add_column :payments, :order_id, :integer, :null => false, :default => 0
64
+ add_column :adjustments, :order_id, :integer, :null => false, :default => 0
65
+
66
+ add_column :orders, :tax_charge, :decimal, :null => false, :default => 0.0
67
+
68
+ to_delete = []
69
+ Piggybak::LineItem.all.each do |line_item|
70
+ if line_item.line_item_type == "payment"
71
+ line_item.payment.update_attributes({ :order_id => line_item.order_id, :total => line_item.price })
72
+ to_delete << line_item
73
+ elsif line_item.line_item_type == "shipment"
74
+ line_item.shipment.update_attributes({ :order_id => line_item.order_id, :total => line_item.price })
75
+ to_delete << line_item
76
+ elsif line_item.line_item_type == "adjustment"
77
+ to_delete << line_item
78
+ line_item.adjustment.update_attributes({ :order_id => line_item.order_id, :total => line_item.price })
79
+ elsif line_item.line_item_type == "tax"
80
+ line_item.order.update_attribute(:tax_charge, line_item.price)
81
+ to_delete << line_item
82
+ end
83
+ end
84
+ Piggybak::LineItem.destroy(to_delete)
85
+
86
+ remove_column :shipments, :line_item_id
87
+ remove_column :payments, :line_item_id
88
+
89
+ remove_column :line_items, :line_item_type
90
+ remove_column :line_items, :updated_at
91
+ remove_column :line_items, :created_at
92
+ remove_column :line_items, :sort
93
+ rename_column :line_items, :price, :total
94
+ rename_column :line_items, :unit_price, :price
95
+ end
96
+ end
@@ -0,0 +1,21 @@
1
+ module Piggybak
2
+ module ActsAsSellable
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+
7
+ def acts_as_sellable
8
+
9
+ has_one :piggybak_sellable, :as => "item", :class_name => "::Piggybak::Sellable"
10
+
11
+ accepts_nested_attributes_for :piggybak_sellable, :allow_destroy => true
12
+
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+
19
+ ::ActiveRecord::Base.send :include, Piggybak::ActsAsSellable
20
+
21
+
@@ -5,7 +5,7 @@ module Piggybak
5
5
  def new_destroy_changes(type)
6
6
  text = "#{self.class.to_s.gsub(/Piggybak::/, '')} ##{self.id} #{type}:<br />"
7
7
  self.attributes.each do |k, v|
8
- if !["upated_at", "created_at", "id", "order_id", "billing_address_id", "shipping_address_id"].include?(k)
8
+ if !["updated_at", "created_at", "id", "order_id", "billing_address_id", "shipping_address_id", "sellable_id", "line_item_type", "unit_price", "sort"].include?(k)
9
9
  if v.is_a?(BigDecimal)
10
10
  text += "#{k}: $#{format("%.2f", v)}<br />"
11
11
  else
@@ -20,7 +20,7 @@ module Piggybak
20
20
  def formatted_changes
21
21
  text = "#{self.class.to_s.gsub(/Piggybak::/, '')} ##{self.id} changes:<br />"
22
22
  self.changes.each do |k, v|
23
- if !["updated_at", "id", "billing_address_id", "shipping_address_id", "created_at"].include?(k)
23
+ if !["updated_at", "id", "billing_address_id", "shipping_address_id", "created_at", "sellable_id", "line_item_type", "unit_price", "sort"].include?(k)
24
24
  if v[0].is_a?(BigDecimal)
25
25
  text += "#{k}: $#{format("%.2f", v[0])} to $#{format("%.2f", v[1])}<br />"
26
26
  else
data/lib/piggybak.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'piggybak/config'
2
- require 'acts_as_variant'
2
+ require 'acts_as_sellable'
3
3
  require 'acts_as_orderer'
4
4
  require 'acts_as_changer'
5
5
  require 'active_merchant'
@@ -9,6 +9,7 @@ require 'mask_submissions'
9
9
 
10
10
  module Piggybak
11
11
  def self.config(entity = nil, &block)
12
+
12
13
  if entity
13
14
  Piggybak::Config.model(entity, &block)
14
15
  elsif block_given? && ENV['SKIP_RAILS_ADMIN_INITIALIZER'] != "true"
@@ -23,17 +24,83 @@ module Piggybak
23
24
  end
24
25
 
25
26
  class Engine < Rails::Engine
27
+
26
28
  initializer "piggybak.add_helper" do |app|
27
29
  ApplicationController.class_eval do
28
30
  helper :piggybak
29
31
  end
30
32
  end
31
33
 
34
+ # Needed for development
35
+ config.to_prepare do
36
+ Piggybak.config.line_item_types.each do |k, v|
37
+ plural_k = k.to_s.pluralize.to_sym
38
+ if v[:nested_attrs]
39
+ Piggybak::LineItem.class_eval do
40
+ # TODO: dependent destroy destroys all line items. Figure out why
41
+ has_one k, :class_name => v[:class_name] #, :dependent => :destroy
42
+ accepts_nested_attributes_for k
43
+ attr_accessible "#{k}_attributes".to_sym
44
+ end
45
+ end
46
+ Piggybak::LineItem.class_eval do
47
+ scope plural_k, where(:line_item_type => "#{k}" )
48
+ end
49
+ Piggybak::Order.class_eval do
50
+ define_method "#{k}_charge" do
51
+ self.line_items.send(plural_k).inject(0) { |subtotal, li| subtotal + li.price }
52
+ end
53
+ end
54
+ end
55
+ end
56
+
32
57
  initializer "piggybak.rails_admin_config" do |app|
33
- # RailsAdmin config file. Generated on December 21, 2011 13:04
34
- # See github.com/sferik/rails_admin for more informations
58
+ Piggybak.config.line_item_types.each do |k, v|
59
+ plural_k = k.to_s.pluralize.to_sym
60
+ if v[:nested_attrs]
61
+ Piggybak::LineItem.class_eval do
62
+ # TODO: dependent destroy destroys all line items. Figure out why
63
+ has_one k, :class_name => v[:class_name] #, :dependent => :destroy
64
+ accepts_nested_attributes_for k
65
+ attr_accessible "#{k}_attributes".to_sym
66
+ end
67
+ end
68
+ end
69
+ RailsAdmin::Config.reset_model(Piggybak::LineItem)
35
70
 
36
71
  RailsAdmin.config do |config|
72
+ config.model Piggybak::LineItem do
73
+ label "Line Item"
74
+ object_label_method :admin_label
75
+ visible false
76
+
77
+ edit do
78
+ field :line_item_type do
79
+ label "Line Item Type"
80
+ partial "polymorphic_nested"
81
+ help ""
82
+ end
83
+ Piggybak.config.line_item_types.each do |k, v|
84
+ if v[:nested_attrs]
85
+ field k do
86
+ active true
87
+ end
88
+ end
89
+ end
90
+ field :sellable_id, :enum do
91
+ label "Sellable"
92
+ help "Required"
93
+ end
94
+ field :price
95
+ field :quantity
96
+ field :description
97
+ end
98
+ end
99
+
100
+ config.model Piggybak::Sellable do
101
+ visible false
102
+ end
103
+
37
104
  config.model Piggybak::Order do
38
105
  label "Order"
39
106
  navigation_label "Orders"
@@ -47,11 +114,6 @@ module Piggybak
47
114
  "$%.2f" % value
48
115
  end
49
116
  end
50
- field :tax_charge do
51
- formatted_value do
52
- "$%.2f" % value
53
- end
54
- end
55
117
  field :total_due do
56
118
  formatted_value do
57
119
  "$%.2f" % value
@@ -60,13 +122,12 @@ module Piggybak
60
122
  field :created_at
61
123
  field :email
62
124
  field :phone
63
- field :user
125
+
126
+ field :user if defined?(User)
64
127
 
65
128
  field :line_items
66
129
  field :billing_address
67
130
  field :shipping_address
68
- field :shipments
69
- field :payments
70
131
  field :order_notes do
71
132
  pretty_value do
72
133
  value.inject([]) { |arr, o| arr << o.details }.join("<br /><br />").html_safe
@@ -99,12 +160,6 @@ module Piggybak
99
160
  field :recorded_changer, :hidden do
100
161
  partial "recorded_changer"
101
162
  end
102
- # TODO: Figure out why this doesn't work here
103
- #field :recorded_changer, :hidden do
104
- # default_value do
105
- # bindings[:view]._current_user.id
106
- # end
107
- #end
108
163
  field :status do
109
164
  visible do
110
165
  !bindings[:object].new_record?
@@ -122,7 +177,7 @@ module Piggybak
122
177
  end
123
178
  end
124
179
 
125
- field :user
180
+ field :user if defined?(User)
126
181
  field :email
127
182
  field :phone
128
183
  field :ip_address do
@@ -131,28 +186,18 @@ module Piggybak
131
186
  field :user_agent do
132
187
  read_only true
133
188
  end
134
- field :billing_address do
135
- help "Required"
189
+ field :billing_address do
190
+ active true
191
+ help "Required"
136
192
  end
137
193
  field :shipping_address do
194
+ active true
138
195
  help "Required"
139
196
  end
140
197
  field :line_items do
141
198
  active true
142
199
  help ""
143
200
  end
144
- field :shipments do
145
- active true
146
- help ""
147
- end
148
- field :adjustments do
149
- active true
150
- help ""
151
- end
152
- field :payments do
153
- active true
154
- help ""
155
- end
156
201
  field :order_notes do
157
202
  active true
158
203
  end
@@ -163,7 +208,7 @@ module Piggybak
163
208
  object_label_method :admin_label
164
209
  visible false
165
210
  list do
166
- field :user
211
+ field :user if defined?(User)
167
212
  field :note
168
213
  field :created_at
169
214
  end
@@ -211,26 +256,7 @@ module Piggybak
211
256
  end
212
257
  end
213
258
 
214
- config.model Piggybak::LineItem do
215
- label "Line Item"
216
- object_label_method :admin_label
217
- visible false
218
-
219
- edit do
220
- field :variant
221
- field :quantity
222
- field :total do
223
- read_only true
224
- formatted_value do
225
- value ? "$%.2f" % value : '-'
226
- end
227
- help "This will automatically be calculated at the time of processing."
228
- end
229
- end
230
- end
231
-
232
259
  config.model Piggybak::Shipment do
233
- object_label_method :admin_label
234
260
  visible false
235
261
 
236
262
  edit do
@@ -242,53 +268,14 @@ module Piggybak
242
268
  field :status do
243
269
  label "Shipping Status"
244
270
  end
245
- field :total do
246
- read_only true
247
- formatted_value do
248
- "$%.2f" % value
249
- end
250
- help "This will automatically be calculated at the time of processing."
251
- end
252
271
  end
253
272
  end
254
-
273
+
255
274
  config.model Piggybak::Adjustment do
256
- object_label_method :admin_label
257
275
  visible false
258
- edit do
259
- field :user_id, :hidden do
260
- default_value do
261
- bindings[:view]._current_user.id
262
- end
263
- end
264
- field :source do
265
- help "Source of adjustment."
266
- visible do
267
- !bindings[:object].new_record?
268
- end
269
- read_only do
270
- !bindings[:object].new_record?
271
- end
272
- end
273
- field :total do
274
- help "<ul><li>Enter a negative value representing the customer refund amount. (This should be done AFTER completing a refund in the payment gateway) This will balance the invoice and remove the unbalanced status.</li></ul>".html_safe
275
- read_only do
276
- !bindings[:object].new_record?
277
- end
278
- formatted_value do
279
- "$%.2f" % value
280
- end
281
- end
282
- field :note do
283
- read_only do
284
- !bindings[:object].new_record?
285
- end
286
- end
287
- end
288
276
  end
289
-
277
+
290
278
  config.model Piggybak::Payment do
291
- object_label_method :admin_label
292
279
  visible false
293
280
 
294
281
  edit do
@@ -331,16 +318,6 @@ module Piggybak
331
318
  !bindings[:object].new_record?
332
319
  end
333
320
  end
334
- field :total do
335
- read_only true
336
- visible do
337
- !bindings[:object].new_record?
338
- end
339
- formatted_value do
340
- "$%.2f" % value
341
- end
342
- help "This will automatically be calculated at the time of processing."
343
- end
344
321
  end
345
322
  end
346
323
 
@@ -470,29 +447,6 @@ module Piggybak
470
447
  field :country
471
448
  end
472
449
  end
473
-
474
- config.model Piggybak::Variant do
475
- label "Variant"
476
- navigation_label "Orders"
477
- object_label_method :admin_label
478
- edit do
479
- field :item do
480
- read_only do
481
- !bindings[:object].new_record?
482
- end
483
- end
484
- include_all_fields
485
- field :unlimited_inventory do
486
- help "If true, backorders on this variant will be allowed, regardless of quantity on hand."
487
- end
488
- end
489
- list do
490
- field :description
491
- field :price
492
- field :quantity
493
- field :active
494
- end
495
- end
496
450
  end
497
451
  end
498
452
  end