piggybak 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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