From 68924c5e6bb5cf18bd22b7345259a436240ce231 Mon Sep 17 00:00:00 2001 From: plg Date: Wed, 17 May 2006 16:06:23 +0000 Subject: [PATCH] New feature from SAN Ouest Provence: ability to reserve a specific item in the intranet. The development was made on branch 2.2 by Arnaud Laurin from Ouest Provence and integrated on HEAD by Pierrick Le Gall from INEO media system. New page reserve/request.pl taking a biblionumber as entry point. New functions: - C4::Biblio::get_iteminfos_of retrieves item informations for a list of itemnumbers - C4::Biblio::get_biblioiteminfos_of retrieves biblioitem informations for a list of biblioitemnumbers - C4::Biblio::get_itemnumbers_of retrieve the list of itemnumbers related to each biblionumber given in argument. - C4::Circulation::Circ2::get_return_date_of retrieves return date for a list of itemnumbers. - C4::Koha::get_itemtypeinfos_of retrieves the informations related to a list of itemtypes. - C4::Koha::get_branchinfos_of retrieves the informations related to a list of branchcodes. - C4::Koha::get_notforloan_label_of retrives the list of status/label for the authorised_values related to notforloan. - C4::Koha::get_infos_of is the generic function used by all get_*infos_of. - C4::Reserves2::GetNumberReservesFromBorrower - C4::Reserves2::GetFirstReserveDateFromItem Modified functions: - C4::Reserves2::FindReserves was simplified to be more readable. The reservation page is reserve/request.pl and is linked from nowhere as long as zebra is not stable yet on HEAD. --- C4/Biblio.pm | 113 ++++- C4/Circulation/Circ2.pm | 59 ++- C4/Koha.pm | 137 ++++++ C4/Reserves2.pm | 184 +++++--- .../prog/en/reserve/request.tmpl | 303 +++++++++++++ reserve/request.pl | 419 ++++++++++++++++++ 6 files changed, 1139 insertions(+), 76 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/en/reserve/request.tmpl create mode 100755 reserve/request.pl diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 5d8a5fe166..5c78d0cd80 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -23,10 +23,11 @@ use C4::Context; use C4::Database; use C4::Date; use C4::Search; +use C4::Koha; use MARC::Record; use MARC::File::USMARC; use MARC::File::XML; -use Smart::Comments; +# use Smart::Comments; use ZOOM; use vars qw($VERSION @ISA @EXPORT); @@ -82,6 +83,9 @@ $VERSION = do { my @v = '$Revision$' =~ /\d+/g; &get_item_from_barcode &MARCfind_MARCbibid_from_oldbiblionumber + get_itemnumbers_of + get_iteminfos_of + get_biblioiteminfos_of ); =head1 NAME @@ -2020,8 +2024,8 @@ create a biblioitem, the parameter is a hash =cut sub newbiblioitem { - my ($dbh, $biblioitem) = @_; - #my $dbh = C4::Context->dbh; + my ($biblioitem) = @_; + my $dbh = C4::Context->dbh; # add biblio information to the hash my $MARCbiblio = MARCkoha2marcBiblio( $dbh, $biblioitem ); $biblioitem->{marc} = $MARCbiblio->as_usmarc(); @@ -2504,6 +2508,7 @@ all copies are lost; otherwise, there is at least one copy available. #' sub bibitems { my ($bibnum) = @_; + my $dbh = C4::Context->dbh; my $sth = $dbh->prepare("SELECT biblioitems.*, itemtypes.*, @@ -3049,6 +3054,64 @@ sub DisplayISBN { return "$seg1-$seg2-$seg3-$seg4"; } +=head2 get_itemnumbers_of + + my @itemnumbers_of = get_itemnumbers_of(@biblionumbers); + +Given a list of biblionumbers, return the list of corresponding itemnumbers +for each biblionumber. + +Return a reference on a hash where keys are biblionumbers and values are +references on array of itemnumbers. + +=cut +sub get_itemnumbers_of { + my @biblionumbers = @_; + + my $dbh = C4::Context->dbh; + + my $query = ' +SELECT itemnumber, + biblionumber + FROM items + WHERE biblionumber IN (?'.(',?' x scalar @biblionumbers - 1).') +'; + my $sth = $dbh->prepare($query); + $sth->execute(@biblionumbers); + + my %itemnumbers_of; + + while (my ($itemnumber, $biblionumber) = $sth->fetchrow_array) { + push @{$itemnumbers_of{$biblionumber}}, $itemnumber; + } + + return \%itemnumbers_of; +} + +sub get_iteminfos_of { + my @itemnumbers = @_; + + my $query = ' +SELECT * + FROM items + WHERE itemnumber IN ('.join(',', @itemnumbers).') +'; + return get_infos_of($query, 'itemnumber'); +} + +sub get_biblioiteminfos_of { + my @biblioitemnumbers = @_; + + my $query = ' +SELECT biblioitemnumber, + publicationyear, + itemtype + FROM biblioitems + WHERE biblioitemnumber IN ('.join(',', @biblioitemnumbers).') +'; + + return get_infos_of($query, 'biblioitemnumber'); +} END { } # module clean-up code here (global destructor) @@ -3064,6 +3127,50 @@ Paul POULAIN paul.poulain@free.fr # $Id$ # $Log$ +# Revision 1.171 2006/05/17 16:06:24 plg +# New feature from SAN Ouest Provence: ability to reserve a specific item in +# the intranet. The development was made on branch 2.2 by Arnaud Laurin from +# Ouest Provence and integrated on HEAD by Pierrick Le Gall from INEO media +# system. +# +# New page reserve/request.pl taking a biblionumber as entry point. +# +# New functions: +# +# - C4::Biblio::get_iteminfos_of retrieves item informations for a list of +# itemnumbers +# +# - C4::Biblio::get_biblioiteminfos_of retrieves biblioitem informations for a +# list of biblioitemnumbers +# +# - C4::Biblio::get_itemnumbers_of retrieve the list of itemnumbers related to +# each biblionumber given in argument. +# +# - C4::Circulation::Circ2::get_return_date_of retrieves return date for a +# list of itemnumbers. +# +# - C4::Koha::get_itemtypeinfos_of retrieves the informations related to a +# list of itemtypes. +# +# - C4::Koha::get_branchinfos_of retrieves the informations related to a list +# of branchcodes. +# +# - C4::Koha::get_notforloan_label_of retrives the list of status/label for +# the authorised_values related to notforloan. +# +# - C4::Koha::get_infos_of is the generic function used by all get_*infos_of. +# +# - C4::Reserves2::GetNumberReservesFromBorrower +# +# - C4::Reserves2::GetFirstReserveDateFromItem +# +# Modified functions: +# +# - C4::Reserves2::FindReserves was simplified to be more readable. +# +# The reservation page is reserve/request.pl and is linked from nowhere as +# long as zebra is not stable yet on HEAD. +# # Revision 1.170 2006/04/15 02:47:47 tgarip1957 # Change the MARC Leader to UTF-8 incase user did not set it. Important for Zebra. # The new M::F::XML is sensitive to leader settings diff --git a/C4/Circulation/Circ2.pm b/C4/Circulation/Circ2.pm index d037a30517..e47e6e51b2 100755 --- a/C4/Circulation/Circ2.pm +++ b/C4/Circulation/Circ2.pm @@ -64,10 +64,26 @@ Also deals with stocktaking. =cut @ISA = qw(Exporter); -@EXPORT = qw(&getpatroninformation - ¤tissues &getissues &getiteminformation &renewstatus &renewbook - &canbookbeissued &issuebook &returnbook &find_reserves &transferbook &decode - &calc_charges &listitemsforinventory &itemseen &fixdate); +@EXPORT = qw( + &getpatroninformation + ¤tissues + &getissues + &getiteminformation + &renewstatus + &renewbook + &canbookbeissued + &issuebook + &returnbook + &find_reserves + &transferbook + &decode + &calc_charges + &listitemsforinventory + &itemseen + &fixdate + get_return_date_of + get_transfert_infos + ); # &getbranches &getprinters &getbranch &getprinter => moved to C4::Koha.pm @@ -1916,6 +1932,41 @@ sub fixdate { } +sub get_return_date_of { + my (@itemnumbers) = @_; + + my $query = ' +SELECT date_due, + itemnumber + FROM issues + WHERE itemnumber IN ('.join(',', @itemnumbers).') +'; + return get_infos_of($query, 'itemnumber', 'date_due'); +} + +sub get_transfert_infos { + my ($itemnumber) = @_; + + my $dbh = C4::Context->dbh; + + my $query = ' +SELECT datesent, + frombranch, + tobranch + FROM branchtransfers + WHERE itemnumber = ? + AND datearrived IS NULL +'; + my $sth = $dbh->prepare($query); + $sth->execute($itemnumber); + + my @row = $sth->fetchrow_array(); + + $sth->finish; + + return @row; +} + 1; __END__ diff --git a/C4/Koha.pm b/C4/Koha.pm index 22429f88fe..12d9415393 100644 --- a/C4/Koha.pm +++ b/C4/Koha.pm @@ -52,6 +52,7 @@ Koha.pm provides many functions for Koha scripts. &getbranches &getbranch &getbranchdetail &getprinters &getprinter &getitemtypes &getitemtypeinfo + get_itemtypeinfos_of &getframeworks &getframeworkinfo &getauthtypes &getauthtype &getallthemes &getalllanguages @@ -62,6 +63,9 @@ Koha.pm provides many functions for Koha scripts. getitemtypeimagesrcfromurl &getcities &getroadtypes + get_branchinfos_of + get_notforloan_label_of + get_infos_of $DEBUG); use vars qw(); @@ -304,6 +308,21 @@ sub getitemtypes { return (\%itemtypes); } +# FIXME this function is better and should replace getitemtypes everywhere +sub get_itemtypeinfos_of { + my @itemtypes = @_; + + my $query = ' +SELECT itemtype, + description, + notforloan + FROM itemtypes + WHERE itemtype IN ('.join(',', map({"'".$_."'"} @itemtypes)).') +'; + + return get_infos_of($query, 'itemtype'); +} + =head2 getauthtypes $authtypes = &getauthtypes(); @@ -767,6 +786,124 @@ while (my $data=$sth->fetchrow_hashref){ } } +=head2 get_branchinfos_of + + my $branchinfos_of = get_branchinfos_of(@branchcodes); + +Associates a list of branchcodes to the information of the branch, taken in +branches table. + +Returns a href where keys are branchcodes and values are href where keys are +branch information key. + + print 'branchname is ', $branchinfos_of->{$code}->{branchname}; + +=cut +sub get_branchinfos_of { + my @branchcodes = @_; + + my $query = ' +SELECT branchcode, + branchname + FROM branches + WHERE branchcode IN ('.join(',', map({"'".$_."'"} @branchcodes)).') +'; + return get_infos_of($query, 'branchcode'); +} + +=head2 get_notforloan_label_of + + my $notforloan_label_of = get_notforloan_label_of(); + +Each authorised value of notforloan (information available in items and +itemtypes) is link to a single label. + +Returns a href where keys are authorised values and values are corresponding +labels. + + foreach my $authorised_value (keys %{$notforloan_label_of}) { + printf( + "authorised_value: %s => %s\n", + $authorised_value, + $notforloan_label_of->{$authorised_value} + ); + } + +=cut +sub get_notforloan_label_of { + my $dbh = C4::Context->dbh; + + my $query = ' +SELECT authorised_value + FROM marc_subfield_structure + WHERE kohafield = \'items.notforloan\' + LIMIT 0, 1 +'; + my $sth = $dbh->prepare($query); + $sth->execute(); + my ($statuscode) = $sth->fetchrow_array(); + + $query = ' +SELECT lib, + authorised_value + FROM authorised_values + WHERE category = ? +'; + $sth = $dbh->prepare($query); + $sth->execute($statuscode); + my %notforloan_label_of; + while (my $row = $sth->fetchrow_hashref) { + $notforloan_label_of{ $row->{authorised_value} } = $row->{lib}; + } + $sth->finish; + + return \%notforloan_label_of; +} + +=head2 get_infos_of + +Return a href where a key is associated to a href. You give a query, the +name of the key among the fields returned by the query. If you also give as +third argument the name of the value, the function returns a href of scalar. + + my $query = ' +SELECT itemnumber, + notforloan, + barcode + FROM items +'; + + # generic href of any information on the item, href of href. + my $iteminfos_of = get_infos_of($query, 'itemnumber'); + print $iteminfos_of->{$itemnumber}{barcode}; + + # specific information, href of scalar + my $barcode_of_item = get_infos_of($query, 'itemnumber', 'barcode'); + print $barcode_of_item->{$itemnumber}; + +=cut +sub get_infos_of { + my ($query, $key_name, $value_name) = @_; + + my $dbh = C4::Context->dbh; + + my $sth = $dbh->prepare($query); + $sth->execute(); + + my %infos_of; + while (my $row = $sth->fetchrow_hashref) { + if (defined $value_name) { + $infos_of{ $row->{$key_name} } = $row->{$value_name}; + } + else { + $infos_of{ $row->{$key_name} } = $row; + } + } + $sth->finish; + + return \%infos_of; +} + 1; __END__ diff --git a/C4/Reserves2.pm b/C4/Reserves2.pm index 054ddb212e..e5e519e09f 100755 --- a/C4/Reserves2.pm +++ b/C4/Reserves2.pm @@ -66,6 +66,8 @@ FIXME &UpdateReserve &getreservetitle &Findgroupreserve + GetFirstReserveDateFromItem + GetNumberReservesFromBorrower ); # make all your functions, whether exported or not; @@ -93,79 +95,123 @@ C<&FindReserves> returns a two-element array: C<$count> is the number of elements in C<$results>. -C<$results> is a reference-to-array; each element is a -reference-to-hash, whose keys are (I think) all of the fields of the -reserves, borrowers, and biblio tables of the Koha database. +C<$results> is a reference to an array of references of hashes. Each hash +has for keys a list of column from reserves table (see details in function). =cut #' sub FindReserves { - my ($bib,$bor)=@_; - my $dbh = C4::Context->dbh; - # Find the desired items in the reserves - my $query="SELECT *,reserves.branchcode,biblio.title AS btitle, reserves.timestamp as rtimestamp FROM reserves,borrowers,biblio "; - # FIXME - These three bits of SQL seem to contain a fair amount of - # redundancy. Wouldn't it be better to have a @clauses array, add - # one or two clauses as necessary, then join(" AND ", @clauses) ? - # FIXME: not keen on quote() and interpolation either, but it looks safe - if ($bib ne ''){ - $bib = $dbh->quote($bib); - if ($bor ne ''){ - # Both $bib and $bor specified - # Find a particular book for a particular patron - $bor = $dbh->quote($bor); - $query .= " where reserves.biblionumber = $bib - and borrowers.borrowernumber = $bor - and reserves.borrowernumber = borrowers.borrowernumber - and biblio.biblionumber = $bib - and cancellationdate is NULL - and (found <> 'F' or found is NULL)"; - } else { - # $bib specified, but not $bor - # Find a particular book for all patrons - $query .= " where reserves.borrowernumber = borrowers.borrowernumber - and biblio.biblionumber = $bib - and reserves.biblionumber = $bib - and cancellationdate is NULL - and (found <> 'F' or found is NULL)"; - } - } else { - # FIXME - Check that $bor was given - # No $bib given. - # Find all books for the given patron. - $query .= " where borrowers.borrowernumber = $bor - and reserves.borrowernumber = borrowers.borrowernumber - and reserves.biblionumber = biblio.biblionumber - and cancellationdate is NULL and - (found <> 'F' or found is NULL)"; - } - $query.=" order by priority"; - my $sth=$dbh->prepare($query); - $sth->execute; - my @results; - while (my $data=$sth->fetchrow_hashref){ - # FIXME - What is this if-statement doing? How do constraints work? - if ($data->{'constrainttype'} eq 'o') { - my $csth=$dbh->prepare("SELECT biblioitemnumber FROM reserveconstraints - WHERE biblionumber = ? - AND borrowernumber = ? - AND reservedate = ?"); - $csth->execute($data->{'biblionumber'}, $data->{'borrowernumber'}, $data->{'reservedate'}); - my ($bibitemno) = $csth->fetchrow_array; - $csth->finish; - # Look up the book we just found. - my $bdata = bibitemdata($bibitemno); - # Add the results of this latest search to the current - # results. - # FIXME - An 'each' would probably be more efficient. - foreach my $key (keys %$bdata) { - $data->{$key} = $bdata->{$key}; - } - } - push @results, $data; - } - $sth->finish; - return($#results+1,\@results); + my ($bib, $bor) = @_; + my $dbh = C4::Context->dbh; + my @bind; + + # Find the desired items in the reserves + my $query = ' +SELECT branchcode, + timestamp AS rtimestamp, + priority, + biblionumber, + borrowernumber, + reservedate, + constrainttype, + found + FROM reserves + WHERE cancellationdate IS NULL + AND (found <> \'F\' OR found IS NULL) +'; + + if ($bib ne '') { + $query.= ' + AND biblionumber = ? +'; + push @bind, $bib; + } + + if ($bor ne '') { + $query.= ' + AND borrowernumber = ? +'; + push @bind, $bor; + } + + $query.= ' + ORDER BY priority +'; + my $sth=$dbh->prepare($query); + $sth->execute(@bind); + my @results; + while (my $data = $sth->fetchrow_hashref){ + # FIXME - What is this if-statement doing? How do constraints work? + if ($data->{constrainttype} eq 'o') { + $query = ' +SELECT biblioitemnumber + FROM reserveconstraints + WHERE biblionumber = ? + AND borrowernumber = ? + AND reservedate = ? +'; + my $csth=$dbh->prepare($query); + $csth->execute( + $data->{biblionumber}, + $data->{borrowernumber}, + $data->{reservedate}, + ); + my ($bibitemno) = $csth->fetchrow_array; + $csth->finish; + # Look up the book we just found. + my $bdata = bibitemdata($bibitemno); + # Add the results of this latest search to the current + # results. + # FIXME - An 'each' would probably be more efficient. + foreach my $key (keys %$bdata) { + $data->{$key} = $bdata->{$key}; + } + } + push @results, $data; + } + $sth->finish; + + return($#results+1,\@results); +} + +sub GetNumberReservesFromBorrower { + my ($borrowernumber) = @_; + + my $dbh = C4::Context->dbh; + + my $query = ' +SELECT COUNT(*) AS counter + FROM reserves + WHERE borrowernumber = ? + AND cancellationdate IS NULL + AND (found != \'F\' OR found IS NULL) +'; + my $sth = $dbh->prepare($query); + $sth->execute($borrowernumber); + my $row = $sth->fetchrow_hashref; + $sth->finish; + + return $row->{counter}; +} + +sub GetFirstReserveDateFromItem { + my ($itemnumber) = @_; + + my $dbh = C4::Context->dbh; + + my $query = ' +SELECT reservedate + FROM reserves + WHERE itemnumber = ? + AND cancellationdate IS NULL + AND (found != \'F\' OR found IS NULL) +'; + my $sth = $dbh->prepare($query); + $sth->execute($itemnumber); + my $row = $sth->fetchrow_hashref; + $sth->finish; + + return $row->{reservedate}; } =item CheckReserves diff --git a/koha-tmpl/intranet-tmpl/prog/en/reserve/request.tmpl b/koha-tmpl/intranet-tmpl/prog/en/reserve/request.tmpl new file mode 100644 index 0000000000..14e0c02601 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/reserve/request.tmpl @@ -0,0 +1,303 @@ + +Koha -- Circulation + + + +

