7 [% USE AuthorisedValues %]
9 [% INCLUDE 'doc-head-open.inc' %]
10 <title>Library checkin and transfer policy › Administration › Koha</title>
11 [% INCLUDE 'doc-head-close.inc' %]
12 <style>td { text-align: center; } .sorted { min-width: 50%; }</style>
15 [% SET BranchTransferLimitsType = Koha.Preference('BranchTransferLimitsType') %]
16 [% SET branches = Branches.all %]
18 <body id="admin_branch_transfer_limits" class="admin">
19 [% INCLUDE 'header.inc' %]
20 [% INCLUDE 'prefs-admin-search.inc' %]
22 <nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
25 <a href="/cgi-bin/koha/mainpage.pl">Home</a>
28 <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
31 <a href="#" aria-current="page">Set library checkin and transfer policy</a>
37 <div class="main container-fluid">
39 <div class="col-sm-10 col-sm-push-2">
41 <h1>Checkin and transfer policy</h1>
44 [% IF BranchTransferLimitsType == "itemtype" %]
45 <label for="value_selector">Select an item type:</label>
46 <select id="value_selector">
47 <option value="" selected></option>
48 [% SET itemtypes = ItemTypes.Get %]
49 [% FOREACH i IN itemtypes %]
50 <option value="[% i.itemtype | html %]">[% i.description | html %]</option>
53 [% ELSE #BranchTransferLimitsType == "ccode" %]
54 <label for="value_selector">Select a collection:</label>
55 <select id="value_selector">
56 <option value="" selected></option>
57 [% SET ccodes = AuthorisedValues.Get('CCODE') %]
58 [% FOREACH c IN ccodes %]
59 <option value="[% c.authorised_value | html %]">[% c.lib | html %]</option>
64 <span id="loading_limits">
65 <i class="fa fa-spinner fa-pulse fa-fw"></i>
66 <span>Loading...</span>
70 <p class="help">Check the boxes for the libraries you allow your items to be transferred to.</p>
72 <a id="check-all" class="limit-action" href="#"><i class="fa fa-check"></i> Check all</a>
74 <a id="uncheck-all" class="limit-action" href="#"><i class="fa fa-remove"></i> Uncheck all</a>
76 <a href="/cgi-bin/koha/admin/branch_transfer_limits.pl">Switch to basic editor</a>
79 <table id="transfer_limits" class="table table-striped table-bordered table-hover table-condensed">
85 [% FOREACH to IN branches %]
87 <p><a class="btn btn-default btn-xs check-all-col limit-action" data-to="[% to.branchcode | html %]" href="#"><i class="fa fa-check"></i> Check</a></p>
88 <p><a class="btn btn-default btn-xs uncheck-all-col limit-action" data-to="[% to.branchcode | html %]" href="#"><i class="fa fa-remove"></i> Uncheck</a></p>
96 [% FOREACH b IN branches %]
97 <th style="word-break: break-all !important" title="[% b.branchname | html %]">[% b.branchname | html %]</th>
103 [% FOREACH from IN branches %]
106 <p><a class="btn btn-default btn-xs check-all-row limit-action" data-from="[% from.branchcode | html %]" href="#"><i class="fa fa-check"></i> Check</a></p>
107 <p><a class="btn btn-default btn-xs uncheck-all-row limit-action" data-from="[% from.branchcode | html %]" href="#"><i class="fa fa-remove"></i> Uncheck</a></p>
109 <th>[% from.branchname | html %]</th>
110 [% FOREACH to IN branches %]
111 <td class="checkbox-cell">
112 [% IF to.branchcode == from.branchcode %]
115 <input class="limit-checkboxes from-[% from.branchcode | html %] to-[% to.branchcode | html %]" id="limit-[% from.branchcode | html %]-[% to.branchcode | html %]" type="checkbox" title="From: [% from.branchname | html %], To: [% to.branchname | html %]" checked/>
116 <i id="spinner-limit-[% from.branchcode | html %]-[% to.branchcode | html %]" class="spinner fa fa-spinner fa-pulse fa-fw"></i>
125 </div> <!-- /.col-sm-10.col-sm-push-2 -->
127 <div class="col-sm-2 col-sm-pull-10">
129 [% INCLUDE 'admin-menu.inc' %]
131 </div> <!-- /.col-sm-2.col-sm-pull-10 -->
132 </div> <!-- /.row -->
134 [% MACRO jsinclude BLOCK %]
135 [% Asset.js("js/admin-menu.js") | $raw %]
136 [% INCLUDE 'datatables.inc' %]
138 const branchTransferLimitsType = "[% BranchTransferLimitsType | html %]";
139 const val_type = branchTransferLimitsType == "itemtype" ? "item_type" : "collection_code";
140 const branches = [% To.json(branches) | $raw %];
142 $('#loading_limits').hide();
143 $('.spinner').hide();
145 $(document).ready(function() {
146 $("#check-all").click(function() {
147 const val = $('#value_selector').val();
149 $('.limit-action').addClass('disabled');
150 $('#value_selector').prop('disabled',true);
153 $(".limit-checkboxes").each(function() {
154 const checkbox = $(this);
155 if (checkbox.data('limit_id')) {
156 checkboxes.push(checkbox);
158 $(`#spinner-${checkbox.attr('id')}`).show();
162 del_limits( checkboxes, val );
167 $("#uncheck-all").click(function() {
168 const val = $('#value_selector').val();
170 $('.limit-action').addClass('disabled');
171 $('#value_selector').prop('disabled',true);
174 $(".limit-checkboxes").each(function() {
175 const checkbox = $(this);
176 if (!checkbox.data('limit_id')) {
177 checkboxes.push(checkbox);
179 $(`#spinner-${checkbox.attr('id')}`).show();
183 add_limits( checkboxes, val );
187 $('.check-all-col').click(function() {
189 const to = $(this).data('to');
190 const val = $('#value_selector').val();
192 $('.limit-action').addClass('disabled');
193 $('#value_selector').prop('disabled',true);
195 $(`.to-${to}`).each(function() {
196 const checkbox = $(this);
197 if (checkbox.data('limit_id')) {
198 checkboxes.push(checkbox);
200 $(`#spinner-${checkbox.attr('id')}`).show();
204 del_limits( checkboxes, val, to );
208 $('.uncheck-all-col').click(function() {
210 const to = $(this).data('to');
211 const val = $('#value_selector').val();
213 $('.limit-action').addClass('disabled');
214 $('#value_selector').prop('disabled',true);
216 $(`.to-${to}`).each(function() {
217 const checkbox = $(this);
218 if (!checkbox.data('limit_id')) {
220 $(`#spinner-${checkbox.attr('id')}`).show();
224 add_limits( checkboxes, val, to );
228 $('.check-all-row').click(function() {
230 const from = $(this).data('from');
231 const val = $('#value_selector').val();
233 $('.limit-action').addClass('disabled');
234 $('#value_selector').prop('disabled',true);
236 $(`.from-${from}`).each(function() {
237 const checkbox = $(this);
238 if (checkbox.data('limit_id')) {
239 checkboxes.push(checkbox);
241 $(`#spinner-${checkbox.attr('id')}`).show();
245 del_limits( checkboxes, val, null, from );
250 $('.uncheck-all-row').click(function() {
252 const from = $(this).data('from');
253 const val = $('#value_selector').val();
255 $('.limit-action').addClass('disabled');
256 $('#value_selector').prop('disabled',true);
258 $(`.from-${from}`).each(function() {
259 const checkbox = $(this);
260 if (!checkbox.data('limit_id')) {
262 $(`#spinner-${checkbox.attr('id')}`).show();
266 add_limits( checkboxes, val, null, from );
270 $(".checkbox-cell").click(function(e) {
271 var checkbox = $(this).find(".limit-checkboxes").get(0);
272 if (checkbox && !checkbox.disabled) {
273 if (e.target != checkbox) {
274 checkbox.checked = !checkbox.checked;
275 $(checkbox).change();
280 $("#value_selector").on('change', function() {
281 const val = $('#value_selector').val();
282 window.history.replaceState(null, "", `/cgi-bin/koha/admin/transfer_limits.pl?code=${val}`);
283 updateTransferLimitsTable();
286 $(".limit-checkboxes").on('change', function() {
287 const checkbox = $(this);
288 const id = checkbox.attr('id');
291 $(`#spinner-${id}`).show();
293 const limit_id = checkbox.data('limit_id');
295 if (limit_id) { // limit id exists, so limit needs to be deleted
297 } else { // limit does not exist, needs to be created
302 updateTransferLimitsTable();
304 const queryString = window.location.search;
305 const urlParams = new URLSearchParams(queryString);
306 const code = urlParams.get('code');
308 $('#value_selector').val(code);
309 updateTransferLimitsTable();
313 function delLimit(checkbox) {
314 const id = checkbox.attr('id');
315 const limit_id = checkbox.data('limit_id');
318 url: `/api/v1/transfer_limits/${limit_id}`,
320 success: function(result) {
321 checkbox.data('limit_id', null);
322 checkbox.attr('checked', true);
323 $(`#spinner-${id}`).hide();
326 error: function(xhr, status, error) {
327 var errorMessage = xhr.status + ': ' + xhr.statusText
328 alert('Error - ' + errorMessage);
333 function addLimit(checkbox) {
334 const id = checkbox.attr('id');
335 const parts = id.split('-');
336 const from = parts[1];
339 const val = $('#value_selector').val();
343 from_library_id: from,
345 data[val_type] = val;
347 url: `/api/v1/transfer_limits`,
349 data: JSON.stringify(data),
351 success: function(result) {
352 checkbox.data('limit_id', result.limit_id);
353 checkbox.attr('checked', false);
354 $(`#spinner-${id}`).hide();
357 error: function(xhr, status, error) {
358 var errorMessage = xhr.status + ': ' + xhr.statusText
359 alert('Error - ' + errorMessage);
364 function add_limits( checkboxes, val, to, from ){
366 data[val_type] = val;
367 if (to) data["to_library_id"] = to;
368 if (from) data["from_library_id"] = from;
371 url: `/api/v1/transfer_limits/batch`,
373 data: JSON.stringify(data),
375 success: function(result) {
376 for ( i = 0; i < result.length; i++ ) {
378 let checkbox = $(`#limit-${r.from_library_id}-${r.to_library_id}`);
379 const id = checkbox.attr('id');
380 checkbox.data('limit_id', r.limit_id);
381 checkbox.attr('checked', false);
382 $(`#spinner-${id}`).hide();
386 complete: function() {
387 $('.limit-action').removeClass('disabled');
388 $('#value_selector').prop('disabled',false);
390 error: function(xhr, status, error) {
391 var errorMessage = xhr.status + ': ' + xhr.statusText
392 alert('Error - ' + errorMessage);
397 function del_limits( checkboxes, val, to, from ){
399 data[val_type] = val;
400 if (to) data["to_library_id"] = to;
401 if (from) data["from_library_id"] = from;
404 url: `/api/v1/transfer_limits/batch`,
406 data: JSON.stringify(data),
408 success: function(result) {
409 for ( i = 0; i < checkboxes.length; i++ ) {
410 const checkbox = checkboxes[i];
411 const id = checkbox.attr('id');
412 checkbox.data('limit_id', '');
413 checkbox.attr('checked', true);
414 $(`#spinner-${id}`).hide();
418 complete: function() {
419 $('.limit-action').removeClass('disabled');
420 $('#value_selector').prop('disabled',false);
422 error: function(xhr, status, error) {
423 var errorMessage = xhr.status + ': ' + xhr.statusText
424 alert('Error - ' + errorMessage);
429 function updateTransferLimitsTable() {
430 const val = $('#value_selector').val();
431 const url = `/api/v1/transfer_limits?_per_page=-1&q={"${val_type}": "${val}"}`;
434 $('#transfer_limits').show();
436 $('#transfer_limits').hide();
439 $(".limit-checkboxes").attr("disabled", true);
440 $(".limit-checkboxes").attr("checked", false);
443 $('#loading_limits').show();
448 success: function(data) {
449 $(".limit-checkboxes").attr("disabled", false);
450 $(".limit-checkboxes").attr("checked", true);
451 $(".limit-checkboxes").data('limit_id', null);
453 for (var i = 0; i < data.length; i++) {
455 let checkbox = $(`#limit-${limit.from_library_id}-${limit.to_library_id}`);
456 checkbox.attr('checked', false);
457 checkbox.data('limit_id', limit.limit_id);
460 complete: function() {
461 $('#loading_limits').hide();
463 error: function(xhr, status, error) {
464 var errorMessage = xhr.status + ': ' + xhr.statusText
465 alert('Error - ' + errorMessage);
472 [% INCLUDE 'intranet-bottom.inc' %]