From 59bdc96b7344b31e0fad703cbd0e91600763f266 Mon Sep 17 00:00:00 2001 From: erickson Date: Mon, 13 Feb 2006 15:14:04 +0000 Subject: [PATCH] more checkout code created hold possibility checker method more transit work.. needs testing git-svn-id: svn://svn.open-ils.org/ILS/trunk@3035 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../perlmods/OpenILS/Application/AppUtils.pm | 4 + .../OpenILS/Application/Circ/Circulate.pm | 161 ++++++++++++++---- .../OpenILS/Application/Circ/Transit.pm | 38 ++++- .../src/perlmods/OpenILS/Utils/PermitHold.pm | 2 + .../support-scripts/test-scripts/checkout.pl | 14 ++ 5 files changed, 186 insertions(+), 33 deletions(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Application/AppUtils.pm b/Open-ILS/src/perlmods/OpenILS/Application/AppUtils.pm index 38338b79f9..512f803cd8 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/AppUtils.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/AppUtils.pm @@ -861,5 +861,9 @@ sub update_copy { return undef; } + + + + 1; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm index 044674d454..c2793e3aae 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm @@ -10,6 +10,7 @@ use OpenILS::Utils::ScriptRunner; use OpenILS::Application::AppUtils; use OpenILS::Application::Circ::Holds; use OpenILS::Application::Circ::Transit; +use OpenILS::Utils::PermitHold; use OpenSRF::Utils::Logger qw(:logger); $Data::Dumper::Indent = 0; @@ -27,8 +28,6 @@ my $cache_handle; # - memcache handle sub PRECAT_FINE_LEVEL { return 2; } sub PRECAT_LOAN_DURATION { return 2; } -my $SUCCESS; - # for security, this is a process-defined and not # a client-defined variable @@ -52,11 +51,10 @@ sub initialize { my $f = $conf->config_value( @pfx, 'circ_recurring_fines' ); my $m = $conf->config_value( @pfx, 'circ_max_fines' ); my $pr = $conf->config_value( @pfx, 'circ_permit_renew' ); - my $ph = $conf->config_value( @pfx, 'circ_permit_hold' ); my $lb = $conf->config_value( @pfx2, 'script_path' ); $logger->error( "Missing circ script(s)" ) - unless( $p and $c and $d and $f and $m and $pr and $ph ); + unless( $p and $c and $d and $f and $m and $pr ); $scripts{circ_permit_patron} = $p; $scripts{circ_permit_copy} = $c; @@ -64,7 +62,6 @@ sub initialize { $scripts{circ_recurring_fines}= $f; $scripts{circ_max_fines} = $m; $scripts{circ_permit_renew} = $pr; - $scripts{hold_permit_permit} = $ph; $lb = [ $lb ] unless ref($lb); $script_libs = $lb; @@ -72,10 +69,7 @@ sub initialize { $logger->debug("Loaded rules scripts for circ: " . "circ permit patron: $p, circ permit copy: $c, ". "circ duration :$d , circ recurring fines : $f, " . - "circ max fines : $m, circ renew permit : $pr, permit hold: $ph"); - - - $SUCCESS = OpenILS::Event->new('SUCCESS'); + "circ max fines : $m, circ renew permit : $pr"); } @@ -173,7 +167,7 @@ sub _ctx_add_copy_objects { ($copy, $evt) = _find_copy_by_attr(%params); return $evt if $evt; - if( $copy ) { + if( $copy and !$ctx->{title} ) { $logger->debug("Copy status: " . $copy->status); ( $ctx->{title}, $evt ) = $U->fetch_record_by_copy( $copy->id ); return $evt if $evt; @@ -283,7 +277,7 @@ sub _build_circ_script_runner { if( $runner = $contexts{$ctx->{type}} ) { $runner->refresh_context; } else { - $runner = OpenILS::Utils::ScriptRunner->new unless $runner; + $runner = OpenILS::Utils::ScriptRunner->new; $contexts{type} = $runner; } @@ -292,18 +286,36 @@ sub _build_circ_script_runner { $runner->add_path( $_ ); } + # Note: inserting the number 0 into the script turns into the + # string "0", and thus evaluates to true in JS land + # inserting undef will insert "", which evaluates to false - $runner->insert( 'environment.patron', $ctx->{patron}, 1); - $runner->insert( 'environment.title', $ctx->{title}, 1); - $runner->insert( 'environment.copy', $ctx->{copy}, 1); + $runner->insert( 'environment.patron', $ctx->{patron}, 1); + $runner->insert( 'environment.title', $ctx->{title}, 1); + $runner->insert( 'environment.copy', $ctx->{copy}, 1); # circ script result $runner->insert( 'result', {} ); $runner->insert( 'result.event', 'SUCCESS' ); - $runner->insert('environment.isRenewal', 1) if $__isrenewal; - $runner->insert('environment.isNonCat', 1) if $ctx->{noncat}; - $runner->insert('environment.nonCatType', $ctx->{noncat_type}) if $ctx->{noncat}; + if($__isrenewal) { + $runner->insert('environment.isRenewal', 1); + } else { + $runner->insert('environment.isRenewal', undef); + } + + if($ctx->{ishold} ) { + $runner->insert('environment.isHold', 1); + } else{ + $runner->insert('environment.isHold', undef) + } + + if( $ctx->{noncat} ) { + $runner->insert('environment.isNonCat', 1); + $runner->insert('environment.nonCatType', $ctx->{noncat_type}); + } else { + $runner->insert('environment.isNonCat', undef); + } if(ref($ctx->{patron_circ_summary})) { $runner->insert( 'environment.patronItemsOut', $ctx->{patron_circ_summary}->[0], 1 ); @@ -375,15 +387,75 @@ sub permit_circ { return $evt if $evt; } - ($circ, $evt) = $U->fetch_open_circulation($ctx->{copy}->id) - if ( !$__isrenewal and $ctx->{copy}); - - return OpenILS::Event->new('OPEN_CIRCULATION_EXISTS') if $circ; + if( !$ctx->{ishold} and !$__isrenewal and $ctx->{copy} ) { + ($circ, $evt) = $U->fetch_open_circulation($ctx->{copy}->id); + return OpenILS::Event->new('OPEN_CIRCULATION_EXISTS') if $circ; + } return _run_permit_scripts($ctx); } +__PACKAGE__->register_method( + method => "check_title_hold", + api_name => "open-ils.circ.title_hold.is_possible", + notes => q/ + Determines if a hold were to be placed by a given user, + whether or not said hold would have any potential copies + to fulfill it. + @param authtoken The login session key + @param params A hash of named params including: + patronid - the id of the hold recipient + titleid (brn) - the id of the title to be held + depth - the hold range depth (defaults to 0) + /); + +sub check_title_hold { + my( $self, $client, $authtoken, $params ) = @_; + my %params = %$params; + my $titleid = $params{titleid}; + + my ( $requestor, $patron, $evt ) = $U->checkses_requestor( + $authtoken, $params{patronid}, 'VIEW_HOLD_PERMIT' ); + return $evt if $evt; + + my $rangelib = $patron->home_ou; + my $depth = $params{depth} || 0; + + $logger->debug("Fetching ranged title tree for title $titleid, org $rangelib, depth $depth"); + + my $title = $U->storagereq( + 'open-ils.storage.biblio.record_entry.ranged_tree', $titleid, $rangelib ); + + my $org = $U->simplereq( + 'open-ils.actor', + 'open-ils.actor.org_unit.retrieve', + $authtoken, $requestor->home_ou ); + + for my $cn (@{$title->call_numbers}) { + + $logger->debug("Checking callnumber ".$cn->id." for hold fulfillment possibility"); + + for my $copy (@{$cn->copies}) { + + $logger->debug("Checking copy ".$copy->id." for hold fulfillment possibility"); + + return 1 if OpenILS::Utils::PermitHold::permit_copy_hold( + { patron => $patron, + requestor => $requestor, + copy => $copy, + title => $title, + title_descriptor => $title->fixed_fields, # this is fleshed into the title object + request_lib => $org } ); + + $logger->debug("Copy ".$copy->id." for hold fulfillment possibility failed..."); + } + } + + return 0; +} + + # Runs the patron and copy permit scripts # if this is a non-cat circulation, the copy permit script @@ -414,6 +486,11 @@ sub _run_permit_scripts { return OpenILS::Event->new('ITEM_NOT_CATALOGED', payload => $key); } + if($ctx->{ishold}) { + $logger->debug("Exiting circ permit early because request is for hold patron permit"); + return OpenILS::Event->new('SUCCESS'); + } + $runner->load($scripts{circ_permit_copy}); $runner->run or throw OpenSRF::EX::ERROR ("Circ Permit Copy Script Died: $@"); $evtname = $runner->retrieve('result.event'); @@ -760,6 +837,8 @@ sub _handle_related_holds { $logger->debug("Related hold found in checkout: " . $hold->id ); + # if the hold was never officially captured, capture it. + $hold->capture_time('now') unless $hold->capture_time; $hold->fulfillment_time('now'); my $r = $ctx->{session}->request( "open-ils.storage.direct.action.hold_request.update", $hold )->gather(1); @@ -808,7 +887,7 @@ sub checkin { my( $self, $client, $authtoken, $params ) = @_; $U->logmark; - my( $ctx, $requestor, $evt, $circ, $copy, $payload ); + my( $ctx, $requestor, $evt, $circ, $copy, $payload, $transit ); ( $requestor, $evt ) = $U->checkses($authtoken) if $__isrenewal; ( $requestor, $evt ) = $U->checksesperm( @@ -828,6 +907,7 @@ sub checkin { return $evt if $evt; } $ctx->{session} = $U->start_db_session() unless $ctx->{session}; + $ctx->{authtoken} = $authtoken; $copy = $ctx->{copy}; return OpenILS::Event->new('COPY_NOT_FOUND') unless $copy; @@ -880,16 +960,16 @@ sub checkin { # see if there is any other processing required on this copy # ------------------------------------------------------------------------------ - if( !($evt = _check_checkin_holds($ctx)) ) { - # if no hold is found for the copy, see if it needs to be transited - if( $copy->circ_lib != $requestor->home_ou ) { - $logger->debug("Checkin copy needs to go back to it's circ lib: ". - "current loc: ".$requestor->home_ou.", copy circ_lib: ".$copy->circ_lib); - $evt = OpenILS::Event->new('ROUTE_ITEM', org => $copy->circ_lib ); + if(!$__isrenewal) { + if( !($evt = _check_checkin_holds($ctx)) ) { + # if no hold is found for the copy, see if it needs to be transited + ($evt, $transit) = $self->check_copy_transit($ctx); + return $evt if ($evt and !$transit); + $payload->{transit} = $transit if $transit; } } - $logger->debug("Checkin committing objects..."); + $logger->debug("Checkin succeeded. Committing objects..."); $U->commit_db_session($ctx->{session}); # if the item is not cataloged and no superceding @@ -897,7 +977,7 @@ sub checkin { if ( $copy->call_number == -1 and !$evt ) { $evt = OpenILS::Event->new('ITEM_NOT_CATALOGED') } - $evt = $SUCCESS if (!$evt or $__isrenewal); + $evt = OpenILS::Event->new('SUCCESS') if (!$evt or $__isrenewal); $evt->{payload} = $payload; $logger->info("Checkin of copy ".$copy->id." returned event: ".$evt->{textcode}); @@ -907,6 +987,27 @@ sub checkin { return $evt; } +# returns (undef) if no transit is needed +# returns (ROUTE_ITEM, $transit) on succsessful transit creation +# return (other event) on failure +sub check_copy_transit { + my( $self, $ctx ) = @_; + my $copy = $ctx->{copy}; + + return (undef) if( $copy->circ_lib == $ctx->{requestor}->home_ou ); + + my ($evt) = $self->method_lookup( + 'open-ils.circ.copy_transit.create')->run( + $ctx->{authtoken}, + { session => $ctx->{session}, copyid => $copy->id } ); + + return ($evt, undef) unless $U->event_equals($evt,'SUCCESS'); + + my $transit = $evt->{payload}->{transit}; + $evt = OpenILS::Event->new('ROUTE_ITEM', org => $copy->circ_lib ); + return ($evt, $transit); +} + sub _check_checkin_holds { my $ctx = shift; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Transit.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Transit.pm index beea6ad89c..fd5c18071f 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Transit.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Transit.pm @@ -17,6 +17,36 @@ $Data::Dumper::Indent = 0; +__PACKAGE__->register_method( + method => "copy_transit_receive", + api_name => "open-ils.circ.copy_transit.receive", + notes => q/ + Closes out a copy transit + Requestor needs the COPY_TRANSIT_RECEIVE permission + @param authtoken The login session key + @param params An object of named params including + copyid - the id of the copy in quest + barcode - the barcode of the copy in question + If copyid is not sent, this is used. + @return A ROUTE_ITEM if the copy is destined for a different location. + A SUCCESS event on success. Other events on error. + /); + +sub copy_transit_receive { + my( $self, $client, $authtoken, $params ) = @_; + my %params = %$params; + my( $evt, $copy, $requestor ); + ($requestor, $evt) = $U->checksesperm($authtoken, 'COPY_TRANSIT_RECEIVE'); + return $evt if $evt; + ($copy, $evt) = $U->fetch_copy($params{copyid}); + ($copy, $evt) = $U->fetch_copy_by_barcode($params{barcode}) unless $copy; + return $evt if $evt; + my $session = $U->start_db_session(); + $evt = $self->transit_receive( $copy, $requestor, $session ); + $U->commit_db_session($session) if $U->event_equals($evt,'SUCCESS'); + return $evt; +} + # ------------------------------------------------------------------------------ # If the transit destination is different than the requestor's lib, # a ROUTE_TO event is returned with the org set. @@ -61,7 +91,7 @@ sub transit_receive { #recover this copy's status from the transit $copy->status( $transit->copy_status ); - return OpenILS::Event->('SUCCESS', payload => $copy); + return OpenILS::Event->new('SUCCESS', payload => $copy); } @@ -69,7 +99,7 @@ sub transit_receive { # ------------------------------------------------------------------------------ # If we have a hold transit, set the copy's status to 'on holds shelf', -# update the copy, and return the ROUTE_TO_COPY_LOATION event +# update the copy, and return SUCCESS # ------------------------------------------------------------------------------ sub _finish_hold_transit { my( $session, $requestor, $copy, $transid ) = @_; @@ -119,7 +149,7 @@ sub copy_transit_create { ($copy,$evt) = $U->fetch_copy($params{copyid}); return $evt if $evt; - my $session = $U->start_db_session(); + my $session = $params{session} || $U->start_db_session(); my $source = $requestor->home_ou; my $dest = $params{destination} || $copy->circ_lib; my $transit = Fieldmapper::action::transit_copy->new; @@ -145,6 +175,8 @@ sub copy_transit_create { return $evt if ($evt = $U->update_copy( copy => $copy, editor => $requestor->id, session => $session )); + $U->commit_db_session($session) unless $params{session}; + return OpenILS::Event->new('SUCCESS', payload => { copy => $copy, transit => $transit } ); } diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/PermitHold.pm b/Open-ILS/src/perlmods/OpenILS/Utils/PermitHold.pm index a415b53795..3080bde79c 100644 --- a/Open-ILS/src/perlmods/OpenILS/Utils/PermitHold.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/PermitHold.pm @@ -32,6 +32,8 @@ sub permit_copy_hold { # we get the script result from the event $runner->insert( "result.event", 'SUCCESS' ); + $logger->debug("Running permit_copy_hold on copy " . $$params{copy}->id); + load_scripts($runner); $runner->run or throw OpenSRF::EX::ERROR ("Hold Copy Permit Script Died: $@"); my $evtname = $runner->retrieve('result.event'); diff --git a/Open-ILS/src/support-scripts/test-scripts/checkout.pl b/Open-ILS/src/support-scripts/test-scripts/checkout.pl index da57fa3646..a498ff492b 100755 --- a/Open-ILS/src/support-scripts/test-scripts/checkout.pl +++ b/Open-ILS/src/support-scripts/test-scripts/checkout.pl @@ -36,6 +36,9 @@ sub go { if($type eq 'renew') { do_renew($patronid, $barcode); + } elsif( $type eq 'transit_receive' ) { + do_transit_receive($barcode); + } elsif( $type eq 'checkin' ) { do_checkin($barcode); } else { @@ -134,3 +137,14 @@ sub do_checkin { printl("Checkin succeeded\nTime: $t"); } + +sub do_transit_receive { + my $barcode = shift; + my $args = { barcode => $barcode }; + my $t = time(); + my $resp = simplereq( + CIRC(), 'open-ils.circ.copy_transit.receive', $authtoken, $args ); + my $e = time() - $t; + oils_event_die($resp); + printl("Transit receive succeeded\nTime: $t"); +} -- 2.43.2