kaui 0.1.11 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. data/app/controllers/kaui/accounts_controller.rb +12 -2
  2. data/app/controllers/kaui/bundles_controller.rb +1 -1
  3. data/app/controllers/kaui/invoice_items_controller.rb +11 -0
  4. data/app/controllers/kaui/invoices_controller.rb +3 -0
  5. data/app/controllers/kaui/refunds_controller.rb +12 -2
  6. data/app/controllers/kaui/subscriptions_controller.rb +1 -1
  7. data/app/helpers/kaui/killbill_helper.rb +35 -10
  8. data/app/models/kaui/account.rb +6 -0
  9. data/app/models/kaui/refund.rb +2 -1
  10. data/app/views/kaui/account_timelines/show.html.erb +104 -46
  11. data/app/views/kaui/accounts/show.html.erb +32 -3
  12. data/app/views/kaui/invoices/show.html.erb +25 -2
  13. data/app/views/kaui/refunds/new.html.erb +212 -15
  14. data/app/views/kaui/subscriptions/_subscriptions_table.html.erb +25 -3
  15. data/config/routes.rb +2 -1
  16. data/lib/kaui/version.rb +1 -1
  17. data/test/dummy/app/assets/javascripts/application.js +1 -0
  18. data/test/dummy/log/development.log +13530 -0
  19. data/test/dummy/log/test.log +1634 -0
  20. data/test/dummy/test/fixtures/refunds.yml +2 -1
  21. data/test/dummy/tmp/cache/assets/C8D/080/sprockets%2F4556c595251e3b8d4f688467e330da26 +0 -0
  22. data/test/dummy/tmp/cache/assets/CFF/A00/sprockets%2F642f58fb154eff788f45c881b294e818 +0 -0
  23. data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  24. data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  25. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  26. data/test/dummy/tmp/pids/server.pid +1 -0
  27. data/test/test_helper.rb +6 -2
  28. data/test/unit/kaui/base_test.rb +18 -12
  29. data/test/unit/kaui/refund_test.rb +2 -1
  30. metadata +8 -2
@@ -15,7 +15,7 @@ class Kaui::AccountsController < Kaui::EngineController
15
15
  key.strip!
16
16
 
17
17
  begin
18
- @account = Kaui::KillbillHelper::get_account_by_key(key, true)
18
+ @account = Kaui::KillbillHelper::get_account_by_key_with_balance_and_cba(key)
19
19
  rescue URI::InvalidURIError => e
20
20
  flash[:error] = "Error while retrieving the account for #{key}: #{e.message}"
21
21
  render :action => :index and return
@@ -161,9 +161,19 @@ class Kaui::AccountsController < Kaui::EngineController
161
161
  begin
162
162
  @account = Kaui::KillbillHelper::update_email_notifications(params[:id], params[:is_notified])
163
163
  flash[:notice] = "Email preferences updated"
164
- redirect_to :back
165
164
  rescue => e
166
165
  flash[:error] = "Error while switching email notifications #{invoice_id}: #{as_string(e)}"
167
166
  end
167
+ redirect_to :back
168
+ end
169
+
170
+ def pay_all_invoices
171
+ begin
172
+ @account = Kaui::KillbillHelper::pay_all_invoices(params[:id], false, current_user, params[:reason], params[:comment])
173
+ flash[:notice] = "Successfully triggered a payment for all unpaid invoices"
174
+ rescue => e
175
+ flash[:error] = "Error while triggering payments: #{as_string(e)}"
176
+ end
177
+ redirect_to :back
168
178
  end
169
179
  end
@@ -46,7 +46,7 @@ class Kaui::BundlesController < Kaui::EngineController
46
46
  key = params[:new_account_key]
47
47
  if key.present?
48
48
  begin
49
- result = Kaui::KillbillHelper.get_account_by_key(key, false)
49
+ result = Kaui::KillbillHelper.get_account_by_key(key)
50
50
  rescue => e
51
51
  flash[:error] = "Error while retrieving account for #{key}: #{as_string(e)}"
52
52
  render :action => :index
