From 020239359124d5a8dfca6720531eaacfdf5337f2 Mon Sep 17 00:00:00 2001
From: Matthias Meusburger <matthias.meusburger@biblibre.com>
Date: Wed, 26 Jun 2019 14:58:44 +0200
Subject: [PATCH] Bug 23114 - Inventory: allow to scan barcodes

This patch allows the user to scan barcodes in the inventory tool
(in addition to upload a barcode file, like in other tools)

Test plan:
 1) Apply the patch.
 2) Check that you can still upload a barcode file.
 3) Check that you can scan/enter barcodes in the new textarea.
 4) Check that if you both upload a barcode file and enter barcodes,
    you will be prompted to choose only one method.
 5) Check that you can then proceed to the next step by either resetting the
    upload file input or emptying the textarea.
---
 .../prog/en/modules/tools/inventory.tt             | 91 ++++++++++++++--------
 tools/inventory.pl                                 | 18 +++--
 2 files changed, 71 insertions(+), 38 deletions(-)

diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt
index 7739c83..0fdaf8c 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt
@@ -42,14 +42,28 @@
         <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" disabled /></li>
-            <li><label for="compareinv2barcd">Compare barcodes list to results: </label><input type="checkbox" name="compareinv2barcd" id="compareinv2barcd" disabled /></li>
-            <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>
-            <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>
+            <li><label for="uploadbarcodes">Barcode file: </label> <input type="file" id="uploadbarcodes" name="uploadbarcodes" />
+            <input type="button" id="resetuploadbarcodes" name="resetuploadbarcodes" value="Reset" /></li>
           </ol>
         </fieldset>
-
+        <fieldset class="rows">
+            <legend>Or scan items one by one</legend>
+            <ol>
+                <li>
+                  <label for="barcodelist">Barcode list (one barcode per line): </label>
+                  <textarea rows="10" cols="30" id="barcodelist" name="barcodelist"></textarea>
+                </li>
+            </ol>
+        </fieldset>
+        <fieldset class="rows">
+            <legend>Parameters</legend>
+            <ol>
+                <li><label for="setdate">Set inventory date to:</label> <input type="text" id="setdate" name="setdate" value="[% today | $KohaDates %]" class="datepicker" disabled /></li>
+                <li><label for="compareinv2barcd">Compare barcodes list to results: </label><input type="checkbox" name="compareinv2barcd" id="compareinv2barcd" disabled /></li>
+                <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>
+                <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>
+            </ol>
+        </fieldset>
         <fieldset class="rows">
         <legend>Item location filters</legend>
         <ol><li>
