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 [% WRAPPER 'header.inc' %]
20 [% INCLUDE 'prefs-admin-search.inc' %]
23 [% WRAPPER 'sub-header.inc' %]
24 [% WRAPPER breadcrumbs %]
25 [% WRAPPER breadcrumb_item %]
26 <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
28 [% WRAPPER breadcrumb_item bc_active= 1 %]
29 <span>Set library checkin and transfer policy</span>
31 [% END #/ WRAPPER breadcrumbs %]
32 [% END #/ WRAPPER sub-header.inc %]
34 <div class="main container-fluid">
36 <div class="col-sm-10 col-sm-push-2">
38 <h1>Checkin and transfer policy</h1>
41 [% IF BranchTransferLimitsType == "itemtype" %]
42 <label for="value_selector">Select an item type:</label>
43 <select id="value_selector">
44 <option value="" selected></option>
45 [% SET itemtypes = ItemTypes.Get %]
46 [% FOREACH i IN itemtypes %]
47 <option value="[% i.itemtype | html %]">[% i.description | html %]</option>
50 [% ELSE #BranchTransferLimitsType == "ccode" %]
51 <label for="value_selector">Select a collection:</label>
52 <select id="value_selector">
53 <option value="" selected></option>
54 [% SET ccodes = AuthorisedValues.Get('CCODE') %]
55 [% FOREACH c IN ccodes %]
56 <option value="[% c.authorised_value | html %]">[% c.lib | html %]</option>
61 <span id="loading_limits">
62 <i class="fa fa-spinner fa-pulse fa-fw"></i>
63 <span>Loading...</span>
67 <p class="help">Check the boxes for the libraries you allow your items to be transferred to.</p>
69 <a id="check-all" class="limit-action" href="#"><i class="fa fa-check"></i> Check all</a>
71 <a id="uncheck-all" class="limit-action" href="#"><i class="fa fa-times"></i> Uncheck all</a>
73 <a href="/cgi-bin/koha/admin/branch_transfer_limits.pl">Switch to basic editor</a>
76 <table id="transfer_limits" class="table table-striped table-bordered table-hover table-condensed">
82 [% FOREACH to IN branches %]
84 <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>
85 <p><a class="btn btn-default btn-xs uncheck-all-col limit-action" data-to="[% to.branchcode | html %]" href="#"><i class="fa fa-times"></i> Uncheck</a></p>
93 [% FOREACH b IN branches %]
94 <th style="word-break: break-all !important" title="[% b.branchname | html %]">[% b.branchname | html %]</th>
100 [% FOREACH from IN branches %]
103 <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>
104 <p><a class="btn btn-default btn-xs uncheck-all-row limit-action" data-from="[% from.branchcode | html %]" href="#"><i class="fa fa-times"></i> Uncheck</a></p>
106 <th>[% from.branchname | html %]</th>
107 [% FOREACH to IN branches %]
108 <td class="checkbox-cell">
109 [% IF to.branchcode == from.branchcode %]
112 <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/>
113 <i id="spinner-limit-[% from.branchcode | html %]-[% to.branchcode | html %]" class="spinner fa fa-spinner fa-pulse fa-fw"></i>
122 </div> <!-- /.col-sm-10.col-sm-push-2 -->
124 <div class="col-sm-2 col-sm-pull-10">
126 [% INCLUDE 'admin-menu.inc' %]
128 </div> <!-- /.col-sm-2.col-sm-pull-10 -->
129 </div> <!-- /.row -->
131 [% MACRO jsinclude BLOCK %]
132 [% Asset.js("js/admin-menu.js") | $raw %]
133 [% INCLUDE 'datatables.inc' %]
135 const branchTransferLimitsType = "[% BranchTransferLimitsType | html %]";
136 const val_type = branchTransferLimitsType == "itemtype" ? "item_type" : "collection_code";
137 const branches = [% To.json(branches) | $raw %];
139 $('#loading_limits').hide();
140 $('.spinner').hide();
142 $(document).ready(function() {
143 $("#check-all").click(function() {
144 const val = $('#value_selector').val();
146 $('.limit-action').addClass('disabled');
147 $('#value_selector').prop('disabled',true);
150 $(".limit-checkboxes").each(function() {
151 const checkbox = $(this);
152 if (checkbox.data('limit_id')) {
153 checkboxes.push(checkbox);
155 $(`#spinner-${checkbox.attr('id')}`).show();
159 del_limits( checkboxes, val );
164 $("#uncheck-all").click(function() {
165 const val = $('#value_selector').val();
167 $('.limit-action').addClass('disabled');
168 $('#value_selector').prop('disabled',true);
171 $(".limit-checkboxes").each(function() {
172 const checkbox = $(this);
173 if (!checkbox.data('limit_id')) {
174 checkboxes.push(checkbox);
176 $(`#spinner-${checkbox.attr('id')}`).show();
180 add_limits( checkboxes, val );
184 $('.check-all-col').click(function() {
186 const to = $(this).data('to');
187 const val = $('#value_selector').val();
189 $('.limit-action').addClass('disabled');
190 $('#value_selector').prop('disabled',true);
192 $(`.to-${to}`).each(function() {
193 const checkbox = $(this);
194 if (checkbox.data('limit_id')) {
195 checkboxes.push(checkbox);
197 $(`#spinner-${checkbox.attr('id')}`).show();
201 del_limits( checkboxes, val, to );
205 $('.uncheck-all-col').click(function() {
207 const to = $(this).data('to');
208 const val = $('#value_selector').val();
210 $('.limit-action').addClass('disabled');
211 $('#value_selector').prop('disabled',true);
213 $(`.to-${to}`).each(function() {
214 const checkbox = $(this);
215 if (!checkbox.data('limit_id')) {
217 $(`#spinner-${checkbox.attr('id')}`).show();
221 add_limits( checkboxes, val, to );
225 $('.check-all-row').click(function() {
227 const from = $(this).data('from');
228 const val = $('#value_selector').val();
230 $('.limit-action').addClass('disabled');
231 $('#value_selector').prop('disabled',true);
233 $(`.from-${from}`).each(function() {
234 const checkbox = $(this);
235 if (checkbox.data('limit_id')) {
236 checkboxes.push(checkbox);
238 $(`#spinner-${checkbox.attr('id')}`).show();
242 del_limits( checkboxes, val, null, from );
247 $('.uncheck-all-row').click(function() {
249 const from = $(this).data('from');
250 const val = $('#value_selector').val();
252 $('.limit-action').addClass('disabled');
253 $('#value_selector').prop('disabled',true);
255 $(`.from-${from}`).each(function() {
256 const checkbox = $(this);
257 if (!checkbox.data('limit_id')) {
259 $(`#spinner-${checkbox.attr('id')}`).show();
263 add_limits( checkboxes, val, null, from );
267 $(".checkbox-cell").click(function(e) {
268 var checkbox = $(this).find(".limit-checkboxes").get(0);
269 if (checkbox && !checkbox.disabled) {
270 if (e.target != checkbox) {
271 checkbox.checked = !checkbox.checked;
272 $(checkbox).change();
277 $("#value_selector").on('change', function() {
278 const val = $('#value_selector').val();
279 window.history.replaceState(null, "", `/cgi-bin/koha/admin/transfer_limits.pl?code=${val}`);
280 updateTransferLimitsTable();
283 $(".limit-checkboxes").on('change', function() {
284 const checkbox = $(this);
285 const id = checkbox.attr('id');
288 $(`#spinner-${id}`).show();
290 const limit_id = checkbox.data('limit_id');
292 if (limit_id) { // limit id exists, so limit needs to be deleted
294 } else { // limit does not exist, needs to be created
299 updateTransferLimitsTable();
301 const queryString = window.location.search;
302 const urlParams = new URLSearchParams(queryString);
303 const code = urlParams.get('code');
305 $('#value_selector').val(code);
306 updateTransferLimitsTable();
310 function delLimit(checkbox) {
311 const id = checkbox.attr('id');
312 const limit_id = checkbox.data('limit_id');
315 url: `/api/v1/transfer_limits/${limit_id}`,
317 success: function(result) {
318 checkbox.data('limit_id', null);
319 checkbox.attr('checked', true);
320 $(`#spinner-${id}`).hide();
323 error: function(xhr, status, error) {
324 var errorMessage = xhr.status + ': ' + xhr.statusText
325 alert('Error - ' + errorMessage);
330 function addLimit(checkbox) {
331 const id = checkbox.attr('id');
332 const parts = id.split('-');
333 const from = parts[1];
336 const val = $('#value_selector').val();
340 from_library_id: from,
342 data[val_type] = val;
344 url: `/api/v1/transfer_limits`,
346 data: JSON.stringify(data),
348 success: function(result) {
349 checkbox.data('limit_id', result.limit_id);
350 checkbox.attr('checked', false);
351 $(`#spinner-${id}`).hide();
354 error: function(xhr, status, error) {
355 var errorMessage = xhr.status + ': ' + xhr.statusText
356 alert('Error - ' + errorMessage);
361 function add_limits( checkboxes, val, to, from ){
363 data[val_type] = val;
364 if (to) data["to_library_id"] = to;
365 if (from) data["from_library_id"] = from;
368 url: `/api/v1/transfer_limits/batch`,
370 data: JSON.stringify(data),
372 success: function(result) {
373 for ( i = 0; i < result.length; i++ ) {
375 let checkbox = $(`#limit-${r.from_library_id}-${r.to_library_id}`);
376 const id = checkbox.attr('id');
377 checkbox.data('limit_id', r.limit_id);
378 checkbox.attr('checked', false);
379 $(`#spinner-${id}`).hide();
383 complete: function() {
384 $('.limit-action').removeClass('disabled');
385 $('#value_selector').prop('disabled',false);
387 error: function(xhr, status, error) {
388 var errorMessage = xhr.status + ': ' + xhr.statusText
389 alert('Error - ' + errorMessage);
394 function del_limits( checkboxes, val, to, from ){
396 data[val_type] = val;
397 if (to) data["to_library_id"] = to;
398 if (from) data["from_library_id"] = from;
401 url: `/api/v1/transfer_limits/batch`,
403 data: JSON.stringify(data),
405 success: function(result) {
406 for ( i = 0; i < checkboxes.length; i++ ) {
407 const checkbox = checkboxes[i];
408 const id = checkbox.attr('id');
409 checkbox.data('limit_id', '');
410 checkbox.attr('checked', true);
411 $(`#spinner-${id}`).hide();
415 complete: function() {
416 $('.limit-action').removeClass('disabled');
417 $('#value_selector').prop('disabled',false);
419 error: function(xhr, status, error) {
420 var errorMessage = xhr.status + ': ' + xhr.statusText
421 alert('Error - ' + errorMessage);
426 function updateTransferLimitsTable() {
427 const val = $('#value_selector').val();
428 const url = `/api/v1/transfer_limits?_per_page=-1&q={"${val_type}": "${val}"}`;
431 $('#transfer_limits').show();
433 $('#transfer_limits').hide();
436 $(".limit-checkboxes").attr("disabled", true);
437 $(".limit-checkboxes").attr("checked", false);
440 $('#loading_limits').show();
445 success: function(data) {
446 $(".limit-checkboxes").attr("disabled", false);
447 $(".limit-checkboxes").attr("checked", true);
448 $(".limit-checkboxes").data('limit_id', null);
450 for (var i = 0; i < data.length; i++) {
452 let checkbox = $(`#limit-${limit.from_library_id}-${limit.to_library_id}`);
453 checkbox.attr('checked', false);
454 checkbox.data('limit_id', limit.limit_id);
457 complete: function() {
458 $('#loading_limits').hide();
460 error: function(xhr, status, error) {
461 var errorMessage = xhr.status + ': ' + xhr.statusText
462 alert('Error - ' + errorMessage);
469 [% INCLUDE 'intranet-bottom.inc' %]