use C4::Letters;
use C4::Branch qw( GetBranchDetail );
use C4::Dates qw( format_date_in_iso );
+
+use Koha::DateUtils;
+
use List::MoreUtils qw( firstidx );
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
BEGIN {
# set the version for version checking
- $VERSION = 3.01;
+ $VERSION = 3.07.00.049;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(
return (@transreserv);
}
+=head2 GetReserveStatus
+
+ $reservestatus = GetReserveStatus($itemnumber, $biblionumber);
+
+Take an itemnumber or a biblionumber and return the status of the reserve places on it.
+If several reserves exist, the reserve with the lower priority is given.
+
+=cut
+
sub GetReserveStatus {
- my ($itemnumber) = @_;
-
+ my ($itemnumber, $biblionumber) = @_;
+
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;
+
+ my ($sth, $found, $priority);
+ if ( $itemnumber ) {
+ $sth = $dbh->prepare("SELECT found, priority FROM reserves WHERE itemnumber = ? order by priority LIMIT 1");
+ $sth->execute($itemnumber);
+ ($found, $priority) = $sth->fetchrow_array;
+ }
+
+ if ( $biblionumber and not defined $found and not defined $priority ) {
+ $sth = $dbh->prepare("SELECT found, priority FROM reserves WHERE biblionumber = ? order by priority LIMIT 1");
+ $sth->execute($biblionumber);
+ ($found, $priority) = $sth->fetchrow_array;
+ }
+
+ if(defined $found) {
+ return 'Waiting' if $found eq 'W' and $priority == 0;
+ return 'Finished' if $found eq 'F';
+ return 'Reserved' if $priority > 0;
+ }
+ return '';
+ #empty string here will remove need for checking undef, or less log lines
}
=head2 CheckReserves
Note that IsAvailableForItemLevelRequest() does not
check if the staff operator is authorized to place
a request on the item - in particular,
-this routine does not check IndependantBranches
+this routine does not check IndependentBranches
and canreservefromotherbranches.
=cut
if (C4::Context->preference('AllowOnShelfHolds')) {
return $available_per_item;
} else {
- return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "W"));
+ return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "Waiting"));
}
}
=cut
sub ToggleSuspend {
- my ( $borrowernumber, $biblionumber ) = @_;
+ my ( $borrowernumber, $biblionumber, $suspend_until ) = @_;
+
+ $suspend_until = output_pref( dt_from_string( $suspend_until ), 'iso' ) if ( $suspend_until );
+
+ my $do_until = ( $suspend_until ) ? '?' : 'NULL';
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare(
"UPDATE reserves SET suspend = NOT suspend,
- suspend_until = CASE WHEN suspend = 0 THEN NULL ELSE suspend_until END
+ suspend_until = CASE WHEN suspend = 0 THEN NULL ELSE $do_until END
WHERE biblionumber = ?
AND borrowernumber = ?
");
- $sth->execute(
- $biblionumber,
- $borrowernumber,
- );
+
+ my @params;
+ push( @params, $suspend_until ) if ( $suspend_until );
+ push( @params, $biblionumber );
+ push( @params, $borrowernumber );
+
+ $sth->execute( @params );
$sth->finish;
}
my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber);
# Try to get the borrower's email address
- my $to_address;
- my $which_address = C4::Context->preference('AutoEmailPrimaryAddress');
- # If the system preference is set to 'first valid' (value == OFF), look up email address
- if ($which_address eq 'OFF') {
- $to_address = C4::Members::GetFirstValidEmailAddress( $borrowernumber );
- } else {
- $to_address = $borrower->{$which_address};
- }
+ my $to_address = C4::Members::GetNoticeEmailAddress($borrowernumber);
my $letter_code;
my $print_mode = 0;
my $messagingprefs;
if ( $to_address || $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 $admin_email_address = $branch_details->{'branchemail'} || C4::Context->preference('KohaAdminEmailAddress');
- my $letter = C4::Letters::GetPreparedLetter (
+ my %letter_params = (
module => 'reserves',
- letter_code => $letter_code,
branchcode => $reserve->{branchcode},
tables => {
'branches' => $branch_details,
'items', $reserve->{'itemnumber'},
},
substitute => { today => C4::Dates->new()->output() },
- ) or die "Could not find a letter called '$letter_code' in the 'reserves' module";
-
+ );
if ( $print_mode ) {
+ $letter_params{ 'letter_code' } = 'HOLD_PRINT';
+ my $letter = C4::Letters::GetPreparedLetter ( %letter_params ) or die "Could not find a letter called '$letter_params{'letter_code'}' in the 'reserves' module";
+
C4::Letters::EnqueueLetter( {
letter => $letter,
borrowernumber => $borrowernumber,
return;
}
- if ( grep { $_ eq 'email' } @{$messagingprefs->{transports}} ) {
- # aka, 'email' in ->{'transports'}
+ if ( $to_address && defined $messagingprefs->{transports}->{'email'} ) {
+ $letter_params{ 'letter_code' } = $messagingprefs->{transports}->{'email'};
+ my $letter = C4::Letters::GetPreparedLetter ( %letter_params ) or die "Could not find a letter called '$letter_params{'letter_code'}' in the 'reserves' module";
+
C4::Letters::EnqueueLetter(
{ letter => $letter,
borrowernumber => $borrowernumber,
);
}
- if ( grep { $_ eq 'sms' } @{$messagingprefs->{transports}} ) {
+ if ( $borrower->{'smsalertnumber'} && defined $messagingprefs->{transports}->{'sms'} ) {
+ $letter_params{ 'letter_code' } = $messagingprefs->{transports}->{'sms'};
+ my $letter = C4::Letters::GetPreparedLetter ( %letter_params ) or die "Could not find a letter called '$letter_params{'letter_code'}' in the 'reserves' module";
+
C4::Letters::EnqueueLetter(
{ letter => $letter,
borrowernumber => $borrowernumber,
ModReserveFill($borr_res);
}
- if ($cancelreserve) { # cancel reserves on this item
+ if ( $cancelreserve eq 'revert' ) { ## Revert waiting reserve to priority 1
+ RevertWaitingStatus({ itemnumber => $itemnumber });
+ }
+ elsif ( $cancelreserve eq 'cancel' || $cancelreserve ) { # cancel reserves on this item
CancelReserve(0, $res->{'itemnumber'}, $res->{'borrowernumber'});
CancelReserve($res->{'biblionumber'}, 0, $res->{'borrowernumber'});
}
}
}
+=head2 RevertWaitingStatus
+
+ $success = RevertWaitingStatus({ itemnumber => $itemnumber });
+
+ Reverts a 'waiting' hold back to a regular hold with a priority of 1.
+
+ Caveat: Any waiting hold fixed with RevertWaitingStatus will be an
+ item level hold, even if it was only a bibliolevel hold to
+ begin with. This is because we can no longer know if a hold
+ was item-level or bib-level after a hold has been set to
+ waiting status.
+
+=cut
+
+sub RevertWaitingStatus {
+ my ( $params ) = @_;
+ my $itemnumber = $params->{'itemnumber'};
+
+ return unless ( $itemnumber );
+
+ my $dbh = C4::Context->dbh;
+
+ ## Get the waiting reserve we want to revert
+ my $query = "
+ SELECT * FROM reserves
+ WHERE itemnumber = ?
+ AND found IS NOT NULL
+ ";
+ my $sth = $dbh->prepare( $query );
+ $sth->execute( $itemnumber );
+ my $reserve = $sth->fetchrow_hashref();
+
+ ## Increment the priority of all other non-waiting
+ ## reserves for this bib record
+ $query = "
+ UPDATE reserves
+ SET
+ priority = priority + 1
+ WHERE
+ biblionumber = ?
+ AND
+ priority > 0
+ ";
+ $sth = $dbh->prepare( $query );
+ $sth->execute( $reserve->{'biblionumber'} );
+
+ ## Fix up the currently waiting reserve
+ $query = "
+ UPDATE reserves
+ SET
+ priority = 1,
+ found = NULL,
+ waitingdate = NULL
+ WHERE
+ reserve_id = ?
+ ";
+ $sth = $dbh->prepare( $query );
+ return $sth->execute( $reserve->{'reserve_id'} );
+}
+
=head2 ReserveSlip
ReserveSlip($branchcode, $borrowernumber, $biblionumber)
tables => {
'reserves' => $reserve,
'branches' => $reserve->{branchcode},
- 'borrowers' => $reserve,
- 'biblio' => $reserve,
- 'items' => $reserve,
+ 'borrowers' => $reserve->{borrowernumber},
+ 'biblio' => $reserve->{biblionumber},
+ 'items' => $reserve->{itemnumber},
},
);
}