Koha/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt
Marcel de Rooy 6da97c7c87 Bug 14399: Numerous small refinements to the inventory script
This patch contains the following changes:

[01] Label "Inventory date" reworded to "Last inventory date", adding a
small explanation for its purpose.
[02] Restructured the results: it was an array with items and possible
error messages. Multiple messages duplicated individual items. Now the
results are in a hash, pulling all error messages for one item together.
At the end of the script they are copied to an array. (A helper sub
additemtoresults is added in this regard.) We no longer use array
@items_with_problems.
[03] Both datepickers are no longer connected to the same class. This
prevents changing the set date by filling the last inventory date.
[04] Input markseen in the template and $markseen in the script are
no longer needed.
[05] The paragraph before the detail link in the results table in the
Title column has been removed. Same for problems column. This makes
vertical spacing consistent.
[06] Problem status 'missingitem' is no longer used; the missing items
are marked as 'not_scanned'. Two additional statuses are: no_barcode and
checkedout.
[07] Removed unused $itemtype, $totalrecords and $count. We use variable
$moddatecount to report a count to the template.
[08] The script updated scanned items twice. The first time with ModItem
and the second time with ModDateLastSeen. The second call is removed.
[09] If a book is checked in, we do no longer return an error message when
the checkin is successful (ERR_ONLOAN_RET). The updated datelastseen is
passed to the results.
[10] $wrongplacelist is renamed to $rightplacelist. It is only built when
we need it. (Same for inventorylist now.)
[11] Datelastseen (last inventory date) is always used for building the
inventory list. It allows you to process partial barcode lists or make
a list of items not seen after some date. We do no longer use variable
$paramdatelastseen.
[12] The section where items.datelastseen was compared with the inventory
date has been removed. Scanned items were already updated; to get items
seen before some date, you can now use last inventory date without passing
barcodes.

The form can mainly be used for the following three cases:
[1] Prepare an inventory list or csv file; we do not upload barcodes.
[2] Update items for uploaded barcodes without comparing to inventory.
    Last inventory date is useless in this case.
    Errors wrongplace, checkedout and changestatus are reported.
    Use this scenario for partial scanned barcode lists (all but last).
[3] Update items for uploaded barcodes and compare to inventory, filtered
    by an optional last inventory date.
    Apart from the errors mentioned under [2], this also reports
    not_scanned ("missing") and no_barcode.
    Use this scenario too for the last partial barcode file (together with
    inventory date).

Test plan:
See next patch ("Interface changes").

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>

Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
2017-05-10 16:23:55 +00:00

333 lines
14 KiB
Text