@@ -25,6 +25,17 @@ class Kaui::InvoiceItemsController < Kaui::EngineController
25
25
  end
26
26
  end
27
27
 
28
+ def destroy
29
+ begin
30
+ Kaui::KillbillHelper.delete_cba(params[:account_id], params[:invoice_id], params[:id], current_user, params[:reason], params[:comment])
31
+ flash[:notice] = "CBA deleted"
32
+ redirect_to kaui_engine.invoice_path(params[:invoice_id])
33
+ rescue => e
34
+ flash[:error] = "Error while deleting the CBA: #{as_string(e)}"
35
+ redirect_to kaui_engine.invoice_path(params[:invoice_id])
36
+ end
37
+ end
38
+
28
39
  private
29
40
 
30
41
  def find_invoice_item
@@ -16,8 +16,11 @@ class Kaui::InvoicesController < Kaui::EngineController
16
16
 
17
17
  @subscriptions = {}
18
18
  @bundles = {}
19
+ @cba_items_not_deleteable = []
19
20
  if @invoice.items.present?
20
21
  @invoice.items.each do |item|
22
+ @cba_items_not_deleteable << item.linked_invoice_item_id if item.description =~ /account credit/ and item.amount < 0
23
+
21
24
  unless item.subscription_id.nil? || @subscriptions.has_key?(item.subscription_id)
22
25
  @subscriptions[item.subscription_id] = Kaui::KillbillHelper.get_subscription(item.subscription_id)
23
26
  end
@@ -53,9 +53,19 @@ class Kaui::RefundsController < Kaui::EngineController
53
53
  def create
54
54
  payment_id = params[:payment_id]
55
55
  account_id = params[:account_id]
56
-
57
56
  refund = Kaui::Refund.new(params[:refund])
58
- refund.adjusted = (refund.adjusted == "1")
57
+ refund.adjusted = (refund.adjustment_type != "noInvoiceAdjustment")
58
+ if refund.adjustment_type == "invoiceItemAdjustment"
59
+ refund.adjustments = []
60
+ params[:adjustments].each_with_index do |ii, idx|
61
+ h = Hash.new
62
+ h[:invoice_item_id] = ii[0]
63
+ h[:amount] = ii[1]
64
+ kaui_ii = Kaui::InvoiceItem.new(h)
65
+ puts "Got #{kaui_ii.inspect}"
66
+ refund.adjustments[idx] = kaui_ii
67
+ end
68
+ end
59
69
  if refund.present?
60
70
  begin
61
71
  Kaui::KillbillHelper::create_refund(params[:payment_id], refund, current_user, params[:reason], params[:comment])
@@ -157,7 +157,7 @@ class Kaui::SubscriptionsController < Kaui::EngineController
157
157
  subscription_id = params[:id]
158
158
  if subscription_id.present?
159
159
  begin
160
- Kaui::KillbillHelper::delete_subscription(subscription_id, current_user)
160
+ Kaui::KillbillHelper::delete_subscription(subscription_id, params[:policy], current_user)
161
161
  rescue => e
162
162
  flash[:error] = "Error while reinstating subscription: #{as_string(e)}"
163
163
  end
@@ -39,12 +39,16 @@ module Kaui
39
39
 
40
40
  ############## ACCOUNT ##############
41
41
 
42
- def self.get_account_by_key(key, with_balance)
42
+ def self.get_account_by_key_with_balance_and_cba(key)
43
+ self.get_account_by_key(key, false, true)
44
+ end
45
+
46
+ def self.get_account_by_key(key, with_balance = false, with_balance_and_cba = false)
43
47
  # support id (UUID) and external key search
44
48
  if key =~ /[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}/
45
- Kaui::KillbillHelper.get_account(key, with_balance)
49
+ Kaui::KillbillHelper.get_account(key, with_balance, with_balance_and_cba)
46
50
  else
47
- Kaui::KillbillHelper.get_account_by_external_key(key, with_balance)
51
+ Kaui::KillbillHelper.get_account_by_external_key(key, with_balance, with_balance_and_cba)
48
52
  end
