[open-ils-commits] r13591 - trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ (erickson)
svn at svn.open-ils.org
svn at svn.open-ils.org
Tue Jul 14 15:57:33 EDT 2009
Author: erickson
Date: 2009-07-14 15:57:29 -0400 (Tue, 14 Jul 2009)
New Revision: 13591
Modified:
trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm
Log:
when patron checks out an item and they have no holds that directly target the item,
allow for a setting that tells the system to look for an alternate hold to fulfil the item.
also cleaned up some unnecessarily complicated checkout hold fulfil code
Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm 2009-07-14 18:42:30 UTC (rev 13590)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm 2009-07-14 19:57:29 UTC (rev 13591)
@@ -1258,77 +1258,106 @@
sub handle_checkout_holds {
my $self = shift;
-
my $copy = $self->copy;
my $patron = $self->patron;
- my $holds = $self->editor->search_action_hold_request(
- {
- current_copy => $copy->id ,
- cancel_time => undef,
- fulfillment_time => undef
- }
- );
+ my $e = $self->editor;
+ $self->fulfilled_holds([]);
- my @fulfilled;
+ my $hold = $e->search_action_hold_request({
+ current_copy => $copy->id ,
+ cancel_time => undef,
+ fulfillment_time => undef,
+ '-or' => [
+ {expire_time => undef},
+ {expire_time => {'>' => 'now'}}
+ ]
+ })->[0];
- # XXX We should only fulfill one hold here...
- # XXX If a hold was transited to the user who is checking out
- # the item, we need to make sure that hold is what's grabbed
- if(@$holds) {
+ if($hold and $hold->usr != $patron->id) {
+ # reset the hold since the copy is now checked out
+
+ $logger->info("circulator: un-targeting hold ".$hold->id.
+ " because copy ".$copy->id." is getting checked out");
- # for now, just sort by id to get what should be the oldest hold
- $holds = [ sort { $a->id <=> $b->id } @$holds ];
- my @myholds = grep { $_->usr eq $patron->id } @$holds;
- my @altholds = grep { $_->usr ne $patron->id } @$holds;
+ $hold->clear_prev_check_time;
+ $hold->clear_current_copy;
+ $hold->clear_capture_time;
- if(@myholds) {
- my $hold = $myholds[0];
+ return $self->bail_on_event($e->event)
+ unless $e->update_action_hold_request($hold);
- $logger->debug("circulator: related hold found in checkout: " . $hold->id );
+ $hold = undef;
+ }
- # if the hold was never officially captured, capture it.
- $hold->capture_time('now') unless $hold->capture_time;
+ $hold = $self->find_related_uncaptured_hold($copy, $patron) unless $hold;
- # just make sure it's set correctly
- $hold->current_copy($copy->id);
+ $logger->debug("circulator: checkout filfilling hold " . $hold->id);
- $hold->fulfillment_time('now');
- $hold->fulfillment_staff($self->editor->requestor->id);
- $hold->fulfillment_lib($self->editor->requestor->ws_ou);
+ # if the hold was never officially captured, capture it.
+ $hold->capture_time('now') unless $hold->capture_time;
+ $hold->fulfillment_time('now');
+ $hold->fulfillment_staff($e->requestor->id);
+ $hold->fulfillment_lib($e->requestor->ws_ou);
- return $self->bail_on_events($self->editor->event)
- unless $self->editor->update_action_hold_request($hold);
+ return $self->bail_on_events($e->event)
+ unless $e->update_action_hold_request($hold);
- $holdcode->delete_hold_copy_maps($self->editor, $hold->id);
+ $holdcode->delete_hold_copy_maps($e, $hold->id);
+ return $self->fulfilled_holds([$hold->id]);
+}
- push( @fulfilled, $hold->id );
- }
- # If there are any holds placed for other users that point to this copy,
- # then we need to un-target those holds so the targeter can pick a new copy
- for(@altholds) {
+# ------------------------------------------------------------------------------
+# If the circ.checkout_fill_related_hold setting is turned on and no hold for
+# the patron directly targets the checked out item, see if there is another hold
+# (with hold_type T or V) for the patron that could be fulfilled by the checked
+# out item. Fulfill the oldest hold and only fulfill 1 of them.
+# ------------------------------------------------------------------------------
+sub find_related_uncaptured_hold {
+ my($self, $copy, $patron) = @_;
+ my $e = $self->editor;
- $logger->info("circulator: un-targeting hold ".$_->id.
- " because copy ".$copy->id." is getting checked out");
+ return undef if $self->volume->id == OILS_PRECAT_CALL_NUMBER;
- # - make the targeter process this hold at next run
- $_->clear_prev_check_time;
+ return undef unless $U->ou_ancestor_setting_value(
+ $self->requestor->ws_ou, 'circ.checkout_fills_related_hold', $e);
- # - clear out the targetted copy
- $_->clear_current_copy;
- $_->clear_capture_time;
+ my $args = {
+ cancel_time => undef,
+ fulfillment_time => undef,
+ usr => $patron->id,
+ order_by => {ahr => 'request_time asc'},
+ '-or' => [
+ {expire_time => undef},
+ {expire_time => {'>' => 'now'}}
+ ]
+ };
- return $self->bail_on_event($self->editor->event)
- unless $self->editor->update_action_hold_request($_);
- }
- }
+ $args->{hold_type} = 'V';
+ $args->{target} = $self->volume->id;
+ my $v_hold = $e->search_action_hold_request([$args, {limit => 1}])->[0];
- $self->fulfilled_holds(\@fulfilled);
+ $args->{hold_type} = 'T';
+ $args->{target} = $self->title->id;
+ my $t_hold = $e->search_action_hold_request([$args, {limit => 1}])->[0];
+
+ if($t_hold and $v_hold) {
+
+ my $t_date = DateTime::Format::ISO8601->new->parse_datetime(
+ clense_ISO8601($t_hold->request_time));
+
+ my $v_date = DateTime::Format::ISO8601->new->parse_datetime(
+ clense_ISO8601($v_hold->request_time));
+
+ return $t_hold if $t_date < $v_date;
+ return $v_hold;
+ }
+
+ return $t_hold || $v_hold;
}
-
sub run_checkout_scripts {
my $self = shift;
More information about the open-ils-commits
mailing list