[% USE KohaDates %]
[% USE Branches %]
[% INCLUDE 'doc-head-open.inc' %]
<title>Koha &rsaquo; Tools &rsaquo; Inventory</title>
[% INCLUDE 'doc-head-close.inc' %]
<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/css/datatables.css" />
[% INCLUDE 'datatables.inc' %]
[% INCLUDE 'calendar.inc' %]
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
<script type="text/javascript">
//<![CDATA[
function checkForm() {
if ( $('#uploadbarcodes').val() ) {
if ( !(
$('#branchloop').val() ||
$('#locationloop').val() ||
$('#minlocation').val() ||
$('#maxlocation').val() ||
$('#statuses input:checked').length
) ) {
return confirm(
_("You have not selected any catalog filters and are about to compare a file of barcodes to your entire catalog.") + "\n\n" +
_("For large catalogs this can result in unexpected behavior") + "\n\n" +
_("Are you sure you want to do this?")
);
}
}
return true;
}
$(document).ready(function(){
inventorydt = $('#inventoryt').dataTable($.extend(true, {}, dataTablesDefaults, {
'sPaginationType': 'full_numbers',
[% IF compareinv2barcd %]
"aoColumnDefs": [ { "bSortable": false, "aTargets": [ 1 ] } ],
[% ELSE %]
"aoColumnDefs": [ { "bSortable": false, "aTargets": [ 0 ] } ],
[% END %]
'fnDrawCallback': function() {
//bind the click handler script to the newly created elements held in the table
$('.openWin').bind('click',function(e){
e.preventDefault();
openWindow(this.href,'marcview',800,600);
});
}
} ));
$("#continuewithoutmarkingbutton").click(function(){
inventorydt.fnPageChange( 'next' );
return false;
});
$("#markseenandcontinuebutton").click(function(){
var param = '';
$("input:checked").each(function() {
param += "|" + $(this).attr('name');
});
$.post('/cgi-bin/koha/tools/ajax-inventory.pl', { seen: param });
inventorydt.fnPageChange( 'next' );
return false;
});
$("#markseenandquit").click(function(){
var param = '';
$("input:checked").each(function() {
param += "|" + $(this).attr('name');
});
$.ajax({
type: 'POST',
url: '/cgi-bin/koha/tools/ajax-inventory.pl',
data: { seen: param},
async: false
});
document.location.href = '/cgi-bin/koha/tools/inventory.pl';
return false;
});
$(".checkall").click(function(){
$(".checkboxed").checkCheckboxes();
return false;
});
$(".clearall").click(function(){
$(".checkboxed").unCheckCheckboxes();
return false;
});
$("#inventory_form").on("submit",function(){
return checkForm();
});
});
//]]>
</script>
</head>
<body id="tools_inventory" class="tools">
[% INCLUDE 'header.inc' %]
[% INCLUDE 'cat-search.inc' %]
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; [% IF (loop) %]<a href="/cgi-bin/koha/tools/inventory.pl">Inventory</a> &rsaquo; Results[% ELSE %]Inventory[% END %]</div>
<div id="doc3" class="yui-t2">
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<h1>Inventory</h1>
[% IF (moddatecount) %]<div class="dialog message">[% moddatecount %] items modified : datelastseen set to [% date | $KohaDates %]</div>
<div class="dialog alert">Number of potential barcodes read: [% LinesRead %]</div>[% END %]
[% IF (errorfile) %]<div class="dialog alert">[% errorfile %] can't be opened</div>[% END %]
[% IF (err_length && err_length==1) %]<div class="dialog alert">There was 1 barcode that was too long.</div>[% END %]
[% IF (err_length && err_length>1) %]<div class="dialog alert">There were [% err_length %] barcodes that were too long.</div>[% END %]
[% IF (err_data && err_data==1) %]<div class="dialog alert">There was 1 barcode that contained at least one unprintable character.</div>[% END %]
[% IF (err_data && err_data>1) %]<div class="dialog alert">There were [% err_data %] barcodes that contained at least one unprintable character.</div>[% END %]
[% FOREACH error IN errorloop %]
<div class="dialog alert">
[% error.barcode %]
[% IF (error.ERR_BARCODE) %]: barcode not found[% END %]
[% IF (error.ERR_WTHDRAWN) %]: item withdrawn[% END %]
[% IF (error.ERR_ONLOAN_RET) %]: item was on loan. It was returned before marked as seen[% END %]
[% IF (error.ERR_ONLOAN_NOT_RET) %]: item was on loan. couldn't be returned.[% END %]
</div>
[% END %]
[% UNLESS op %]
<div class="yui-g">
<form method="post" id="inventory_form" action="/cgi-bin/koha/tools/inventory.pl" enctype="multipart/form-data">
<fieldset class="rows">
<legend>Use a barcode file</legend>
<ol>
<li><label for="uploadbarcodes">Barcode file: </label> <input type="file" id="uploadbarcodes" name="uploadbarcodes" /></li>
<li><label for="setdate">Set inventory date to:</label> <input type="text" id="setdate" name="setdate" value="[% today | $KohaDates %]" class="datepicker" />
</li>
</ol>
</fieldset>
<fieldset class="rows">
<legend>Select items you want to check</legend>
<ol><li>
<label for="branch">Library: </label>
<input type="radio" name="branch" value="homebranch"> Home library</input>
<input type="radio" name="branch" value="holdingbranch"> Current library</input>
</li><li>
<label for="branchloop">Library: </label><select id="branchloop" name="branchcode" style="width:12em;">
<option value="">All libraries</option>
[% PROCESS options_for_libraries libraries => Branches.all( selected => branchcode, unfiltered => 1, ) %]
</select>
</li>
[% IF (authorised_values) %]
<li>
<label for="locationloop">Shelving location (items.location) is: </label>
<select id="locationloop" name="location">
<option value="">Filter location</option>
[% FOREACH value IN authorised_values %]
[% IF (value.selected) %]
<option value="[% value.authorised_value %]" selected="selected">[% value.lib %]</option>
[% ELSE %]
<option value="[% value.authorised_value %]">[% value.lib %]</option>
[% END %]
[% END %]
</select> </li>
[% END %]
<li>
<label for="minlocation">Item callnumber between: </label>
<input type="text" name="minlocation" id="minlocation" value="[% minlocation %]" /> (items.itemcallnumber) </li>
<li><label for="maxlocation">...and: </label>
<input type="text" name="maxlocation" id="maxlocation" value="[% maxlocation %]" />
</li>
[% IF (statuses) %]
</ol>
</fieldset>
<fieldset class="rows">
<legend>Item statuses</legend>
<div id="statuses" style="display: block;">
[% FOREACH status IN statuses %]
[% IF (status.values) %]
<fieldset style="float: left; padding: 5px; margin: 5px;text-align:right">
<legend>[% status.fieldname %]</legend>
<ul id="statuses-[% fieldname %]" style="display: inline;">
[% FOREACH value IN status.values %]
[% IF (value.lib) %]
<li>
<label for="[% value.id %]">
[% IF value.authorised_value==0 %]
For loan
[% ELSE %]
[% value.lib %]
[% END %]
</label>
<input type="checkbox" name="status-[% status.fieldname %]-[% value.authorised_value %]" id="[% value.authorised_value %]" />
</li>
[% END %]
[% END %]
</ul>
</fieldset>
[% END %]
[% END %]
</div>
</fieldset>
<fieldset class="rows">
<ol>
[% END %]
<li><label for="datelastseen">Last inventory date:</label>
<input type="text" id="datelastseen" name="datelastseen" value="[% datelastseen | $KohaDates %]" class="datepicker" />
(Skip records marked as seen on or after this date.)
</li>
<li><label for="ignoreissued">Skip items on loan: </label>
[% IF (ignoreissued) %]
<input type="checkbox" id="ignoreissued" name="ignoreissued" checked="checked" /></li>
[% ELSE %]
<input type="checkbox" id="ignoreissued" name="ignoreissued" /></li>
[% END %]
<li>
<label for="CSVexport">Export to CSV file: </label>
<input type="checkbox" name="CSVexport" id="CSVexport" />
</li>
<li>
<label for="compareinv2barcd">Compare barcodes list to results: </label>
<input type="checkbox" name="compareinv2barcd" id="compareinv2barcd" />
</li>
<li>
<label for="dont_checkin">Do not check in items scanned during inventory: </label>
<input type="checkbox" name="dont_checkin" id="dont_checkin" />
</li>
</ol>
</fieldset>
<input type="hidden" name="op" value="do_it" />
<fieldset class="action"><input type="submit" value="Submit" class="button" /></fieldset>
</form>
</div>
</div>
[% END %]
[% IF (op) %]
<form method="post" action="/cgi-bin/koha/tools/inventory.pl" class="checkboxed">
<input type="hidden" name="minlocation" value="[% minlocation %]" />
<input type="hidden" name="maxlocation" value="[% maxlocation %]" />
<input type="hidden" name="location" value="[% location %]" />
<input type="hidden" name="branchcode" value="[% branchcode %]" />
<input type="hidden" name="datelastseen" value="[% datelastseen %]" />
[% UNLESS compareinv2barcd %]
<div><a href="#" class="checkall"><i class="fa fa-check"></i> Select all</a> <a href="#" class="clearall"><i class="fa fa-remove"></i> Clear all</a></div>
[% END %]
<table id="inventoryt">
<thead>
<tr>
[% UNLESS compareinv2barcd %]<th>Seen</th>[% END %]
<th>Barcode</th>
<th>Call number</th>
<th>Library</th>
<th>Title</th>
<th>Status</th>
<th>Lost</th>
<th>Damaged</th>
<th>Withdrawn</th>
<th>Last seen</th>
<th>Problems</th>
</tr>
</thead>
<tbody>
[% FOREACH result IN loop %]
<tr>
[% UNLESS compareinv2barcd %]
<td>
<input type="checkbox" name="SEEN-[% result.itemnumber %]" value="1" />
</td>
[% END %]
<td>
[% result.barcode | html %]
</td>
<td>[% result.itemcallnumber | html %]</td>
<td>
[% Branches.GetName( result.homebranch ) %]
[% result.location | html %]
</td>
<td>
<a href="/cgi-bin/koha/catalogue/MARCdetail.pl?biblionumber=[% result.biblionumber %]" class="openWin">[% result.title | html %]</a>
<p>[% result.author | html %]</p>
</td>
<td>
[% result.notforloan | html %]
</td>
<td>
[% result.itemlost | html %]
</td>
<td>
[% result.damaged | html %]
</td>
<td>
[% result.withdrawn | html %]
</td>
<td>
[% result.datelastseen | $KohaDates | html %]
</td>
<td>
[% FOREACH problem IN result.problems %]
[% IF problem.key == 'wrongplace' %]
Found in wrong place<br/>
[% ELSIF problem.key == 'changestatus' %]
Unknown not-for-loan status<br/>
[% ELSIF problem.key == 'not_scanned' %]
Missing (not scanned)<br/>
[% ELSIF problem.key == 'checkedout' %]
Still checked out<br/>
[% ELSIF problem.key == 'no_barcode' %]
No barcode<br/>
[% END %]
[% END %]
</td>
</tr>
[% END %]
</tbody>
</table>
<div class="spacer"></div>
[% UNLESS compareinv2barcd %]
<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-remove"></i> Clear all</a></div>
<input type="submit" id="markseenandquit" value="Mark seen and quit" />
<input type="submit" value="Mark seen and continue &gt;&gt;" id="markseenandcontinuebutton" />
<input type="submit" value="Continue without marking &gt;&gt;" id="continuewithoutmarkingbutton" class="submit" />
[% END %]
</form>
</div>
[% END %]
</div>
<div class="yui-b">
[% INCLUDE 'tools-menu.inc' %]
</div>
</div>
[% INCLUDE 'intranet-bottom.inc' %]