bug 3435: SIP Checkin extension for 3M SmartChute - partial
Signed-off-by: Galen Charlton <galen.charlton@liblime.com>
This commit is contained in:
parent
3a058fcc9d
commit
08816bab07
|
|
@ -559,6 +559,7 @@ sub GetReservesForBranch {
|
|||
=item CheckReserves
|
||||
|
||||
($status, $reserve) = &CheckReserves($itemnumber);
|
||||
($status, $reserve) = &CheckReserves(undef, $barcode);
|
||||
|
||||
Find a book in the reserves.
|
||||
|
||||
|
|
@ -586,65 +587,50 @@ sub CheckReserves {
|
|||
my ( $item, $barcode ) = @_;
|
||||
my $dbh = C4::Context->dbh;
|
||||
my $sth;
|
||||
my $select = "
|
||||
SELECT items.biblionumber,
|
||||
items.biblioitemnumber,
|
||||
itemtypes.notforloan,
|
||||
items.notforloan AS itemnotforloan,
|
||||
items.itemnumber
|
||||
FROM items
|
||||
LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber
|
||||
LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype
|
||||
";
|
||||
|
||||
if ($item) {
|
||||
my $qitem = $dbh->quote($item);
|
||||
# Look up the item by itemnumber
|
||||
my $query = "
|
||||
SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan, items.notforloan AS itemnotforloan
|
||||
FROM items
|
||||
LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber
|
||||
LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype
|
||||
WHERE itemnumber=$qitem
|
||||
";
|
||||
$sth = $dbh->prepare($query);
|
||||
$sth = $dbh->prepare("$select WHERE itemnumber = ?");
|
||||
$sth->execute($item);
|
||||
}
|
||||
else {
|
||||
my $qbc = $dbh->quote($barcode);
|
||||
# Look up the item by barcode
|
||||
my $query = "
|
||||
SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan, items.notforloan AS itemnotforloan
|
||||
FROM items
|
||||
LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber
|
||||
LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype
|
||||
WHERE items.biblioitemnumber = biblioitems.biblioitemnumber
|
||||
AND biblioitems.itemtype = itemtypes.itemtype
|
||||
AND barcode=$qbc
|
||||
";
|
||||
$sth = $dbh->prepare($query);
|
||||
|
||||
# FIXME - This function uses $item later on. Ought to set it here.
|
||||
$sth = $dbh->prepare("$select WHERE barcode = ?");
|
||||
$sth->execute($barcode);
|
||||
}
|
||||
$sth->execute;
|
||||
my ( $biblio, $bibitem, $notforloan_per_itemtype, $notforloan_per_item ) = $sth->fetchrow_array;
|
||||
$sth->finish;
|
||||
# note: we get the itemnumber because we might have started w/ just the barcode. Now we know for sure we have it.
|
||||
my ( $biblio, $bibitem, $notforloan_per_itemtype, $notforloan_per_item, $itemnumber ) = $sth->fetchrow_array;
|
||||
|
||||
return ( 0, 0 ) unless $itemnumber; # bail if we got nothing.
|
||||
|
||||
# if item is not for loan it cannot be reserved either.....
|
||||
# execption to notforloan is where items.notforloan < 0 : This indicates the item is holdable.
|
||||
# execpt where items.notforloan < 0 : This indicates the item is holdable.
|
||||
return ( 0, 0 ) if ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype;
|
||||
|
||||
# get the reserves...
|
||||
# Find this item in the reserves
|
||||
my @reserves = _Findgroupreserve( $bibitem, $biblio, $item );
|
||||
my $count = scalar @reserves;
|
||||
my @reserves = _Findgroupreserve( $bibitem, $biblio, $itemnumber );
|
||||
|
||||
# $priority and $highest are used to find the most important item
|
||||
# in the list returned by &_Findgroupreserve. (The lower $priority,
|
||||
# the more important the item.)
|
||||
# $highest is the most important item we've seen so far.
|
||||
my $priority = 10000000;
|
||||
my $highest;
|
||||
if ($count) {
|
||||
if (scalar @reserves) {
|
||||
my $priority = 10000000;
|
||||
foreach my $res (@reserves) {
|
||||
# FIXME - $item might be undefined or empty: the caller
|
||||
# might be searching by barcode.
|
||||
if ( $res->{'itemnumber'} == $item && $res->{'priority'} == 0) {
|
||||
# Found it
|
||||
return ( "Waiting", $res );
|
||||
}
|
||||
else {
|
||||
# See if this item is more important than what we've got
|
||||
# so far.
|
||||
if ( $res->{'priority'} != 0 && $res->{'priority'} < $priority )
|
||||
{
|
||||
if ( $res->{'itemnumber'} == $itemnumber && $res->{'priority'} == 0) {
|
||||
return ( "Waiting", $res ); # Found it
|
||||
} else {
|
||||
# See if this item is more important than what we've got so far
|
||||
if ( $res->{'priority'} && $res->{'priority'} < $priority ) {
|
||||
$priority = $res->{'priority'};
|
||||
$highest = $res;
|
||||
}
|
||||
|
|
@ -652,10 +638,9 @@ sub CheckReserves {
|
|||
}
|
||||
}
|
||||
|
||||
# If we get this far, then no exact match was found. Print the
|
||||
# most important item on the list. I think this tells us who's
|
||||
# next in line to get this book.
|
||||
if ($highest) { # FIXME - $highest might be undefined
|
||||
# If we get this far, then no exact match was found.
|
||||
# We return the most important (i.e. next) reservation.
|
||||
if ($highest) {
|
||||
$highest->{'itemnumber'} = $item;
|
||||
return ( "Reserved", $highest );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ sub checkout {
|
|||
$item->{patron} = $patron_id;
|
||||
$item->{due_date} = $circ->{due};
|
||||
push(@{$patron->{items}}, $item_id);
|
||||
$circ->desensitize(!$item->magnetic);
|
||||
$circ->desensitize(!$item->magnetic_media);
|
||||
|
||||
syslog("LOG_DEBUG", "ILS::Checkout: patron %s has checked out %s",
|
||||
$patron_id, join(', ', @{$patron->{items}}));
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
#
|
||||
# ILS::Item.pm
|
||||
#
|
||||
# A Class for hiding the ILS's concept of the item from the OpenSIP
|
||||
# system
|
||||
# A Class for hiding the ILS's concept of the item from OpenSIP
|
||||
#
|
||||
|
||||
package ILS::Item;
|
||||
|
|
@ -11,6 +10,7 @@ use strict;
|
|||
use warnings;
|
||||
|
||||
use Sys::Syslog qw(syslog);
|
||||
use Carp;
|
||||
|
||||
use ILS::Transaction;
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ use C4::Reserves;
|
|||
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
|
||||
|
||||
BEGIN {
|
||||
$VERSION = 2.10;
|
||||
$VERSION = 2.11;
|
||||
require Exporter;
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT_OK = qw();
|
||||
|
|
@ -82,22 +82,27 @@ sub new {
|
|||
my $type = ref($class) || $class;
|
||||
my $self;
|
||||
my $itemnumber = GetItemnumberFromBarcode($item_id);
|
||||
my $item = GetBiblioFromItemNumber($itemnumber);
|
||||
my $item = GetBiblioFromItemNumber($itemnumber); # actually biblio.*, biblioitems.* AND items.* (overkill)
|
||||
if (! $item) {
|
||||
syslog("LOG_DEBUG", "new ILS::Item('%s'): not found", $item_id);
|
||||
warn "new ILS::Item($item_id) : No item '$item_id'.";
|
||||
return undef;
|
||||
}
|
||||
$item->{itemnumber} = $itemnumber;
|
||||
$item->{'id'} = $item->{'barcode'};
|
||||
$item->{ 'itemnumber' } = $itemnumber;
|
||||
$item->{ 'id' } = $item->{barcode}; # to SIP, the barcode IS the id.
|
||||
$item->{permanent_location}= $item->{homebranch};
|
||||
$item->{'collection_code'} = $item->{ccode};
|
||||
$item->{ 'call_number' } = $item->{itemcallnumber};
|
||||
# $item->{'destination_loc'} = ?
|
||||
|
||||
# check if its on issue and if so get the borrower
|
||||
my $issue = GetItemIssue($item->{'itemnumber'});
|
||||
my $borrower = GetMember($issue->{'borrowernumber'},'borrowernumber');
|
||||
$item->{patron} = $borrower->{'cardnumber'};
|
||||
my @reserves = (@{ GetReservesFromBiblionumber($item->{biblionumber}) });
|
||||
$item->{hold_queue} = [ sort priority_sort @reserves ];
|
||||
my ($whatever, $arrayref) = GetReservesFromBiblionumber($item->{biblionumber});
|
||||
$item->{hold_queue} = [ sort priority_sort @$arrayref ];
|
||||
$item->{hold_shelf} = [( grep { defined $_->{found} and $_->{found} eq 'W' } @{$item->{hold_queue}} )];
|
||||
$item->{pending_queue} = [( grep {(! defined $_->{found}) or ($_->{found} ne 'W')} @{$item->{hold_queue}} )];
|
||||
$item->{pending_queue} = [( grep {(! defined $_->{found}) or $_->{found} ne 'W' } @{$item->{hold_queue}} )];
|
||||
$self = $item;
|
||||
bless $self, $type;
|
||||
|
||||
|
|
@ -107,17 +112,93 @@ sub new {
|
|||
return $self;
|
||||
}
|
||||
|
||||
sub magnetic {
|
||||
my $self = shift;
|
||||
return $self->{magnetic_media};
|
||||
# 0 means read-only
|
||||
# 1 means read/write
|
||||
|
||||
my %fields = (
|
||||
id => 0,
|
||||
sip_media_type => 0,
|
||||
sip_item_properties => 0,
|
||||
magnetic_media => 0,
|
||||
permanent_location => 0,
|
||||
current_location => 0,
|
||||
print_line => 1,
|
||||
screen_msg => 1,
|
||||
itemnumber => 0,
|
||||
biblionumber => 0,
|
||||
barcode => 0,
|
||||
onloan => 0,
|
||||
collection_code => 0,
|
||||
call_number => 0,
|
||||
enumchron => 0,
|
||||
location => 0,
|
||||
author => 0,
|
||||
title => 0,
|
||||
);
|
||||
|
||||
sub next_hold {
|
||||
my $self = shift or return;
|
||||
foreach (@$self->{hold_shelf}) { # If this item was taken from the hold shelf, then that reserve still governs
|
||||
next unless ($_->{itemnumber} and $_->{itemnumber} == $self->{itemnumber});
|
||||
return $_;
|
||||
}
|
||||
if (scalar @$self->{pending_queue}) { # Otherwise, if there is at least one hold, the first (best priority) gets it
|
||||
return $self->{pending_queue}->[0];
|
||||
}
|
||||
return;
|
||||
}
|
||||
sub sip_media_type {
|
||||
my $self = shift;
|
||||
return $self->{sip_media_type};
|
||||
|
||||
sub hold_patron_id {
|
||||
my $self = shift or return;
|
||||
my $hold = $self->next_hold() or return;
|
||||
return $hold->{borrowernumber};
|
||||
}
|
||||
sub sip_item_properties {
|
||||
sub hold_patron_name {
|
||||
my $self = shift or return;
|
||||
# return $self->{hold_patron_name} if $self->{hold_patron_name}; TODO: consider caching
|
||||
my $borrowernumber = (@_ ? shift: $self->hold_patron_id()) or return;
|
||||
my $holder = GetMember($borrowernumber, 'borrowernumber');
|
||||
unless ($holder) {
|
||||
syslog("LOG_ERR", "While checking hold, GetMember failed for borrowernumber '$borrowernumber'");
|
||||
return;
|
||||
}
|
||||
my $email = $holder{email} || '';
|
||||
my $phone = $holder{phone} || '';
|
||||
my $extra = ($email and $phone) ? " ($email, $phone)" : # both populated, employ comma
|
||||
($email or $phone) ? " ($email$phone)" : # only 1 populated, we don't care which: no comma
|
||||
"" ; # niether populated, empty string
|
||||
my $name = $holder->{firstname} ? $holder->{firstname} . ' ' : '';
|
||||
$name .= $holder->{surname} . $extra;
|
||||
# $self->{hold_patron_name} = $name; # TODO: consider caching
|
||||
return $name;
|
||||
}
|
||||
sub destination_loc {
|
||||
my $self = shift or return;
|
||||
my $hold = $self->next_hold();
|
||||
return ($hold ? $hold->{branchcode}
|
||||
}
|
||||
|
||||
our $AUTOLOAD;
|
||||
|
||||
sub DESTROY { } # keeps AUTOLOAD from catching inherent DESTROY calls
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
return $self->{sip_item_properties};
|
||||
my $class = ref($self) or croak "$self is not an object";
|
||||
my $name = $AUTOLOAD;
|
||||
|
||||
$name =~ s/.*://;
|
||||
|
||||
unless (exists $fields{$name}) {
|
||||
croak "Cannot access '$name' field of class '$class'";
|
||||
}
|
||||
|
||||
if (@_) {
|
||||
$fields{$name} or croak "Field '$name' of class '$class' is READ ONLY.";
|
||||
return $self->{$name} = shift;
|
||||
} else {
|
||||
return $self->{$name};
|
||||
}
|
||||
}
|
||||
|
||||
sub status_update { # FIXME: this looks unimplemented
|
||||
|
|
@ -128,22 +209,10 @@ sub status_update { # FIXME: this looks unimplemented
|
|||
return $status;
|
||||
}
|
||||
|
||||
sub id {
|
||||
my $self = shift;
|
||||
return $self->{id};
|
||||
}
|
||||
sub title_id {
|
||||
my $self = shift;
|
||||
return $self->{title};
|
||||
}
|
||||
sub permanent_location {
|
||||
my $self = shift;
|
||||
return $self->{permanent_location} || '';
|
||||
}
|
||||
sub current_location {
|
||||
my $self = shift;
|
||||
return $self->{current_location} || '';
|
||||
}
|
||||
|
||||
sub sip_circulation_status {
|
||||
my $self = shift;
|
||||
|
|
@ -173,7 +242,7 @@ sub fee_currency {
|
|||
}
|
||||
sub owner {
|
||||
my $self = shift;
|
||||
return 'CPL'; # FIXME: UWOLS was hardcoded
|
||||
return $self->{homebranch};
|
||||
}
|
||||
sub hold_queue {
|
||||
my $self = shift;
|
||||
|
|
@ -217,14 +286,6 @@ sub hold_pickup_date {
|
|||
my $self = shift;
|
||||
return $self->{hold_pickup_date} || 0;
|
||||
}
|
||||
sub screen_msg {
|
||||
my $self = shift;
|
||||
return $self->{screen_msg} || '';
|
||||
}
|
||||
sub print_line {
|
||||
my $self = shift;
|
||||
return $self->{print_line} || '';
|
||||
}
|
||||
|
||||
# This is a partial check of "availability". It is not supposed to check everything here.
|
||||
# An item is available for a patron if it is:
|
||||
|
|
|
|||
|
|
@ -11,30 +11,30 @@ ILS::Item - Portable Item status object class for SIP
|
|||
my $item = new ILS::Item $item_id;
|
||||
|
||||
# Basic object access methods
|
||||
$item_id = $item->id;
|
||||
$title = $item->title_id;
|
||||
$media_type = $item->sip_media_type;
|
||||
$bool = $item->magnetic;
|
||||
$locn = $item->permanent_location;
|
||||
$locn = $item->current_location;
|
||||
$props = $item->sip_item_props;
|
||||
$owner = $item->owner;
|
||||
$str = $item->sip_circulation_status;
|
||||
$bool = $item->available;
|
||||
@hold_queue = $item->hold_queue;
|
||||
$pos = $item->hold_queue_position($patron_id);
|
||||
$due = $item->due_date;
|
||||
$pickup = $item->hold_pickup_date;
|
||||
$recall = $item->recall_date;
|
||||
$fee = $item->fee;
|
||||
$currency = $item->fee_currency;
|
||||
$type = $item->sip_fee_type;
|
||||
$mark = $item->sip_security_marker;
|
||||
$msg = $item->screen_msg;
|
||||
$msg = $item->print_line;
|
||||
$item_id = $item->id;
|
||||
$title = $item->title_id;
|
||||
$media_type = $item->sip_media_type;
|
||||
$bool = $item->magnetic_media;
|
||||
$locn = $item->permanent_location;
|
||||
$locn = $item->current_location;
|
||||
$props = $item->sip_item_props;
|
||||
$owner = $item->owner;
|
||||
$str = $item->sip_circulation_status;
|
||||
$bool = $item->available;
|
||||
@hold_queue = $item->hold_queue;
|
||||
$pos = $item->hold_queue_position($patron_id);
|
||||
$due = $item->due_date;
|
||||
$pickup = $item->hold_pickup_date;
|
||||
$recall = $item->recall_date;
|
||||
$fee = $item->fee;
|
||||
$currency = $item->fee_currency;
|
||||
$type = $item->sip_fee_type;
|
||||
$mark = $item->sip_security_marker;
|
||||
$msg = $item->screen_msg;
|
||||
$msg = $item->print_line;
|
||||
|
||||
# Operations on items
|
||||
$status = $item->status_update($item_props);
|
||||
# Operations on items
|
||||
$status = $item->status_update($item_props);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
|
@ -93,9 +93,9 @@ behavior at all; it merely passes it through to the self-service
|
|||
terminal. In particular, it does not set indicators related to
|
||||
whether an item is magnetic, or whether it should be
|
||||
desensitized, based on this return type. The
|
||||
C<$item-E<gt>magnetic> method will be used for that purpose.
|
||||
C<$item-E<gt>magnetic_media> method will be used for that purpose.
|
||||
|
||||
=item C<magnetic>
|
||||
=item C<magnetic_media>
|
||||
|
||||
Is the item some form of magnetic media (eg, a video or a book
|
||||
with an accompanying floppy)? This method will not be called
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ package ILS::Transaction::Checkin;
|
|||
use warnings;
|
||||
use strict;
|
||||
|
||||
use POSIX qw(strftime);
|
||||
# use POSIX qw(strftime);
|
||||
|
||||
use ILS;
|
||||
use ILS::Transaction;
|
||||
|
|
@ -31,7 +31,7 @@ my %fields = (
|
|||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new();
|
||||
my $self = $class->SUPER::new(); # start with an ILS::Transaction object
|
||||
|
||||
foreach (keys %fields) {
|
||||
$self->{_permitted}->{$_} = $fields{$_}; # overlaying _permitted
|
||||
|
|
@ -59,7 +59,7 @@ sub do_checkin {
|
|||
$self->alert_type('99');
|
||||
}
|
||||
}
|
||||
defined $self->alert_type and $self->alert(1); # alert_type could be "00"
|
||||
$self->alert(1) if defined $self->alert_type; # alert_type could be "00"
|
||||
$self->ok($return);
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ sub resensitize {
|
|||
warn "no item found in object to resensitize";
|
||||
return;
|
||||
}
|
||||
return !$self->{item}->magnetic;
|
||||
return !$self->{item}->magnetic_media;
|
||||
}
|
||||
|
||||
sub patron_id {
|
||||
|
|
@ -78,7 +78,7 @@ sub patron_id {
|
|||
warn "no patron found in object";
|
||||
return;
|
||||
}
|
||||
return !$self->{patron}->id;
|
||||
return $self->{patron}->id;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -531,7 +531,7 @@ sub handle_checkout {
|
|||
$resp = CHECKOUT_RESP . '1';
|
||||
$resp .= sipbool($status->renew_ok);
|
||||
if ($ils->supports('magnetic media')) {
|
||||
$resp .= sipbool($item->magnetic);
|
||||
$resp .= sipbool($item->magnetic_media);
|
||||
} else {
|
||||
$resp .= 'U';
|
||||
}
|
||||
|
|
@ -634,10 +634,9 @@ sub handle_checkin {
|
|||
$resp .= $status->ok ? '1' : '0';
|
||||
$resp .= $status->resensitize ? 'Y' : 'N';
|
||||
if ($item && $ils->supports('magnetic media')) {
|
||||
$resp .= sipbool($item->magnetic);
|
||||
$resp .= sipbool($item->magnetic_media);
|
||||
} else {
|
||||
# The item barcode was invalid or the system doesn't support
|
||||
# the 'magnetic media' indicator
|
||||
# item barcode is invalid or system doesn't support 'magnetic media' indicator
|
||||
$resp .= 'U';
|
||||
}
|
||||
$resp .= $status->alert ? 'Y' : 'N';
|
||||
|
|
@ -656,17 +655,17 @@ sub handle_checkin {
|
|||
$resp .= add_field(FID_PATRON_ID, $patron->id);
|
||||
}
|
||||
if ($item) {
|
||||
$resp .= maybe_add(FID_MEDIA_TYPE, $item->sip_media_type );
|
||||
$resp .= maybe_add(FID_ITEM_PROPS, $item->sip_item_properties);
|
||||
# $resp .= maybe_add(FID_COLLECTION_CODE, $item->collection_code );
|
||||
# $resp .= maybe_add(FID_CALL_NUMBER, $item->call_number );
|
||||
# $resp .= maybe_add(FID_DESTINATION, $item->destination_loc );
|
||||
# $resp .= maybe_add(FID_ALERT_TYPE, $item->alert_type );
|
||||
# $resp .= maybe_add(FID_PATRON_ID, $item->hold_patron_id );
|
||||
# $resp .= maybe_add(FID_PATRON_NAME, $item->hold_patron_name );
|
||||
$resp .= maybe_add(FID_MEDIA_TYPE, $item->sip_media_type );
|
||||
$resp .= maybe_add(FID_ITEM_PROPS, $item->sip_item_properties);
|
||||
$resp .= maybe_add(FID_COLLECTION_CODE, $item->collection_code );
|
||||
$resp .= maybe_add(FID_CALL_NUMBER, $item->call_number );
|
||||
$resp .= maybe_add(FID_DESTINATION_LOCATION, $item->destination_loc );
|
||||
$resp .= maybe_add(FID_HOLD_PATRON_ID, $item->hold_patron_id );
|
||||
$resp .= maybe_add(FID_HOLD_PATRON_NAME, $item->hold_patron_name );
|
||||
}
|
||||
}
|
||||
|
||||
$resp .= maybe_add(FID_ALERT_TYPE, $status->alert_type) if $status->alert;
|
||||
$resp .= maybe_add(FID_SCREEN_MSG, $status->screen_msg);
|
||||
$resp .= maybe_add(FID_PRINT_LINE, $status->print_line);
|
||||
|
||||
|
|
@ -1328,7 +1327,7 @@ sub handle_renew {
|
|||
$resp .= '1';
|
||||
$resp .= $status->renewal_ok ? 'Y' : 'N';
|
||||
if ($ils->supports('magnetic media')) {
|
||||
$resp .= sipbool($item->magnetic);
|
||||
$resp .= sipbool($item->magnetic_media);
|
||||
} else {
|
||||
$resp .= 'U';
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue