kaui 0.1.11 → 0.1.12

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 (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
  });