tb_checkout 1.0.3
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +162 -0
- data/Rakefile +24 -0
- data/app/assets/images/tb_checkout/admin/shopping_carts.png +0 -0
- data/app/assets/images/tb_checkout/admin/transactions.png +0 -0
- data/app/assets/javascripts/tb_checkout/admin/carts.js +2 -0
- data/app/assets/javascripts/tb_checkout/admin/transactions.js +2 -0
- data/app/assets/javascripts/tb_checkout/application.js +13 -0
- data/app/assets/javascripts/tb_checkout/cart_items.js +2 -0
- data/app/assets/javascripts/tb_checkout/carts.js +2 -0
- data/app/assets/javascripts/tb_checkout/transactions.js +2 -0
- data/app/assets/stylesheets/tb_checkout/admin/carts.css +4 -0
- data/app/assets/stylesheets/tb_checkout/admin/transactions.css +4 -0
- data/app/assets/stylesheets/tb_checkout/application.css +15 -0
- data/app/assets/stylesheets/tb_checkout/cart_items.css +4 -0
- data/app/assets/stylesheets/tb_checkout/carts.css +4 -0
- data/app/assets/stylesheets/tb_checkout/transactions.css +4 -0
- data/app/controllers/concerns/tb_checkout/controller_helpers.rb +16 -0
- data/app/controllers/tb_checkout/admin/carts_controller.rb +39 -0
- data/app/controllers/tb_checkout/admin/transactions_controller.rb +26 -0
- data/app/controllers/tb_checkout/application_controller.rb +6 -0
- data/app/controllers/tb_checkout/cart_items_controller.rb +63 -0
- data/app/controllers/tb_checkout/carts_controller.rb +8 -0
- data/app/controllers/tb_checkout/transactions_controller.rb +87 -0
- data/app/helpers/tb_checkout/admin/carts_helper.rb +13 -0
- data/app/helpers/tb_checkout/admin/transactions_helper.rb +16 -0
- data/app/helpers/tb_checkout/application_helper.rb +138 -0
- data/app/helpers/tb_checkout/transactions_helper.rb +2 -0
- data/app/models/concerns/tb_checkout/belongs_to_user_session.rb +15 -0
- data/app/models/concerns/tb_checkout/purchasable.rb +81 -0
- data/app/models/tb_checkout/basic_product.rb +6 -0
- data/app/models/tb_checkout/cart.rb +56 -0
- data/app/models/tb_checkout/cart_item.rb +48 -0
- data/app/models/tb_checkout/transaction.rb +253 -0
- data/app/views/tb_checkout/admin/carts/index.html.erb +54 -0
- data/app/views/tb_checkout/admin/carts/show.html.erb +45 -0
- data/app/views/tb_checkout/admin/transactions/_table.html.erb +24 -0
- data/app/views/tb_checkout/admin/transactions/index.html.erb +7 -0
- data/app/views/tb_checkout/admin/transactions/show.html.erb +70 -0
- data/app/views/tb_checkout/cart_items/create.html.erb +2 -0
- data/app/views/tb_checkout/cart_items/destroy.html.erb +2 -0
- data/app/views/tb_checkout/cart_items/update.html.erb +2 -0
- data/app/views/tb_checkout/carts/_cart.html.erb +65 -0
- data/app/views/tb_checkout/carts/show.html.erb +10 -0
- data/app/views/tb_checkout/transactions/_details.html.erb +17 -0
- data/app/views/tb_checkout/transactions/confirm.html.erb +11 -0
- data/app/views/tb_checkout/transactions/index.html.erb +29 -0
- data/app/views/tb_checkout/transactions/new.html.erb +90 -0
- data/app/views/tb_checkout/transactions/show.html.erb +14 -0
- data/config/locales/en.yml +23 -0
- data/config/routes.rb +20 -0
- data/db/migrate/20140703185256_create_tb_checkout_carts.rb +12 -0
- data/db/migrate/20140703185258_create_tb_checkout_cart_items.rb +15 -0
- data/db/migrate/20140703185259_create_tb_checkout_transactions.rb +23 -0
- data/db/migrate/20140707142350_create_tb_checkout_basic_products.rb +8 -0
- data/db/migrate/20140915202848_add_spud_user_and_session_id_to_transactions.rb +10 -0
- data/lib/tasks/tb_checkout_tasks.rake +19 -0
- data/lib/tb_checkout.rb +4 -0
- data/lib/tb_checkout/configuration.rb +8 -0
- data/lib/tb_checkout/engine.rb +36 -0
- data/lib/tb_checkout/schema.rb +51 -0
- data/lib/tb_checkout/version.rb +3 -0
- data/spec/controllers/tb_checkout/carts_controller_spec.rb +11 -0
- data/spec/controllers/tb_checkout/transactions_controller_spec.rb +110 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +30 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +13 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +82 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/migrate/20140915202259_create_spud_admin_permissions.tb_core.rb +12 -0
- data/spec/dummy/db/migrate/20140915202260_create_spud_users.tb_core.rb +30 -0
- data/spec/dummy/db/migrate/20140915202261_add_time_zone_to_spud_user.tb_core.rb +7 -0
- data/spec/dummy/db/migrate/20140915202262_add_scope_to_spud_admin_permissions.tb_core.rb +7 -0
- data/spec/dummy/db/migrate/20140915202263_create_spud_user_settings.tb_core.rb +12 -0
- data/spec/dummy/db/migrate/20140915202264_create_spud_roles.tb_core.rb +11 -0
- data/spec/dummy/db/migrate/20140915202265_create_spud_permissions.tb_core.rb +11 -0
- data/spec/dummy/db/migrate/20140915202266_create_spud_role_permissions.tb_core.rb +12 -0
- data/spec/dummy/db/migrate/20140915202267_drop_spud_admin_permissions.tb_core.rb +16 -0
- data/spec/dummy/db/migrate/20140915202268_create_tb_checkout_carts.tb_checkout_engine.rb +13 -0
- data/spec/dummy/db/migrate/20140915202269_create_tb_checkout_cart_items.tb_checkout_engine.rb +16 -0
- data/spec/dummy/db/migrate/20140915202270_create_tb_checkout_transactions.tb_checkout_engine.rb +24 -0
- data/spec/dummy/db/migrate/20140915202271_create_tb_checkout_basic_products.tb_checkout_engine.rb +9 -0
- data/spec/dummy/db/migrate/20140915234534_add_spud_user_and_session_id_to_transactions.tb_checkout_engine.rb +11 -0
- data/spec/dummy/db/schema.rb +135 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/spud_users.rb +16 -0
- data/spec/factories/tb_checkout_basic_products.rb +8 -0
- data/spec/factories/tb_checkout_cart_items.rb +11 -0
- data/spec/factories/tb_checkout_carts.rb +14 -0
- data/spec/factories/tb_checkout_transactions.rb +37 -0
- data/spec/models/tb_checkout/transaction_spec.rb +5 -0
- data/spec/rails_helper.rb +73 -0
- data/spec/spec_helper.rb +85 -0
- metadata +335 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
module TbCheckout
|
|
2
|
+
class Transaction < ActiveRecord::Base
|
|
3
|
+
self.table_name = 'tb_checkout_transactions'
|
|
4
|
+
belongs_to :cart, :inverse_of => :transactions
|
|
5
|
+
|
|
6
|
+
attr_accessor :card_number
|
|
7
|
+
attr_accessor :card_ccv
|
|
8
|
+
attr_reader :card_expiration
|
|
9
|
+
self.columns_hash['card_expiration'] = OpenStruct.new(type: :date, klass: Date)
|
|
10
|
+
|
|
11
|
+
attr_reader :response
|
|
12
|
+
|
|
13
|
+
validates_presence_of :cart, :billing_first_name, :billing_last_name, :billing_address_1,
|
|
14
|
+
:billing_city, :billing_state, :billing_postal, :card_type
|
|
15
|
+
validates_numericality_of :amount_charged, :greater_than => 0
|
|
16
|
+
validate :credit_card_is_valid, :on => :create
|
|
17
|
+
before_validation :set_amount_charged
|
|
18
|
+
before_create :set_invoice_num, :set_spud_user_and_session_id
|
|
19
|
+
|
|
20
|
+
include TbCheckout::BelongsToUserSession
|
|
21
|
+
|
|
22
|
+
# Transaction status
|
|
23
|
+
#
|
|
24
|
+
# Status describes the current state of a transaction
|
|
25
|
+
#
|
|
26
|
+
# * Pending: The transaction is newly created
|
|
27
|
+
# * Authorized: The transaction has been submitted to the payment gateway and successfully authorized
|
|
28
|
+
# * Captured: The transaction has been submitted to the payment gateway and the purchase is finalized
|
|
29
|
+
# * Fail: A failure code was received from the payment gateway
|
|
30
|
+
# * Voided: The transaction is voided in the gateway
|
|
31
|
+
# * Refunded: The transaction is refunded in the gateway
|
|
32
|
+
module Status
|
|
33
|
+
PENDING = 'pending'
|
|
34
|
+
AUTHORIZED = 'authorized'
|
|
35
|
+
CAPTURED = 'captured'
|
|
36
|
+
FAIL = 'fail'
|
|
37
|
+
VOIDED = 'voided'
|
|
38
|
+
REFUNDED = 'refunded'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Scopes
|
|
42
|
+
default_scope { order('created_at desc') }
|
|
43
|
+
scope :pending, ->{ where(:status => Status::PENDING) }
|
|
44
|
+
scope :authorized, ->{ where(:status => Status::AUTHORIZED) }
|
|
45
|
+
scope :captured, ->{ where(:status => Status::CAPTURED) }
|
|
46
|
+
scope :failed, ->{ where(:status => Status::FAIL) }
|
|
47
|
+
|
|
48
|
+
# Authorize the transaction against the payment gateway
|
|
49
|
+
#
|
|
50
|
+
# * The transaction must be in PENDING state in order ot take this action
|
|
51
|
+
def authorize!
|
|
52
|
+
self.with_lock(true) do
|
|
53
|
+
if self.status != Status::PENDING
|
|
54
|
+
raise StandardError, 'Payment must be in Pending state before authorization'
|
|
55
|
+
end
|
|
56
|
+
@response = TbCheckout.gateway.authorize(amount_in_cents, build_credit_card(), build_purchase_options())
|
|
57
|
+
if @response.success?
|
|
58
|
+
self.update_columns(:status => Status::AUTHORIZED, :gateway_transaction_id => @response.params['transaction_id'], :response_text => @response.to_json)
|
|
59
|
+
return true
|
|
60
|
+
else
|
|
61
|
+
self.update_columns(:status => Status::FAIL, :response_text => @response.to_json)
|
|
62
|
+
logger.fatal @response.inspect
|
|
63
|
+
return false
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Capture the funds from an authorized transaction through the payment gateway
|
|
69
|
+
#
|
|
70
|
+
# * The transaction must be in AUTHORIZED state in order ot take this action
|
|
71
|
+
def capture!
|
|
72
|
+
self.with_lock(true) do
|
|
73
|
+
if self.status != Status::AUTHORIZED
|
|
74
|
+
raise StandardError, 'Payment must be in Authorized state before capture'
|
|
75
|
+
end
|
|
76
|
+
@response = TbCheckout.gateway.capture(amount_in_cents, self.gateway_transaction_id)
|
|
77
|
+
if @response.success? || @response.params['action'] == 'PRIOR_AUTH_CAPTURE'
|
|
78
|
+
self.update_columns(:status => Status::CAPTURED, :response_text => @response.to_json)
|
|
79
|
+
else
|
|
80
|
+
self.update_columns(:status => Status::FAIL, :response_text => @response.to_json)
|
|
81
|
+
logger.fatal @response.inspect
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
if self.status == Status::CAPTURED
|
|
85
|
+
self.cart.update_attributes(:is_completed => true)
|
|
86
|
+
self.cart.cart_items.each do |cart_item|
|
|
87
|
+
cart_item.item.run_callbacks(:capture)
|
|
88
|
+
end
|
|
89
|
+
return true
|
|
90
|
+
else
|
|
91
|
+
return false
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Voids or Refunds the transaction
|
|
96
|
+
#
|
|
97
|
+
# * An unsettled trasanction cannot be refunded, and a settled transaction cannot be voided
|
|
98
|
+
# * Transactions are settled nightly
|
|
99
|
+
# * If the transaction is less than 24 hours old, attempt to void it and if that fails attempt a refund
|
|
100
|
+
def void_or_refund!
|
|
101
|
+
if (1.days.ago < self.created_at && void!) || refund!
|
|
102
|
+
return true
|
|
103
|
+
else
|
|
104
|
+
return false
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def amount_in_cents
|
|
109
|
+
return amount_charged * 100
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def billing_full_name
|
|
113
|
+
return "#{billing_first_name} #{billing_last_name}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def billing_full_address
|
|
117
|
+
street = [billing_address_1, billing_address_2].reject(&:blank?).join(', ')
|
|
118
|
+
return "#{street}, #{billing_city} #{billing_state}, #{billing_postal}"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Check for card_expiration value in String format and convert to Date format
|
|
122
|
+
#
|
|
123
|
+
def card_expiration=(date)
|
|
124
|
+
if date.is_a? String
|
|
125
|
+
begin
|
|
126
|
+
@card_expiration = Date.parse(date)
|
|
127
|
+
rescue ArgumentError => e
|
|
128
|
+
@card_expiration = nil
|
|
129
|
+
end
|
|
130
|
+
else
|
|
131
|
+
@card_expiration = date
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
|
|
137
|
+
def void!
|
|
138
|
+
self.with_lock(true) do
|
|
139
|
+
if self.status != Status::CAPTURED
|
|
140
|
+
raise StandardError, 'Payment must be in captured state before it can be voided'
|
|
141
|
+
end
|
|
142
|
+
@response = TbCheckout.gateway.void(gateway_transaction_id)
|
|
143
|
+
if @response.success?
|
|
144
|
+
self.update_columns(:status => Status::VOIDED, :response_text => @response.to_json)
|
|
145
|
+
return true
|
|
146
|
+
else
|
|
147
|
+
self.update_columns(:response_text => @response.to_json)
|
|
148
|
+
logger.fatal @response.inspect
|
|
149
|
+
return false
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def refund!
|
|
155
|
+
self.with_lock(true) do
|
|
156
|
+
if self.status != Status::CAPTURED
|
|
157
|
+
raise StandardError, 'Payment must be in captured state before it can be voided'
|
|
158
|
+
end
|
|
159
|
+
cc_last_four_digits = self.card_display.chars.last(4).join()
|
|
160
|
+
@response = TbCheckout.gateway.refund(amount_in_cents, self.gateway_transaction_id, {
|
|
161
|
+
:order_id => invoice_num,
|
|
162
|
+
:description => "REFUND: #{self.cart.description}",
|
|
163
|
+
:card_number => cc_last_four_digits,
|
|
164
|
+
:first_name => billing_first_name,
|
|
165
|
+
:last_name => billing_last_name,
|
|
166
|
+
:zip => billing_postal
|
|
167
|
+
})
|
|
168
|
+
if @response.success? || @response.params['response_reason_code'] == '55' # already refunded
|
|
169
|
+
self.update_columns(:status => Status::REFUNDED, :response_text => @response.to_json, :refund_gateway_transaction_id => @response.params['gateway_transaction_id'])
|
|
170
|
+
return true
|
|
171
|
+
else
|
|
172
|
+
self.update_columns(:response_text => @response.to_json)
|
|
173
|
+
logger.fatal @response.inspect
|
|
174
|
+
return false
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def credit_card_is_valid
|
|
180
|
+
if self.card_number.blank?
|
|
181
|
+
errors.add(:card_number, 'cannot be blank')
|
|
182
|
+
end
|
|
183
|
+
if self.card_ccv.blank?
|
|
184
|
+
errors.add(:card_ccv, 'cannot be blank')
|
|
185
|
+
end
|
|
186
|
+
if errors.size == 0
|
|
187
|
+
credit_card = build_credit_card()
|
|
188
|
+
if credit_card.valid?()
|
|
189
|
+
self.card_display = credit_card.display_number()
|
|
190
|
+
else
|
|
191
|
+
credit_card.errors.full_messages.each do |msg|
|
|
192
|
+
errors.add(:base, msg)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def build_credit_card
|
|
199
|
+
return ActiveMerchant::Billing::CreditCard.new({
|
|
200
|
+
:brand => card_type,
|
|
201
|
+
:number => card_number,
|
|
202
|
+
:verification_value => card_ccv,
|
|
203
|
+
:month => card_expiration.month,
|
|
204
|
+
:year => card_expiration.year,
|
|
205
|
+
:first_name => billing_first_name,
|
|
206
|
+
:last_name => billing_last_name
|
|
207
|
+
})
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def build_purchase_options
|
|
211
|
+
return {
|
|
212
|
+
:email => self.cart.spud_user.try(:email) || nil,
|
|
213
|
+
:order_id => self.invoice_num,
|
|
214
|
+
:description => self.cart.description,
|
|
215
|
+
:billing_address => {
|
|
216
|
+
:name => billing_full_name,
|
|
217
|
+
:address1 => billing_address_1,
|
|
218
|
+
:address2 => billing_address_2,
|
|
219
|
+
:city => billing_city,
|
|
220
|
+
:state => billing_state,
|
|
221
|
+
:country => country_for_billing_state(),
|
|
222
|
+
:zip => billing_postal,
|
|
223
|
+
:phone => self.cart.spud_user.try(:phone) || nil
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def set_amount_charged
|
|
229
|
+
if self.cart
|
|
230
|
+
self.amount_charged = self.cart.total_price
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def set_invoice_num
|
|
235
|
+
user_id = self.cart.spud_user_id || 0
|
|
236
|
+
self.invoice_num = [user_id, Time.now.to_i].join('-')
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def set_spud_user_and_session_id
|
|
240
|
+
self.spud_user_id = self.cart.spud_user_id || 0
|
|
241
|
+
self.session_id = self.cart.session_id || 0
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def country_for_billing_state
|
|
245
|
+
if ['AB', 'BC', 'MB', 'NB', 'NL', 'NS', 'NT', 'NU', 'ON', 'PE', 'QC', 'SK', 'YT'].include?(billing_state)
|
|
246
|
+
return 'Canada'
|
|
247
|
+
else
|
|
248
|
+
return 'USA'
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
end
|
|
253
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<% content_for :data_controls do %>
|
|
2
|
+
<%= form_tag tb_checkout_admin_carts_path, :method => :get, :class => 'tb-checkout-cart-filter-form' do %>
|
|
3
|
+
<%= select_tag :status, options_for_select([
|
|
4
|
+
['All', 'all'],
|
|
5
|
+
['Complete', 'completed'],
|
|
6
|
+
['In Progress', 'in-progress'],
|
|
7
|
+
['Abandoned', 'abandoned']
|
|
8
|
+
], params[:status]) %>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
11
|
+
|
|
12
|
+
<% content_for :detail do %>
|
|
13
|
+
<table class="table table-striped">
|
|
14
|
+
<thead>
|
|
15
|
+
<th>User</th>
|
|
16
|
+
<th>Description</th>
|
|
17
|
+
<th>Total Price</th>
|
|
18
|
+
<th>Status</th>
|
|
19
|
+
<th>Last Modified</th>
|
|
20
|
+
<th></th>
|
|
21
|
+
</thead>
|
|
22
|
+
<tbody>
|
|
23
|
+
<% @carts.each do |cart| %>
|
|
24
|
+
<tr>
|
|
25
|
+
<td class="no-wrap"><%= cart.user_full_name %></td>
|
|
26
|
+
<td><%= cart.description %></td>
|
|
27
|
+
<td>
|
|
28
|
+
<% if cart.is_empty? %>
|
|
29
|
+
Empty
|
|
30
|
+
<% else %>
|
|
31
|
+
<%= number_to_currency cart.total_price %>
|
|
32
|
+
<% end %>
|
|
33
|
+
</td>
|
|
34
|
+
<td>
|
|
35
|
+
<%= tb_checkout_status_label_for_cart(cart) %>
|
|
36
|
+
</td>
|
|
37
|
+
<td class="no-wrap"><%= cart.updated_at.strftime('%I:%M %p, %D') %></td>
|
|
38
|
+
<td>
|
|
39
|
+
<%= link_to 'Detail', tb_checkout_admin_cart_path(cart, :status => params[:status]), :class => 'btn btn-mini' %>
|
|
40
|
+
</td>
|
|
41
|
+
</tr>
|
|
42
|
+
<% end %>
|
|
43
|
+
</tbody>
|
|
44
|
+
</table>
|
|
45
|
+
<%= will_paginate @carts %>
|
|
46
|
+
|
|
47
|
+
<script>
|
|
48
|
+
$(document).ready(function(){
|
|
49
|
+
$('.tb-checkout-cart-filter-form').on('change', 'select', function(e){
|
|
50
|
+
$(this).parents('form').submit();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
<% end %>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<h3>General Info</h3>
|
|
2
|
+
|
|
3
|
+
<ul>
|
|
4
|
+
<li><strong>User</strong> <%= @cart.user_full_name %></li>
|
|
5
|
+
<li><strong>Created At</strong> <%= @cart.created_at.strftime('%I:%M %p, %D') %></li>
|
|
6
|
+
<li><strong>Last Modified</strong> <%= @cart.updated_at.strftime('%I:%M %p, %D') %></li>
|
|
7
|
+
<li><strong>Status</strong> <%= tb_checkout_status_label_for_cart(@cart) %></li>
|
|
8
|
+
</ul>
|
|
9
|
+
|
|
10
|
+
<h3>Products</h3>
|
|
11
|
+
|
|
12
|
+
<% if @cart.is_empty? %>
|
|
13
|
+
<p>This cart does not contain any items.</p>
|
|
14
|
+
<% else %>
|
|
15
|
+
<table class="table table-striped">
|
|
16
|
+
<thead>
|
|
17
|
+
<th>Product</th>
|
|
18
|
+
<th>Quantity</th>
|
|
19
|
+
<th>Price</th>
|
|
20
|
+
</thead>
|
|
21
|
+
<tbody>
|
|
22
|
+
<% @cart.cart_items.each do |cart_item| %>
|
|
23
|
+
<tr>
|
|
24
|
+
<td><%= cart_item.item_description %></td>
|
|
25
|
+
<td><%= cart_item.quantity %></td>
|
|
26
|
+
<td><%= number_to_currency cart_item.total_price %></td>
|
|
27
|
+
</tr>
|
|
28
|
+
<% end %>
|
|
29
|
+
</tbody>
|
|
30
|
+
<tfoot>
|
|
31
|
+
<tr>
|
|
32
|
+
<td colspan="2">Total</td>
|
|
33
|
+
<td><%= number_to_currency @cart.total_price %></td>
|
|
34
|
+
</tr>
|
|
35
|
+
</tfoot>
|
|
36
|
+
</table>
|
|
37
|
+
<% end %>
|
|
38
|
+
|
|
39
|
+
<h3>Transactions</h3>
|
|
40
|
+
|
|
41
|
+
<% if @cart.transactions.blank? %>
|
|
42
|
+
<p>There are no transactions associated with this shopping cart.</p>
|
|
43
|
+
<% else %>
|
|
44
|
+
<%= render :partial => '/tb_checkout/admin/transactions/table', :locals => {:transactions => @cart.transactions} %>
|
|
45
|
+
<% end %>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<table class="table table-striped">
|
|
2
|
+
<thead>
|
|
3
|
+
<th>Invoice Number</th>
|
|
4
|
+
<th>Transaction ID</th>
|
|
5
|
+
<th>Billing Name</th>
|
|
6
|
+
<th>Card</th>
|
|
7
|
+
<th>Amount Charged</th>
|
|
8
|
+
<th>Status</th>
|
|
9
|
+
<th></th>
|
|
10
|
+
</thead>
|
|
11
|
+
<tbody>
|
|
12
|
+
<% transactions.each do |transaction| %>
|
|
13
|
+
<tr>
|
|
14
|
+
<td><%= transaction.invoice_num %></td>
|
|
15
|
+
<td><%= transaction.gateway_transaction_id %></td>
|
|
16
|
+
<td class="no-wrap"><%= transaction.billing_full_name %></td>
|
|
17
|
+
<td class="no-wrap"><%= transaction.card_display %> (<%= transaction.card_type %>)</td>
|
|
18
|
+
<td><%= number_to_currency transaction.amount_charged %></td>
|
|
19
|
+
<td><%= tb_checkout_status_label_for_transaction(transaction.status) %></td>
|
|
20
|
+
<td><%= link_to 'Detail', tb_checkout_admin_transaction_path(transaction), :class => 'btn btn-mini' %></td>
|
|
21
|
+
</tr>
|
|
22
|
+
<% end %>
|
|
23
|
+
</tbody>
|
|
24
|
+
</table>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<h3>Summary</h3>
|
|
2
|
+
<table class="table table-bordered">
|
|
3
|
+
<thead>
|
|
4
|
+
<tr>
|
|
5
|
+
<th>User</th>
|
|
6
|
+
<th>Invoice Number</th>
|
|
7
|
+
<th>Transaction ID</th>
|
|
8
|
+
<th>Card</th>
|
|
9
|
+
<th>Amount Charged</th>
|
|
10
|
+
<th>Status</th>
|
|
11
|
+
</tr>
|
|
12
|
+
</thead>
|
|
13
|
+
<tbody>
|
|
14
|
+
<td><%= @transaction.cart.user_full_name %></td>
|
|
15
|
+
<td><%= @transaction.invoice_num %></td>
|
|
16
|
+
<td><%= @transaction.gateway_transaction_id %></td>
|
|
17
|
+
<td><%= @transaction.card_display %> (<%= @transaction.card_type %>)</td>
|
|
18
|
+
<td><%= number_to_currency @transaction.amount_charged %></td>
|
|
19
|
+
<td><%= tb_checkout_status_label_for_transaction(@transaction.status) %></td>
|
|
20
|
+
</tbody>
|
|
21
|
+
</table>
|
|
22
|
+
|
|
23
|
+
<h3>Billing Address</h3>
|
|
24
|
+
<table class="table table-bordered">
|
|
25
|
+
<thead>
|
|
26
|
+
<tr>
|
|
27
|
+
<th>Name</th>
|
|
28
|
+
<th>Address</th>
|
|
29
|
+
<th>Address 2</th>
|
|
30
|
+
<th>City</th>
|
|
31
|
+
<th>State</th>
|
|
32
|
+
<th>Postal</th>
|
|
33
|
+
</tr>
|
|
34
|
+
</thead>
|
|
35
|
+
<tbody>
|
|
36
|
+
<tr>
|
|
37
|
+
<td><%= @transaction.billing_full_name %></td>
|
|
38
|
+
<td><%= @transaction.billing_address_1 %></td>
|
|
39
|
+
<td><%= @transaction.billing_address_2 || "--" %></td>
|
|
40
|
+
<td><%= @transaction.billing_city %></td>
|
|
41
|
+
<td><%= @transaction.billing_state %></td>
|
|
42
|
+
<td><%= @transaction.billing_postal %></td>
|
|
43
|
+
</tr>
|
|
44
|
+
</table>
|
|
45
|
+
|
|
46
|
+
<h3>Line Items</h3>
|
|
47
|
+
<table class="table table-bordered">
|
|
48
|
+
<thead>
|
|
49
|
+
<tr>
|
|
50
|
+
<th>Product</th>
|
|
51
|
+
<th>Quantity</th>
|
|
52
|
+
<th>Price</th>
|
|
53
|
+
</tr>
|
|
54
|
+
</thead>
|
|
55
|
+
<tbody>
|
|
56
|
+
<% @transaction.cart.cart_items.each do |cart_item| %>
|
|
57
|
+
<tr>
|
|
58
|
+
<td><%= cart_item.item_description %></td>
|
|
59
|
+
<td><%= cart_item.quantity %></td>
|
|
60
|
+
<td><%= number_to_currency cart_item.total_price %></td>
|
|
61
|
+
</tr>
|
|
62
|
+
<% end %>
|
|
63
|
+
</tbody>
|
|
64
|
+
<tfoot>
|
|
65
|
+
<tr>
|
|
66
|
+
<td colspan="2">Total</td>
|
|
67
|
+
<td><%= number_to_currency @transaction.cart.total_price %></td>
|
|
68
|
+
</tr>
|
|
69
|
+
</tfoot>
|
|
70
|
+
</table>
|