piggybak 0.1.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 (63) hide show
  1. data/.document +5 -0
  2. data/Gemfile +13 -0
  3. data/Gemfile.lock +18 -0
  4. data/README.rdoc +19 -0
  5. data/Rakefile +56 -0
  6. data/VERSION +1 -0
  7. data/app/assets/javascripts/piggybak.js +72 -0
  8. data/app/controllers/piggybak/cart_controller.rb +29 -0
  9. data/app/controllers/piggybak/orders_controller.rb +86 -0
  10. data/app/mailers/piggybak/notifier.rb +10 -0
  11. data/app/models/piggybak/address.rb +23 -0
  12. data/app/models/piggybak/cart.rb +77 -0
  13. data/app/models/piggybak/line_item.rb +31 -0
  14. data/app/models/piggybak/order.rb +141 -0
  15. data/app/models/piggybak/payment.rb +80 -0
  16. data/app/models/piggybak/payment_calculator.rb +7 -0
  17. data/app/models/piggybak/payment_calculator/authorize_net.rb +6 -0
  18. data/app/models/piggybak/payment_calculator/fake.rb +24 -0
  19. data/app/models/piggybak/payment_method.rb +40 -0
  20. data/app/models/piggybak/payment_method_value.rb +11 -0
  21. data/app/models/piggybak/product.rb +19 -0
  22. data/app/models/piggybak/shipment.rb +21 -0
  23. data/app/models/piggybak/shipping_calculator.rb +12 -0
  24. data/app/models/piggybak/shipping_calculator/flat_rate.rb +13 -0
  25. data/app/models/piggybak/shipping_calculator/pickup.rb +23 -0
  26. data/app/models/piggybak/shipping_calculator/range.rb +16 -0
  27. data/app/models/piggybak/shipping_method.rb +55 -0
  28. data/app/models/piggybak/shipping_method_value.rb +11 -0
  29. data/app/models/piggybak/state.rb +4 -0
  30. data/app/models/piggybak/tax_calculator.rb +7 -0
  31. data/app/models/piggybak/tax_calculator/flat_rate.rb +33 -0
  32. data/app/models/piggybak/tax_method.rb +43 -0
  33. data/app/models/piggybak/tax_method_value.rb +11 -0
  34. data/app/views/piggybak/cart/_form.html.erb +18 -0
  35. data/app/views/piggybak/cart/_items.html.erb +68 -0
  36. data/app/views/piggybak/cart/show.html.erb +13 -0
  37. data/app/views/piggybak/notifier/order_notification.text.erb +11 -0
  38. data/app/views/piggybak/orders/_address_form.html.erb +24 -0
  39. data/app/views/piggybak/orders/list.html.erb +12 -0
  40. data/app/views/piggybak/orders/receipt.html.erb +53 -0
  41. data/app/views/piggybak/orders/show.html.erb +112 -0
  42. data/app/views/rails_admin/main/_actions.html.erb +5 -0
  43. data/config/routes.rb +15 -0
  44. data/db/migrate/20111227150106_create_orders.rb +21 -0
  45. data/db/migrate/20111227150322_create_addresses.rb +15 -0
  46. data/db/migrate/20111227150432_create_line_items.rb +10 -0
  47. data/db/migrate/20111227213558_create_products.rb +14 -0
  48. data/db/migrate/20111228231756_create_shipping_methods.rb +9 -0
  49. data/db/migrate/20111228231806_create_payment_methods.rb +11 -0
  50. data/db/migrate/20111228231829_create_payments.rb +17 -0
  51. data/db/migrate/20111228231838_create_shipments.rb +12 -0
  52. data/db/migrate/20111228235852_create_shipping_method_values.rb +9 -0
  53. data/db/migrate/20111228235853_create_payment_method_values.rb +9 -0
  54. data/db/migrate/20120102154050_create_tax_methods.rb +9 -0
  55. data/db/migrate/20120102162415_create_states.rb +8 -0
  56. data/db/migrate/20120102162703_create_tax_method_values.rb +9 -0
  57. data/lib/acts_as_orderer/base.rb +29 -0
  58. data/lib/acts_as_product/base.rb +32 -0
  59. data/lib/application_helper.rb +12 -0
  60. data/lib/currency.rb +5 -0
  61. data/lib/piggybak.rb +295 -0
  62. data/piggybak.gemspec +115 -0
  63. metadata +213 -0
