$circ->screen_msg("Patron Blocked");
} elsif (!$item) {
$circ->screen_msg("Invalid Item");
- } elsif ($item->hold_queue && @{$item->hold_queue} && ! $item->barcode_is_borrowernumber($patron_id, $item->hold_queue->[0]->{borrowernumber})) {
- $circ->screen_msg("Item on Hold for Another User");
+ # holds checked inside do_checkout
+ # } elsif ($item->hold_queue && @{$item->hold_queue} && ! $item->barcode_is_borrowernumber($patron_id, $item->hold_queue->[0]->{borrowernumber})) {
+ # $circ->screen_msg("Item on Hold for Another User");
} elsif ($item->{patron} && ($item->{patron} ne $patron_id)) {
# I can't deal with this right now
$circ->screen_msg("Item checked out to another patron");
my ($class, $item_id) = @_;
my $type = ref($class) || $class;
my $self;
- my $item = GetBiblioFromItemNumber( GetItemnumberFromBarcode($item_id) );
-
+ my $itemnumber = GetItemnumberFromBarcode($item_id);
+ my $item = GetBiblioFromItemNumber($itemnumber);
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'};
# check if its on issue and if so get the borrower
my $issue = GetItemIssue($item->{'itemnumber'});
$item->{patron} = $borrower->{'cardnumber'};
my @reserves = (@{ GetReservesFromBiblionumber($item->{biblionumber}) });
$item->{hold_queue} = [ sort priority_sort @reserves ];
- # $item->{joetest} = 111;
+ $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}} )];
$self = $item;
bless $self, $type;
(defined $self->{hold_queue}) or return [];
return $self->{hold_queue};
}
+sub pending_queue {
+ my $self = shift;
+ (defined $self->{pending_queue}) or return [];
+ return $self->{pending_queue};
+}
+sub hold_shelf {
+ my $self = shift;
+ (defined $self->{hold_shelf}) or return [];
+ return $self->{hold_shelf};
+}
sub hold_queue_position {
my ($self, $patron_id) = @_;
# 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:
-# 1) checked out to the same patron and there's no hold queue
+# 1) checked out to the same patron
+# AND no pending (i.e. non-W) hold queue
# OR
-# 2) not checked out and (there's no hold queue OR patron
-# is at the front of the queue)
+# 2) not checked out
+# AND (not on hold_shelf OR is on hold_shelf for patron)
+#
+# What this means is we are consciously allowing the patron to checkout (but not renew) an item that DOES
+# have non-W holds on it, but has not been "picked" from the stacks. That is to say, the
+# patron has retrieved the item before the librarian.
+#
+# We don't check if the patron is at the front of the pending queue in the first case, because
+# they should not be able to place a hold on an item they already have.
+
sub available {
my ($self, $for_patron) = @_;
- my $count = (defined $self->{hold_queue}) ? scalar @{$self->{hold_queue}} : 0;
- $debug and print STDERR "availability check: hold_queue size $count\n";
+ my $count = (defined $self->{pending_queue}) ? scalar @{$self->{pending_queue}} : 0;
+ my $count2 = (defined $self->{hold_shelf} ) ? scalar @{$self->{hold_shelf} } : 0;
+ $debug and print STDERR "availability check: pending_queue size $count, hold_shelf size $count2\n";
if (defined($self->{patron_id})) {
($self->{patron_id} eq $for_patron) or return 0;
return ($count ? 0 : 1);
} else { # not checked out
- ($count) or return 1;
- ($self->barcode_is_borrowernumber($for_patron, $self->{hold_queue}[0]->{borrowernumber})) and return 1;
+ ($count2) and return $self->barcode_is_borrowernumber($for_patron, $self->{hold_shelf}[0]->{borrowernumber});
}
return 0;
}
my $converted = _barcode_to_borrowernumber($barcode) or return undef;
return ($number eq $converted); # even though both *should* be numbers, eq is safer.
}
+sub fill_reserve ($$) {
+ my $self = shift;
+ my $hold = shift or return undef;
+ foreach (qw(biblionumber borrowernumber reservedate)) {
+ $hold->{$_} or return undef;
+ }
+ return ModReserveFill($hold);
+}
1;
__END__
ptype => $kp->{categorycode}, # 'A'dult. Whatever.
birthdate => $kp->{dateofbirth}, ##$dob,
branchcode => $kp->{branchcode},
+ borrowernumber => $kp->{borrowernumber},
address => $adr,
home_phone => $kp->{phone},
email_addr => $kp->{email},
}
}
- # FIXME: populate items fine_items recall_items
+ # FIXME: populate fine_items recall_items
# $ilspatron{hold_items} = (GetReservesFromBorrowernumber($kp->{borrowernumber},'F'));
$ilspatron{unavail_holds} = [(GetReservesFromBorrowernumber($kp->{borrowernumber}))];
my ($count,$issues) = GetPendingIssues($kp->{borrowernumber});
use C4::Context;
use C4::Circulation;
use C4::Members;
+use C4::Reserves qw(ModReserveFill);
use C4::Debug;
use vars qw($VERSION @ISA $debug);
sub do_checkout {
my $self = shift;
syslog('LOG_DEBUG', "ILS::Transaction::Checkout performing checkout...");
+ my $pending = $self->{item}->pending_queue;
+ my $shelf = $self->{item}->hold_shelf;
my $barcode = $self->{item}->id;
my $patron_barcode = $self->{patron}->id;
$debug and warn "do_checkout: patron (" . $patron_barcode . ")";
- # my $borrower = GetMember( $patron_barcode, 'cardnumber' );
- # my $borrower = $self->{patron};
- # my $borrower = GetMemberDetails(undef, $patron_barcode);
my $borrower = $self->{patron}->getmemberdetails_object();
$debug and warn "do_checkout borrower: . " . Dumper $borrower;
my ($issuingimpossible,$needsconfirmation) = CanBookBeIssued( $borrower, $barcode );
my $noerror=1;
- foreach ( keys %$issuingimpossible ) {
- # do something here so we pass these errors
- $self->screen_msg($_ . ': ' . $issuingimpossible->{$_});
- $noerror = 0;
- }
- foreach my $confirmation ( keys %$needsconfirmation ) {
- if ($confirmation eq 'RENEW_ISSUE'){
- $self->screen_msg("Item already checked out to you: renewing item.");
- } elsif ($confirmation eq 'RESERVED' or $confirmation eq 'RESERVE_WAITING') {
- my $x = $self->{item}->available($patron_barcode);
- if ($x) {
- $self->screen_msg("Item was reserved for you.");
+ if (scalar keys %$issuingimpossible) {
+ foreach (keys %$issuingimpossible) {
+ # do something here so we pass these errors
+ $self->screen_msg($_ . ': ' . $issuingimpossible->{$_});
+ $noerror = 0;
+ }
+ } else {
+ foreach my $confirmation (keys %$needsconfirmation) {
+ if ($confirmation eq 'RENEW_ISSUE'){
+ $self->screen_msg("Item already checked out to you: renewing item.");
+ } elsif ($confirmation eq 'RESERVED' or $confirmation eq 'RESERVE_WAITING') {
+ my $x = $self->{item}->available($patron_barcode);
+ if ($x) {
+ $self->screen_msg("Item was reserved for you.");
+ } else {
+ $self->screen_msg("Item is reserved for another patron upon return.");
+ # $noerror = 0;
+ }
+ } elsif ($confirmation eq 'ISSUED_TO_ANOTHER') {
+ $self->screen_msg("Item already checked out to another patron. Please return item for check-in.");
+ $noerror = 0;
+ } elsif ($confirmation eq 'DEBT') { # don't do anything, it's the minor debt, and alarms fire elsewhere
} else {
- $self->screen_msg("Item is reserved for another patron.");
+ $self->screen_msg($needsconfirmation->{$confirmation});
$noerror = 0;
}
- } elsif ($confirmation eq 'ISSUED_TO_ANOTHER') {
- $self->screen_msg("Item already checked out to another patron. Please return item for check-in.");
- $noerror = 0;
- } elsif ($confirmation eq 'DEBT') { # don't do anything, it's the minor debt, and alarms fire elsewhere
- } else {
- $self->screen_msg($needsconfirmation->{$confirmation});
- $noerror = 0;
- }
- }
+ }
+ }
+ my $itemnumber = $self->{item}->{itemnumber};
+ foreach (@$shelf) {
+ $debug and warn "shelf has ($_->{itemnumber} for $_->{borrowernumber}). this is ($itemnumber, $self->{patron}->{borrowernumber})";
+ ($_->{itemnumber} eq $itemnumber) or next; # skip it if not this item
+ ($_->{borrowernumber} == $self->{patron}->{borrowernumber}) and last;
+ # if item was waiting for this patron, we're done. AddIssue takes care of the "W" hold.
+ $debug and warn "Item is on hold shelf for another patron.";
+ $self->screen_msg("Item is on hold shelf for another patron.");
+ $noerror = 0;
+ }
unless ($noerror) {
- warn "cannot issue: " . Dumper($issuingimpossible) . "\n" . Dumper($needsconfirmation);
+ $debug and warn "cannot issue: " . Dumper($issuingimpossible) . "\n" . Dumper($needsconfirmation);
$self->ok(0);
return $self;
}
+ # Fill any reserves the patron had on the item.
+ # TODO: this logic should be pulled internal to AddIssue for all Koha.
+ $debug and warn "pending_queue: " . (@$pending) ? Dumper($pending) : '[]';
+ foreach (grep {$_->{borrowernumber} eq $self->{patron}->{borrowernumber}} @$pending) {
+ $debug and warn "Filling reserve (borrowernumber,biblionumber,reservedate): "
+ . sprintf("(%s,%s,%s)\n",$_->{borrowernumber},$_->{biblionumber},$_->{reservedate});
+ ModReserveFill($_);
+ # TODO: adjust representation in $self->item
+ }
# can issue
$debug and warn "do_checkout: calling AddIssue(\$borrower,$barcode, undef, 0)\n"
# . "w/ \$borrower: " . Dumper($borrower)
. "w/ C4::Context->userenv: " . Dumper(C4::Context->userenv);
- my $c4due = AddIssue( $borrower, $barcode, undef, 0 );
+ my $c4due = AddIssue($borrower, $barcode, undef, 0);
my $due = $c4due->output('iso') || undef;
$debug and warn "Item due: $due";
$self->{'due'} = $due;