X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FReserves.pm;h=9b7014ef14b2769567542c229f29287ecd93052f;hb=a70822480ec1b479603092cea627f7c785d38a77;hp=d98b838ed4ec7ebaa0bff3140e511ff40558031c;hpb=7a4f725c8b9e8cc7e2b47cb1fe42f972119292db;p=koha.git diff --git a/C4/Reserves.pm b/C4/Reserves.pm index d98b838ed4..9b7014ef14 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -15,15 +15,16 @@ package C4::Reserves; # 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 +# 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: someday +#use warnings; FIXME - Bug 2505 use C4::Context; use C4::Biblio; +use C4::Members; use C4::Items; use C4::Search; use C4::Circulation; @@ -31,7 +32,7 @@ use C4::Accounts; # for _koha_notify_reserve use C4::Members::Messaging; -use C4::Members qw( GetMember ); +use C4::Members qw(); use C4::Letters; use C4::Branch qw( GetBranchDetail ); use C4::Dates qw( format_date_in_iso ); @@ -49,14 +50,15 @@ C4::Reserves - Koha functions for dealing with reservation. =head1 DESCRIPTION - this modules provides somes functions to deal with reservations. - +This modules provides somes functions to deal with reservations. + Reserves are stored in reserves table. The following columns contains important values : - priority >0 : then the reserve is at 1st stage, and not yet affected to any item. =0 : then the reserve is being dealed - found : NULL : means the patron requested the 1st available, and we haven't choosen the item - W(aiting) : the reserve has an itemnumber affected, and is on the way + T(ransit) : the reserve is linked to an item but is in transit to the pickup branch + W(aiting) : the reserve is linked to an item, is at the pickup branch, and is waiting on the hold shelf F(inished) : the reserve has been completed, and is done - itemnumber : empty : the reserve is still unaffected to an item filled: the reserve is attached to an item @@ -66,20 +68,18 @@ C4::Reserves - Koha functions for dealing with reservation. a library having it run "transfertodo", and clic on the list if there is no transfer to do, the reserve waiting patron can pick it up P =0, F=W, I=filled - if there is a transfer to do, write in branchtransfer P =0, F=NULL, I=filled + if there is a transfer to do, write in branchtransfer P =0, F=T, I=filled The pickup library recieve the book, it check in P =0, F=W, I=filled The patron borrow the book P =0, F=F, I=filled ==== 2nd use case ==== patron requests a document, a given item, If pickup is holding branch P =0, F=W, I=filled - If transfer needed, write in branchtransfer P =0, F=NULL, I=filled - The pickup library recieve the book, it checks it in P =0, F=W, I=filled + If transfer needed, write in branchtransfer P =0, F=T, I=filled + The pickup library receive the book, it checks it in P =0, F=W, I=filled The patron borrow the book P =0, F=F, I=filled - -=head1 FUNCTIONS -=over 2 +=head1 FUNCTIONS =cut @@ -99,7 +99,8 @@ BEGIN { &GetReserveCount &GetReserveFee &GetReserveInfo - + &GetReserveStatus + &GetOtherReserves &ModReserveFill @@ -113,21 +114,25 @@ BEGIN { &CanBookBeReserved &CanItemBeReserved &CancelReserve + &CancelExpiredReserves &IsAvailableForItemLevelRequest + + &AlterPriority + &ToggleLowestPriority ); } -=item AddReserve +=head2 AddReserve - AddReserve($branch,$borrowernumber,$biblionumber,$constraint,$bibitems,$priority,$notes,$title,$checkitem,$found) + AddReserve($branch,$borrowernumber,$biblionumber,$constraint,$bibitems,$priority,$resdate,$expdate,$notes,$title,$checkitem,$found) =cut sub AddReserve { my ( $branch, $borrowernumber, $biblionumber, - $constraint, $bibitems, $priority, $resdate, $notes, + $constraint, $bibitems, $priority, $resdate, $expdate, $notes, $title, $checkitem, $found ) = @_; my $fee = @@ -137,6 +142,11 @@ sub AddReserve { my $const = lc substr( $constraint, 0, 1 ); $resdate = format_date_in_iso( $resdate ) if ( $resdate ); $resdate = C4::Dates->today( 'iso' ) unless ( $resdate ); + if ($expdate) { + $expdate = format_date_in_iso( $expdate ); + } else { + undef $expdate; # make reserves.expirationdate default to null rather than '0000-00-00' + } if ( C4::Context->preference( 'AllowHoldDateInFuture' ) ) { # Make room in reserves for this before those of a later reserve date $priority = _ShiftPriorityByDateAndPriority( $biblionumber, $resdate, $priority ); @@ -167,18 +177,45 @@ sub AddReserve { my $query = qq/ INSERT INTO reserves (borrowernumber,biblionumber,reservedate,branchcode,constrainttype, - priority,reservenotes,itemnumber,found,waitingdate) + priority,reservenotes,itemnumber,found,waitingdate,expirationdate) VALUES (?,?,?,?,?, - ?,?,?,?,?) + ?,?,?,?,?,?) /; my $sth = $dbh->prepare($query); $sth->execute( $borrowernumber, $biblionumber, $resdate, $branch, $const, $priority, $notes, $checkitem, - $found, $waitingdate + $found, $waitingdate, $expdate ); + # Send e-mail to librarian if syspref is active + if(C4::Context->preference("emailLibrarianWhenHoldIsPlaced")){ + my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); + my $biblio = GetBiblioData($biblionumber); + my $letter = C4::Letters::getletter( 'reserves', 'HOLDPLACED'); + my $admin_email_address = C4::Context->preference('KohaAdminEmailAddress'); + + my %keys = (%$borrower, %$biblio); + foreach my $key (keys %keys) { + my $replacefield = "<<$key>>"; + $letter->{content} =~ s/$replacefield/$keys{$key}/g; + $letter->{title} =~ s/$replacefield/$keys{$key}/g; + } + + C4::Letters::EnqueueLetter( + { letter => $letter, + borrowernumber => $borrowernumber, + message_transport_type => 'email', + from_address => $admin_email_address, + to_address => $admin_email_address, + } + ); + + + } + + #} ($const eq "o" || $const eq "e") or return; # FIXME: why not have a useful return value? $query = qq/ @@ -191,12 +228,13 @@ sub AddReserve { foreach (@$bibitems) { $sth->execute($borrowernumber, $biblionumber, $resdate, $_); } + return; # FIXME: why not have a useful return value? } -=item GetReservesFromBiblionumber +=head2 GetReservesFromBiblionumber -($count, $title_reserves) = &GetReserves($biblionumber); + ($count, $title_reserves) = &GetReserves($biblionumber); This function gets the list of reservations for one C<$biblionumber>, returning a count of the reserves and an arrayref pointing to the reserves for C<$biblionumber>. @@ -219,7 +257,9 @@ sub GetReservesFromBiblionumber { constrainttype, found, itemnumber, - reservenotes + reservenotes, + expirationdate, + lowestPriority FROM reserves WHERE biblionumber = ? "; unless ( $all_dates ) { @@ -272,11 +312,11 @@ sub GetReservesFromBiblionumber { return ( $#results + 1, \@results ); } -=item GetReservesFromItemnumber +=head2 GetReservesFromItemnumber ( $reservedate, $borrowernumber, $branchcode ) = GetReservesFromItemnumber($itemnumber); - TODO :: Description here +TODO :: Description here =cut @@ -297,12 +337,12 @@ sub GetReservesFromItemnumber { return ( $reservedate, $borrowernumber, $branchcode ); } -=item GetReservesFromBorrowernumber +=head2 GetReservesFromBorrowernumber $borrowerreserv = GetReservesFromBorrowernumber($borrowernumber,$tatus); - - TODO :: Descritpion - + +TODO :: Descritpion + =cut sub GetReservesFromBorrowernumber { @@ -331,9 +371,9 @@ sub GetReservesFromBorrowernumber { return @$data; } #------------------------------------------------------------------------------------- -=item CanBookBeReserved +=head2 CanBookBeReserved -$error = &CanBookBeReserved($borrowernumber, $biblionumber) + $error = &CanBookBeReserved($borrowernumber, $biblionumber) =cut @@ -412,11 +452,11 @@ sub CanBookBeReserved{ } -=item CanItemBeReserved +=head2 CanItemBeReserved -$error = &CanItemBeReserved($borrowernumber, $itemnumber) + $error = &CanItemBeReserved($borrowernumber, $itemnumber) -this function return 1 if an item can be issued by this borrower. +This function return 1 if an item can be issued by this borrower. =cut @@ -503,9 +543,9 @@ sub CanItemBeReserved{ } } #-------------------------------------------------------------------------------- -=item GetReserveCount +=head2 GetReserveCount -$number = &GetReserveCount($borrowernumber); + $number = &GetReserveCount($borrowernumber); this function returns the number of reservation for a borrower given on input arg. @@ -527,9 +567,9 @@ sub GetReserveCount { return $row->{counter}; } -=item GetOtherReserves +=head2 GetOtherReserves -($messages,$nextreservinfo)=$GetOtherReserves(itemnumber); + ($messages,$nextreservinfo)=$GetOtherReserves(itemnumber); Check queued list of this document and check if this document must be transfered @@ -577,9 +617,9 @@ sub GetOtherReserves { return ( $messages, $nextreservinfo ); } -=item GetReserveFee +=head2 GetReserveFee -$fee = GetReserveFee($borrowernumber,$biblionumber,$constraint,$biblionumber); + $fee = GetReserveFee($borrowernumber,$biblionumber,$constraint,$biblionumber); Calculate the fee for a reserve @@ -680,9 +720,9 @@ sub GetReserveFee { return $fee; } -=item GetReservesToBranch +=head2 GetReservesToBranch -@transreserv = GetReservesToBranch( $frombranch ); + @transreserv = GetReservesToBranch( $frombranch ); Get reserve list for a given branch @@ -707,9 +747,9 @@ sub GetReservesToBranch { return (@transreserv); } -=item GetReservesForBranch +=head2 GetReservesForBranch -@transreserv = GetReservesForBranch($frombranch); + @transreserv = GetReservesForBranch($frombranch); =cut @@ -740,7 +780,19 @@ sub GetReservesForBranch { return (@transreserv); } -=item CheckReserves +sub GetReserveStatus { + my ($itemnumber) = @_; + + my $dbh = C4::Context->dbh; + + my $itemstatus = $dbh->prepare("SELECT found FROM reserves WHERE itemnumber = ?"); + + $itemstatus->execute($itemnumber); + my ($found) = $itemstatus->fetchrow_array; + return $found; +} + +=head2 CheckReserves ($status, $reserve) = &CheckReserves($itemnumber); ($status, $reserve) = &CheckReserves(undef, $barcode); @@ -833,7 +885,30 @@ sub CheckReserves { } } -=item CancelReserve +=head2 CancelExpiredReserves + + CancelExpiredReserves(); + +Cancels all reserves with an expiration date from before today. + +=cut + +sub CancelExpiredReserves { + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare( " + SELECT * FROM reserves WHERE DATE(expirationdate) < DATE( CURDATE() ) + AND expirationdate IS NOT NULL + " ); + $sth->execute(); + + while ( my $res = $sth->fetchrow_hashref() ) { + CancelReserve( $res->{'biblionumber'}, '', $res->{'borrowernumber'} ); + } + +} + +=head2 CancelReserve &CancelReserve($biblionumber, $itemnumber, $borrowernumber); @@ -931,17 +1006,13 @@ sub CancelReserve { $sth->execute( $biblio, $borr ); # now fix the priority on the others.... - _FixPriority( $priority, $biblio ); + _FixPriority( $biblio, $borr ); } } -=item ModReserve +=head2 ModReserve -=over 4 - -ModReserve($rank, $biblio, $borrower, $branch[, $itemnumber]) - -=back + ModReserve($rank, $biblio, $borrower, $branch[, $itemnumber]) Change a hold request's priority or cancel it. @@ -963,7 +1034,7 @@ C<$rank> is a non-zero integer; if supplied, the itemnumber of the hold request is set accordingly; if omitted, the itemnumber is cleared. -FIXME: Note that the forgoing can have the effect of causing +B Note that the forgoing can have the effect of causing item-level hold requests to turn into title-level requests. This will be fixed once reserves has separate columns for requested itemnumber and supplying itemnumber. @@ -1017,7 +1088,7 @@ sub ModReserve { } } -=item ModReserveFill +=head2 ModReserveFill &ModReserveFill($reserve); @@ -1081,13 +1152,13 @@ sub ModReserveFill { # now fix the priority on the others (if the priority wasn't # already sorted!).... unless ( $priority == 0 ) { - _FixPriority( $priority, $biblionumber ); + _FixPriority( $biblionumber, $borrowernumber ); } } -=item ModReserveStatus +=head2 ModReserveStatus -&ModReserveStatus($itemnumber, $newstatus); + &ModReserveStatus($itemnumber, $newstatus); Update the reserve status for the active (priority=0) reserve. @@ -1116,9 +1187,9 @@ sub ModReserveStatus { } } -=item ModReserveAffect +=head2 ModReserveAffect -&ModReserveAffect($itemnumber,$borrowernumber,$diffBranchSend); + &ModReserveAffect($itemnumber,$borrowernumber,$diffBranchSend); This function affect an item and a status for a given reserve The itemnumber parameter is used to find the biblionumber. @@ -1128,6 +1199,7 @@ to the correct reserve. if $transferToDo is not set, then the status is set to "Waiting" as well. otherwise, a transfer is on the way, and the end of the transfer will take care of the waiting status + =cut sub ModReserveAffect { @@ -1151,7 +1223,8 @@ sub ModReserveAffect { $query = " UPDATE reserves SET priority = 0, - itemnumber = ? + itemnumber = ?, + found = 'T' WHERE borrowernumber = ? AND biblionumber = ? "; @@ -1179,11 +1252,11 @@ sub ModReserveAffect { return; } -=item ModReserveCancelAll +=head2 ModReserveCancelAll -($messages,$nextreservinfo) = &ModReserveCancelAll($itemnumber,$borrowernumber); + ($messages,$nextreservinfo) = &ModReserveCancelAll($itemnumber,$borrowernumber); - function to cancel reserv,check other reserves, and transfer document if it's necessary +function to cancel reserv,check other reserves, and transfer document if it's necessary =cut @@ -1201,9 +1274,9 @@ sub ModReserveCancelAll { return ( $messages, $nextreservinfo ); } -=item ModReserveMinusPriority +=head2 ModReserveMinusPriority -&ModReserveMinusPriority($itemnumber,$borrowernumber,$biblionumber) + &ModReserveMinusPriority($itemnumber,$borrowernumber,$biblionumber) Reduce the values of queuded list @@ -1226,34 +1299,53 @@ sub ModReserveMinusPriority { _FixPriority($biblionumber, $borrowernumber, '0'); } -=item GetReserveInfo +=head2 GetReserveInfo -&GetReserveInfo($borrowernumber,$biblionumber); + &GetReserveInfo($borrowernumber,$biblionumber); + +Get item and borrower details for a current hold. +Current implementation this query should have a single result. - Get item and borrower details for a current hold. - Current implementation this query should have a single result. =cut sub GetReserveInfo { my ( $borrowernumber, $biblionumber ) = @_; my $dbh = C4::Context->dbh; - my $strsth="SELECT reservedate, reservenotes, reserves.borrowernumber, - reserves.biblionumber, reserves.branchcode, - notificationdate, reminderdate, priority, found, - firstname, surname, phone, - email, address, address2, - cardnumber, city, zipcode, - biblio.title, biblio.author, - items.holdingbranch, items.itemcallnumber, items.itemnumber, - barcode, notes - FROM reserves left join items - ON items.itemnumber=reserves.itemnumber , - borrowers, biblio + my $strsth="SELECT + reservedate, + reservenotes, + reserves.borrowernumber, + reserves.biblionumber, + reserves.branchcode, + reserves.waitingdate, + notificationdate, + reminderdate, + priority, + found, + firstname, + surname, + phone, + email, + address, + address2, + cardnumber, + city, + zipcode, + biblio.title, + biblio.author, + items.holdingbranch, + items.itemcallnumber, + items.itemnumber, + items.location, + barcode, + notes + FROM reserves + LEFT JOIN items USING(itemnumber) + LEFT JOIN borrowers USING(borrowernumber) + LEFT JOIN biblio ON (reserves.biblionumber=biblio.biblionumber) WHERE - reserves.borrowernumber=? && - reserves.biblionumber=? && - reserves.borrowernumber=borrowers.borrowernumber && - reserves.biblionumber=biblio.biblionumber "; + reserves.borrowernumber=? + AND reserves.biblionumber=?"; my $sth = $dbh->prepare($strsth); $sth->execute($borrowernumber,$biblionumber); @@ -1262,13 +1354,9 @@ sub GetReserveInfo { } -=item IsAvailableForItemLevelRequest - -=over 4 - -my $is_available = IsAvailableForItemLevelRequest($itemnumber); +=head2 IsAvailableForItemLevelRequest -=back + my $is_available = IsAvailableForItemLevelRequest($itemnumber); Checks whether a given item record is available for an item-level hold request. An item is available if @@ -1334,38 +1422,102 @@ sub IsAvailableForItemLevelRequest { if (C4::Context->preference('AllowOnShelfHolds')) { return $available_per_item; } else { - return ($available_per_item and $item->{onloan}); + return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "W")); } } -=item _FixPriority +=head2 AlterPriority -&_FixPriority($biblio,$borrowernumber,$rank); + AlterPriority( $where, $borrowernumber, $biblionumber, $reservedate ); + +This function changes a reserve's priority up, down, to the top, or to the bottom. +Input: $where is 'up', 'down', 'top' or 'bottom'. Biblionumber, Date reserve was placed + +=cut - Only used internally (so don't export it) - Changed how this functions works # - Now just gets an array of reserves in the rank order and updates them with - the array index (+1 as array starts from 0) - and if $rank is supplied will splice item from the array and splice it back in again - in new priority rank +sub AlterPriority { + my ( $where, $borrowernumber, $biblionumber ) = @_; + + my $dbh = C4::Context->dbh; + + ## Find this reserve + my $sth = $dbh->prepare('SELECT * FROM reserves WHERE biblionumber = ? AND borrowernumber = ? AND cancellationdate IS NULL'); + $sth->execute( $biblionumber, $borrowernumber ); + my $reserve = $sth->fetchrow_hashref(); + $sth->finish(); + + if ( $where eq 'up' || $where eq 'down' ) { + + my $priority = $reserve->{'priority'}; + $priority = $where eq 'up' ? $priority - 1 : $priority + 1; + _FixPriority( $biblionumber, $borrowernumber, $priority ) + + } elsif ( $where eq 'top' ) { + + _FixPriority( $biblionumber, $borrowernumber, '1' ) + + } elsif ( $where eq 'bottom' ) { + + _FixPriority( $biblionumber, $borrowernumber, '999999' ) + + } +} + +=head2 ToggleLowestPriority + + ToggleLowestPriority( $borrowernumber, $biblionumber ); + +This function sets the lowestPriority field to true if is false, and false if it is true. + +=cut + +sub ToggleLowestPriority { + my ( $borrowernumber, $biblionumber ) = @_; + + my $dbh = C4::Context->dbh; + + my $sth = $dbh->prepare( + "UPDATE reserves SET lowestPriority = NOT lowestPriority + WHERE biblionumber = ? + AND borrowernumber = ?" + ); + $sth->execute( + $biblionumber, + $borrowernumber, + ); + $sth->finish; + + _FixPriority( $biblionumber, $borrowernumber, '999999' ); +} + +=head2 _FixPriority + + &_FixPriority($biblio,$borrowernumber,$rank,$ignoreSetLowestRank); + +Only used internally (so don't export it) +Changed how this functions works # +Now just gets an array of reserves in the rank order and updates them with +the array index (+1 as array starts from 0) +and if $rank is supplied will splice item from the array and splice it back in again +in new priority rank =cut sub _FixPriority { - my ( $biblio, $borrowernumber, $rank ) = @_; + my ( $biblio, $borrowernumber, $rank, $ignoreSetLowestRank ) = @_; my $dbh = C4::Context->dbh; if ( $rank eq "del" ) { CancelReserve( $biblio, undef, $borrowernumber ); } if ( $rank eq "W" || $rank eq "0" ) { - # make sure priority for waiting items is 0 + # make sure priority for waiting or in-transit items is 0 my $query = qq/ UPDATE reserves SET priority = 0 WHERE biblionumber = ? AND borrowernumber = ? - AND found ='W' + AND found IN ('W', 'T') /; my $sth = $dbh->prepare($query); $sth->execute( $biblio, $borrowernumber ); @@ -1382,7 +1534,7 @@ sub _FixPriority { SELECT borrowernumber, reservedate, constrainttype FROM reserves WHERE biblionumber = ? - AND ((found <> 'W') or found is NULL) + AND ((found <> 'W' AND found <> 'T') or found is NULL) ORDER BY priority ASC /; my $sth = $dbh->prepare($query); @@ -1428,9 +1580,18 @@ sub _FixPriority { ); $sth->finish; } + + $sth = $dbh->prepare( "SELECT borrowernumber FROM reserves WHERE lowestPriority = 1 ORDER BY priority" ); + $sth->execute(); + + unless ( $ignoreSetLowestRank ) { + while ( my $res = $sth->fetchrow_hashref() ) { + _FixPriority( $biblio, $res->{'borrowernumber'}, '999999', 1 ); + } + } } -=item _Findgroupreserve +=head2 _Findgroupreserve @results = &_Findgroupreserve($biblioitemnumber, $biblionumber, $itemnumber); @@ -1543,13 +1704,9 @@ sub _Findgroupreserve { return @results; } -=item _koha_notify_reserve - -=over 4 - -_koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ); +=head2 _koha_notify_reserve -=back + _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ); Sends a notification to the patron that their hold has been filled (through ModReserveAffect, _not_ ModReserveFill) @@ -1560,9 +1717,19 @@ sub _koha_notify_reserve { my ($itemnumber, $borrowernumber, $biblionumber) = @_; my $dbh = C4::Context->dbh; - my $messagingprefs = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'Hold Filled' } ); - - return if ( !defined( $messagingprefs->{'letter_code'} ) ); + my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); + my $letter_code; + my $print_mode = 0; + my $messagingprefs; + if ( $borrower->{'email'} || $borrower->{'smsalertnumber'} ) { + $messagingprefs = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'Hold Filled' } ); + + return if ( !defined( $messagingprefs->{'letter_code'} ) ); + $letter_code = $messagingprefs->{'letter_code'}; + } else { + $letter_code = 'HOLD_PRINT'; + $print_mode = 1; + } my $sth = $dbh->prepare(" SELECT * @@ -1576,19 +1743,33 @@ sub _koha_notify_reserve { my $admin_email_address = $branch_details->{'branchemail'} || C4::Context->preference('KohaAdminEmailAddress'); - my $letter = getletter( 'reserves', $messagingprefs->{'letter_code'} ); + my $letter = getletter( 'reserves', $letter_code ); + die "Could not find a letter called '$letter_code' in the 'reserves' module" unless( $letter ); C4::Letters::parseletter( $letter, 'branches', $reserve->{'branchcode'} ); - C4::Letters::parseletter( $letter, 'borrowers', $reserve->{'borrowernumber'} ); - C4::Letters::parseletter( $letter, 'biblio', $reserve->{'biblionumber'} ); - C4::Letters::parseletter( $letter, 'reserves', $reserve->{'borrowernumber'}, $reserve->{'biblionumber'} ); + C4::Letters::parseletter( $letter, 'borrowers', $borrowernumber ); + C4::Letters::parseletter( $letter, 'biblio', $biblionumber ); + C4::Letters::parseletter( $letter, 'reserves', $borrowernumber, $biblionumber ); if ( $reserve->{'itemnumber'} ) { C4::Letters::parseletter( $letter, 'items', $reserve->{'itemnumber'} ); } + my $today = C4::Dates->new()->output(); + $letter->{'title'} =~ s/<>/$today/g; + $letter->{'content'} =~ s/<>/$today/g; $letter->{'content'} =~ s/<<[a-z0-9_]+\.[a-z0-9]+>>//g; #remove any stragglers - if ( -1 != firstidx { $_ eq 'email' } @{$messagingprefs->{transports}} ) { + if ( $print_mode ) { + C4::Letters::EnqueueLetter( { + letter => $letter, + borrowernumber => $borrowernumber, + message_transport_type => 'print', + } ); + + return; + } + + if ( grep { $_ eq 'email' } @{$messagingprefs->{transports}} ) { # aka, 'email' in ->{'transports'} C4::Letters::EnqueueLetter( { letter => $letter, @@ -1599,7 +1780,7 @@ sub _koha_notify_reserve { ); } - if ( -1 != firstidx { $_ eq 'sms' } @{$messagingprefs->{transports}} ) { + if ( grep { $_ eq 'sms' } @{$messagingprefs->{transports}} ) { C4::Letters::EnqueueLetter( { letter => $letter, borrowernumber => $borrowernumber, @@ -1609,25 +1790,21 @@ sub _koha_notify_reserve { } } -=item _ShiftPriorityByDateAndPriority +=head2 _ShiftPriorityByDateAndPriority -=over 4 - -$new_priority = _ShiftPriorityByDateAndPriority( $biblionumber, $reservedate, $priority ); - -=back + $new_priority = _ShiftPriorityByDateAndPriority( $biblionumber, $reservedate, $priority ); This increments the priority of all reserves after the one - with either the lowest date after C<$reservedate> - or the lowest priority after C<$priority>. +with either the lowest date after C<$reservedate> +or the lowest priority after C<$priority>. It effectively makes room for a new reserve to be inserted with a certain - priority, which is returned. +priority, which is returned. This is most useful when the reservedate can be set by the user. It allows - the new reserve to be placed before other reserves that have a later - reservedate. Since priority also is set by the form in reserves/request.pl - the sub accounts for that too. +the new reserve to be placed before other reserves that have a later +reservedate. Since priority also is set by the form in reserves/request.pl +the sub accounts for that too. =cut @@ -1635,39 +1812,36 @@ sub _ShiftPriorityByDateAndPriority { my ( $biblio, $resdate, $new_priority ) = @_; my $dbh = C4::Context->dbh; - my $query = "SELECT priority FROM reserves WHERE biblionumber = ? AND ( reservedate > ? OR priority > ? ) ORDER BY priority ASC"; + my $query = "SELECT priority FROM reserves WHERE biblionumber = ? AND ( reservedate > ? OR priority > ? ) ORDER BY priority ASC LIMIT 1"; my $sth = $dbh->prepare( $query ); $sth->execute( $biblio, $resdate, $new_priority ); - my ( $min_priority ) = $sth->fetchrow; - $sth->finish; # $sth might have more data. + my $min_priority = $sth->fetchrow; + # if no such matches are found, $new_priority remains as original value $new_priority = $min_priority if ( $min_priority ); - my $updated_priority = $new_priority + 1; - $query = " - UPDATE reserves - SET priority = ? - WHERE biblionumber = ? - AND borrowernumber = ? - AND reservedate = ? - AND found IS NULL"; + # Shift the priority up by one; works in conjunction with the next SQL statement + $query = "UPDATE reserves + SET priority = priority+1 + WHERE biblionumber = ? + AND borrowernumber = ? + AND reservedate = ? + AND found IS NULL"; my $sth_update = $dbh->prepare( $query ); - $query = "SELECT * FROM reserves WHERE priority >= ?"; + # Select all reserves for the biblio with priority greater than $new_priority, and order greatest to least + $query = "SELECT borrowernumber, reservedate FROM reserves WHERE priority >= ? AND biblionumber = ? ORDER BY priority DESC"; $sth = $dbh->prepare( $query ); - $sth->execute( $new_priority ); + $sth->execute( $new_priority, $biblio ); while ( my $row = $sth->fetchrow_hashref ) { - $sth_update->execute( $updated_priority, $biblio, $row->{borrowernumber}, $row->{reservedate} ); - $updated_priority++; + $sth_update->execute( $biblio, $row->{borrowernumber}, $row->{reservedate} ); } - return $new_priority; # so the caller knows what priority they end up at + return $new_priority; # so the caller knows what priority they wind up receiving } -=back - =head1 AUTHOR -Koha Developement team +Koha Development Team =cut