data/config/routes.rb ADDED
@@ -0,0 +1,15 @@
1
+ Piggybak::Engine.routes.draw do
2
+ scope :module => "piggybak" do
3
+ match "/show" => "orders#show", :as => :orders
4
+ match "/cart" => "cart#show", :as => :cart
5
+ match "/cart/add" => "cart#add", :via => :post, :as => :cart_add
6
+ match "/cart/update" => "cart#update", :via => :post, :as => :cart_update
7
+ match "/cart/remove/:item" => "cart#remove", :via => :delete, :as => :remove_item
8
+ match "/submit" => "orders#submit", :via => :post, :as => :order_submit
9
+ match "/receipt" => "orders#receipt", :as => :receipt
10
+ match "/orders" => "orders#list", :as => :orders_list
11
+ match "/admin/orders/:id/email" => "orders#email", :as => :orders_email
12
+ match "/orders/shipping" => "orders#shipping", :as => :orders_shipping
13
+ match "/orders/tax" => "orders#tax", :as => :orders_tax
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ class CreateOrders < ActiveRecord::Migration
2
+ def change
3
+ create_table :orders do |t|
4
+ t.references :billing_address, :null => false
5
+ t.references :shipping_address, :null => false
6
+
7
+ t.references :user
8
+ t.string :email, :null => false
9
+ t.string :phone, :null => false
10
+
11
+ t.float :total, :null => false
12
+ t.float :total_due, :null => false
13
+ t.float :tax_charge, :null => false
14
+ t.string :status, :null => false
15
+
16
+ t.timestamps
17
+ end
18
+ end
19
+ end
20
+
21
+ # Note: To force precision, alter column type in database console
@@ -0,0 +1,15 @@
1
+ class CreateAddresses < ActiveRecord::Migration
2
+ def change
3
+ create_table :addresses do |t|
4
+ t.string :firstname, :null => false
5
+ t.string :lastname, :null => false
6
+ t.string :address1, :null => false
7
+ t.string :address2
8
+ t.string :city, :null => false
9
+ t.references :state, :null => false
10
+ t.string :zip, :null => false
11
+
12
+ t.timestamps
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ class CreateLineItems < ActiveRecord::Migration
2
+ def change
3
+ create_table :line_items do |t|
4
+ t.references :order, :null => false
5
+ t.integer :quantity, :null => false
6
+ t.references :product, :null => false
7
+ t.float :total
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ class CreateProducts < ActiveRecord::Migration
2
+ def change
3
+ create_table :products do |t|
4
+ t.string :sku, :null => false
5
+ t.string :description, :null => false
6
+ t.float :price, :null => false
7
+ t.integer :quantity, :null => false, :default => 0
8
+ t.integer :item_id, :null => false
9
+ t.string :item_type, :null => false
10
+ t.boolean :active, :null => false, :default => false
11
+ t.boolean :unlimited_inventory, :null => false, :default => false
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ class CreateShippingMethods < ActiveRecord::Migration
2
+ def change
3
+ create_table :shipping_methods do |t|
4
+ t.string :description, :null => false
5
+ t.string :klass, :null => false
6
+ t.boolean :active, :null => false, :default => false
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class CreatePaymentMethods < ActiveRecord::Migration
2
+ def change
3
+ create_table :payment_methods do |t|
4
+ t.string :description, :null => false
5
+ t.string :klass, :null => false
6
+ t.boolean :active, :null => false, :default => false
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ class CreatePayments < ActiveRecord::Migration
2
+ def change
3
+ create_table :payments do |t|
4
+ t.references :order
5
+ t.references :payment_method
6
+ t.string :status, :null => false, :default => 'paid'
7
+ t.float :total, :null => false, :default => 0.0
8
+
9
+ t.string :number
10
+ t.integer :month
11
+ t.integer :year
12
+ t.string :verification_value
13
+
14
+ t.timestamps
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ class CreateShipments < ActiveRecord::Migration
2
+ def change
3
+ create_table :shipments do |t|
4
+ t.references :order, :null => false
5
+ t.references :shipping_method, :null => false
6
+ t.string :status, :null => false, :default => "new"
7
+ t.float :total, :null => false, :default => 0.0
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ class CreateShippingMethodValues < ActiveRecord::Migration
2
+ def change
3
+ create_table :shipping_method_values do |t|
4
+ t.references :shipping_method
5
+ t.string :key
6
+ t.string :value
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class CreatePaymentMethodValues < ActiveRecord::Migration
2
+ def change
3
+ create_table :payment_method_values do |t|
4
+ t.references :payment_method
5
+ t.string :key
6
+ t.string :value
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class CreateTaxMethods < ActiveRecord::Migration
2
+ def change
3
+ create_table :tax_methods do |t|
4
+ t.string :description, :null => false
5
+ t.string :klass, :null => false
6
+ t.boolean :active, :null => false, :default => false
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ class CreateStates < ActiveRecord::Migration
2
+ def change
3
+ create_table :states do |t|
4
+ t.string :name
5
+ t.string :abbr
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ class CreateTaxMethodValues < ActiveRecord::Migration
2
+ def change
3
+ create_table :tax_method_values do |t|
4
+ t.references :tax_method
5
+ t.string :key
6
+ t.string :value
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ module Piggybak
2
+ module ActsAsOrderer
3
+ module Base
4
+ def self.included(klass)
5
+ klass.class_eval do
6
+ extend ClassMethods
7
+ end
8
+ end
9
+
10
+ module ClassMethods
11
+ def acts_as_orderer
12
+ has_many :piggybak_orders, :foreign_key => "user_id", :class_name => "::Piggybak::Order"
13
+
14
+ include Piggybak::ActsAsOrderer::Base::InstanceMethods
15
+ end
16
+ end
17
+
18
+ module InstanceMethods
19
+
20
+ def factory_name
21
+ "this is an example instance method"
22
+ end
23
+
24
+ end # InstanceMethods
25
+ end
26
+ end
27
+ end
28
+
29
+ ::ActiveRecord::Base.send :include, Piggybak::ActsAsOrderer::Base
@@ -0,0 +1,32 @@
1
+ module Piggybak
2
+ module ActsAsProduct
3
+ ## Define ModelMethods
4
+ module Base
5
+ def self.included(klass)
6
+ klass.class_eval do
7
+ extend ClassMethods
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ def acts_as_product
13
+ has_one :piggybak_product, :as => "item", :class_name => "::Piggybak::Product"
14
+
15
+ accepts_nested_attributes_for :piggybak_product, :allow_destroy => true
16
+
17
+ include Piggybak::ActsAsProduct::Base::InstanceMethods
18
+ end
19
+ end
20
+
21
+ module InstanceMethods
22
+
23
+ def factory_name
24
+ "this is an example instance method"
25
+ end
26
+
27
+ end # InstanceMethods
28
+ end
29
+ end
30
+ end
31
+
32
+ ::ActiveRecord::Base.send :include, Piggybak::ActsAsProduct::Base
@@ -0,0 +1,12 @@
1
+ module ApplicationHelper
2
+ def cart_form(object)
3
+ render "piggybak/cart/form", :object => object
4
+ end
5
+ def cart_link
6
+ cart = Piggybak::Cart.new(request.cookies["cart"])
7
+ nitems = cart.items.inject(0) { |nitems, item| nitems + item[:quantity] }
8
+ if nitems > 0
9
+ link_to "#{pluralize(nitems, 'item')}: #{number_to_currency(cart.total)}", piggybak.cart_url
10
+ end
11
+ end
12
+ end
data/lib/currency.rb ADDED
@@ -0,0 +1,5 @@
1
+ class Float
2
+ def to_c
3
+ ((self*100).to_i).to_f/100
4
+ end
5
+ end
data/lib/piggybak.rb ADDED
@@ -0,0 +1,295 @@
1
+ require 'acts_as_product/base'
2
+ require 'acts_as_orderer/base'
3
+ require 'application_helper'
4
+ require 'active_merchant'
5
+ require 'currency'
6
+
7
+ ActiveMerchant::Billing::Base.mode = :test
8
+
9
+ module Piggybak
10
+ class Engine < Rails::Engine
11
+ initializer "define rails_admin config" do |app|
12
+ # RailsAdmin config file. Generated on December 21, 2011 13:04
13
+ # See github.com/sferik/rails_admin for more informations
14
+
15
+ RailsAdmin.config do |config|
16
+ config.model Piggybak::Order do
17
+ label "Order"
18
+ navigation_label "Piggybak Orders"
19
+ weight 1
20
+ object_label_method :admin_label
21
+
22
+ show do
23
+ field :status
24
+ field :total
25
+ field :tax_charge
26
+ field :total_due
27
+ field :created_at
28
+ field :email
29
+ field :phone
30
+ field :user
31
+
32
+ field :line_items
33
+ field :billing_address
34
+ field :shipping_address
35
+ field :shipments
36
+ field :payments
37
+ end
38
+ list do
39
+ field :status
40
+ field :total do
41
+ formatted_value do
42
+ "$%.2f" % value
43
+ end
44
+ end
45
+ field :created_at do
46
+ strftime_format "%d-%m-%Y"
47
+ end
48
+ field :user
49
+ end
50
+ edit do
51
+ field :details do
52
+ read_only true
53
+ help "Autopopulated"
54
+ end
55
+ field :user do
56
+ read_only do
57
+ !bindings[:object].new_record?
58
+ end
59
+ end
60
+ field :email
61
+ field :phone
62
+ field :billing_address
63
+ field :shipping_address
64
+ field :line_items
65
+ field :shipments
66
+ field :payments
67
+ field :actions do
68
+ partial "actions"
69
+ help "Click above to resend email with current order details."
70
+ end
71
+ end
72
+ end
73
+
74
+ config.model Piggybak::Address do
75
+ label "Address"
76
+ parent Piggybak::Order
77
+ object_label_method :admin_label
78
+ visible false
79
+ end
80
+
81
+ config.model Piggybak::LineItem do
82
+ label "Line Item"
83
+ object_label_method :admin_label
84
+ visible false
85
+
86
+ edit do
87
+ field :product
88
+ field :quantity
89
+ field :total do
90
+ read_only true
91
+ formatted_value do
92
+ value ? "$%.2f" % value : '-'
93
+ end
94
+ help "This will automatically be calculated at the time of processing."
95
+ end
96
+ end
97
+ end
98
+
99
+ config.model Piggybak::Shipment do
100
+ parent Piggybak::Order
101
+ object_label_method :admin_label
102
+ visible false
103
+
104
+ edit do
105
+ field :shipping_method
106
+ field :status
107
+ field :total do
108
+ read_only true
109
+ formatted_value do
110
+ "$%.2f" % value
111
+ end
112
+ help "This will automatically be calculated at the time of processing."
113
+ end
114
+ end
115
+ end
116
+
117
+ config.model Piggybak::Payment do
118
+ parent Piggybak::Order
119
+ object_label_method :admin_label
120
+ visible false
121
+
122
+ edit do
123
+ #field :details do
124
+ # read_only true
125
+ # help "Autopopulated"
126
+ #end
127
+ field :payment_method do
128
+ read_only do
129
+ !bindings[:object].new_record?
130
+ end
131
+ end
132
+ field :number do
133
+ read_only do
134
+ !bindings[:object].new_record?
135
+ end
136
+ end
137
+ field :month do
138
+ read_only do
139
+ !bindings[:object].new_record?
140
+ end
141
+ end
142
+ field :year do
143
+ read_only do
144
+ !bindings[:object].new_record?
145
+ end
146
+ end
147
+ field :verification_value do
148
+ read_only do
149
+ !bindings[:object].new_record?
150
+ end
151
+ end
152
+ field :total do
153
+ read_only true
154
+ formatted_value do
155
+ "$%.2f" % value
156
+ end
157
+ help "This will automatically be calculated at the time of processing."
158
+ end
159
+ end
160
+ end
161
+
162
+ config.model Piggybak::PaymentMethod do
163
+ navigation_label "Piggybak Configuration"
164
+ weight 2
165
+ object_label_method :admin_label
166
+ list do
167
+ field :description
168
+ field :active
169
+ end
170
+ edit do
171
+ field :description do
172
+ help "This is the label the user sees."
173
+ end
174
+ field :klass do
175
+ label "Calculator"
176
+ end
177
+ field :active
178
+ field :payment_method_values do
179
+ label "Metadata"
180
+ end
181
+ end
182
+ end
183
+
184
+ config.model Piggybak::PaymentMethodValue do
185
+ object_label_method :admin_label
186
+ visible false
187
+ edit do
188
+ include_all_fields
189
+ field :payment_method do
190
+ visible false
191
+ end
192
+ end
193
+ end
194
+
195
+ config.model Piggybak::ShippingMethod do
196
+ parent Piggybak::PaymentMethod
197
+ object_label_method :admin_label
198
+ edit do
199
+ field :description do
200
+ help "This is the label the user sees."
201
+ end
202
+ field :klass do
203
+ label "Calculator"
204
+ end
205
+ field :active
206
+ field :shipping_method_values do
207
+ label "Metadata"
208
+ end
209
+ end
210
+ list do
211
+ field :description
212
+ field :active
213
+ end
214
+ end
215
+
216
+ config.model Piggybak::ShippingMethodValue do
217
+ object_label_method :admin_label
218
+ visible false
219
+ edit do
220
+ include_all_fields
221
+ field :shipping_method do
222
+ visible false
223
+ end
224
+ end
225
+ end
226
+
227
+ config.model Piggybak::TaxMethod do
228
+ parent Piggybak::PaymentMethod
229
+ object_label_method :admin_label
230
+ edit do
231
+ field :description
232
+ field :klass do
233
+ label "Calculator"
234
+ end
235
+ field :active
236
+ field :tax_method_values do
237
+ label "Metadata"
238
+ end
239
+ end
240
+ list do
241
+ field :description
242
+ field :active
243
+ end
244
+ end
245
+
246
+ config.model Piggybak::TaxMethodValue do
247
+ object_label_method :admin_label
248
+ visible false
249
+ edit do
250
+ include_all_fields
251
+ field :tax_method do
252
+ visible false
253
+ end
254
+ end
255
+ end
256
+
257
+ config.model Piggybak::State do
258
+ weight 1
259
+ parent Piggybak::PaymentMethod
260
+ list do
261
+ field :name
262
+ field :abbr
263
+ end
264
+ edit do
265
+ field :name
266
+ field :abbr
267
+ end
268
+ end
269
+
270
+ config.model Piggybak::Product do
271
+ label "Product"
272
+ parent Piggybak::Order
273
+ object_label_method :admin_label
274
+ edit do
275
+ field :item do
276
+ read_only do
277
+ !bindings[:object].new_record?
278
+ end
279
+ end
280
+ include_all_fields
281
+ field :unlimited_inventory do
282
+ help "If true, backorders on this product will be allowed, regardless of quantity on hand."
283
+ end
284
+ end
285
+ list do
286
+ field :description
287
+ field :price
288
+ field :quantity
289
+ field :active
290
+ end
291
+ end
292
+ end
293
+ end
294
+ end
295
+ end