Bug 22440: ILL API changes
[koha.git] / koha-tmpl / intranet-tmpl / prog / js / ill-list-table.js
1 $(document).ready(function() {
2     // Display the modal containing request supplier metadata
3     $('#ill-request-display-log').on('click', function(e) {
4         e.preventDefault();
5         $('#requestLog').modal({show:true});
6     });
7
8     // Toggle request attributes in Illview
9     $('#toggle_requestattributes').on('click', function(e) {
10         e.preventDefault();
11         $('#requestattributes').toggleClass('content_hidden');
12     });
13
14     // Toggle new comment form in Illview
15     $('#toggle_addcomment').on('click', function(e) {
16         e.preventDefault();
17         $('#addcomment').toggleClass('content_hidden');
18     });
19
20     // Filter partner list
21     // Record the list of all options
22     var ill_partner_options = $('#partners > option');
23     $('#partner_filter').keyup(function() {
24         var needle = $('#partner_filter').val();
25         var regex = new RegExp(needle, 'i');
26         var filtered = [];
27         ill_partner_options.each(function() {
28             if (
29                 needle.length == 0 ||
30                 $(this).is(':selected') ||
31                 $(this).text().match(regex)
32             ) {
33                 filtered.push($(this));
34             }
35         });
36         $('#partners').empty().append(filtered);
37     });
38
39     // Display the modal containing request supplier metadata
40     $('#ill-request-display-metadata').on('click', function(e) {
41         e.preventDefault();
42         $('#dataPreview').modal({show:true});
43     });
44
45     function display_extended_attribute(row, type) {
46         var arr = $.grep(row.extended_attributes, ( x => x.type === type ));
47         if (arr.length > 0) {
48             return escape_str(arr[0].value);
49         }
50
51         return '';
52     }
53
54     // At the moment, the only prefilter possible is borrowernumber
55     // see ill/ill-requests.pl and members/ill-requests.pl
56     let additional_prefilters = [];
57     if(prefilters){
58             let prefilters_array = prefilters.split("&");
59             prefilters_array.forEach((prefilter) => {
60                 let prefilter_split = prefilter.split("=");
61                 additional_prefilters.push( {
62                      "key": prefilter_split[0],
63                      "value": prefilter_split[1]
64                 } );
65
66             });
67     }
68
69     let additional_filters = {
70         "me.backend": function(){
71             let backend = $("#illfilter_backend").val();
72             if (!backend) return "";
73             return { "=": backend  }
74         },
75         "me.branchcode": function(){
76             let branchcode = $("#illfilter_branchname").val();
77             if (!branchcode) return "";
78             return { "=": branchcode }
79         },
80         "me.borrowernumber": function(){
81             let borrowernumber_pre_filter = additional_prefilters.find(e => e.key === 'borrowernumber');
82             if ( additional_prefilters.length == 0 || typeof borrowernumber_pre_filter === undefined) return "";
83             return { "=": borrowernumber_pre_filter["value"] }
84         },
85         "-or": function(){
86             let patron = $("#illfilter_patron").val();
87             let status = $("#illfilter_status").val();
88             let filters = [];
89             let patron_sub_or = [];
90             let status_sub_or = [];
91             let subquery_and = [];
92
93             if (!patron && !status) return "";
94
95             if(patron){
96                 const patron_search_fields = "me.borrowernumber,patron.cardnumber,patron.firstname,patron.surname";
97                 patron_search_fields.split(',').forEach(function(attr){
98                     let operator = "=";
99                     let patron_data = patron;
100                     if ( attr != "me.borrowernumber" && attr != "patron.cardnumber") {
101                         operator = "like";
102                         patron_data = "%" + patron + "%";
103                     }
104                     patron_sub_or.push({
105                         [attr]:{[operator]: patron_data }
106                     });
107                 });
108                 subquery_and.push(patron_sub_or);
109             }
110
111             if(status){
112                 const status_search_fields = "me.status,me.status_av";
113                 status_search_fields.split(',').forEach(function(attr){
114                     status_sub_or.push({
115                         [attr]:{"=": status }
116                     });
117                 });
118                 subquery_and.push(status_sub_or);
119             }
120
121             filters.push({"-and": subquery_and});
122
123             return filters;
124         },
125         "me.placed": function(){
126             if ( additional_prefilters.length != 0 && !additional_prefilters.find(e => e.key === 'placed')) return "";
127             let placed_start = $('#illfilter_dateplaced_start').get(0)._flatpickr.selectedDates[0];
128             let placed_end = $('#illfilter_dateplaced_end').get(0)._flatpickr.selectedDates[0];
129             if (!placed_start && !placed_end) return "";
130             return {
131                 ...(placed_start && {">=": placed_start}),
132                 ...(placed_end && {"<=": placed_end})
133             }
134         },
135         "me.updated": function(){
136             if ( additional_prefilters.length != 0 && !additional_prefilters.find(e => e.key === 'updated')) return "";
137             let updated_start = $('#illfilter_datemodified_start').get(0)._flatpickr.selectedDates[0];
138             let updated_end = $('#illfilter_datemodified_end').get(0)._flatpickr.selectedDates[0];
139             if (!updated_start && !updated_end) return "";
140             // set selected datetime hours and minutes to the end of the day
141             // to grab any request updated during that day
142             let updated_end_value = new Date(updated_end);
143             updated_end_value.setHours(updated_end_value.getHours()+23);
144             updated_end_value.setMinutes(updated_end_value.getMinutes()+59);
145             return {
146                 ...(updated_start && {">=": updated_start}),
147                 ...(updated_end && {"<=": updated_end_value})
148             }
149         },
150         "-and": function(){
151             let keyword = $("#illfilter_keyword").val();
152             if (!keyword) return "";
153
154             let filters = [];
155             let subquery_and = [];
156
157             const search_fields = "me.illrequest_id,me.borrowernumber,me.biblio_id,me.due_date,me.branchcode,library.name,me.status,me.status_alias,me.placed,me.replied,me.updated,me.completed,me.medium,me.accessurl,me.cost,me.price_paid,me.notesopac,me.notesstaff,me.orderid,me.backend,patron.firstname,patron.surname";
158             let sub_or = [];
159             search_fields.split(',').forEach(function(attr){
160                 sub_or.push({
161                         [attr]:{"like":"%" + keyword + "%"}
162                 });
163             });
164             subquery_and.push(sub_or);
165             filters.push({"-and": subquery_and});
166
167             const extended_attributes = "title,type,author,article_title,pages,issue,volume,year";
168             let extended_sub_or = [];
169             subquery_and = [];
170             extended_sub_or.push({
171                 "extended_attributes.type": extended_attributes.split(','),
172                 "extended_attributes.value":{"like":"%" + keyword + "%"}
173             });
174             subquery_and.push(extended_sub_or);
175
176             filters.push({"-and": subquery_and});
177             return filters;
178         }
179     };
180
181     var ill_requests_table = $("#ill-requests").kohaTable({
182         "ajax": {
183             "url": '/api/v1/ill/requests'
184         },
185         "embed": [
186             '+strings',
187             'biblio',
188             'comments+count',
189             'extended_attributes',
190             'library',
191             'id_prefix',
192             'patron'
193         ],
194         "stateSave": true, // remember state on page reload
195         "columns": [
196             {
197                 "data": "ill_request_id",
198                 "searchable": true,
199                 "orderable": true,
200                 "render": function( data, type, row, meta ) {
201                     return '<a href="/cgi-bin/koha/ill/ill-requests.pl?' +
202                             'method=illview&amp;illrequest_id=' +
203                             encodeURIComponent(data) +
204                             '">' + escape_str(row.id_prefix) + escape_str(data) + '</a>';
205                 }
206             },
207             {
208                 "data": "", // author
209                 "orderable": false,
210                 "render": function(data, type, row, meta) {
211                     return display_extended_attribute(row, 'author');
212                 }
213             },
214             {
215                 "data": "", // title
216                 "orderable": false,
217                 "render": function(data, type, row, meta) {
218                     return display_extended_attribute(row, 'title');
219                 }
220             },
221             {
222                 "data": "", // article_title
223                 "orderable": false,
224                 "render": function(data, type, row, meta) {
225                     return display_extended_attribute(row, 'article_title');
226                 }
227             },
228             {
229                 "data": "", // issue
230                 "orderable": false,
231                 "render": function(data, type, row, meta) {
232                     return display_extended_attribute(row, 'issue');
233                 }
234             },
235             {
236                 "data": "", // volume
237                 "orderable": false,
238                 "render": function(data, type, row, meta) {
239                     return display_extended_attribute(row, 'volume');
240                 }
241             },
242             {
243                 "data": "",  // year
244                 "orderable": false,
245                 "render": function(data, type, row, meta) {
246                     return display_extended_attribute(row, 'year');
247                 }
248             },
249             {
250                 "data": "", // pages
251                 "orderable": false,
252                 "render": function(data, type, row, meta) {
253                     return display_extended_attribute(row, 'pages');
254                 }
255             },
256             {
257                 "data": "", // type
258                 "orderable": false,
259                 "render": function(data, type, row, meta) {
260                     return display_extended_attribute(row, 'type');
261                 }
262             },
263             {
264                 "data": "ill_backend_request_id",
265                 "orderable": true,
266                 "render": function(data, type, row, meta) {
267                     return escape_str(data);
268                 }
269             },
270             {
271                 "data": "patron.firstname:patron.surname:patron.cardnumber",
272                 "render": function(data, type, row, meta) {
273                     return (row.patron) ? $patron_to_html( row.patron, { display_cardnumber: true, url: true } ) : ''; }                    },
274             {
275                 "data": "biblio_id",
276                 "orderable": true,
277                 "render": function(data, type, row, meta) {
278                     if ( data === null ) {
279                         return "";
280                     }
281                     return $biblio_to_html(row.biblio, { biblio_id_only: 1, link: 1 });
282                 }
283             },
284             {
285                 "data": "library.name",
286                 "orderable": true,
287                 "render": function(data, type, row, meta) {
288                     return escape_str(data);
289                 }
290             },
291             {
292                 "data": "status",
293                 "orderable": true,
294                 "render": function(data, type, row, meta) {
295                     let status_label = row._strings.status_av ?
296                         row._strings.status_av.str ?
297                             row._strings.status_av.str :
298                             row._strings.status_av.code :
299                         row._strings.status.str
300                     return escape_str(status_label);
301                 }
302             },
303             {
304                 "data": "requested_date",
305                 "orderable": true,
306                 "render": function(data, type, row, meta) {
307                     return $date(data);
308                 }
309             },
310             {
311                 "data": "timestamp",
312                 "orderable": true,
313                 "render": function(data, type, row, meta) {
314                     return $date(data);
315                 }
316             },
317             {
318                 "data": "replied_date",
319                 "orderable": true,
320                 "render": function(data, type, row, meta) {
321                     return $date(data);
322                 }
323             },
324             {
325                 "data": "completed_date",
326                 "orderable": true,
327                 "render": function(data, type, row, meta) {
328                     return $date(data);
329                 }
330             },
331             {
332                 "data": "access_url",
333                 "orderable": true,
334                 "render": function(data, type, row, meta) {
335                     return escape_str(data);
336                 }
337             },
338             {
339                 "data": "cost",
340                 "orderable": true,
341                 "render": function(data, type, row, meta) {
342                     return escape_str(data);
343                 }
344             },
345             {
346                 "data": "paid_price",
347                 "orderable": true,
348                 "render": function(data, type, row, meta) {
349                     return escape_str(data);
350                 }
351             },
352             {
353                 "data": "comments_count",
354                 "orderable": true,
355                 "searchable": false,
356                 "render": function(data, type, row, meta) {
357                     return escape_str(data);
358                 }
359             },
360             {
361                 "data": "opac_notes",
362                 "orderable": true,
363                 "render": function(data, type, row, meta) {
364                     return escape_str(data);
365                 }
366             },
367             {
368                 "data": "staff_notes",
369                 "orderable": true,
370                 "render": function(data, type, row, meta) {
371                     return escape_str(data);
372                 }
373             },
374             {
375                 "data": "ill_backend_id",
376                 "orderable": true,
377                 "render": function(data, type, row, meta) {
378                     return escape_str(data);
379                 }
380             },
381             {
382                 "data": "ill_request_id",
383                 "orderable": false,
384                 "searchable": false,
385                 "render": function( data, type, row, meta ) {
386                     return '<a class="btn btn-default btn-sm" ' +
387                             'href="/cgi-bin/koha/ill/ill-requests.pl?' +
388                             'method=illview&amp;illrequest_id=' +
389                             encodeURIComponent(data) +
390                             '">' + ill_manage + '</a>';
391                 }
392             }
393         ]
394     }, table_settings, null, additional_filters);
395
396     $("#illfilter_form").on('submit', filter);
397
398     function redrawTable() {
399         let table_dt = ill_requests_table.DataTable();
400         table_dt.draw();
401     }
402
403     function filter() {
404         redrawTable();
405         return false;
406     }
407
408     function clearSearch() {
409         let filters = [
410             "illfilter_backend",
411             "illfilter_branchname",
412             "illfilter_patron",
413             "illfilter_keyword",
414         ];
415         filters.forEach((filter) => {
416             $("#"+filter).val("");
417         });
418
419         //Clear flatpickr date filters
420         $('#illfilter_form > fieldset > ol > li:nth-child(4) > span > a').click();
421         $('#illfilter_form > fieldset > ol > li:nth-child(5) > span > a').click();
422         $('#illfilter_form > fieldset > ol > li:nth-child(6) > span > a').click();
423         $('#illfilter_form > fieldset > ol > li:nth-child(7) > span > a').click();
424
425         disableStatusFilter();
426
427         redrawTable();
428     }
429
430     function populateStatusFilter(backend) {
431         $.ajax({
432             type: "GET",
433             url: "/api/v1/ill/backends/"+backend+"/statuses",
434             success: function(statuses){
435                 $('#illfilter_status').append(
436                     '<option value="">'+ill_all_statuses+'</option>'
437                 );
438                 statuses.sort((a, b) => a.str.localeCompare(b.str)).forEach(function(status) {
439                     $('#illfilter_status').append(
440                         '<option value="' + status.code  +
441                         '">' + status.str +  '</option>'
442                     );
443                 });
444             }
445         });
446     }
447
448     function populateBackendFilter() {
449         $.ajax({
450             type: "GET",
451             url: "/api/v1/ill/backends",
452             success: function(backends){
453                 backends.sort((a, b) => a.ill_backend_id.localeCompare(b.ill_backend_id)).forEach(function(backend) {
454                     $('#illfilter_backend').append(
455                         '<option value="' + backend.ill_backend_id  +
456                         '">' + backend.ill_backend_id +  '</option>'
457                     );
458                 });
459             }
460         });
461     }
462
463     function disableStatusFilter() {
464         $('#illfilter_status').children().remove();
465         $("#illfilter_status").attr('title', ill_manage_select_backend_first);
466         $('#illfilter_status').prop("disabled", true);
467     }
468
469     function enableStatusFilter() {
470         $('#illfilter_status').children().remove();
471         $("#illfilter_status").attr('title', '');
472         $('#illfilter_status').prop("disabled", false);
473     }
474
475     $('#illfilter_backend').change(function() {
476         var selected_backend = $('#illfilter_backend option:selected').val();
477         if (selected_backend && selected_backend.length > 0) {
478             populateStatusFilter(selected_backend);
479             enableStatusFilter();
480         } else {
481             disableStatusFilter();
482         }
483     });
484
485     disableStatusFilter();
486     populateBackendFilter();
487
488     // Clear all filters
489     $('#clear_search').click(function() {
490         clearSearch();
491     });
492
493 });