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