piggybak 0.1.0

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