Request for reserve

+ +
+ Biblio informations + +
+ + +
" method="post" onSubmit="request.pl" name="getborrower"> +
+ Member search + + + + + + +
Member (number or name) + +
+ +
+ +
+ + + +
+ +
+ + +
+
+ + + +
+

+ + Currently, this member has active reserves. +

+ + + +
+

+ + The card of this member is expired +

+ + + +

+ + Le lecteur n'est pas dans sa bibliothèque d'appartenance +

+ + + +

+ + Ce lecteur a déjà fait une demande de réservation pour ce document +

+ + + +
attention, il n'y a pas de lecteur à ce nom, veuillez en saisir un autre
+ + + +
+
+ Reservation properties + + "> + "> + + "> + + + + + + + + + + + + + + + + + + + + + + +
Member + + + (card number: ) + + Not defined yet + +
+ +
+ + + +
+ + + +
+
+ +
+ Items + +
    +
  • Item type:
  • +
  • Publication year:
  • +
+ + + + + + + + + + "> + + + + + + +
Item numberHome branchHolding branchInformation
+ + + + + + + + + + On loan, Return expected on + + + + + + + + Item reserved on + + + + Ne peut être sélectionné (Document perdu ou en grand retard) + + + + Ce document, n'est pas prêtable () + + + + Document en tranfert du site : , + vers : , le : + +
+ + +