@@ -277,7 +291,11 @@
     [% Asset.js("lib/jquery/plugins/jquery.checkboxes.min.js") | $raw %]
     <script type="text/javascript">
         function checkForm() {
-            if ( $('#uploadbarcodes').val() ) {
+            if ( $('#uploadbarcodes').val() && $('#barcodelist').val() ) {
+                alert(_("You have uploaded a barcode file and scanned barcodes at the same time. Please choose one of the options before."));
+                return false;
+            }
+            if ( $('#uploadbarcodes').val() || $('#barcodelist').val() ) {
                 if ( !(
                     $('#branchloop').val()   ||
                     $('#locationloop').val() ||
@@ -296,6 +314,32 @@
             return true;
         }
 
+        function barcodesProvided() {
+            if( $("#uploadbarcodes").val() || $("#barcodelist").val() ) {
+                $("#setdate").prop('disabled',false);
+                $("#compareinv2barcd").prop('disabled',false);
+                $("#compareinv2barcd").attr('checked',true); // default
+                $("#dont_checkin").prop('disabled',false);
+                $("#out_of_order").prop('disabled',false);
+                if( $("#compareinv2barcd").attr('checked') ) {
+                    $("fieldset#optionalfilters").show();
+                    $("#ignoreissued").attr('checked',true); // default
+                } else {
+                    $("fieldset#optionalfilters").hide();
+                    $("#ignoreissued").attr('checked',false);
+                }
+            } else {
+                $("#setdate").prop('disabled',true);
+                $("#compareinv2barcd").prop('disabled',true);
+                $("#compareinv2barcd").attr('checked',false);
+                $("#dont_checkin").prop('disabled',true);
+                $("#dont_checkin").attr('checked',false);
+                $("#out_of_order").prop('disabled',true);
+                $("#out_of_order").attr('checked',false);
+                $("fieldset#optionalfilters").show();
+            }
+        }
+
         $(document).ready(function(){
             inventorydt = $('#inventoryt').dataTable($.extend(true, {}, dataTablesDefaults, {
                 'sPaginationType': 'full_numbers',
@@ -363,33 +407,16 @@
                 return checkForm();
             });
 
+            $("#resetuploadbarcodes").click(function() {
+                $("#uploadbarcodes").val("");
+                barcodesProvided();
+            });
+
             // #uploadbarcodes and #compareinv2barcd determine the behavior of
             // the controls within the barcode fieldset and the optional filters
-            $("#uploadbarcodes").change(function() {
-                if( $("#uploadbarcodes").val() ) {
-                    $("#setdate").prop('disabled',false);
-                    $("#compareinv2barcd").prop('disabled',false);
-                    $("#compareinv2barcd").attr('checked',true); // default
-                    $("#dont_checkin").prop('disabled',false);
-                    $("#out_of_order").prop('disabled',false);
-                    if( $("#compareinv2barcd").attr('checked') ) {
-                        $("fieldset#optionalfilters").show();
-                        $("#ignoreissued").attr('checked',true); // default
-                    } else {
-                        $("fieldset#optionalfilters").hide();
-                        $("#ignoreissued").attr('checked',false);
-                    }
-                } else {
-                    $("#setdate").prop('disabled',true);
-                    $("#compareinv2barcd").prop('disabled',true);
-                    $("#compareinv2barcd").attr('checked',false);
-                    $("#dont_checkin").prop('disabled',true);
-                    $("#dont_checkin").attr('checked',false);
-                    $("#out_of_order").prop('disabled',true);
-                    $("#out_of_order").attr('checked',false);
-                    $("fieldset#optionalfilters").show();
-                }
-            });
+            $("#uploadbarcodes").change(barcodesProvided);
+            $("#barcodelist").on("change keyup paste", barcodesProvided);
+
             $("#compareinv2barcd").click(function() {
                 if( $("#compareinv2barcd").attr('checked') ) {
                     $("fieldset#optionalfilters").show();
diff --git a/tools/inventory.pl b/tools/inventory.pl
index 19d7090..f268b4b 100755
--- a/tools/inventory.pl
+++ b/tools/inventory.pl
@@ -24,6 +24,7 @@ use Modern::Perl;
 use CGI qw ( -utf8 );
 my $input = CGI->new;
 my $uploadbarcodes = $input->param('uploadbarcodes');
+my $barcodelist = $input->param('barcodelist');
 
 use C4::Auth;
 use C4::Context;
@@ -134,7 +135,7 @@ $template->param(
     branch                   => $branch,
     datelastseen             => $datelastseen,
     compareinv2barcd         => $compareinv2barcd,
-    uploadedbarcodesflag     => $uploadbarcodes ? 1 : 0,
+    uploadedbarcodesflag     => ($uploadbarcodes || $barcodelist) ? 1 : 0,
     ignore_waiting_holds     => $ignore_waiting_holds,
     class_sources            => \@class_sources,
     pref_class               => $pref_class
@@ -145,7 +146,7 @@ my $results = {};
 my @scanned_items;
 my @errorloop;
 my $moddatecount = 0;
-if ( $uploadbarcodes && length($uploadbarcodes) > 0 ) {
+if ( ($uploadbarcodes && length($uploadbarcodes) > 0) || ($barcodelist && length($barcodelist) > 0) ) {
     my $dbh = C4::Context->dbh;
     my $date = dt_from_string( scalar $input->param('setdate') );
     $date = output_pref ( { dt => $date, dateformat => 'iso' } );
@@ -164,10 +165,15 @@ if ( $uploadbarcodes && length($uploadbarcodes) > 0 ) {
     my $err_length=0;
     my $err_data=0;
     my $lines_read=0;
-    binmode($uploadbarcodes, ":encoding(UTF-8)");
-    while (my $barcode=<$uploadbarcodes>) {
-        my $split_chars = C4::Context->preference('BarcodeSeparators');
-        push @uploadedbarcodes, grep { /\S/ } split( /[$split_chars]/, $barcode );
+    if ($uploadbarcodes && length($uploadbarcodes) > 0) {
+        binmode($uploadbarcodes, ":encoding(UTF-8)");
+        while (my $barcode=<$uploadbarcodes>) {
+            my $split_chars = C4::Context->preference('BarcodeSeparators');
+            push @uploadedbarcodes, grep { /\S/ } split( /[$split_chars]/, $barcode );
+        }
+    } else {
+        push @uploadedbarcodes, split(/\s\n/, $input->param('barcodelist') );
+        $uploadbarcodes = $barcodelist;
     }
     for my $barcode (@uploadedbarcodes) {
         next unless $barcode;
-- 
2.7.4