49
53
  end
50
54
 
@@ -53,13 +57,13 @@ module Kaui
53
57
  process_response(data, :single) {|json| Kaui::AccountTimeline.new(json) }
54
58
  end
55
59
 
56
- def self.get_account(account_id, with_balance=false)
57
- data = call_killbill :get, "/1.0/kb/accounts/#{account_id}?accountWithBalance=#{with_balance}"
60
+ def self.get_account(account_id, with_balance = false, with_balance_and_cba = false)
61
+ data = call_killbill :get, "/1.0/kb/accounts/#{account_id}?accountWithBalance=#{with_balance}&accountWithBalanceAndCBA=#{with_balance_and_cba}"
58
62
  process_response(data, :single) {|json| Kaui::Account.new(json) }
59
63
  end
60
64
 
61
- def self.get_account_by_external_key(external_key, with_balance=false)
62
- data = call_killbill :get, "/1.0/kb/accounts?externalKey=#{external_key}&accountWithBalance=#{with_balance}"
65
+ def self.get_account_by_external_key(external_key, with_balance = false, with_balance_and_cba = false)
66
+ data = call_killbill :get, "/1.0/kb/accounts?externalKey=#{external_key}&accountWithBalance=#{with_balance}&accountWithBalanceAndCBA=#{with_balance_and_cba}"
63
67
  process_response(data, :single) {|json| Kaui::Account.new(json) }
64
68
  end
65
69
 
@@ -201,9 +205,10 @@ module Kaui
201
205
  "X-Killbill-Comment" => "#{comment}"
202
206
  end
203
207
 
204
- def self.delete_subscription(subscription_id, current_user = nil, reason = nil, comment = nil)
208
+ def self.delete_subscription(subscription_id, policy = nil, current_user = nil, reason = nil, comment = nil)
209
+ params = "?policy=#{policy}" unless policy.blank?
205
210
  call_killbill :delete,
206
- "/1.0/kb/subscriptions/#{subscription_id}",
211
+ "/1.0/kb/subscriptions/#{subscription_id}#{params}",
207
212
  "X-Killbill-CreatedBy" => current_user,
208
213
  "X-Killbill-Reason" => "#{reason}",
209
214
  "X-Killbill-Comment" => "#{comment}"
@@ -267,6 +272,14 @@ module Kaui
267
272
  end
268
273
  end
269
274
 
275
+ def self.delete_cba(account_id, invoice_id, invoice_item_id, current_user = nil, reason = nil, comment = nil)
276
+ call_killbill :delete,
277
+ "/1.0/kb/invoices/#{invoice_id}/#{invoice_item_id}/cba?accountId=#{account_id}",
278
+ "X-Killbill-CreatedBy" => current_user,
279
+ "X-Killbill-Reason" => "#{reason}",
280
+ "X-Killbill-Comment" => "#{comment}"
281
+ end
282
+
270
283
  ############## CATALOG ##############
271
284
 
272
285
  def self.get_full_catalog
@@ -301,11 +314,21 @@ module Kaui
301
314
  return response_data
302
315
  end
303
316
 
317
+ def self.pay_all_invoices(account_id, external = false, current_user = nil, reason = nil, comment = nil)
318
+ call_killbill :post,
319
+ "/1.0/kb/invoices/payments?externalPayment=#{external}",
320
+ ActiveSupport::JSON.encode({:accountId => account_id}, :root => false),
321
+ :content_type => "application/json",
322
+ "X-Killbill-CreatedBy" => current_user,
323
+ "X-Killbill-Reason" => extract_reason_code(reason),
324
+ "X-Killbill-Comment" => "#{comment}"
325
+ end
326
+
304
327
  def self.create_payment(payment, external, current_user = nil, reason = nil, comment = nil)
305
328
  payment_data = Kaui::Payment.camelize(payment.to_hash)
306
329
 
307
330
  if payment.invoice_id.present?
308
- # We should use different model for POST and GEt, this seems fragile...
331
+ # We should use different model for POST and GET, this seems fragile...
309
332
  payment_data.delete(:external)
