Bug 34820: (QA follow-up) Replace em tags with quotes
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / tools / inventory.tt
1 [% USE raw %]
2 [% USE Asset %]
3 [% USE AuthorisedValues %]
4 [% USE KohaDates %]
5 [% USE Branches %]
6 [% SET footerjs = 1 %]
7 [% INCLUDE 'doc-head-open.inc' %]
8 <title>Inventory &rsaquo; Cataloging &rsaquo; Koha</title>
9 [% INCLUDE 'doc-head-close.inc' %]
10 </head>
11
12 <body id="tools_inventory" class="tools">
13 [% WRAPPER 'header.inc' %]
14     [% INCLUDE 'cat-search.inc' %]
15 [% END %]
16
17 [% WRAPPER 'sub-header.inc' %]
18     [% WRAPPER breadcrumbs %]
19         [% WRAPPER breadcrumb_item %]
20             <a href="/cgi-bin/koha/cataloguing/cataloging-home.pl">Cataloging</a>
21         [% END %]
22
23         [% IF (loop) %]
24             [% WRAPPER breadcrumb_item %]
25                 <a href="/cgi-bin/koha/tools/inventory.pl">Inventory</a>
26             [% END %]
27             [% WRAPPER breadcrumb_item bc_active= 1 %]
28                 <span>Results</span>
29             [% END %]
30         [% ELSE %]
31             [% WRAPPER breadcrumb_item bc_active= 1 %]
32                 <span>Inventory</span>
33             [% END %]
34         [% END %]
35     [% END #/ WRAPPER breadcrumbs %]
36 [% END #/ WRAPPER sub-header.inc %]
37
38 <div class="main container-fluid">
39     <div class="row">
40         <div class="col-sm-10 col-sm-push-2">
41             <main>
42
43     <h1>Inventory</h1>
44     [% IF (moddatecount) %]<div class="dialog message">[% moddatecount | html %] items modified : datelastseen set to [% date | $KohaDates with_hours => 1 %]</div>
45     <div class="dialog alert">Number of potential barcodes read: [% LinesRead | html %]</div>[% END %]
46     [% IF (errorfile) %]<div class="dialog alert">[% errorfile | html %] can't be opened</div>[% END %]
47     [% IF (err_length && err_length==1) %]<div class="dialog alert">There was 1 barcode that was too long.</div>[% END %]
48     [% IF (err_length && err_length>1) %]<div class="dialog alert">There were [% err_length | html %] barcodes that were too long.</div>[% END %]
49     [% IF (err_data && err_data==1) %]<div class="dialog alert">There was 1 barcode that contained at least one unprintable character.</div>[% END %]
50     [% IF (err_data && err_data>1) %]<div class="dialog alert">There were [% err_data | html %] barcodes that contained at least one unprintable character.</div>[% END %]
51     [% FOREACH error IN errorloop %]
52         <div class="dialog alert">
53             [% error.barcode | html %]
54             [% IF (error.ERR_BARCODE) %]: <span>Barcode not found.</span>[% END %]
55             [% IF (error.ERR_WTHDRAWN) %]: <span>Item withdrawn.</span>[% END %]
56             [% IF (error.ERR_ONLOAN_RET) %]: <span>Item was on loan. It was checked in before being marked as seen.</span>[% END %]
57             [% IF (error.ERR_ONLOAN_NOT_RET) %]: <span>Item was on loan and could not be checked in.</span>[% END %]
58         </div>
59     [% END %]
60        [% UNLESS op %]
61
62     <form method="post" id="inventory_form" action="/cgi-bin/koha/tools/inventory.pl" enctype="multipart/form-data">
63         <fieldset class="rows">
64           <legend>Use a barcode file</legend>
65           <ol>
66             <li><label for="uploadbarcodes">Barcode file: </label> <input type="file" id="uploadbarcodes" name="uploadbarcodes" />
67             <input type="button" id="resetuploadbarcodes" name="resetuploadbarcodes" value="Reset" /></li>
68           </ol>
69         </fieldset>
70         <fieldset class="rows">
71             <legend>Or scan items one by one</legend>
72             <ol>
73                 <li>
74                   <label for="barcodelist">Barcode list (one barcode per line): </label>
75                   <textarea rows="10" cols="30" id="barcodelist" name="barcodelist"></textarea>
76                 </li>
77             </ol>
78         </fieldset>
79         <fieldset class="rows">
80             <legend>Parameters</legend>
81             <ol>
82                 <li><label for="setdate">Set inventory date to:</label> <input type="text" id="setdate" name="setdate" value="[% today | html %]" class="flatpickr" /></li>
83                 <li><label for="compareinv2barcd">Compare barcodes list to results: </label><input type="checkbox" name="compareinv2barcd" id="compareinv2barcd" disabled /></li>
84                 <li><label for="dont_checkin">Do not check in items scanned during inventory: </label><input type="checkbox" name="dont_checkin" id="dont_checkin" disabled /></li>
85                 <li><label for="out_of_order">Check barcodes list for items shelved out of order: </label><input type="checkbox" name="out_of_order" id="out_of_order" disabled /></li>
86             </ol>
87         </fieldset>
88         <fieldset class="rows">
89         <legend>Item location filters</legend>
90         <ol><li>
91         <label for="branch">Location: </label>
92             <input type="radio" name="branch" value="homebranch"> Home library</input>
93             <input type="radio" name="branch" value="holdingbranch"> Current library</input>
94         </li><li>
95         <label for="branchloop">Library: </label><select id="branchloop" name="branchcode" style="width:12em;">
96             <option value="">All libraries</option>
97             [% PROCESS options_for_libraries libraries => Branches.all( selected => branchcode, unfiltered => 1, ) %]
98         </select>
99         </li>
100         [% IF (authorised_values) %]
101         <li>
102             <label for="locationloop">Shelving location (items.location) is: </label>
103         <select id="locationloop" name="location">
104                 <option value="">Filter location</option>
105         [% FOREACH value IN authorised_values %]
106             [% IF (value.selected) %]
107                 <option value="[% value.authorised_value | html %]" selected="selected">[% value.lib | html %]</option>
108             [% ELSE %]
109                 <option value="[% value.authorised_value | html %]">[% value.lib | html %]</option>
110             [% END %]
111         [% END %]
112         </select>        </li>
113         [% END %]
114         [% SET ccodes = AuthorisedValues.GetAuthValueDropbox('CCODE') %]
115         [% IF ( ccodes.count > 0 ) %]
116         <li>
117             <label for="ccode">Collection code: </label>
118             <select id="ccodeloop" name="ccode">
119                         <option value="">Filter collection</option>
120                 [% FOREACH cc IN ccodes %]
121                     [% IF (ccode == cc.authorised_value) %]
122                         <option value="[% cc.authorised_value | html %]" selected="selected">[% cc.lib | html %]</option>
123                     [% ELSE %]
124                         <option value="[% cc.authorised_value | html %]">[% cc.lib | html %]</option>
125                     [% END %]
126                 [% END %]
127             </select>
128         </li>
129         [% END %]
130         <li>
131             <label for="minlocation">Item call number between: </label>
132                 <input type="text" name="minlocation" id="minlocation" value="[% minlocation | html %]" /> (items.itemcallnumber)  </li>
133            <li><label for="maxlocation">...and: </label>
134                 <input type="text" name="maxlocation" id="maxlocation" value="[% maxlocation | html %]" />
135            <li>
136             <label for="class_source">Call number classification scheme</label>
137             <select name="class_source">
138             [% FOREACH class_source IN class_sources %]
139                 [% IF class_source.cn_source == pref_class %]
140                 <option value="[% class_source.cn_source | html %]" selected="selected">[% class_source.description | html %] (default)</option>
141                 [% ELSE %]
142                 <option value="[% class_source.cn_source | html %]">[% class_source.description | html %]</option>
143                 [% END %]
144             [% END %]
145             </select>
146           </li>
147     </ol>
148     </fieldset>
149
150     <fieldset class="rows" id="optionalfilters">
151             <legend>Optional filters for inventory list or comparing barcodes</legend>
152             <span class="hint">Scanned items are expected to match one of the selected "not for loan" criteria if any are checked.</span>
153             <br/>
154             <div id="statuses" style="display: block;">
155                   [% FOREACH status IN statuses %]
156                       [% IF (status.values) %]
157                           <fieldset style="float: left; padding: 5px; margin: 5px;text-align:right">
158                               <legend>[% status.fieldname | html %]</legend>
159                               <ul id="statuses-[% fieldname | html %]" style="display: inline;">
160                               [% FOREACH value IN status.values %]
161                                   [% IF (value.lib) %]
162                                     <li style="list-style: none;">
163                                     <label for="[% value.id | html %]">
164                                         [% IF ( status.fieldname == 'items.notforloan' && value.authorised_value == 0 && value.lib == '__IGNORE__' ) %]
165                                             For loan
166                                         [% ELSE %]
167                                             [% value.lib | html %]
168                                         [% END %]
169                                     </label>
170                                     <input type="checkbox" name="status-[% status.fieldname | html %]-[% value.authorised_value | html %]" id="[% value.authorised_value | html %]" />
171                                     </li>
172                                   [% END %]
173                               [% END %]
174                               </ul>
175                           </fieldset>
176                       [% END %]
177                   [% END %]
178                 </div>
179         <ol>
180         <li>
181             <br/>
182             <label for="datelastseen">Last inventory date:</label>
183             <input type="text" id="datelastseen" name="datelastseen" value="[% datelastseen | html %]" class="flatpickr" />
184             (Skip records marked as seen on or after this date.)
185         </li>
186         <li>
187             <label for="ignoreissued">Skip items on loan: </label>
188             [% IF (ignoreissued) %]
189                 <input type="checkbox" id="ignoreissued" name="ignoreissued" checked="checked" />
190             [% ELSE %]
191                 <input type="checkbox" id="ignoreissued" name="ignoreissued" />
192             [% END %]
193         </li>
194         <li>
195             <label for="ignore_waiting_holds">Skip items on hold awaiting pickup: </label>
196             <input type="checkbox" id="ignore_waiting_holds" name="ignore_waiting_holds" />
197         </li>
198         <li>
199             <label>Item types: </label>
200             <div class="branchselector">
201                 <p><a href="#" id="checkallitemtypes"> <i class="fa fa-check"></i> Select all</a> | <a href="#" id="checknoneitemtypes"> <i class="fa fa-times"></i> Clear all</a></p>
202                 <div class="branchgridrow">
203                     [% FOREACH itemtype IN itemtypes %]
204                         <div class="branchgriditem">
205                             <input id="itemtype-[% itemtype.itemtype | html %]" class="branch_select" type="checkbox" name="itemtype-[% itemtype.itemtype | html %]" value="[% itemtype.itemtype | html %]" />
206                             <label for="itemtype-[% itemtype.itemtype | html %]">[% itemtype.description | html %]</label>
207                         </div>
208                         [% IF loop.count() % 4 == 0 && !loop.last() %]
209                             </div>
210                             <div class="branchgridrow">
211                         [% END %]
212                     [% END %]
213                 </div>
214             </div>
215         </li>
216
217         </ol>
218
219     </fieldset>
220
221         <fieldset class="rows">
222           <legend>Additional options</legend>
223           <ol>
224
225         <li>
226            <label for="CSVexport">Export to CSV file: </label>
227            <input type="checkbox" name="CSVexport" id="CSVexport" />
228         </li>
229         </ol>
230             <input type="hidden" name="op" value="do_it" />
231   </fieldset>
232
233             <fieldset class="action"><input type="submit" class="btn btn-primary" value="Submit" /></fieldset>
234     </form>
235
236     [% END %]
237     [% IF (op) %]
238     <form method="post" action="/cgi-bin/koha/tools/inventory.pl">
239     <input type="hidden" name="minlocation" value="[% minlocation | html %]" />
240     <input type="hidden" name="maxlocation" value="[% maxlocation | html %]" />
241     <input type="hidden" name="location" value="[% location | html %]" />
242     <input type="hidden" name="branchcode" value="[% branchcode | html %]" />
243     <input type="hidden" name="datelastseen" value="[% datelastseen | html %]" />
244     <input type="hidden" name="ccode" value="[% ccode | html %]" />
245
246     [% UNLESS uploadedbarcodesflag %]
247       <div><a href="#" class="checkall"><i class="fa fa-check"></i> Select all</a> <a href="#" class="clearall"><i class="fa fa-times"></i> Clear all</a></div>
248     [% END %]
249
250     <div class="page-section">
251     <table id="inventoryt">
252     <thead>
253         <tr>
254             [% UNLESS uploadedbarcodesflag %]<th>Seen</th>[% END %]
255             <th>Barcode</th>
256             <th>Call number</th>
257             <th>Library</th>
258             <th>Collection code</th>
259             <th class="anti-the">Title</th>
260             <th>Not for loan</th>
261             <th>Lost</th>
262             <th>Damaged</th>
263             <th>Withdrawn</th>
264             <th>Last seen</th>
265             <th>Problems</th>
266         </tr>
267     </thead>
268     <tbody>
269     [% FOREACH result IN loop %]
270         <tr>
271             [% UNLESS uploadedbarcodesflag %]
272               <td>
273                 <input type="checkbox" name="SEEN-[% result.itemnumber | html %]" value="1" />
274               </td>
275             [% END %]
276             <td>
277             [% result.barcode | html %]
278             </td>
279             <td data-order="[% result.cn_sort | html %]">
280                 [% result.itemcallnumber | html %]
281             </td>
282             <td>
283                 [% Branches.GetName( result.homebranch ) | html %]
284                 <span class="shelvingloc">[% result.location | html %]</span>
285             </td>
286             <td>
287                 <span class="ccode">[% result.ccode | html %]</span>
288             </td>
289             <td>
290                 <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% result.biblionumber | uri %]" class="openWin">[% result.title | html %]</a>
291                 [% IF ( result.author ) %]
292                     by <span class="author">[% result.author | html %]</span>
293                 [% END %]
294             </td>
295             <td>
296             [% result.notforloan | html %]
297             </td>
298             <td>
299             [% result.itemlost | html %]
300             </td>
301             <td>
302             [% result.damaged | html %]
303             </td>
304             <td>
305             [% result.withdrawn | html %]
306             </td>
307             <td data-order="[% result.datelastseen | html %]">
308                 [% result.datelastseen | $KohaDates with_hours => 1 %]
309             </td>
310             <td>
311             [% FOREACH problem IN result.problems %]
312                 [% IF problem.key == 'wrongplace' %]
313                     <span>Found in wrong place</span><br/>
314                 [% ELSIF problem.key == 'changestatus' %]
315                     [% IF result.notforloan %]
316                         <span>Item has unselected "Not for loan" status "[% result.notforloan | html %]"/span><br/>
317                     [% ELSE %]
318                         <span>Items has no "not for loan" status</span><br/>
319                     [% END %]
320                 [% ELSIF problem.key == 'not_scanned' %]
321                     <span>Missing (not scanned)</span><br/>
322                 [% ELSIF problem.key == 'checkedout' %]
323                     <span>Still checked out</span><br/>
324                 [% ELSIF problem.key == 'no_barcode' %]
325                     <span>No barcode</span><br/>
326                 [% ELSIF problem.key == 'out_of_order' %]
327                     <span>Item may be shelved out of order</span><br/>
328                 [% END %]
329             [% END %]
330             </td>
331         </tr>
332     [% END %]
333     </tbody>
334     </table>
335     </div>
336
337     <div class="spacer"></div>
338     [% UNLESS uploadedbarcodesflag %]
339       <div style="padding : .3em 0"><a href="#" class="checkall"><i class="fa fa-check"></i> Select all</a> <a href="#" class="clearall"><i class="fa fa-times"></i> Clear all</a></div>
340       <input type="submit" id="markseenandquit" class="btn btn-primary" value="Mark seen and quit" />
341       <input type="submit" value="Mark seen and continue &gt;&gt;" id="markseenandcontinuebutton" />
342       <input type="submit" value="Continue without marking &gt;&gt;" id="continuewithoutmarkingbutton" class="submit" />
343     [% END %]
344     </form>
345
346
347     [% END %]
348
349             </main>
350         </div> <!-- /.col-sm-10.col-sm-push-2 -->
351
352         <div class="col-sm-2 col-sm-pull-10">
353             <aside>
354                 [% INCLUDE 'cat-menu.inc' %]
355             </aside>
356         </div> <!-- .col-sm-2.col-sm-pull-10 -->
357      </div> <!-- /.row -->
358
359 [% MACRO jsinclude BLOCK %]
360     [% INCLUDE 'datatables.inc' %]
361     [% INCLUDE 'calendar.inc' %]
362     <script>
363         function checkForm() {
364             if ( $('#uploadbarcodes').val() && $('#barcodelist').val() ) {
365                 alert(_("You have uploaded a barcode file and scanned barcodes at the same time. Please choose one of the two options."));
366                 return false;
367             }
368             if ( $('#uploadbarcodes').val() || $('#barcodelist').val() ) {
369                 if ( !(
370                     $('#branchloop').val()   ||
371                     $('#locationloop').val() ||
372                     $('#minlocation').val()  ||
373                     $('#maxlocation').val()  ||
374                     $('#statuses input:checked').length
375                 ) ) {
376                     return confirm(
377                         _("You have not selected any catalog filters and are about to compare a file of barcodes to your entire catalog.") + "\n\n" +
378                         _("For large catalogs this can result in unexpected behavior") + "\n\n" +
379                         _("Are you sure you want to do this?")
380                     );
381                 }
382             }
383
384             return true;
385         }
386
387         function barcodesProvided() {
388             if( $("#uploadbarcodes").val() || $("#barcodelist").val() ) {
389                 $("#setdate").prop('disabled',false);
390                 $("#compareinv2barcd").prop('disabled',false);
391                 $("#compareinv2barcd").attr('checked',true); // default
392                 $("#dont_checkin").prop('disabled',false);
393                 $("#out_of_order").prop('disabled',false);
394                 if( $("#compareinv2barcd").attr('checked') ) {
395                     $("fieldset#optionalfilters").show();
396                     $("#ignoreissued").attr('checked',true); // default
397                 } else {
398                     $("fieldset#optionalfilters").hide();
399                     $("#ignoreissued").attr('checked',false);
400                 }
401             } else {
402                 $("#setdate").prop('disabled',true);
403                 $("#compareinv2barcd").prop('disabled',true);
404                 $("#compareinv2barcd").attr('checked',false);
405                 $("#dont_checkin").prop('disabled',true);
406                 $("#dont_checkin").attr('checked',false);
407                 $("#out_of_order").prop('disabled',true);
408                 $("#out_of_order").attr('checked',false);
409                 $("fieldset#optionalfilters").show();
410             }
411         }
412
413         $(document).ready(function(){
414             inventorydt = $('#inventoryt').dataTable($.extend(true, {}, dataTablesDefaults, {
415                 'sPaginationType': 'full_numbers',
416                 [% IF compareinv2barcd %]
417                     // sort on callnumber
418                     "aaSorting": [[ 1, "asc" ]],
419                 [% ELSE %]
420                     // first column contains checkboxes
421                     "aoColumnDefs": [
422                         { "sType": "anti-the", "aTargets" : [ "anti-the" ] },
423                         { "bSortable": false, "bSearchable": false, "aTargets": [ 0 ] }
424                     ],
425                     // 3rd column is callnumber
426                     "aaSorting": [[ 2, "asc" ]],
427                 [% END %]
428                 'fnDrawCallback': function() {
429                     //bind the click handler script to the newly created elements held in the table
430                     $('.openWin').bind('click',function(e){
431                         e.preventDefault();
432                         openWindow(this.href,'marcview',800,600);
433                     });
434                 }
435             } ));
436
437
438             $("#continuewithoutmarkingbutton").click(function(){
439                 inventorydt.fnPageChange( 'next' );
440                 return false;
441             });
442
443             $("#markseenandcontinuebutton").click(function(){
444                 var param = '';
445                 $("input:checked").each(function() {
446                     param += "|" + $(this).attr('name');
447                 });
448                 $.post('/cgi-bin/koha/tools/ajax-inventory.pl', { seen: param });
449                 inventorydt.fnPageChange( 'next' );
450                 return false;
451             });
452
453             $("#markseenandquit").click(function(){
454                 var param = '';
455                 $("input:checked").each(function() {
456                     param += "|" + $(this).attr('name');
457                 });
458                 $.ajax({
459                   type: 'POST',
460                   url: '/cgi-bin/koha/tools/ajax-inventory.pl',
461                   data: { seen: param},
462                   async: false
463                 });
464                 document.location.href = '/cgi-bin/koha/tools/inventory.pl';
465                 return false;
466             });
467
468             $(".checkall").click(function(e){
469                 e.preventDefault();
470                 $("#inventoryt input:checkbox").each(function(){
471                     $(this).prop("checked", true);
472                 });
473             });
474             $(".clearall").click(function(e){
475                 e.preventDefault();
476                 $("#inventoryt input:checkbox").each(function(){
477                     $(this).prop("checked", false);
478                 });
479             });
480             $("#inventory_form").on("submit",function(){
481                 return checkForm();
482             });
483
484             $("#resetuploadbarcodes").click(function() {
485                 $("#uploadbarcodes").val("");
486                 barcodesProvided();
487             });
488
489             // #uploadbarcodes and #compareinv2barcd determine the behavior of
490             // the controls within the barcode fieldset and the optional filters
491             $("#uploadbarcodes").change(barcodesProvided);
492             $("#barcodelist").on("change keyup paste", barcodesProvided);
493
494             $("#compareinv2barcd").click(function() {
495                 if( $("#compareinv2barcd").attr('checked') ) {
496                     $("fieldset#optionalfilters").show();
497                     $("#ignoreissued").attr('checked',true); // default
498                 } else {
499                     $("#ignoreissued").attr('checked',false);
500                     $("fieldset#optionalfilters").hide();
501                 }
502             });
503
504             $("#checkallitemtypes").on("click",function(e){
505                 e.preventDefault();
506                 $(".branch_select").prop("checked",1);
507             });
508             $("#checknoneitemtypes").on("click",function(e){
509                 e.preventDefault();
510                 $(".branch_select").prop("checked",0);
511             });
512         });
513     </script>
514 [% END %]
515
516 [% INCLUDE 'intranet-bottom.inc' %]