kaui 3.0.2 → 3.0.4

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/kaui/logo.svg +37 -0
  3. data/app/controllers/kaui/account_timelines_controller.rb +121 -0
  4. data/app/controllers/kaui/accounts_controller.rb +51 -14
  5. data/app/controllers/kaui/admin_tenants_controller.rb +19 -6
  6. data/app/controllers/kaui/audit_logs_controller.rb +40 -3
  7. data/app/controllers/kaui/bundles_controller.rb +5 -1
  8. data/app/controllers/kaui/charges_controller.rb +1 -1
  9. data/app/controllers/kaui/credits_controller.rb +1 -1
  10. data/app/controllers/kaui/custom_fields_controller.rb +3 -3
  11. data/app/controllers/kaui/engine_controller.rb +3 -28
  12. data/app/controllers/kaui/engine_controller_util.rb +8 -2
  13. data/app/controllers/kaui/home_controller.rb +5 -5
  14. data/app/controllers/kaui/invoice_items_controller.rb +1 -1
  15. data/app/controllers/kaui/invoices_controller.rb +59 -34
  16. data/app/controllers/kaui/payment_methods_controller.rb +3 -3
  17. data/app/controllers/kaui/payments_controller.rb +66 -10
  18. data/app/controllers/kaui/refunds_controller.rb +3 -2
  19. data/app/controllers/kaui/sessions_controller.rb +7 -0
  20. data/app/controllers/kaui/subscriptions_controller.rb +8 -8
  21. data/app/controllers/kaui/transactions_controller.rb +2 -2
  22. data/app/helpers/kaui/exception_helper.rb +25 -0
  23. data/app/helpers/kaui/subscription_helper.rb +4 -0
  24. data/app/models/kaui/account.rb +2 -0
  25. data/app/models/kaui/custom_field.rb +1 -1
  26. data/app/models/kaui/invoice.rb +2 -0
  27. data/app/models/kaui/payment_method.rb +4 -4
  28. data/app/views/kaui/account_timelines/_multi_functions_bar.html.erb +184 -0
  29. data/app/views/kaui/account_timelines/show.html.erb +2 -0
  30. data/app/views/kaui/accounts/_account_info.html.erb +7 -0
  31. data/app/views/kaui/accounts/_multi_functions_bar.html.erb +347 -0
  32. data/app/views/kaui/accounts/index.html.erb +46 -33
  33. data/app/views/kaui/audit_logs/_multi_functions_bar.html.erb +218 -0
  34. data/app/views/kaui/audit_logs/index.html.erb +1 -0
  35. data/app/views/kaui/bundles/index.html.erb +34 -0
  36. data/app/views/kaui/errors/500.html.erb +29 -0
  37. data/app/views/kaui/invoices/_multi_functions_bar.html.erb +340 -0
  38. data/app/views/kaui/invoices/index.html.erb +41 -19
  39. data/app/views/kaui/layouts/kaui_navbar.html.erb +1 -1
  40. data/app/views/kaui/payments/_multi_functions_bar.html.erb +344 -0
  41. data/app/views/kaui/payments/index.html.erb +64 -25
  42. data/config/locales/en.yml +3 -0
  43. data/config/routes.rb +7 -0
  44. data/lib/kaui/error_handler.rb +37 -0
  45. data/lib/kaui/version.rb +1 -1
  46. data/lib/kaui.rb +105 -29
  47. data/lib/tasks/kaui_tasks.rake +1 -0
  48. metadata +11 -3
  49. data/app/assets/images/kaui/logo.png +0 -0
@@ -4,11 +4,12 @@
4
4
 
5
5
  <h1>Invoices</h1>
6
6
 
7
- <table id="invoices-table" class="table table-condensed mobile-data">
7
+ <%= render :partial => 'multi_functions_bar' %>
8
+
9
+ <table id="invoices-table" class="table table-condensed mobile-data" style="width:100%">
8
10
  <thead>
9
11
  <tr>
