From 999afe1d7f6d42f1c61597f8f27d970e5cdb9a11 Mon Sep 17 00:00:00 2001
From: Mark Tompsett <mtompset@hotmail.com>
Date: Sat, 12 Jul 2014 09:42:52 -0400
Subject: [PATCH] [Signed-off] Bug 4162 The inventory tool lacks validation
 for barcodes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The inventory tool had no form of validating on what was assumed
to be a valid barcode number.

To solve this, an extra loop to read before processing was added.
This allows to validate length and content (assumed that
[:print:] was good enough).

The template was modified to accomodate validation messages
related to the length and content errors.

TEST PLAN
---------
1) Attempt to select a file which does not contain barcodes and
   is not a text file.
   -- a horrible lack of validation and spamminess ensues.
2) Apply patch
3) Create three files.
   a) One containing valid barcodes on each line
      -- this file should trigger no errors.
   b) A copy of the first with an extra line of >20 characters
      (e.g. The Quick Red Fox Jumped Over The Brown Fence^A^B^C)
      -- this file should trigger the singular error message case.
         ^A^B^C are actually CTRL-A,CTRL-B,CTRL-C, and it is left
         as an exercise to the reader to add them to the line.
   c) A copy of the second with the last line duplicated
      -- this file should trigger the plural error message case.
4) Attempt each of the three files.
5) Run koha-qa tools.

Followed test plan 1-4. Patch behaves as expected.
Signed-off-by: Marc Véron <veron@veron.ch>
---
 .../prog/en/modules/tools/inventory.tt             |    4 +++
 tools/inventory.pl                                 |   26 ++++++++++++++++++++
 2 files changed, 30 insertions(+)

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 c751230..fb5bbea 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt
@@ -104,6 +104,10 @@ $(document).ready(function(){
     <h1>Inventory/Stocktaking</h1>
     [% IF (moddatecount) %]<div class="dialog message">[% moddatecount %] items modified : datelastseen set to [% date | $KohaDates %]</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 %]
diff --git a/tools/inventory.pl b/tools/inventory.pl
index f79f9d6..545102b 100755
--- a/tools/inventory.pl
+++ b/tools/inventory.pl
@@ -160,9 +160,35 @@ if ( $uploadbarcodes && length($uploadbarcodes) > 0 ) {
 
     my $count = 0;
 
+    my @barcodes;
+
+    my $sth = $dbh->column_info(undef,undef,"items","barcode");
+    my $barcode_def = $sth->fetchall_hashref('COLUMN_NAME');
+    my $barcode_size = $barcode_def->{barcode}->{COLUMN_SIZE};
+    my $err_length=0;
+    my $err_data=0;
     while (my $barcode=<$uploadbarcodes>){
         $barcode =~ s/\r?\n$//;
         next unless $barcode;
+        if (length($barcode)>$barcode_size) {
+            $err_length += 1;
+        }
+        if ($barcode =~ /[^[:print:]]/) { # Only printable characters allowed.
+            $err_data += 1;
+        }
+        next if length($barcode)>$barcode_size;
+        next if ( $barcode =~ /[^[:print:]]/ );
+        push @barcodes,$barcode;
+    }
+    if (! @barcodes) {
+        push @errorloop, {'barcode'=>'No valid barcodes!'};
+        $op=''; # force the initial inventory screen again.
+    }
+    else {
+        $template->param( err_length => $err_length,
+                          err_data   => $err_data );
+    }
+    foreach my $barcode (@barcodes) {
         if ( $qwithdrawn->execute($barcode) && $qwithdrawn->rows ) {
             push @errorloop, { 'barcode' => $barcode, 'ERR_WTHDRAWN' => 1 };
         } else {
-- 
1.7.10.4