310
333
  payment_data.delete(:refunds)
311
334
  payment_data.delete(:chargebacks)
@@ -380,6 +403,8 @@ module Kaui
380
403
 
381
404
  def self.create_refund(payment_id, refund, current_user = nil, reason = nil, comment = nil)
382
405
  refund_data = Kaui::Refund.camelize(refund.to_hash)
406
+ # We don't want to pass adjustment_type
407
+ refund_data.delete(:adjustmentType)
383
408
 
384
409
  call_killbill :post,
385
410
  "/1.0/kb/payments/#{payment_id}/refunds",
@@ -16,6 +16,7 @@ class Kaui::Account < Kaui::Base
16
16
  define_attr :country
17
17
  define_attr :phone
18
18
  define_attr :balance
19
+ define_attr :cba
19
20
  define_attr :is_notified_for_invoices
20
21
  has_one :bill_cycle_day, Kaui::BillCycleDay
21
22
 
@@ -36,6 +37,7 @@ class Kaui::Account < Kaui::Base
36
37
  :phone => data['phone'],
37
38
  :bill_cycle_day => data['billCycleDay'],
38
39
  :balance => data['accountBalance'],
40
+ :cba => data['accountCBA'],
39
41
  :is_notified_for_invoices => data['isNotifiedForInvoices'])
40
42
  end
41
43
 
@@ -46,4 +48,8 @@ class Kaui::Account < Kaui::Base
46
48
  def balance_to_money
47
49
  Kaui::Base.to_money(balance.abs, currency)
48
50
  end
51
+
52
+ def cba_to_money
53
+ Kaui::Base.to_money(cba.abs, currency)
54
+ end
49
55
  end
@@ -13,9 +13,10 @@ class Kaui::Refund < Kaui::Base
13
13
  define_attr :currency
14
14
  define_attr :requested_date
15
15
  define_attr :effective_date
16
- define_attr :adjustments
16
+ define_attr :adjustment_type
17
17
 
18
18
  has_many :audit_logs, Kaui::AuditLog
19
+ has_many :adjustments, Kaui::InvoiceItem
19
20
 
20
21
  def amount_to_money
21
22
  Kaui::Base.to_money(amount, currency)
@@ -15,13 +15,13 @@
15
15
  </div>
16
16
  </form>
17
17
  <hr/>
18
- <table id="timeline-table" class="table table-condensed data-table">
18
+ <table id="timeline-table" class="table table-condensed">
19
19
  <thead>
20
20
  <tr>
21
- <th class="sort-title-string">Requested Date</th>
22
- <th class="data-table-sort-desc sort-title-string">Effective Date</th>
21
+ <th>Requested Date</th>
22
+ <th>Effective Date</th>
23
23
  <th>Bundle Name</th>
24
- <th class="data-table-sort-desc">Event Type</th>
24
+ <th>Event Type</th>
25
25
  <th>Details</th>
26
26
  <th>Reason Code / Comments</th>
27
27
  <th>Actions</th>
@@ -41,14 +41,12 @@
41
41
  <tr title="<%= bundles %>">
42
42
  <td>
43
43
  <% if invoice.invoice_date.present? %>
44
- <span class="hide" title="<%= invoice.invoice_date %>"></span>
45
44
  <%= invoice.invoice_date %>
46
45
  <% else %>
47
46
  [unknown]
48
47
  <% end %>
49
48
  <td>
50
49
  <% if invoice.target_date.present? %>
51
- <span class="hide" title="<%= invoice.target_date %>"></span>
52
50
  <%= invoice.target_date %>
53
51
  <% else %>
54
52
  [unknown]
@@ -62,7 +60,8 @@
62
60
  <% end %>
63
61
  </td>
64
62
  <td><%= "INVOICE" %></td>
