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.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +18 -0
- data/README.rdoc +19 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/app/assets/javascripts/piggybak.js +72 -0
- data/app/controllers/piggybak/cart_controller.rb +29 -0
- data/app/controllers/piggybak/orders_controller.rb +86 -0
- data/app/mailers/piggybak/notifier.rb +10 -0
- data/app/models/piggybak/address.rb +23 -0
- data/app/models/piggybak/cart.rb +77 -0
- data/app/models/piggybak/line_item.rb +31 -0
- data/app/models/piggybak/order.rb +141 -0
- data/app/models/piggybak/payment.rb +80 -0
- data/app/models/piggybak/payment_calculator.rb +7 -0
- data/app/models/piggybak/payment_calculator/authorize_net.rb +6 -0
- data/app/models/piggybak/payment_calculator/fake.rb +24 -0
- data/app/models/piggybak/payment_method.rb +40 -0
- data/app/models/piggybak/payment_method_value.rb +11 -0
- data/app/models/piggybak/product.rb +19 -0
- data/app/models/piggybak/shipment.rb +21 -0
- data/app/models/piggybak/shipping_calculator.rb +12 -0
- data/app/models/piggybak/shipping_calculator/flat_rate.rb +13 -0
- data/app/models/piggybak/shipping_calculator/pickup.rb +23 -0
- data/app/models/piggybak/shipping_calculator/range.rb +16 -0
- data/app/models/piggybak/shipping_method.rb +55 -0
- data/app/models/piggybak/shipping_method_value.rb +11 -0
- data/app/models/piggybak/state.rb +4 -0
- data/app/models/piggybak/tax_calculator.rb +7 -0
- data/app/models/piggybak/tax_calculator/flat_rate.rb +33 -0
- data/app/models/piggybak/tax_method.rb +43 -0
- data/app/models/piggybak/tax_method_value.rb +11 -0
- data/app/views/piggybak/cart/_form.html.erb +18 -0
- data/app/views/piggybak/cart/_items.html.erb +68 -0
- data/app/views/piggybak/cart/show.html.erb +13 -0
- data/app/views/piggybak/notifier/order_notification.text.erb +11 -0
- data/app/views/piggybak/orders/_address_form.html.erb +24 -0
- data/app/views/piggybak/orders/list.html.erb +12 -0
- data/app/views/piggybak/orders/receipt.html.erb +53 -0
- data/app/views/piggybak/orders/show.html.erb +112 -0
- data/app/views/rails_admin/main/_actions.html.erb +5 -0
- data/config/routes.rb +15 -0
- data/db/migrate/20111227150106_create_orders.rb +21 -0
- data/db/migrate/20111227150322_create_addresses.rb +15 -0
- data/db/migrate/20111227150432_create_line_items.rb +10 -0
- data/db/migrate/20111227213558_create_products.rb +14 -0
- data/db/migrate/20111228231756_create_shipping_methods.rb +9 -0
- data/db/migrate/20111228231806_create_payment_methods.rb +11 -0
- data/db/migrate/20111228231829_create_payments.rb +17 -0
- data/db/migrate/20111228231838_create_shipments.rb +12 -0
- data/db/migrate/20111228235852_create_shipping_method_values.rb +9 -0
- data/db/migrate/20111228235853_create_payment_method_values.rb +9 -0
- data/db/migrate/20120102154050_create_tax_methods.rb +9 -0
- data/db/migrate/20120102162415_create_states.rb +8 -0
- data/db/migrate/20120102162703_create_tax_method_values.rb +9 -0
- data/lib/acts_as_orderer/base.rb +29 -0
- data/lib/acts_as_product/base.rb +32 -0
- data/lib/application_helper.rb +12 -0
- data/lib/currency.rb +5 -0
- data/lib/piggybak.rb +295 -0
- data/piggybak.gemspec +115 -0
- metadata +213 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
module Piggybak
|
|
2
|
+
class Order < ActiveRecord::Base
|
|
3
|
+
has_many :line_items, :inverse_of => :order
|
|
4
|
+
has_many :payments, :inverse_of => :order
|
|
5
|
+
has_many :shipments, :inverse_of => :order
|
|
6
|
+
belongs_to :billing_address, :class_name => "Piggybak::Address"
|
|
7
|
+
belongs_to :shipping_address, :class_name => "Piggybak::Address"
|
|
8
|
+
belongs_to :user
|
|
9
|
+
|
|
10
|
+
accepts_nested_attributes_for :billing_address, :allow_destroy => true
|
|
11
|
+
accepts_nested_attributes_for :shipping_address, :allow_destroy => true
|
|
12
|
+
accepts_nested_attributes_for :shipments, :allow_destroy => true
|
|
13
|
+
accepts_nested_attributes_for :line_items, :allow_destroy => true
|
|
14
|
+
accepts_nested_attributes_for :payments
|
|
15
|
+
|
|
16
|
+
validates_presence_of :status
|
|
17
|
+
validates_presence_of :email
|
|
18
|
+
validates_presence_of :phone
|
|
19
|
+
validates_presence_of :total
|
|
20
|
+
validates_presence_of :total_due
|
|
21
|
+
validates_presence_of :tax_charge
|
|
22
|
+
validates_presence_of :created_at
|
|
23
|
+
|
|
24
|
+
before_validation :set_defaults
|
|
25
|
+
after_validation :update_totals
|
|
26
|
+
before_save :process_payments, :update_status
|
|
27
|
+
|
|
28
|
+
def process_payments
|
|
29
|
+
has_errors = false
|
|
30
|
+
self.payments.each do |payment|
|
|
31
|
+
if(!payment.process)
|
|
32
|
+
has_errors = true
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
self.total_due = self.total
|
|
37
|
+
payments.each do |payment|
|
|
38
|
+
self.total_due -= payment.total
|
|
39
|
+
end
|
|
40
|
+
!has_errors
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def details
|
|
44
|
+
if !self.new_record?
|
|
45
|
+
subtotal = self.line_items.inject(0) { |subtotal, li| subtotal + li.total }
|
|
46
|
+
shipping = self.shipments.inject(0) { |shipping, shipment| shipping + shipment.total }
|
|
47
|
+
return "Status: #{self.status}<br />" +
|
|
48
|
+
"Subtotal: $#{"%.2f" % subtotal}<br />" +
|
|
49
|
+
"Shipping: $#{"%.2f" % shipping}<br />" +
|
|
50
|
+
"Tax: $#{"%.2f" % self.tax_charge}<br />" +
|
|
51
|
+
"Due: $#{"%.2f" % self.total_due}<br />" +
|
|
52
|
+
"Created at: #{self.created_at.strftime("%m-%d-%Y")}<br />" #details here"
|
|
53
|
+
else
|
|
54
|
+
return "New Order"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def add_line_items(cart)
|
|
59
|
+
cart.update_quantities
|
|
60
|
+
cart.items.each do |item|
|
|
61
|
+
line_item = Piggybak::LineItem.new({ :product_id => item[:product].id,
|
|
62
|
+
:total => item[:product].price*item[:quantity],
|
|
63
|
+
:quantity => item[:quantity] })
|
|
64
|
+
self.line_items << line_item
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def set_defaults
|
|
69
|
+
self.created_at ||= Time.now
|
|
70
|
+
self.status ||= "new"
|
|
71
|
+
self.total = 0
|
|
72
|
+
self.total_due = 0
|
|
73
|
+
self.tax_charge = 0
|
|
74
|
+
|
|
75
|
+
self.line_items.each do |line_item|
|
|
76
|
+
line_item.total = line_item.product.price * line_item.quantity
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def update_totals
|
|
81
|
+
self.total = 0
|
|
82
|
+
|
|
83
|
+
self.line_items.each do |line_item|
|
|
84
|
+
self.total += line_item.total
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
self.tax_charge = TaxMethod.calculate_tax(self)
|
|
88
|
+
self.total += self.tax_charge
|
|
89
|
+
|
|
90
|
+
shipments.each do |shipment|
|
|
91
|
+
if shipment.new_record?
|
|
92
|
+
calculator = shipment.shipping_method.klass.constantize
|
|
93
|
+
shipment.total = calculator.rate(shipment.shipping_method, self)
|
|
94
|
+
end
|
|
95
|
+
logger.warn "steph shipment total is #{shipment.total}"
|
|
96
|
+
self.total += shipment.total
|
|
97
|
+
end
|
|
98
|
+
logger.warn "steph: total is #{self.total}"
|
|
99
|
+
self.total = self.total.to_c
|
|
100
|
+
|
|
101
|
+
self.total_due = self.total
|
|
102
|
+
payments.each do |payment|
|
|
103
|
+
self.total_due -= payment.total
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def update_status
|
|
108
|
+
if self.total_due > 0.00
|
|
109
|
+
self.status = "payment owed"
|
|
110
|
+
elsif self.total_due < 0.00
|
|
111
|
+
self.status = "credit_owed"
|
|
112
|
+
else
|
|
113
|
+
if self.total == 0.00
|
|
114
|
+
self.status = "new"
|
|
115
|
+
elsif self.shipments.all? { |s| s.status == "shipped" }
|
|
116
|
+
self.status = "shipped"
|
|
117
|
+
else
|
|
118
|
+
self.status = "paid"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def status_enum
|
|
124
|
+
["incomplete", "paid", "shipped"]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def avs_address
|
|
128
|
+
{
|
|
129
|
+
:address1 => self.billing_address.address1,
|
|
130
|
+
:city => self.billing_address.city,
|
|
131
|
+
:state => self.billing_address.state,
|
|
132
|
+
:zip => self.billing_address.zip,
|
|
133
|
+
:country => "US"
|
|
134
|
+
}
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def admin_label
|
|
138
|
+
"Order ##{self.id}"
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
module Piggybak
|
|
2
|
+
class Payment < ActiveRecord::Base
|
|
3
|
+
belongs_to :order
|
|
4
|
+
belongs_to :payment_method
|
|
5
|
+
|
|
6
|
+
validates_presence_of :status
|
|
7
|
+
validates_presence_of :total
|
|
8
|
+
validates_presence_of :payment_method_id
|
|
9
|
+
validates_presence_of :month
|
|
10
|
+
validates_presence_of :year
|
|
11
|
+
|
|
12
|
+
def status_enum
|
|
13
|
+
["paid"]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def month_enum
|
|
17
|
+
1.upto(12)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def year_enum
|
|
21
|
+
Time.now.year.upto(Time.now.year + 10)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def credit_card
|
|
25
|
+
{ "number" => self.number,
|
|
26
|
+
"month" => self.month,
|
|
27
|
+
"year" => self.year,
|
|
28
|
+
"verification_value" => self.verification_value,
|
|
29
|
+
"first_name" => self.order.billing_address.firstname,
|
|
30
|
+
"last_name" => self.order.billing_address.lastname }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def process
|
|
34
|
+
if self.new_record?
|
|
35
|
+
payment_gateway = self.payment_method.klass.constantize
|
|
36
|
+
gateway = payment_gateway::KLASS.new(self.payment_method.key_values)
|
|
37
|
+
credit_card = ActiveMerchant::Billing::CreditCard.new(self.credit_card)
|
|
38
|
+
gateway_response = gateway.authorize(self.order.total_due*100, credit_card, :address => self.order.avs_address)
|
|
39
|
+
if gateway_response.success?
|
|
40
|
+
self.attributes = { :total => self.order.total_due,
|
|
41
|
+
:number => 'hidden',
|
|
42
|
+
:verification_value => 'hidden' }
|
|
43
|
+
gateway.capture(1000, gateway_response.authorization)
|
|
44
|
+
return true
|
|
45
|
+
else
|
|
46
|
+
self.errors.add :payment_method_id, gateway_response.message
|
|
47
|
+
return false
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
return true
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def admin_label
|
|
55
|
+
if !self.new_record?
|
|
56
|
+
return "Payment ##{self.id} (#{self.created_at.strftime("%m-%d-%Y")})<br />" +
|
|
57
|
+
"Payment Method: #{self.payment_method.description}<br />" +
|
|
58
|
+
"Status: #{self.status}<br />" +
|
|
59
|
+
"$#{"%.2f" % self.total}"
|
|
60
|
+
else
|
|
61
|
+
return ""
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
alias :details :admin_label
|
|
65
|
+
|
|
66
|
+
validates_each :payment_method_id do |record, attr, value|
|
|
67
|
+
if record.new_record?
|
|
68
|
+
credit_card = ActiveMerchant::Billing::CreditCard.new(record.credit_card)
|
|
69
|
+
|
|
70
|
+
if !credit_card.valid?
|
|
71
|
+
credit_card.errors.each do |key, value|
|
|
72
|
+
if value.any? && !["first_name", "last_name", "type"].include?(key)
|
|
73
|
+
record.errors.add key, value
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Piggybak
|
|
2
|
+
class PaymentCalculator::Fake < PaymentCalculator
|
|
3
|
+
KEYS = []
|
|
4
|
+
KLASS = ::Piggybak::PaymentCalculator::Fake
|
|
5
|
+
|
|
6
|
+
def self.new(*args)
|
|
7
|
+
return self
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.authorize(*args)
|
|
11
|
+
self
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.success?
|
|
15
|
+
true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.authorization
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.capture(*args)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Piggybak
|
|
2
|
+
class PaymentMethod < ActiveRecord::Base
|
|
3
|
+
has_many :payment_method_values, :dependent => :destroy
|
|
4
|
+
alias :metadata :payment_method_values
|
|
5
|
+
|
|
6
|
+
accepts_nested_attributes_for :payment_method_values, :allow_destroy => true
|
|
7
|
+
|
|
8
|
+
validates_presence_of :klass
|
|
9
|
+
validates_presence_of :description
|
|
10
|
+
|
|
11
|
+
def klass_enum
|
|
12
|
+
#TODO: Troubleshoot use of subclasses here instead
|
|
13
|
+
[Piggybak::PaymentCalculator::AuthorizeNet,
|
|
14
|
+
Piggybak::PaymentCalculator::Fake]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
validates_each :payment_method_values do |record, attr, value|
|
|
18
|
+
if record.klass
|
|
19
|
+
payment_method = record.klass.constantize
|
|
20
|
+
metadata_keys = value.collect { |v| v.key }.sort
|
|
21
|
+
if payment_method::KEYS.sort != metadata_keys
|
|
22
|
+
record.errors.add attr, "You must define key values for #{payment_method::KEYS.join(', ')} for this payment method."
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
validates_each :active do |record, attr, value|
|
|
27
|
+
if value && PaymentMethod.find_all_by_active(true).select { |p| p != record }.size > 0
|
|
28
|
+
record.errors.add attr, "You may only have one active payment method."
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def key_values
|
|
33
|
+
self.metadata.inject({}) { |h, k| h[k.key.to_sym] = k.value; h }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def admin_label
|
|
37
|
+
"#{self.description}"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class Piggybak::Product < ActiveRecord::Base
|
|
2
|
+
belongs_to :item, :polymorphic => true, :inverse_of => :piggybak_product
|
|
3
|
+
attr_accessible :sku, :description, :price, :quantity, :active, :unlimited_inventory, :item_id, :item_type
|
|
4
|
+
|
|
5
|
+
validates_presence_of :sku
|
|
6
|
+
validates_uniqueness_of :sku
|
|
7
|
+
validates_presence_of :description
|
|
8
|
+
validates_presence_of :price
|
|
9
|
+
validates_presence_of :item_type
|
|
10
|
+
validates_numericality_of :quantity, :only_integer => true, :greater_than_or_equal_to => 0
|
|
11
|
+
|
|
12
|
+
def admin_label
|
|
13
|
+
"Product: #{self.description}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def update_inventory(purchased)
|
|
17
|
+
self.update_attribute(:quantity, self.quantity + purchased)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Piggybak
|
|
2
|
+
class Shipment < ActiveRecord::Base
|
|
3
|
+
belongs_to :order
|
|
4
|
+
belongs_to :shipping_method
|
|
5
|
+
|
|
6
|
+
validates_presence_of :status
|
|
7
|
+
validates_presence_of :total
|
|
8
|
+
validates_presence_of :shipping_method_id
|
|
9
|
+
|
|
10
|
+
def status_enum
|
|
11
|
+
["new", "processing", "shipped"]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def admin_label
|
|
15
|
+
"Shipment ##{self.id}<br />" +
|
|
16
|
+
"#{self.shipping_method.description}<br />" +
|
|
17
|
+
"Status: #{self.status}<br />" +
|
|
18
|
+
"$#{"%.2f" % self.total}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Piggybak
|
|
2
|
+
class ShippingCalculator::FlatRate < ShippingCalculator
|
|
3
|
+
KEYS = ["rate"]
|
|
4
|
+
|
|
5
|
+
def self.available?(*args)
|
|
6
|
+
true
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.rate(method, object)
|
|
10
|
+
method.metadata.detect { |m| m.key == "rate" }.value.to_f.to_c
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Piggybak
|
|
2
|
+
class ShippingCalculator::Pickup < ShippingCalculator
|
|
3
|
+
KEYS = ["state_abbr", "rate"]
|
|
4
|
+
|
|
5
|
+
def self.available?(method, object)
|
|
6
|
+
abbr = method.metadata.detect { |t| t.key == "state_abbr" }.value
|
|
7
|
+
|
|
8
|
+
if object.is_a?(Cart)
|
|
9
|
+
state = State.find(object.extra_data["state_id"])
|
|
10
|
+
return true if state.abbr == abbr
|
|
11
|
+
else
|
|
12
|
+
if object.billing_address && object.billing_address.state
|
|
13
|
+
return object.billing_address.state.abbr == abbr
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
return false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.rate(method, object)
|
|
20
|
+
method.metadata.detect { |m| m.key == "rate" }.value.to_f.to_c
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Piggybak
|
|
2
|
+
class ShipppingCalculator::Range < ShippingCalculator
|
|
3
|
+
KEYS = ["cost", "upper", "lower"]
|
|
4
|
+
|
|
5
|
+
def self.available?(method, object)
|
|
6
|
+
low_end = method.metadata.detect { |m| m.key == "lower" }.value
|
|
7
|
+
high_end = method.metadata.detect { |m| m.key == "upper" }.value
|
|
8
|
+
|
|
9
|
+
object.total >= low_end.to_f && object.total <= high_end.to_f
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.rate(method, object)
|
|
13
|
+
method.metadata.detect { |m| m.key == "cost" }.value.to_f.to_c
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Piggybak
|
|
2
|
+
class ShippingMethod < ActiveRecord::Base
|
|
3
|
+
has_many :shipping_method_values, :dependent => :destroy
|
|
4
|
+
alias :metadata :shipping_method_values
|
|
5
|
+
|
|
6
|
+
validates_presence_of :description
|
|
7
|
+
validates_presence_of :klass
|
|
8
|
+
|
|
9
|
+
accepts_nested_attributes_for :shipping_method_values, :allow_destroy => true
|
|
10
|
+
|
|
11
|
+
validates_each :shipping_method_values do |record, attr, value|
|
|
12
|
+
if record.klass
|
|
13
|
+
calculator = record.klass.constantize
|
|
14
|
+
metadata_keys = value.collect { |v| v.key }.sort
|
|
15
|
+
if calculator::KEYS.sort != metadata_keys
|
|
16
|
+
record.errors.add attr, "You must define key values for #{calculator::KEYS.join(', ')} for this shipping method."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def klass_enum
|
|
22
|
+
#TODO: Troubleshoot use of subclasses here instead
|
|
23
|
+
[Piggybak::ShippingCalculator::FlatRate,
|
|
24
|
+
Piggybak::ShippingCalculator::Range,
|
|
25
|
+
Piggybak::ShippingCalculator::Pickup]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.available_methods(cart)
|
|
29
|
+
active_methods = ShippingMethod.find_all_by_active(true)
|
|
30
|
+
|
|
31
|
+
active_methods.select { |method| method.klass.constantize.available?(method, cart) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.lookup_methods(cart)
|
|
35
|
+
active_methods = ShippingMethod.find_all_by_active(true)
|
|
36
|
+
|
|
37
|
+
active_methods.inject([]) do |arr, method|
|
|
38
|
+
klass = method.klass.constantize
|
|
39
|
+
logger.warn "steph: inside here!! #{method.inspect}"
|
|
40
|
+
if klass.available?(method, cart)
|
|
41
|
+
rate = klass.rate(method, cart)
|
|
42
|
+
logger.warn "steph rate is #{rate.inspect}"
|
|
43
|
+
arr << {
|
|
44
|
+
:label => "#{method.description} $#{"%.2f" % rate}",
|
|
45
|
+
:id => method.id,
|
|
46
|
+
:rate => rate }
|
|
47
|
+
end
|
|
48
|
+
arr
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
def admin_label
|
|
52
|
+
self.description
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|