10
- <th>Number</th>
11
- <% (@account.account_id.blank? ? Kaui.invoice_search_columns : Kaui.account_invoices_columns).call()[0].each do |title| %>
12
+ <% Kaui.account_invoices_columns.call[0].each do |title| %>
12
13
  <th><%= title %></th>
13
14
  <% end %>
14
15
  </tr>
@@ -27,22 +28,24 @@
27
28
  <%= javascript_tag do %>
28
29
  $(document).ready(function() {
29
30
  var table = $('#invoices-table').DataTable({
30
- <% if @account.account_id.blank? %>
31
- "dom": "<'row'r>t<'row'<'col-md-6'i><'col-md-6'p>>",
32
- "pagingType": <% if @max_nb_records.nil? -%>"simple"<% else -%>"full_numbers"<% end -%>,
33
- "language": {
34
- <!-- See DefaultPaginationSqlDaoHelper.java -->
35
- "info": <% if @max_nb_records.nil? -%>"Showing _START_ to _END_ of <%= number_with_delimiter(Kaui::EngineControllerUtil::SIMPLE_PAGINATION_THRESHOLD) -%>+ entries"<% else -%>"Showing _START_ to _END_ of _TOTAL_ entries"<% end -%>
36
- },
37
- "pageLength": <%= @limit %>,
38
- "displayStart": <%= @offset %>,
39
- "ajax": "<%= invoices_pagination_path(:ordering => @ordering, :format => :json) %>",
40
- <% else %>
41
- // No paging for per-account listings
42
- "dom": "t",
43
- "paging": false,
44
- "ajax": "<%= invoices_pagination_path :format => :json %>",
45
- <% end %>
31
+ "colReorder": {
32
+ "enable": false
33
+ },
34
+ "stateSave": true,
35
+ "stateSaveCallback": function(settings, data) {
36
+ localStorage.setItem('DataTables_invoices-table', JSON.stringify(data));
37
+ },
38
+ "stateLoadCallback": function(settings) {
39
+ return JSON.parse(localStorage.getItem('DataTables_invoices-table'));
40
+ },
41
+ "scrollX": true,
42
+ "dom": "<'row'r>t<'row'<'col-md-6'i><'col-md-6'p>>",
43
+ "pagingType": <% if @max_nb_records.nil? -%>"simple"<% else -%>"full_numbers"<% end -%>,
44
+ "language": {
45
+ "info": <% if @max_nb_records.nil? -%>"Showing _START_ to _END_ of <%= number_with_delimiter(Kaui::EngineControllerUtil::SIMPLE_PAGINATION_THRESHOLD) -%>+ entries"<% else -%>"Showing _START_ to _END_ of _TOTAL_ entries"<% end -%>
46
+ },
47
+ "pageLength": <%= @limit %>,
48
+ "displayStart": <%= @offset %>,
46
49
  <% if @search_query.blank? %>
47
50
  "ordering": false,
48
51
  <% elsif !@ordering.blank? %>
@@ -51,8 +54,27 @@ $(document).ready(function() {
51
54
  "processing": true,
52
55
  "serverSide": true,
53
56
  "search": {"search": "<%= @search_query %>"},
57
+ "ajax": {
58
+ url: "<%= invoices_pagination_path(:ordering => @ordering, :format => :json) %>",
59
+ dataSrc: function(json) {
60
+ var colOrder = $('#invoices-table').DataTable().colReorder.order();
61
+ var reorderedData = json.data.map(function(row) {
62
+ var newRow = [];
63
+ for (var i = 0; i < colOrder.length; i++) {
64
+ newRow.push(row[colOrder[i]]);
65
+ }
66
+ return newRow;
67
+ });
68
+ return reorderedData;
69
+ }
70
+ }
54
71
  });
55
72
 
73
+ var searchQuery = "<%= @search_query %>";
74
+ if (searchQuery) {
75
+ table.search(searchQuery).draw();
76
+ }
77
+
56
78
  <!-- When we don't know the total number of pages, we need to hide the legend and next button manually -->
57
79
  <% if @max_nb_records.nil? %>
58
80
  $('#invoices-table').on('draw.dt', function() {
@@ -3,7 +3,7 @@
3
3
  <div class="row">
4
4
 
5
5
  <div class="col-md-6">
6
- <%= link_to image_tag('kaui/logo.png', :alt => 'Kill Bill Logo'), kaui_engine.home_path %>
6
+ <%= link_to image_tag('kaui/logo.svg', :alt => 'Kill Bill Logo'), kaui_engine.home_path %>
7
7
 
8
8
  <% if user_signed_in? -%>
9
9
  <% if tenant_selected? %>
@@ -0,0 +1,344 @@
1
+ <div class="dropdown-container">
2
+ <% unless @account.account_id.blank? %>
3
+ <button class="btn btn-default download-button-right" type="button" id="modalDownloadButton">
4
+ <i class="glyphicon glyphicon-download-alt"></i>
5
+ <strong>Download CSV</strong>
6
+ </button>
7
+ <% end %>
8
+ <div class="dropdown">
9
+ <button class="btn btn-default dropdown-toggle toggle-button-right" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
10
+ <i class="glyphicon glyphicon-cog"></i>
11
+ <strong>Edit Columns</strong>
12
+ </button>
13
+ <ul class="dropdown-menu" id="column-visibility" aria-labelledby="v">
14
+ <% Kaui.account_payments_columns.call()[0].each_with_index do |title, index| %>
15
+ <li class="list-group-item-manual" data-id="<%= index %>">
16
+ <label class="label-group-item-manual">
17
+ <input type="checkbox" class="column-toggle" draggable="true" data-column="<%= index %>" checked> <%= title %>
18
+ <span class="glyphicon glyphicon-option-vertical icon-drag" aria-hidden="true"></span>
19
+ </label>
20
+ </li>
21
+ <% end %>
22
+ </ul>
23
+ </div>
24
+ </div>
25
+
26
+ <div class="modal fade" id="downloadCsvModal" tabindex="-1" role="dialog" aria-labelledby="downloadCsvModalLabel" aria-hidden="true">
27
+ <div class="modal-dialog" role="document">
28
+ <div class="modal-content">
29
+ <div class="modal-header">
30
+ <h3 class="modal-title" id="downloadCsvModalLabel">Download</h3>
31
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
32
+ <span aria-hidden="true">&times;</span>
33
+ </button>
34
+ </div>
35
+ <div class="modal-body">
36
+ <form id="downloadCsvForm">
37
+ <div class="row">
38
+ <div class="col-md-6">
39
+ <div class="form-group">
40
+ <label for="startDate">Payment Date From:</label>
41
+ <input type="text" class="form-control" id="startDate" name="startDate">
42
+ </div>
43
+ </div>
44
+ <div class="col-md-6">
45
+ <div class="form-group">
46
+ <label for="endDate">To:</label>
47
+ <input type="text" class="form-control" id="endDate" name="endDate">
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <div class="row">
52
+ <div class="col-md-6">
53
+ <div class="form-check">
54
+ <div>
55
+ <input type="radio" id="customDate" name="download_option" value="customDate">
56
+ <label for="customDate">Custom date</label>
57
+ </div>
58
+ <div>
59
+ <input type="radio" id="allData" name="download_option" value="all">
60
+ <label for="allData">All payments</label>
61
+ </div>
62
+ <div>
63
+ <input type="radio" id="thisWeek" name="download_option" value="thisWeek">
64
+ <label for="thisWeek">This week</label>
65
+ </div>
66
+ <div>
67
+ <input type="radio" id="thisMonth" name="download_option" value="thisMonth">
68
+ <label for="thisMonth">This month</label>
69
+ </div>
70
+ <div>
71
+ <input type="radio" id="thisYear" name="download_option" value="thisYear">
72
+ <label for="thisYear">This year</label>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ <div class="row">
78
+ <div class="col-md-12">
79
+ <h5>Additional Options</h5>
80
+ </div>
81
+ </div>
82
+ <div class="row">
83
+ <div class="col-md-6">
84
+ <div class="form-check">
85
+ <input type="checkbox" class="form-check-input" id="allFields" name="allFields">
86
+ <label class="form-check-label" for="allFields">All fields</label>
87
+ </div>
88
+ </div>
89
+ </div>
90
+ </form>
91
+ </div>
92
+ <div class="modal-footer">
93
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
94
+ <button type="button" class="btn btn-primary" id="downloadButton">Download</button>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </div>
99
+
100
+ <style>
101
+ .dropdown-menu#column-visibility {
102
+ max-height: 300px;
103
+ width: 220px;
104
+ overflow-y: auto;
105
+ }
106
+
107
+ .dropdown-menu {
108
+ padding: 5px;
109
+ }
110
+ .toggle-button-right {
111
+ float: right;
112
+ margin-bottom: 10px;
113
+ margin-left: 10px;
114
+ background-color: white;
115
+ color: black;
116
+ text-transform: none;
117
+ border: 1px solid #ccc;
118
+ padding: 8px 15px;
119
+ }
120
+
121
+ .download-button-right {
122
+ float: right;
123
+ margin-bottom: 10px;
124
+ margin-left: 10px;
125
+ background-color: white;
126
+ color: black;
127
+ text-transform: none;
128
+ border: 1px solid #ccc;
129
+ padding: 8px 15px;
130
+ }
131
+
132
+ .icon-drag {
133
+ float: right;
134
+ padding: 5px;
135
+ }
136
+
137
+ .dropdown-container {
138
+ display: flex;
139
+ justify-content: flex-end;
140
+ }
141
+
142
+ .label-group-item-manual {
143
+ margin: 5px;
144
+ width: -webkit-fill-available;
145
+ cursor: grab;
146
+ }
147
+ .label-group-item-manual:active {
148
+ cursor: grabbing;
149
+ }
150
+ </style>
151
+
152
+ <%= javascript_tag do %>
153
+ $(document).ready(function() {
154
+ $('.dropdown-menu').on('click', 'input[type="checkbox"], label', function(event) {
155
+ event.stopPropagation();
156
+ });
157
+
158
+ $('#modalDownloadButton').click(function() {
159
+ $('#downloadCsvModal').modal('show');
160
+ });
161
+
162
+ $('#startDate, #endDate').datepicker({
163
+ dateFormat: 'yy-mm-dd'
164
+ });
165
+
166
+ $('#downloadCsvModal').on('show.bs.modal', function (e) {
167
+ $('#allData').prop('checked', true);
168
+ $('#startDate, #endDate').prop('disabled', true);
169
+ $('#startDate').val(null);
170
+ $('#endDate').val(null);
171
+ });
172
+
173
+ $('#allData').change(function() {
174
+ $('#startDate').val(null);
175
+ $('#endDate').val(null);
176
+ var isChecked = $(this).is(':checked');
177
+ $('#startDate, #endDate').prop('disabled', true);
178
+ });
179
+
180
+ function setDateRange(option) {
181
+ var currentDate = new Date();
182
+ var startDate, endDate;
183
+
184
+ if (option === "day") {
185
+ startDate = new Date();
186
+ endDate = new Date();
187
+ endDate.setDate(endDate.getDate() + 1);
188
+ } else if (option === "week") {
189
+ startDate = new Date(currentDate.setDate(currentDate.getDate() - currentDate.getDay() + 1));
190
+ currentDate = new Date();
191
+ endDate = new Date(currentDate.setDate(currentDate.getDate() - currentDate.getDay() + 7));
192
+ } else if (option === "month") {
193
+ startDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
194
+ endDate = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0);
195
+ } else if (option === "year") {
196
+ startDate = new Date(currentDate.getFullYear(), 0, 1);
197
+ endDate = new Date(currentDate.getFullYear(), 11, 31);
198
+ }
199
+
200
+ var startDateFormatted = startDate.toISOString().split('T')[0];
201
+ var endDateFormatted = endDate.toISOString().split('T')[0];
202
+
203
+ $('#startDate').val(startDateFormatted);
204
+ $('#endDate').val(endDateFormatted);
205
+ $('#startDate, #endDate').prop('disabled', true);
206
+ }
207
+
208
+ $('#thisWeek').change(function() {
209
+ if ($(this).is(':checked')) {
210
+ setDateRange("week");
211
+ }
212
+ });
213
+
214
+ $('#thisMonth').change(function() {
215
+ if ($(this).is(':checked')) {
216
+ setDateRange("month");
217
+ }
218
+ });
219
+
220
+ $('#thisYear').change(function() {
221
+ if ($(this).is(':checked')) {
222
+ setDateRange("year");
223
+ }
224
+ });
225
+
226
+ $('#customDate').change(function() {
227
+ if ($(this).is(':checked')) {
228
+ setDateRange("day");
229
+ $('#startDate, #endDate').prop('disabled', false);
230
+ }
231
+ });
232
+
233
+ var downloadButton = document.getElementById('downloadButton');
234
+ if (downloadButton) {
235
+ downloadButton.addEventListener('click', function() {
236
+ event.preventDefault();
237
+
238
+ var allFieldsChecked = document.getElementById('allFields').checked;
239
+ var startDate = $('#startDate').val();
240
+ var endDate = $('#endDate').val();
241
+ var downloadAll = $('#allData').is(':checked');
242
+ var thElements = document.querySelectorAll('#payments-table th');
243
+ var columnTitles = Array.from(thElements).map(function(th) {
244
+ return th.textContent.trim();
245
+ });
246
+ var columnsString = columnTitles.join(',')
247
+
248
+ var url = new URL("<%= download_payments_path %>", window.location.origin);
249
+ var params = new URLSearchParams();
250
+ params.append('account_id', "<%=@account.account_id%>");
251
+ params.append('columnsString', columnsString);
252
+ if (!downloadAll) {
253
+ params.append('startDate', startDate);
254
+ params.append('endDate', endDate);
255
+ }
256
+ params.append('allFieldsChecked', allFieldsChecked);
257
+ url.search = params.toString();
258
+ console.log(url.toString());
259
+ window.open(url.toString(), '_blank');
260
+ });
261
+ }
262
+
263
+ updateDropdownOrder();
264
+
265
+ function loadState() {
266
+ var state = JSON.parse(localStorage.getItem('DataTables_payments-table'));
267
+ return state || { columns: [], columnOrder: [] };
268
+ }
269
+
270
+ function updateDropdownOrder() {
271
+ var state = loadState();
272
+ var columnOrder = state.ColReorder;
273
+ var $list = $('#column-visibility');
274
+ var thElements = document.querySelectorAll('#payments-table th');
275
+ var $columnTitles = Array.from(thElements).map(function(th) {
276
+ return th.textContent.trim();
277
+ });
278
+ if (columnOrder !== undefined) {
279
+ $list.empty();
280
+ columnOrder.forEach(function(colIdx, index) {
281
+ var $item = $('<li>', { class: "list-group-item-manual", "data-id": index });
282
+ var column = state.columns[colIdx];
283
+ var col_name = $columnTitles[colIdx];
284
+ var $label = $('<label>', {
285
+ class: "label-group-item-manual",
286
+ });
287
+ var $checkbox = $("<input>", {
288
+ type: "checkbox",
289
+ value: colIdx,
290
+ checked: column.visible,
291
+ "data-column": colIdx,
292
+ class: "column-toggle"
293
+ });
294
+ $label.append($checkbox).append(" " + col_name);
295
+ var $icon = $("<span>", { class: "glyphicon glyphicon-option-vertical icon-drag"});
296
+ $label.append($icon);
297
+ $item.append($label);
298
+ $list.append($item);
299
+ });
300
+ }
301
+ resetDataColumn();
302
+ resetDataId();
303
+ }
304
+
305
+ $("#column-visibility").sortable({
306
+ axis: "y",
307
+ containment: "parent",
308
+ stop: function(event, ui) {
309
+ var order = $("#column-visibility").sortable('toArray', {attribute: 'data-id'});
310
+ reorderTableColumns(order);
311
+ }
312
+ });
313
+ $("#column-visibility").disableSelection();
314
+
315
+ function reorderTableColumns(order) {
316
+ var table = $('#payments-table').DataTable();
317
+ var columnIndexes = order.map(Number);
318
+ console.log('New column order:', columnIndexes);
319
+ table.colReorder.order(columnIndexes);
320
+ resetDataColumn();
321
+ resetDataId();
322
+ }
323
+
324
+ function resetDataId() {
325
+ var elements = document.querySelectorAll('.list-group-item-manual');
326
+ elements.forEach(function(element, index) {
327
+ element.setAttribute('data-id', index);
328
+ });
329
+ }
330
+
331
+ function resetDataColumn() {
332
+ var elements = document.querySelectorAll('.column-toggle');
333
+ elements.forEach(function(element, index) {
334
+ element.setAttribute('data-column', index);
335
+ });
336
+ }
337
+
338
+ $('.column-toggle').on('change', function() {
339
+ var table = $('#payments-table').DataTable();
340
+ var column = table.column($(this).attr('data-column'));
341
+ column.visible(!column.visible());
342
+ });
343
+ });
344
+ <% end %>
@@ -3,18 +3,15 @@
3
3
  <div class="column-block">
4
4
 
5
5
  <h1><%= I18n.translate('payments') %></h1>
6
+ <%= render :partial => 'multi_functions_bar' %>
6
7
 
7
- <table id="payments-table" class="table table-condensed mobile-data">
8
+ <table id="payments-table" class="table table-condensed mobile-data" style="width:100%">
8
9
  <thead>
9
- <tr>
10
- <th><%= I18n.translate('number') %></th>
11
- <th><%= I18n.translate('date') %></th>
12
- <th><%= I18n.translate('auth_amount') %></th>
13
- <th><%= I18n.translate('capture_amount') %></th>
14
- <th><%= I18n.translate('refund_amount') %></th>
15
- <th><%= I18n.translate('last_transaction_status') %></th>
16
- <th><%= I18n.translate('external_key') %></th>
17
- </tr>
10
+ <tr>
11
+ <% Kaui.account_payments_columns.call()[0].each do |title| %>
12
+ <th><%= title %></th>
13
+ <% end %>
14
+ </tr>
18
15
  </thead>
19
16
  <tbody>
20
17
  <tr>
@@ -30,32 +27,74 @@
30
27
  <%= javascript_tag do %>
31
28
  $(document).ready(function() {
32
29
  var table = $('#payments-table').DataTable({
30
+ "colReorder": {
31
+ "enable": false
32
+ },
33
+ "stateSave": true,
34
+ "stateSaveCallback": function(settings, data) {
35
+ localStorage.setItem('DataTables_payments-table', JSON.stringify(data));
36
+ },
37
+ "stateLoadCallback": function(settings) {
38
+ return JSON.parse(localStorage.getItem('DataTables_payments-table'));
39
+ },
40
+ "scrollX": true,
33
41
  <% if @account.account_id.blank? %>
34
- "dom": "<'row'r>t<'row'<'col-md-6'i><'col-md-6'p>>",
35
- "pagingType": <% if @max_nb_records.nil? -%>"simple"<% else -%>"full_numbers"<% end -%>,
36
- "language": {
37
- <!-- See DefaultPaginationSqlDaoHelper.java -->
38
- "info": <% if @max_nb_records.nil? -%>"Showing _START_ to _END_ of <%= number_with_delimiter(Kaui::EngineControllerUtil::SIMPLE_PAGINATION_THRESHOLD) -%>+ entries"<% else -%>"Showing _START_ to _END_ of _TOTAL_ entries"<% end -%>
39
- },
40
- "pageLength": <%= @limit %>,
41
- "displayStart": <%= @offset %>,
42
- "ajax": "<%= payments_pagination_path(:ordering => @ordering, :format => :json) %>",
42
+ "dom": "<'row'r>t<'row'<'col-md-6'i><'col-md-6'p>>",
43
+ "pagingType": <% if @max_nb_records.nil? -%>"simple"<% else -%>"full_numbers"<% end -%>,
44
+ "language": {
45
+ <!-- See DefaultPaginationSqlDaoHelper.java -->
46
+ "info": <% if @max_nb_records.nil? -%>"Showing _START_ to _END_ of <%= number_with_delimiter(Kaui::EngineControllerUtil::SIMPLE_PAGINATION_THRESHOLD) -%>+ entries"<% else -%>"Showing _START_ to _END_ of _TOTAL_ entries"<% end -%>
47
+ },
48
+ "pageLength": <%= @limit %>,
49
+ "displayStart": <%= @offset %>,
50
+ "ajax": {
51
+ url: "<%= payments_pagination_path(:ordering => @ordering, :format => :json) %>",
52
+ dataSrc: function(json) {
53
+ var colOrder = $('#payments-table').DataTable().colReorder.order();
54
+ var reorderedData = json.data.map(function(row) {
55
+ var newRow = [];
56
+ for (var i = 0; i < colOrder.length; i++) {
57
+ newRow.push(row[colOrder[i]]);
58
+ }
59
+ return newRow;
60
+ });
61
+ return reorderedData;
62
+ }
63
+ },
43
64
  <% else %>
44
- // No paging for per-account listings
45
- "dom": "t",
46
- "paging": false,
47
- "ajax": "<%= payments_pagination_path :format => :json %>",
65
+ // No paging for per-account listings
66
+ "dom": "t",
67
+ "paging": false,
68
+ "ajax": {
69
+ url: "<%= payments_pagination_path(:format => :json) %>",
70
+ dataSrc: function(json) {
71
+ var colOrder = $('#payments-table').DataTable().colReorder.order();
72
+ var reorderedData = json.data.map(function(row) {
73
+ var newRow = [];
74
+ for (var i = 0; i < colOrder.length; i++) {
75
+ newRow.push(row[colOrder[i]]);
76
+ }
77
+ return newRow;
78
+ });
79
+ return reorderedData;
80
+ }
81
+ },
48
82
  <% end %>
49
83
  <% if @search_query.blank? %>
50
- "ordering": false,
84
+ "ordering": false,
51
85
  <% elsif !@ordering.blank? %>
52
- "order": [[ 0, "<%= @ordering %>" ]],
86
+ "order": [[ 0, "<%= @ordering %>" ]],
53
87
  <% end %>
54
88
  "processing": true,
55
89
  "serverSide": true,
56
90
  "search": {"search": "<%= @search_query %>"},
57
91
  });
58
92
 
93
+ var searchQuery = "<%= @search_query %>";
94
+ if (searchQuery) {
95
+ table.search(searchQuery).draw();
96
+ }
97
+
59
98
  <!-- When we don't know the total number of pages, we need to hide the legend and next button manually -->
60
99
  <% if @max_nb_records.nil? %>
61
100
  $('#payments-table').on('draw.dt', function() {
@@ -63,6 +63,9 @@ en:
63
63
  invalid_xml: "Invalid XML: %{error}"
64
64
  invalid_min_date: "Invalid min date format"
65
65
  invalid_max_date: "Invalid max date format"
66
+ unable_to_connect_database: "Unable to connect to the database."
67
+ unable_to_connect_killbill: "Unable to connect to the Kill Bill server."
68
+ error_communicating_killbill: "Error while communicating with the Kill Bill server."
66
69
  views:
67
70
  subscriptions:
68
71
  requested_date_for_billing_notice: <ul>
data/config/routes.rb CHANGED
@@ -22,10 +22,13 @@ Kaui::Engine.routes.draw do
22
22
  controllers: { sessions: 'kaui/sessions', registrations: 'kaui/registrations' }
23
23
 
24
24
  root to: 'home#index', as: 'kaui'
25
+ get '/500', to: 'errors#show', code: 500
25
26
 
26
27
  scope '/accounts' do
27
28
  match '/pagination' => 'accounts#pagination', :via => :get, :as => 'accounts_pagination'
28
29
  match '/validate_external_key' => 'accounts#validate_external_key', :via => :get, :as => 'accounts_validate_external_key'
30
+ match '/download' => 'accounts#download', :via => :get, :as => 'download_accounts'
31
+ get '/export/:account_id', to: 'accounts#export_account', as: 'export_account'
29
32
 
30
33
  scope '/email_notifications' do
31
34
  match '/' => 'accounts#set_email_notifications_configuration', :via => :post, :as => 'email_notifications_configuration'
@@ -53,6 +56,7 @@ Kaui::Engine.routes.draw do
53
56
  end
54
57
  scope '/timeline' do
55
58
  match '/' => 'account_timelines#show', :via => :get, :as => 'account_timeline'
59
+ match '/download' => 'account_timelines#download', :via => :get, :as => 'download_account_timeline'
56
60
  end
57
61
  scope '/custom_fields' do
58
62
  match '/' => 'account_custom_fields#index', :via => :get, :as => 'account_custom_fields'
@@ -63,6 +67,7 @@ Kaui::Engine.routes.draw do
63
67
  end
64
68
  scope '/audit_logs' do
65
69
  match '/history' => 'audit_logs#history', :via => :get, :as => 'audit_logs_history'
70
+ match '/download' => 'audit_logs#download', :via => :get, :as => 'download_audit_logs'
66
71
  end
67
72
  end
68
73
  end
@@ -97,6 +102,7 @@ Kaui::Engine.routes.draw do
97
102
 
98
103
  scope '/invoices' do
99
104
  match '/pagination' => 'invoices#pagination', :via => :get, :as => 'invoices_pagination'
105
+ match '/download' => 'invoices#download', :via => :get, :as => 'download_invoices'
100
106
  match '/:id/show_html' => 'invoices#show_html', :via => :get, :as => 'show_html_invoice'
101
107
  match '/:number' => 'invoices#restful_show_by_number', :via => :get, :constraints => { number: /\d+/ }
102
108
  match '/:id' => 'invoices#restful_show', :via => :get, :as => 'invoice'
@@ -112,6 +118,7 @@ Kaui::Engine.routes.draw do
112
118
 
113
119
  scope '/payments' do
114
120
  match '/pagination' => 'payments#pagination', :via => :get, :as => 'payments_pagination'
121
+ match '/download' => 'payments#download', :via => :get, :as => 'download_payments'
115
122
  match '/:id' => 'payments#restful_show', :via => :get, :as => 'payment'
116
123
  match '/:id/cancel_scheduled_payment' => 'payments#cancel_scheduled_payment', :via => :delete, :as => 'payment_cancel_scheduled_payment'
117
124
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kaui
4
+ module ErrorHandler
5
+ extend ActiveSupport::Concern
6
+ include Kaui::EngineControllerUtil
7
+
8
+ included do
9
+ rescue_from(StandardError) do |error|
10
+ flash[:error] = "Error: #{as_string(error)}"
11
+ try_to_redirect_to_account_path = !params[:controller].ends_with?('accounts')
12
+ perform_redirect_after_error(redirect: try_to_redirect_to_account_path)
13
+ end
14
+
15
+ rescue_from(ActionController::ParameterMissing) do |parameter_missing_exception|
16
+ log_rescue_error parameter_missing_exception
17
+ flash[:error] = "Required parameter missing: #{parameter_missing_exception.param}"
18
+ perform_redirect_after_error
19
+ end
20
+
21
+ rescue_from(KillBillClient::API::ResponseError) do |killbill_exception|
22
+ flash[:error] = "Error while communicating with the Kill Bill server: #{as_string(killbill_exception)}"
23
+ try_to_redirect_to_account_path = !killbill_exception.is_a?(KillBillClient::API::Unauthorized) && !(killbill_exception.is_a?(KillBillClient::API::NotFound) && params[:controller].ends_with?('accounts'))
24
+ perform_redirect_after_error(redirect: try_to_redirect_to_account_path)
25
+ end
26
+ end
27
+
28
+ def perform_redirect_after_error(redirect: true)
29
+ account_id = nested_hash_value(params.permit!.to_h, :account_id)
30
+ if redirect && account_id.present?
31
+ redirect_to kaui_engine.account_path(account_id)
32
+ else
33
+ redirect_to kaui_engine.home_path
34
+ end
35
+ end
36
+ end
37
+ end
data/lib/kaui/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kaui
4
- VERSION = '3.0.2'
4
+ VERSION = '3.0.4'
5
5
  end