From 8adffafb8151ca82ce2296e258a14eccdc20c33e Mon Sep 17 00:00:00 2001
From: Kyle M Hall <kyle@bywatersolutions.com>
Date: Tue, 3 Jul 2012 11:01:17 -0400
Subject: [PATCH] Bug 8352 - Add automatic printing of 'hold to pull' notices
Content-Type: text/plain; charset="utf-8"

Adds the ability to have a notice printed automatically
after a hold has been placed.

The system has the ability to define a separate printer
for each branchcode, so each library can receive a printed
notice for any holds placed, assuming they have set up the
ability to print over the LAN, WAN, or Internet. Notices are
printed to the pickup library.
---
 C4/Installer/PerlDependencies.pm                   |    5 +
 .../data/mysql/en/mandatory/sample_notices.sql     |    1 +
 installer/data/mysql/kohastructure.sql             |    4 +-
 installer/data/mysql/updatedatabase.pl             |   25 +++
 misc/cronjobs/holds/print_holds.pl                 |  159 ++++++++++++++++++++
 5 files changed, 193 insertions(+), 1 deletions(-)
 create mode 100755 misc/cronjobs/holds/print_holds.pl

diff --git a/C4/Installer/PerlDependencies.pm b/C4/Installer/PerlDependencies.pm
index 263ae40..92a8020 100644
--- a/C4/Installer/PerlDependencies.pm
+++ b/C4/Installer/PerlDependencies.pm
@@ -610,6 +610,11 @@ our $PERL_DEPS = {
         'required' => '1',
         'min_ver'  => '1.23',
     },
+    'Net::Printer' => {
+        'usage'    => 'Push to printer',
+        'required' => '0',
+        'min_ver'  => '1.11',
+    },
 };
 
 1;