65
- <td><%= "Amount:" %> <%= humanized_money_with_symbol invoice.amount_to_money(@account.currency) %><br/>
63
+ <td><span class="hide" title="<%= invoice.invoice_number %>"></span>
64
+ <%= "Amount:" %> <%= humanized_money_with_symbol invoice.amount_to_money(@account.currency) %><br/>
66
65
  <%= "Balance:" %> <%= humanized_money_with_symbol invoice.balance_to_money(@account.currency) %><br/>
67
66
  <% if invoice.credit_adjustment.present? && invoice.credit_adjustment > 0 %>
68
67
  <%= "Credit adjustment:" %> <%= humanized_money_with_symbol invoice.credit_adjustment_to_money(@account.currency) %><br/>
@@ -84,20 +83,18 @@
84
83
  <% end %>
85
84
  </td>
86
85
  <td>
87
- <% if invoice.balance > 0 %>
88
- <nobr>
89
- <%= link_to "Credit",
90
- kaui_engine.new_credit_path(:params => { :account_id => invoice.account_id,
91
- :invoice_id => invoice.invoice_id }),
92
- :class => "btn btn-mini" %>
93
- </nobr>
94
- <nobr>
95
- <%= link_to "Payment",
96
- kaui_engine.new_payment_path(:params => { :account_id => invoice.account_id,
97
- :invoice_id => invoice.invoice_id }),
98
- :class => "btn btn-mini" %>
99
- </nobr>
100
- <% end %>
86
+ <nobr>
87
+ <%= link_to "Payment",
88
+ kaui_engine.new_payment_path(:params => { :account_id => invoice.account_id,
89
+ :invoice_id => invoice.invoice_id }),
90
+ :class => "btn btn-mini #{"disabled" unless invoice.balance > 0}" %>
91
+ </nobr>
92
+ <nobr>
93
+ <%= link_to "Credit",
94
+ kaui_engine.new_credit_path(:params => { :account_id => invoice.account_id,
95
+ :invoice_id => invoice.invoice_id }),
96
+ :class => "btn btn-mini" %>
97
+ </nobr>
101
98
  <nobr>
102
99
  <%= link_to "Charge",
