Koha/C4/SIP/ILS/Transaction/Checkin.pm
Kyle M Hall 5377bfc624 Bug 25541: Add ability to prevent checkin via SIP of items with holds
Some libraries would like patrons to be unable to return items with
holds via SIP. Instead, the screen message should indicate that the
patron should return that item at the circ desk so a librarian can use
it to fill the next hold right away and place it on the hold shelf.

Test Plan:
1) Apply this patch.
2) Place a hold for an item.
3) Enable the new SIP option no_holds_checkin for a SIP account.
4) Restart the SIP server.
5) Check in the item using the SIP CLI tool using the SIP account
   for which you set the new option.
6) Note the checkin fails with a screen message indicating you should
   return the item to the circulation desk.

Signed-off-by: Peter Lau <peter.lau@yccece.edu.hk>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
2020-09-03 14:18:23 +02:00

175 lines
5.3 KiB
Perl

#
# An object to handle checkin status
#
package C4::SIP::ILS::Transaction::Checkin;
use warnings;
use strict;
# use POSIX qw(strftime);
use C4::SIP::ILS::Transaction;
use C4::Circulation;
use C4::Debug;
use C4::Items qw( ModItemTransfer );
use C4::Reserves qw( ModReserveAffect );
use Koha::DateUtils qw( dt_from_string );
use parent qw(C4::SIP::ILS::Transaction);
my %fields = (
magnetic => 0,
sort_bin => undef,
collection_code => undef,
# 3M extensions:
call_number => undef,
destination_loc => undef,
alert_type => undef, # 00,01,02,03,04 or 99
hold_patron_id => undef,
hold_patron_name => "",
hold => undef,
);
sub new {
my $class = shift;
my $self = $class->SUPER::new(); # start with an ILS::Transaction object
foreach (keys %fields) {
$self->{_permitted}->{$_} = $fields{$_}; # overlaying _permitted
}
@{$self}{keys %fields} = values %fields; # copying defaults into object
return bless $self, $class;
}
sub do_checkin {
my $self = shift;
my $branch = shift;
my $return_date = shift;
my $account = shift;
my $checked_in_ok = $account->{checked_in_ok};
my $cv_triggers_alert = $account->{cv_triggers_alert};
my $no_holds_checkin = $account->{no_holds_checkin};
if (!$branch) {
$branch = 'SIP2';
}
my $barcode = $self->{item}->id;
if ( $return_date ) {
$return_date = substr( $return_date, 0, 4 )
. '-'
. substr( $return_date, 4, 2 )
. '-'
. substr( $return_date, 6, 2 )
. q{ }
. substr( $return_date, 12, 2 )
. ':'
. substr( $return_date, 14, 2 )
. ':'
. substr( $return_date, 16, 2 );
$return_date = dt_from_string($return_date);
}
$debug and warn "do_checkin() calling AddReturn($barcode, $branch)";
my ($return, $messages, $issue, $borrower) = AddReturn($barcode, $branch, undef, $return_date);
if ( $checked_in_ok ) {
delete $messages->{ItemLocationUpdated};
delete $messages->{NotIssued};
delete $messages->{LocalUse};
$return = 1 unless keys %$messages;
}
# biblionumber, biblioitemnumber, itemnumber
# borrowernumber, reservedate, branchcode
# cancellationdate, found, reservenotes, priority, timestamp
if( $messages->{DataCorrupted} ) {
$self->alert_type('98');
}
if ($messages->{BadBarcode}) {
$self->alert_type('99');
}
if ($messages->{withdrawn}) {
$self->alert_type('99');
}
if ($messages->{WasLost}) {
$self->alert_type('99') if C4::Context->preference("BlockReturnOfLostItems");
}
if ($messages->{Wrongbranch}) {
$self->{item}->destination_loc($messages->{Wrongbranch}->{Rightbranch});
$self->alert_type('04'); # send to other branch
}
if ($messages->{WrongTransfer}) {
$self->{item}->destination_loc($messages->{WrongTransfer});
$self->alert_type('04'); # send to other branch
}
if ($messages->{NeedsTransfer}) {
$self->{item}->destination_loc($messages->{NeedsTransfer});
$self->alert_type('04'); # send to other branch
}
if ($messages->{WasTransfered}) { # set into transit so tell unit
$self->{item}->destination_loc($issue->item->homebranch);
$self->alert_type('04'); # send to other branch
}
if ($messages->{ResFound}) {
if ($no_holds_checkin) {
$self->alert_type('99');
$return = 0;
} elsif ($branch eq $messages->{ResFound}->{branchcode}) {
$self->hold($messages->{ResFound});
$self->alert_type('01');
ModReserveAffect( $messages->{ResFound}->{itemnumber},
$messages->{ResFound}->{borrowernumber}, 0, $messages->{ResFound}->{reserve_id});
} else {
$self->hold($messages->{ResFound});
$self->alert_type('02');
ModReserveAffect( $messages->{ResFound}->{itemnumber},
$messages->{ResFound}->{borrowernumber}, 1, $messages->{ResFound}->{reserve_id});
ModItemTransfer( $messages->{ResFound}->{itemnumber},
$branch,
$messages->{ResFound}->{branchcode},
$messages->{TransferTrigger},
);
}
$self->{item}->hold_patron_id( $messages->{ResFound}->{borrowernumber} );
$self->{item}->destination_loc( $messages->{ResFound}->{branchcode} );
}
# ignoring messages: NotIssued, WasTransfered
if ($cv_triggers_alert) {
$self->alert( defined $self->alert_type ); # Overwrites existing alert value, should set to 0 if there is no alert type
}
else {
$self->alert( !$return || defined $self->alert_type );
}
$self->ok($return);
return { messages => $messages };
}
sub resensitize {
my $self = shift;
unless ($self->{item}) {
warn "resensitize(): no item found in object to resensitize";
return;
}
return !$self->{item}->magnetic_media;
}
sub patron_id {
my $self = shift;
unless ($self->{patron}) {
warn "patron_id(): no patron found in object";
return;
}
return $self->{patron}->id;
}
1;