diff --git a/installer/data/mysql/en/mandatory/sample_notices.sql b/installer/data/mysql/en/mandatory/sample_notices.sql
index 6fa0a54..0b5007b 100644
--- a/installer/data/mysql/en/mandatory/sample_notices.sql
+++ b/installer/data/mysql/en/mandatory/sample_notices.sql
@@ -9,6 +9,7 @@ VALUES ('circulation','ODUE','Overdue Notice','Item Overdue','Dear <<borrowers.f
 ('circulation','PREDUEDGST','Advance Notice of Item Due (Digest)','Advance Notice of Item Due','You have <<count>> items due soon'),
 ('reserves', 'HOLD', 'Hold Available for Pickup', 'Hold Available for Pickup at <<branches.branchname>>', 'Dear <<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\nLocation: <<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n<<branches.branchaddress3>>\r\n<<branches.branchcity>> <<branches.branchzip>>'),
 ('reserves', 'HOLD_PRINT', 'Hold Available for Pickup (print notice)', 'Hold Available for Pickup (print notice)', '<<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n\r\n\r\nChange Service Requested\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>>\r\n<<borrowers.address>>\r\n<<borrowers.city>> <<borrowers.zipcode>>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>> <<borrowers.cardnumber>>\r\n\r\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\n'),
+('reserves', 'HOLD_PLACED_PRINT', 'Hold Placed ( Auto-Print )', 'Hold Placed ( Auto-Print )', 'Hold to pull at <<branches.branchname>>\r\nFor <<borrowers.firstname>> <<borrowers.surname>> ( <<borrowers.cardnumber>> )\r\n<<biblio.title>> by <<biblio.author>>'),
 ('circulation','CHECKIN','Item Check-in (Digest)','Check-ins','The following items have been checked in:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you.'),
 ('circulation','CHECKOUT','Item Check-out (Digest)','Checkouts','The following items have been checked out:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you for visiting <<branches.branchname>>.'),
 ('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<biblio.title>> (<<biblio.biblionumber>>) by the user <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql
index 39857b7..1a38145 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -1487,6 +1487,7 @@ CREATE TABLE `old_reserves` ( -- this table holds all holds/reserves that have b
   `lowestPriority` tinyint(1) NOT NULL, -- has this hold been pinned to the lowest priority in the holds queue (1 for yes, 0 for no)
   `suspend` BOOLEAN NOT NULL DEFAULT 0, -- in this hold suspended (1 for yes, 0 for no)
   `suspend_until` DATETIME NULL DEFAULT NULL, -- the date this hold is suspended until (NULL for infinitely)
+  `printed` tinyint(1) DEFAULT NULL,
   PRIMARY KEY (`reserve_id`),
   KEY `old_reserves_borrowernumber` (`borrowernumber`),
   KEY `old_reserves_biblionumber` (`biblionumber`),
@@ -1686,6 +1687,7 @@ CREATE TABLE `reserves` ( -- information related to holds/reserves in Koha
   `lowestPriority` tinyint(1) NOT NULL,
   `suspend` BOOLEAN NOT NULL DEFAULT 0,
   `suspend_until` DATETIME NULL DEFAULT NULL,
+  `printed` tinyint(1) DEFAULT NULL,
   PRIMARY KEY (`reserve_id`),
   KEY priorityfoundidx (priority,found),
   KEY `borrowernumber` (`borrowernumber`),
@@ -2333,7 +2335,7 @@ CREATE TABLE `tmp_holdsqueue` (
   `holdingbranch` varchar(10) default NULL,
   `pickbranch` varchar(10) default NULL,
   `notes` text,
-  `item_level_request` tinyint(4) NOT NULL default 0
+  `item_level_request` tinyint(4) NOT NULL default 0,
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 --
diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl
index eb45fb2..daa369f 100755
--- a/installer/data/mysql/updatedatabase.pl
+++ b/installer/data/mysql/updatedatabase.pl
@@ -5536,6 +5536,7 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
     SetVersion($DBversion);
 }
 
+<<<<<<< HEAD
 $DBversion = "3.09.00.026";
 if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
     $dbh->do("INSERT INTO permissions (module_bit, code, description) VALUES
@@ -5982,6 +5983,30 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
     SetVersion($DBversion);
 }
 
+$DBversion = "3.09.00.XXX";
+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
+    $dbh->do("ALTER TABLE reserves ADD printed BOOLEAN NULL AFTER suspend_until");
+    $dbh->do("INSERT INTO  `letter` (
+    `module` ,
+    `code` ,
+    `branchcode` ,
+    `name` ,
+    `is_html` ,
+    `title` ,
+    `content`
+    )
+    VALUES (
+    'reserves',  'HOLD_PLACED_PRINT',  '',  'Hold Placed ( Auto-Print )',  '0',  'Hold Placed ( Auto-Print )',  'Hold to pull at <<branches.branchname>>
+
+    For <<borrowers.firstname>> <<borrowers.surname>> ( <<borrowers.cardnumber>> )
+
+    <<biblio.title>> by <<biblio.author>>'
+    )");
+
+    print "Upgrade to $DBversion done (Add print holds to pull notices on demand feature)\n";
+    SetVersion($DBversion);
+}
+
 =head1 FUNCTIONS
 
 =head2 TableExists($table)
diff --git a/misc/cronjobs/holds/print_holds.pl b/misc/cronjobs/holds/print_holds.pl
new file mode 100755
index 0000000..ef93ccc
--- /dev/null
+++ b/misc/cronjobs/holds/print_holds.pl
@@ -0,0 +1,159 @@
+#!/usr/bin/perl
+
+# Copyright 2009-2010 Kyle Hall
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+BEGIN {
+
+    # find Koha's Perl modules
+    # test carefully before changing this
+    use FindBin;
+    eval { require "$FindBin::Bin/../kohalib.pl" };
+}
+
+use Getopt::Long;
+use Pod::Usage;
+use Net::Printer;
+
+use C4::Context;
+use C4::Members qw(GetMember);
+use C4::Letters qw(GetPreparedLetter);
+
+my $help    = 0;
+my $test    = 0;
+my $verbose = 0;
+my @printers;
+GetOptions(
+    "help|?"      => \$help,
+    "verbose|v"   => \$verbose,
+    "test|t"      => \$test,
+    "printer|p=s" => \@printers,
+);
+pod2usage(1) if $help;
+pod2usage(1) unless @printers;
+
+my %printers;
+foreach my $p (@printers) {
+    my ( $branchcode, $printer, $server, $port ) = split( /,/, $p );
+    my %options;
+    $options{'printer'} = $printer if ($printer);
+    $options{'server'}  = $server  if ($server);
+    $options{'port'}    = $port    if ($port);
+    $printers{$branchcode} = new Net::Printer(%options);
+}
+
+my $dbh   = C4::Context->dbh;
+my $query = "SELECT * FROM reserves WHERE printed IS NULL";
+my $sth   = $dbh->prepare($query);
+$sth->execute();
+
+my $set_printed_query = "
+    UPDATE reserves
+    SET printed = 1
+    WHERE reserve_id = ?
+";
+my $set_printed_sth = $dbh->prepare($set_printed_query);
+
+while ( my $hold = $sth->fetchrow_hashref() ) {
+    if ($verbose) {
+        print "\nFound Notice to Print\n";
+        print "Borrowernumber: " . $hold->{'borrowernumber'} . "\n";
+        print "Biblionumber: " . $hold->{'biblionumber'} . "\n";
+        print "Branch: " . $hold->{'branchcode'} . "\n";
+    }
+
+    my $borrower =
+      C4::Members::GetMember( 'borrowernumber' => $hold->{'borrowernumber'} );
+
+    my $letter = GetPreparedLetter(
+        module      => 'reserves',
+        letter_code => 'HOLD_PLACED_PRINT',
+        branchcode  => $hold->{branchcode},
+        tables      => {
+            'branches'    => $hold->{'branchcode'},
+            'biblio'      => $hold->{'biblionumber'},
+            'biblioitems' => $hold->{'biblionumber'},
+            'items'       => $hold->{'itemnumber'},
+            'borrowers'   => $borrower,
+        }
+    );
+
+    if ( defined( $printers{ $hold->{branchcode} } ) ) {
+        unless ($test) {
+            my $result =
+              $printers{ $hold->{'branchcode'} }
+              ->printstring( $letter->{'content'} );
+            my $error = $printers{ $hold->{'branchcode'} }->printerror();
+
+            unless ($error) {
+                $set_printed_sth->execute( $hold->{'reserve_id'} );
+            }
+            else {
+                warn "ERROR: $error";
+            }
+        }
+        else {
+            print "TEST MODE, notice will not be printed\n";
+            print $letter->{'content'} . "\n";
+        }
+    }
+    else {
+        print "WARNING: No printer defined for branchcode "
+          . $hold->{'branchcode'}
+          if ($verbose);
+    }
+
+}
+
+__END__
+
+=head1 NAME
+
+Print Holds
+
+=head1 SYNOPSIS
+
+print_holds.pl --printer <branchcode>,<printer>,<server>,<port>
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<-help>
+
+Print a brief help message and exits.
+
+=item B<-printer>
+
+Adds a printer, the value is the branchcode, printer name, server name and server port separated by commas.
+
+e.g. print_holds_to_pull_on_demand.pl --printer MPL,lp,printserver,515 --printer CPL,lp2,printserver,516
+
+would add printers for branchcodes MPL and CPL. If a printer is not defined for a given branch, notices for
+that branch will not be printed.
+
+=head1 DESCRIPTION
+
+B<This program> will print on-demand notices for items in the holds queue as they appear.
+
+=head1 AUTHOR
+
+Kyle M Hall <kyle@bywatersolutions.com>
+
+=cut
-- 
1.7.2.5