From ca342a26fa32d8a6943293e1212a2802708ddfd7 Mon Sep 17 00:00:00 2001 From: Rafal Kopaczka Date: Thu, 30 Jan 2014 14:05:06 +0100 Subject: [PATCH] Bug 11651: Add possibility to print holds from holds queue This patch adds possibility to print holds slip, directly from holds queue page. Added preference to enable or disable. When enabled in holds queue are 2 new buttons and checkboxes to select holds to print. First button prints selected holds on RESERVESLIP form. Second is to switch between display printed or not printed holds. In this mode isn't possible to display printed and non printed together. Test plan: 1) Apply patch 2) Update database 3) Make 2 new holds, 1 on specific copy, another on next available 4) Update holds queue by running $KOHAPATH/misc/cronjobs/holds/build_holds_queue.pl 5) Check holds queue there should be 2 new holds from step 3 6) Enable printSlipFromHoldsQueue in preferences-> circulation-> interface 7) Go to holds after submit branch there should be 2 new buttons and checkboxes in table. 8) Print both holds and check if on slip are all biblio and item info. 9) click show printed to display printed holds 10) click hide printed, now holds queue shuld be empty 11) disable printSlipFromHoldsQueue go to holds queue and check if holds are again visible. Signed-off-by: Aurelie Fichot --- C4/HoldsQueue.pm | 67 +++++++++++++++-- C4/Reserves.pm | 26 +++++++ circ/hold-pull-print.pl | 75 ++++++++++++++++++++ circ/view_holdsqueue.pl | 7 ++- installer/data/mysql/kohastructure.sql | 6 ++- installer/data/mysql/updatedatabase.pl | 10 +++ .../en/modules/admin/preferences/circulation.pref | 6 ++ .../prog/en/modules/circ/view_holdsqueue.tt | 49 +++++++++++++ 8 files changed, 235 insertions(+), 11 deletions(-) create mode 100755 circ/hold-pull-print.pl diff --git a/C4/HoldsQueue.pm b/C4/HoldsQueue.pm index 6c36402..4a5b047 100755 --- a/C4/HoldsQueue.pm +++ b/C4/HoldsQueue.pm @@ -46,6 +46,9 @@ BEGIN { &TransportCostMatrix &UpdateTransportCostMatrix + + &MarkHoldPrinted + &GetItemNumberFromTmpHold ); } @@ -116,7 +119,7 @@ Returns hold queue for a holding branch. If branch is omitted, then whole queue =cut sub GetHoldsQueueItems { - my ($branchlimit) = @_; + my ($branchlimit, $printstatus) = @_; my $dbh = C4::Context->dbh; my @bind_params = (); @@ -130,6 +133,11 @@ sub GetHoldsQueueItems { $query .=" WHERE tmp_holdsqueue.holdingbranch = ?"; push @bind_params, $branchlimit; } + if (C4::Context->preference('printSlipFromHoldsQueue')){ + $query .= $branchlimit ? " AND" : " WHERE"; + $query .= " tmp_holdsqueue.print_status = ?"; + push @bind_params, $printstatus; + } $query .= " ORDER BY ccode, location, cn_sort, author, title, pickbranch, reservedate"; my $sth = $dbh->prepare($query); $sth->execute(@bind_params); @@ -267,8 +275,8 @@ sub GetPendingHoldRequestsForBib { my $dbh = C4::Context->dbh; - my $request_query = "SELECT biblionumber, borrowernumber, itemnumber, priority, reserves.branchcode, - reservedate, reservenotes, borrowers.branchcode AS borrowerbranch + my $request_query = "SELECT reserve_id, biblionumber, borrowernumber, itemnumber, priority, reserves.branchcode, + reservedate, reservenotes, borrowers.branchcode AS borrowerbranch, print_status FROM reserves JOIN borrowers USING (borrowernumber) WHERE biblionumber = ? @@ -386,6 +394,7 @@ sub MapItemsToHoldRequests { if (exists $items_by_itemnumber{$request->{itemnumber}} and not exists $allocated_items{$request->{itemnumber}}) { $item_map{$request->{itemnumber}} = { + reserve_id => $request->{reserve_id}, borrowernumber => $request->{borrowernumber}, biblionumber => $request->{biblionumber}, holdingbranch => $items_by_itemnumber{$request->{itemnumber}}->{holdingbranch}, @@ -393,6 +402,7 @@ sub MapItemsToHoldRequests { item_level => 1, reservedate => $request->{reservedate}, reservenotes => $request->{reservenotes}, + print_status => $request->{print_status}, }; $allocated_items{$request->{itemnumber}}++; $num_items_remaining--; @@ -492,6 +502,7 @@ sub MapItemsToHoldRequests { delete $items_by_branch{$holdingbranch} unless @$holding_branch_items; $item_map{$itemnumber} = { + reserve_id => $request->{reserve_id}, borrowernumber => $request->{borrowernumber}, biblionumber => $request->{biblionumber}, holdingbranch => $holdingbranch, @@ -499,6 +510,7 @@ sub MapItemsToHoldRequests { item_level => 0, reservedate => $request->{reservedate}, reservenotes => $request->{reservenotes}, + print_status => $request->{print_status}, }; $num_items_remaining--; } @@ -516,14 +528,15 @@ sub CreatePicklistFromItemMap { my $dbh = C4::Context->dbh; my $sth_load=$dbh->prepare(" - INSERT INTO tmp_holdsqueue (biblionumber,itemnumber,barcode,surname,firstname,phone,borrowernumber, + INSERT INTO tmp_holdsqueue (reserve_id,biblionumber,itemnumber,barcode,surname,firstname,phone,borrowernumber, cardnumber,reservedate,title, itemcallnumber, - holdingbranch,pickbranch,notes, item_level_request) - VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) + holdingbranch,pickbranch,notes, item_level_request,print_status) + VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "); foreach my $itemnumber (sort keys %$item_map) { my $mapped_item = $item_map->{$itemnumber}; + my $reserve_id = $mapped_item->{reserve_id}; my $biblionumber = $mapped_item->{biblionumber}; my $borrowernumber = $mapped_item->{borrowernumber}; my $pickbranch = $mapped_item->{pickup_branch}; @@ -531,6 +544,7 @@ sub CreatePicklistFromItemMap { my $reservedate = $mapped_item->{reservedate}; my $reservenotes = $mapped_item->{reservenotes}; my $item_level = $mapped_item->{item_level}; + my $print_status = $mapped_item->{print_status}; my $item = GetItem($itemnumber); my $barcode = $item->{barcode}; @@ -545,9 +559,9 @@ sub CreatePicklistFromItemMap { my $bib = GetBiblioData($biblionumber); my $title = $bib->{title}; - $sth_load->execute($biblionumber, $itemnumber, $barcode, $surname, $firstname, $phone, $borrowernumber, + $sth_load->execute($reserve_id,$biblionumber, $itemnumber, $barcode, $surname, $firstname, $phone, $borrowernumber, $cardnumber, $reservedate, $title, $itemcallnumber, - $holdingbranch, $pickbranch, $reservenotes, $item_level); + $holdingbranch, $pickbranch, $reservenotes, $item_level,$print_status); } } @@ -636,6 +650,43 @@ sub least_cost_branch { # XXX return a random @branch with minimum cost instead of the first one; # return $branch[0] if @branch == 1; } +=head2 MarkHoldPrinted + MarkHoldPrinted($reserve_id) + Change print status as printed. +=cut + +sub MarkHoldPrinted { + my ( $reserve_id ) = @_; + my $dbh = C4::Context->dbh; + my $strsth="UPDATE reserves INNER JOIN tmp_holdsqueue USING (reserve_id) + SET reserves.print_status = 1 , tmp_holdsqueue.print_status = 1 + WHERE reserve_id = ? + "; + my $sth = $dbh->prepare($strsth); + $sth->execute($reserve_id); + + return 1; +} +=head2 GetItemNumberFromTmpHold + $itemnumber = GetItemNumberFromTmpHold($reserve_id) + Returns itemnumber associated with hold. + Item number is taken from tmp_holdsqueue table, which is + populated by bulid_holds_queue.pl script. + +=cut +sub GetItemNumberFromTmpHold{ + my ( $reserve_id ) = @_; + my $dbh = C4::Context->dbh; + my $strsth="SELECT itemnumber + FROM tmp_holdsqueue + WHERE reserve_id = ? + "; + my $sth = $dbh->prepare($strsth); + $sth->execute($reserve_id); + + my $data = $sth->fetchrow; + return $data; +} 1; diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 7a914e3..4c0222f 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -129,6 +129,7 @@ BEGIN { &ToggleLowestPriority &ReserveSlip + &HoldSlip &ToggleSuspend &SuspendAll @@ -2231,6 +2232,31 @@ sub ReserveSlip { ); } +=head2 HoldSlip + HoldSlip($branch, $reserve_id, $itemnumber) + + Returns letter hash ( see C4::Letters::GetPreparedLetter ) or undef + +=cut + +sub HoldSlip { + my ($branch, $reserve_id, $itemnumber) = @_; + + my $reserve = GetReserveInfo($reserve_id) or return; + + return C4::Letters::GetPreparedLetter ( + module => 'circulation', + letter_code => 'RESERVESLIP', + branchcode => $branch, + tables => { + 'reserves' => $reserve, + 'branches' => $reserve->{branchcode}, + 'borrowers' => $reserve->{borrowernumber}, + 'biblio' => $reserve->{biblionumber}, + 'items' => $itemnumber, + }, + ); +} =head2 GetReservesControlBranch my $reserves_control_branch = GetReservesControlBranch($item, $borrower); diff --git a/circ/hold-pull-print.pl b/circ/hold-pull-print.pl new file mode 100755 index 0000000..36ee92d --- /dev/null +++ b/circ/hold-pull-print.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl + +# 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 strict; +#use warnings; #FIXME - Bug 2505 +use C4::Context; +use C4::Output; +use CGI; +use C4::Auth qw/:DEFAULT get_session/; +use C4::Reserves qw/HoldSlip/; +use C4::HoldsQueue qw/GetItemNumberFromTmpHold MarkHoldPrinted/; + +use vars qw($debug); + +BEGIN { + $debug = $ENV{DEBUG} || 0; +} + +my $input = new CGI; +my $sessionID = $input->cookie("CGISESSID"); +my $session = get_session($sessionID); + +my @reservations = $input->param('reserve_id'); + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "circ/printslip.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => { circulate => "circulate_remaining_permissions" }, + debug => $debug, + } +); + +my $userenv = C4::Context->userenv; +my $branch = $session->param('branch') || $userenv->{branch} || ''; +my ($slip, $is_html); + +foreach my $reserve_id (@reservations){ + my $itemnumber = GetItemNumberFromTmpHold($reserve_id); + + if ( my $letter = HoldSlip ($branch, $reserve_id, $itemnumber) ) { + $slip .= $letter->{content}; + $is_html = $letter->{is_html}; + } + else { + $slip .= "Reserve not found"; + } + MarkHoldPrinted($reserve_id); +} + +$template->param( + slip => $slip, + plain => !$is_html, + title => "Koha -- Circulation: Hold print", + stylesheet => C4::Context->preference("SlipCSS"), +); + +output_html_with_http_headers $input, $cookie, $template->output; + diff --git a/circ/view_holdsqueue.pl b/circ/view_holdsqueue.pl index 41db32b..09d76ff 100755 --- a/circ/view_holdsqueue.pl +++ b/circ/view_holdsqueue.pl @@ -49,15 +49,18 @@ my $params = $query->Vars; my $run_report = $params->{'run_report'}; my $branchlimit = $params->{'branchlimit'}; my $itemtypeslimit = $params->{'itemtypeslimit'}; +my $showprinted = $params->{'showprinted'} ? 1 : 0; + if ( $run_report ) { # XXX GetHoldsQueueItems() does not support $itemtypeslimit! - my $items = GetHoldsQueueItems($branchlimit, $itemtypeslimit); + my $items = GetHoldsQueueItems( $branchlimit, $showprinted, $itemtypeslimit); $template->param( branchlimit => $branchlimit, total => scalar @$items, itemsloop => $items, run_report => $run_report, + showprinted => $showprinted, ); } @@ -70,10 +73,10 @@ foreach my $thisitemtype ( sort keys %$itemtypes ) { description => $itemtypes->{$thisitemtype}->{'description'}, }; } - $template->param( branchloop => GetBranchesLoop(C4::Context->userenv->{'branch'}), itemtypeloop => \@itemtypesloop, + printenable => C4::Context->preference('printSlipFromHoldsQueue'), ); # writing the template diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 6618d58..8966dc3 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1622,6 +1622,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) + `print_status` BOOLEAN NOT NULL DEFAULT 0, -- is this hold printed (1 - yes, 0 - no) PRIMARY KEY (`reserve_id`), KEY `old_reserves_borrowernumber` (`borrowernumber`), KEY `old_reserves_biblionumber` (`biblionumber`), @@ -1821,6 +1822,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, + `print_status` BOOLEAN NOT NULL DEFAULT 0, -- is this hold printed (1 - yes, 0 - no) PRIMARY KEY (`reserve_id`), KEY priorityfoundidx (priority,found), KEY `borrowernumber` (`borrowernumber`), @@ -2491,6 +2493,7 @@ CREATE TABLE `user_permissions` ( DROP TABLE IF EXISTS `tmp_holdsqueue`; CREATE TABLE `tmp_holdsqueue` ( + `reserve_id` int(11) NOT NULL, `biblionumber` int(11) default NULL, `itemnumber` int(11) default NULL, `barcode` varchar(20) default NULL, @@ -2505,7 +2508,8 @@ 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, + `print_status` BOOLEAN NOT NULL DEFAULT 0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 78ba6ca..fb549f0 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -8065,6 +8065,16 @@ if ( CheckVersion($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.15.00.XXX"; +if (CheckVersion($DBversion)) { + $dbh->do("ALTER TABLE reserves ADD print_status BOOLEAN NOT NULL DEFAULT '0'"); + $dbh->do("ALTER TABLE old_reserves ADD print_status BOOLEAN NOT NULL DEFAULT '0'"); + $dbh->do("ALTER TABLE tmp_holdsqueue ADD print_status BOOLEAN NOT NULL DEFAULT '0'"); + $dbh->do("ALTER TABLE tmp_holdsqueue ADD reserve_id INT ( 11 ) FIRST"); + $dbh->do("INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES('printSlipFromHoldsQueue', '0', 'NULL', 'If enabled reserve slips can be printed from Holds Queue screen,', 'YesNo');"); + print "Upgrade to $DBversion done \n"; +} + =head1 FUNCTIONS =head2 TableExists($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 70ac352..ac0e518 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -112,6 +112,12 @@ Circulation: slip: "open a print slip window" - . - + - pref: printSlipFromHoldsQueue + choices: + yes: Enable + no: "Don't enable" + - print reserve slip from holds queue. + - - Include the stylesheet at - pref: NoticeCSS class: url diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt index f42bb47..ddadd71 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt @@ -24,6 +24,28 @@ $(document).ready(function() { "bAutoWidth": false }); }); + +function printReservations() { + document.hold_print.submit(); +} +function selectAll () { + if(document.hold_print.reserve_id.length == undefined ){ + document.hold_print.reserve_id.checked=true; + }else if(document.hold_print.reserve_id.length > 0) { + for (var i=0; i < document.hold_print.reserve_id.length; i++) { + document.hold_print.reserve_id[i].checked=true; + } + } +} +function clearAll () { + if(document.hold_print.reserve_id.length == undefined ){ + document.hold_print.reserve_id.checked=false; + }else if(document.hold_print.reserve_id.length > 0) { + for (var i=0; i < document.hold_print.reserve_id.length; i++) { + document.hold_print.reserve_id[i].checked=false; + } + } +} //]]> @@ -49,10 +71,31 @@ $(document).ready(function() { [% ELSE %]
No items found.
[% END %] + [% IF ( printenable ) %] +

+ + Select all | + Clear all +
+

+
+ + + [% IF ( showprinted ) %] + + + [% ELSE %] + + + [% END %] +
+ [% END %] [% IF ( itemsloop ) %] +
+ [% IF (printenable) %][% END %] @@ -68,6 +111,9 @@ $(document).ready(function() { [% FOREACH itemsloo IN itemsloop %] + [% IF ( printenable ) %] + + [% END %] [% END %]
CheckTitle Collection Item type

[% itemsloo.title |html %] [% IF ( itemsloo.subtitle ) %][% itemsloo.subtitle %][% END %]

[% itemsloo.author %]

[% IF ( itemsloo.publishercode ) %][% itemsloo.publishercode %][% END %] @@ -96,6 +142,9 @@ $(document).ready(function() {
+ [% IF ( printenable ) %] +
+ [% END %] [% END %] [% END %] -- 1.7.2.5