103
100
  kaui_engine.new_charge_path(:params => { :account_id => invoice.account_id,
@@ -113,7 +110,6 @@
113
110
  <tr title="<%= bundles %>">
114
111
  <td>
115
112
  <% if refund.requested_date.present? %>
116
- <span class="hide" title="<%= refund.requested_date %>"></span>
117
113
  <%= format_date(refund.requested_date).html_safe %>
118
114
  <% else %>
119
115
  [unknown]
@@ -121,7 +117,6 @@
121
117
  </td>
122
118
  <td>
123
119
  <% if refund.effective_date.present? %>
124
- <span class="hide" title="<%= refund.effective_date %>"></span>
125
120
  <%= format_date(refund.effective_date).html_safe %>
126
121
  <% else %>
127
122
  [unknown]
@@ -153,7 +148,6 @@
153
148
  <tr title="<%= bundles %>">
154
149
  <td>
155
150
  <% if chargeback.effective_date.present? %>
156
- <span class="hide" title="<%= chargeback.effective_date %>"></span>
157
151
  <%= format_date(chargeback.effective_date).html_safe %>
158
152
  <% else %>
159
153
  [unknown]
@@ -161,7 +155,6 @@
161
155
  </td>
162
156
  <td>
163
157
  <% if chargeback.effective_date.present? %>
164
- <span class="hide" title="<%= chargeback.effective_date %>"></span>
165
158
  <%= format_date(chargeback.effective_date).html_safe %>
166
159
  <% else %>
167
160
  [unknown]
@@ -197,7 +190,6 @@
197
190
  <tr title="<%= bundles %>">
198
191
  <td>
199
192
  <% if payment.requested_date.present? %>
200
- <span class="hide" title="<%= payment.requested_date %>"></span>
201
193
  <%= format_date(payment.requested_date).html_safe %>
202
194
  <% else %>
203
195
  [unknown]
@@ -205,7 +197,6 @@
205
197
  </td>
206
198
  <td>
207
199
  <% if payment.effective_date.present? %>
208
- <span class="hide" title="<%= payment.effective_date %>"></span>
209
200
  <%= format_date(payment.effective_date).html_safe %>
210
201
  <% else %>
211
202
  [unknown]
@@ -218,6 +209,7 @@
218
209
  </td>
219
210
  <td><%= "PAYMENT" %></td>
220
211
  <td>
212
+ <span class="hide" title="<%= invoice.invoice_number %>"></span>
221
213
  <%= "Payment id:" %> <%= payment.payment_id %><br/>
222
214
  <%= "Total amount:" %> <%= humanized_money_with_symbol payment.amount_to_money %><br/>
223
215
  <%= "Paid amount:" %> <%= humanized_money_with_symbol payment.paid_amount_to_money %><br/>
@@ -235,23 +227,18 @@
235
227
  <% end %>
236
228
  </td>
237
229
  <td>
238
- <% if payment.payment_id.present? %>
239
- <nobr>
240
- <%= link_to 'Refund', kaui_engine.new_refund_path(:params => { :payment_id => payment.payment_id,
241
- :account_id => @account.account_id,
242
- :invoice_id => payment.invoice_id }),
243
- :class => "btn btn-mini" %>
244
- <%= link_to 'Chargeback', kaui_engine.new_chargeback_path(:params => { :payment_id => payment.payment_id,
245
- :account_id => @account.account_id,
246
- :invoice_id => payment.invoice_id }),
247
- :class => "btn btn-mini" %>
248
- </nobr>
249
- <% elsif invoice.balance > 0 %>
250
- <%= link_to 'Pay', kaui_engine.new_payment_path(:params => { :payment_id => payment.payment_id,
230
+ <nobr>
231
+ <%= link_to 'Refund', kaui_engine.new_refund_path(:params => { :payment_id => payment.payment_id,
251
232
  :account_id => @account.account_id,
252
233
  :invoice_id => payment.invoice_id }),
253
- :class => "btn btn-mini" %>
254
- <% end %>
234
+ :class => "btn btn-mini #{"disabled" unless payment.payment_id.present?}" %>
235
+ </nobr>
236
+ <nobr>
237
+ <%= link_to 'Chargeback', kaui_engine.new_chargeback_path(:params => { :payment_id => payment.payment_id,
238
+ :account_id => @account.account_id,
239
+ :invoice_id => payment.invoice_id }),
240
+ :class => "btn btn-mini #{"disabled" unless payment.payment_id.present?}" %>
241
+ </nobr>
255
242
  </td>
256
243
  </tr>
257
244
  <% end %>
@@ -263,7 +250,6 @@
263
250
  <tr title="<%= @bundle_names[bundle.external_key] %>">
264
251
  <td>
265
252
  <% if event.requested_date.present? %>
266
- <span class="hide" title="<%= event.requested_date %>"></span>
267
253
  <%= format_date(event.requested_date).html_safe %>
268
254
  <% else %>
269
255
  [unknown]
@@ -271,7 +257,6 @@
271
257
  </td>
272
258
  <td>
273
259
  <% if event.effective_date.present? %>
274
- <span class="hide" title="<%= event.effective_date %>"></span>
275
260
  <%= format_date(event.effective_date).html_safe %>
276
261
  <% else %>
277
262
  [unknown]
@@ -281,7 +266,7 @@
281
266
  <%= link_to @bundle_names[bundle.external_key], Kaui.bundle_home_path.call(bundle.external_key) %><br/>
282
267
  </td>
283
268
  <td><%= event.event_type %></td>
284
- <td><%= event.product %> <%= event.billing_period == 'NO_BILLING_PERIOD' || event.billing_period.nil? ? "" : event.billing_period.downcase.capitalize %> <%= event.phase.downcase.capitalize if event.phase.present? %></td>
269
+ <td><span class="hide" title="<%= sub.product_category %>"></span><%= event.product %> <%= event.billing_period == 'NO_BILLING_PERIOD' || event.billing_period.nil? ? "" : event.billing_period.downcase.capitalize %> <%= event.phase.downcase.capitalize if event.phase.present? %></td>
285
270
  <td>
286
271
  <% if event.audit_logs.present? %>
287
272
  <% event.audit_logs.each do |entry| %>
@@ -301,10 +286,74 @@
301
286
  <%= link_to 'Back', :back, :class => 'btn' %>
302
287
  </div>
303
288
  <%= javascript_tag do %>
289
+ function disableLinks() {
290
+ $('a.btn.disabled').click(function (e) {
291
+ e.preventDefault();
292
+ });
293
+ }
294
+
295
+ eventsOrder = ["CREATE", "PHASE", "CHANGE", "CANCEL", "INVOICE", "PAYMENT", "REFUND", "CHARGEBACK"];
296
+
297
+ jQuery.fn.dataTableExt.oSort['timeline-event-asc'] = function(e1,e2) {
298
+ var x = eventsOrder.indexOf(e1);
299
+ var y = eventsOrder.indexOf(e2);
300
+ return ((x < y) ? -1 : ((x > y) ? 1 : 0));
301
+ };
302
+
303
+ jQuery.fn.dataTableExt.oSort['timeline-event-desc'] = function(e1,e2) {
304
+ var x = eventsOrder.indexOf(e1);
305
+ var y = eventsOrder.indexOf(e2);
306
+ return ((x < y) ? 1 : ((x > y) ? -1 : 0));
307
+ };
308
+
309
+ function extractTitleAttributeFromText(txt) {
310
+ // Ugly - better way of doing this?
311
+ var matches = txt.match(/title="\w+"/g);
312
+ if (matches == null || matches.size == 0) {
313
+ return null;
314
+ }
315
+ return matches[0].split('=')[1];
316
+ }
317
+
318
+ jQuery.fn.dataTableExt.oSort['timeline-details-asc'] = function(e1,e2) {
319
+ var x = extractTitleAttributeFromText(e1);
320
+ var y = extractTitleAttributeFromText(e2);
321
+ return ((x < y) ? -1 : ((x > y) ? 1 : 0));
322
+ };
323
+
324
+ jQuery.fn.dataTableExt.oSort['timeline-details-desc'] = function(e1,e2) {
325
+ var x = extractTitleAttributeFromText(e1);
326
+ var y = extractTitleAttributeFromText(e2);
327
+ return ((x < y) ? 1 : ((x > y) ? -1 : 0));
328
+ };
329
+
330
+ function initTable() {
331
+ return $("#timeline-table").dataTable({
332
+ "sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
333
+ "sPaginationType": "bootstrap",
334
+ "oLanguage": {
335
+ "sLengthMenu": "_MENU_ records per page"
336
+ },
337
+ "iDisplayLength": 100,
338
+ "bRetrieve": true,
339
+ // Force a predictive order for event types, invoices and payments
340
+ "aaSortingFixed": [[1, 'desc'], [4, 'desc'], [3, 'desc']],
341
+ "aoColumns": [
342
+ { "sType": 'date' },
343
+ { "sType": 'date' },
344
+ null,
345
+ { "sType": 'timeline-event' },
346
+ { "sType": 'timeline-details' },
347
+ null,
348
+ null
349
+ ]
350
+ });
351
+ }
352
+
304
353
  function filterBundles() {
305
354
  var bundle = $("#bundles").val();
306
- var dataTable = $("#timeline-table").dataTable();
307
355
 
356
+ var dataTable = initTable();
308
357
  $(dataTable.fnGetNodes()).each(function() {
309
358
  var tr = $(this);
310
359
  if (bundle == "" || tr.attr("title").split(",").indexOf(bundle) >= 0) {
@@ -316,7 +365,16 @@
316
365
  });
317
366
  dataTable.fnDraw();
318
367
  }
368
+
319
369
  $(document).ready(function() {
370
+ disableLinks();
371
+ // When going through the pages of the table, disable links as needed
372
+ $('#timeline-table').bind('draw', function (e) {
373
+ disableLinks();
374
+ });
375
+
376
+ initTable();
377
+
320
378
  $("#bundles").change(filterBundles);
321
379
  filterBundles();
322
380
  });