+ +

+ + "> + "> +
+ +
+ + + + + +
+ +
+ + +
" action="modrequest.pl" method="post"> +
+ Modify existing reserves + + + + + + + + + + + + + + + + + + + + + + + +
PriorityMemberNotesDatePick up locationInformations
+ "> + "> + + + "> + + + Exemplaire en attente à > + + + + + + &type=intra" onClick="openWindow(this, 'Item', 480, 640); return false;"> + + + + + Suivant Disponible + + + Uniquement ce type : + + + +
+ Supprimer une réservation en sélectionnant + //images/2rightarrow.png"> +
+
+
+ + + diff --git a/reserve/request.pl b/reserve/request.pl new file mode 100755 index 0000000000..6a7ec0e810 --- /dev/null +++ b/reserve/request.pl @@ -0,0 +1,419 @@ +#!/usr/bin/perl + +# $Id$ + +#script to place reserves/requests +#writen 2/1/00 by chris@katipo.oc.nz + + +# Copyright 2000-2002 Katipo Communications +# +# 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., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + +use strict; +use HTML::Template; +use CGI; +use Date::Manip; +use List::MoreUtils qw/uniq/; +use Data::Dumper; + +use C4::Search; +use C4::Output; +use C4::Interface::CGI::Output; +use C4::Auth; +use C4::Reserves2; +use C4::Biblio; +use C4::Koha; +use C4::Circulation::Circ2; +use C4::Acquisition; +use C4::Date; +use C4::Members; + +my $dbh = C4::Context->dbh; +my $sth; +my $input = new CGI; +my ($template, $borrowernumber, $cookie) + = get_template_and_user({ + template_name => "reserve/request.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {reserveforothers => 1}, + }); + +# get biblio information.... +my $bib = $input->param('bib'); +warn '[Debub Pierrick] $bib: ', $bib; +my $dat = bibdata($bib); + +# Select borrowers infos +my $findborrower = $input->param('findborrower'); +$findborrower =~ s|,| |g; +my $cardnumber = $input->param('cardnumber'); +my %env; +my $borrowerslist; +my $messageborrower; + +my $date = today(); + +if ($findborrower) { + my ($count,$borrowers) = BornameSearch(\%env, $findborrower, 'cardnumber', 'web'); + + my @borrowers = @$borrowers; + + if ($#borrowers == -1) { + $input->param('findborrower', ''); + $messageborrower = "'$findborrower'"; + } + elsif ($#borrowers == 0) { + $input->param('cardnumber', $borrowers[0]->{'cardnumber'}); + $cardnumber = $borrowers[0]->{'cardnumber'}; + } + else { + $borrowerslist = \@borrowers; + } +} + +if ($cardnumber) { + my $borrowerinfo = getpatroninformation (\%env,0,$cardnumber); + my $expiry; + my $diffbranch; + my @getreservloop; + my $count_reserv = 0; + my $maxreserves; + +# we check the reserves of the borrower, and if he can reserv a document +# FIXME At this time we have a simple count of reservs, but, later, we could improve the infos "title" ... + + my $number_reserves = + GetNumberReservesFromBorrower($borrowerinfo->{'borrowernumber'}); + + if ($number_reserves > C4::Context->preference('maxreserves')) { + $maxreserves = 1; + } + +# we check the date expiricy of the borrower + my $warning=Date_Cmp(ParseDate("today"),format_date($borrowerinfo->{'expiry'})); + if ( $warning > 0) { + $expiry = 1; + } + +# check if the borrower make the reserv in a different branch + if ($borrowerinfo->{'branchcode'} ne C4::Context->userenv->{'branch'}) { + $diffbranch = 1; + } + + $template->param( + borrowersurname => $borrowerinfo->{'surname'}, + borrowerfirstname => $borrowerinfo->{'firstname'}, + borrowerreservs => $count_reserv, + maxreserves => $maxreserves, + expiry => $expiry, + diffbranch => $diffbranch + ); +} + +$template->param( + messageborrower => $messageborrower +); + +my $CGIselectborrower; +if ($borrowerslist) { + my @values; + my %labels; + + foreach my $borrower ( + sort {$a->{surname}.$a->{firstname} cmp $b->{surname}.$b->{firstname}} + @{$borrowerslist} + ) { + push @values, $borrower->{cardnumber}; + + $labels{ $borrower->{cardnumber} } = sprintf( + '%s, %s ... (%s - %s) ... %s', + $borrower->{surname}, + $borrower->{firstname}, + $borrower->{cardnumber}, + $borrower->{categorycode}, + $borrower->{streetaddress}, + ); + } + + $CGIselectborrower = CGI::scrolling_list( + -name => 'cardnumber', + -values => \@values, + -labels => \%labels, + -size => 7, + -multiple => 0, + ); +} + +# get existing reserves ..... +my ($count, $reserves) = FindReserves($bib, undef); +my $totalcount = $count; +my $alreadyreserved; + +# FIXME launch another time getpatroninformation perhaps until +my $borrowerinfo = getpatroninformation (\%env,0,$cardnumber); + +foreach my $res (@$reserves) { + if (($res->{found} eq 'W') or ($res->{priority} == 0)) { + $count--; + } + + if ($borrowerinfo->{borrowernumber} eq $res->{borrowernumber}) { + $alreadyreserved = 1; + } +} +$template->param(alreadyreserved => $alreadyreserved); + +# make priorities options +my @optionloop; +for (1 .. $count + 1) { + push( + @optionloop, + { + num => $_, + selected => ($_ == $count + 1), + } + ); +} + +my @branchcodes; +my %itemnumbers_of_biblioitem; +my @itemnumbers = @{get_itemnumbers_of($bib)->{$bib}}; +my $iteminfos_of = get_iteminfos_of(@itemnumbers); + +foreach my $itemnumber (@itemnumbers) { + push( + @branchcodes, + $iteminfos_of->{$itemnumber}->{homebranch}, + $iteminfos_of->{$itemnumber}->{holdingbranch} + ); + + my $biblioitemnumber = $iteminfos_of->{$itemnumber}->{biblioitemnumber}; + push( + @{ $itemnumbers_of_biblioitem{$biblioitemnumber} }, + $itemnumber + ); +} + +@branchcodes = uniq @branchcodes; + +my @biblioitemnumbers = keys %itemnumbers_of_biblioitem; + +my $branchinfos_of = get_branchinfos_of(@branchcodes); +my $notforloan_label_of = get_notforloan_label_of(); +my $biblioiteminfos_of = get_biblioiteminfos_of(@biblioitemnumbers); + +my @itemtypes; +foreach my $biblioitemnumber (@biblioitemnumbers) { + push @itemtypes, $biblioiteminfos_of->{$biblioitemnumber}{itemtype}; +} + +my $itemtypeinfos_of = get_itemtypeinfos_of(@itemtypes); + +my $return_date_of = get_return_date_of(@itemnumbers); + +my @bibitemloop; + +foreach my $biblioitemnumber (@biblioitemnumbers) { + my $biblioitem = $biblioiteminfos_of->{$biblioitemnumber}; + + $biblioitem->{description} = + $itemtypeinfos_of->{ $biblioitem->{itemtype} }{description}; + + foreach my $itemnumber (@{$itemnumbers_of_biblioitem{$biblioitemnumber}}) { + my $item = $iteminfos_of->{$itemnumber}; + + $item->{homebranchname} = + $branchinfos_of->{ $item->{homebranch} }{branchname}; + + # if the holdingbranch is different than the homebranch, we show the + # holdingbranch of the document too + if ($item->{homebranch} ne $item->{holdingbranch}) { + $item->{holdingbranchname} = + $branchinfos_of->{ $item->{holdingbranch} }{branchname}; + } + + # if the item is currently on loan, we display its return date and + # change the background color + my $date_due; + + if (defined $return_date_of->{$itemnumber}) { + $date_due = format_date($return_date_of->{$itemnumber}); + + $item->{backgroundcolor} = 'onloan'; + } + + # checking reserve + my $reservedate = GetFirstReserveDateFromItem($itemnumber); + + if (defined $reservedate) { + $item->{backgroundcolor} = 'reserved'; + } + + # Management of the notforloan document + if ($item->{notforloan}) { + $item->{backgroundcolor} = 'other'; + $item->{notforloanvalue} = + $notforloan_label_of->{ $item->{notforloan} }; + } + + # Management of lost or long overdue items + if ($item->{itemlost}) { + + # FIXME localized strings should never be in Perl code + $item->{message} = $item->{itemlost} == 1 + ? "(lost)" + : $item->{itemlost} == 2 + ? "(long overdue)" + : ""; + $item->{backgroundcolor} = 'other'; + } + + # Check of the transfered documents + my ($transfertwhen,$transfertfrom,$transfertto) = + get_transfert_infos($itemnumber); + + if ($transfertwhen ne '') { + $item->{transfertwhen} = format_date($transfertwhen); + $item->{transfertfrom} = + $branchinfos_of->{$transfertfrom}{branchname}; + $item->{transfertto} = + $branchinfos_of->{$transfertto}{branchname}; + } + + # If there is no loan, return and transfer, we show a checkbox. + $item->{notforloan} = $item->{notforloan} || 0; + + # An item is available only if: + if (not defined $reservedate # not reserved yet + and $date_due eq '' # not currently on loan + and not $item->{itemlost} # not lost + and not $item->{notforloan} # not forbidden to loan + and $transfertwhen eq '' # not currently on transfert + ) { + $item->{available} = 1; + } + + push @{$biblioitem->{itemloop}}, $item; + } + + push @bibitemloop, $biblioitem; +} + + +# existingreserves building +my @reserveloop; +my $branches = getbranches(); +foreach my $res (sort {$a->{found} cmp $b->{found}} @$reserves){ + my %reserve; + my @optionloop; + for (my $i=1; $i <= $totalcount; $i++) { + push( + @optionloop, + { + num => $i, + selected => ($i == $res->{priority}), + } + ); + } + my @branchloop; + foreach my $br (keys %$branches) { + my %abranch; + $abranch{'selected'}=($br eq $res->{'branchcode'}); + $abranch{'branch'}=$br; + $abranch{'branchname'}=$branches->{$br}->{'branchname'}; + push(@branchloop,\%abranch); + } + + if (($res->{'found'} eq 'W') or ($res->{'priority'} eq '0')) { + my %env; + my $item = $res->{'itemnumber'}; + $item = getiteminformation(\%env,$item); + $reserve{'holdingbranch'}=$item->{'holdingbranch'}; + $reserve{'barcode'}=$item->{'barcode'}; + $reserve{'biblionumber'}=$item->{'biblionumber'}; + $reserve{'wbrcode'} = $res->{'branchcode'}; + $reserve{'wbrname'} = $branches->{$res->{'branchcode'}}->{'branchname'}; + if($reserve{'holdingbranch'} eq $reserve{'wbrcode'}){ + $reserve{'atdestination'} = 1; + } + } + + $reserve{'date'} = format_date($res->{'reservedate'}); + $reserve{'borrowernumber'}=$res->{'borrowernumber'}; + $reserve{'biblionumber'}=$res->{'biblionumber'}; + $reserve{'bornum'}=$res->{'borrowernumber'}; + $reserve{'firstname'}=$res->{'firstname'}; + $reserve{'surname'}=$res->{'surname'}; + $reserve{'bornum'}=$res->{'borrowernumber'}; + $reserve{'notes'}=$res->{'reservenotes'}; + $reserve{'wait'}=(($res->{'found'} eq 'W') or ($res->{'priority'} eq '0')); + $reserve{'constrainttypea'}=($res->{'constrainttype'} eq 'a'); + $reserve{'constrainttypeo'}=($res->{'constrainttype'} eq 'o'); + $reserve{'voldesc'}=$res->{'volumeddesc'}; + $reserve{'itemtype'}=$res->{'itemtype'}; + $reserve{'branchloop'}=\@branchloop; + $reserve{'optionloop'}=\@optionloop; + + push(@reserveloop,\%reserve); +} + +my $default = C4::Context->userenv->{branch}; +my @values; +my %label_of; + +foreach my $branchcode (keys %{$branches}) { + push @values, $branchcode; + $label_of{$branchcode} = $branches->{$branchcode}->{branchname}; +} + +my $CGIbranch = CGI::scrolling_list( + -name => 'pickup', + -values => \@values, + -default => $default, + -labels => \%label_of, + -size => 1, + -multiple => 0, +); + +# get the time for the form name... +my $time = time(); + +$template->param( + CGIbranch => $CGIbranch, + reserveloop => \@reserveloop, + time => $time, +); + +# setup colors +$template->param( + optionloop =>\@optionloop, + bibitemloop => \@bibitemloop, + date => $date, + bib => $bib, + findborrower => $findborrower, + cardnumber => $cardnumber, + CGIselectborrower => $CGIselectborrower, + title =>$dat->{title}, +); + +# printout the page +print $input->header( + -type => C4::Interface::CGI::Output::guesstype($template->output), + -expires=>'now' +), $template->output; -- 2.39.5