more checkout code
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 13 Feb 2006 15:14:04 +0000 (15:14 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 13 Feb 2006 15:14:04 +0000 (15:14 +0000)
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

Open-ILS/src/perlmods/OpenILS/Application/AppUtils.pm
Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm
Open-ILS/src/perlmods/OpenILS/Application/Circ/Transit.pm
Open-ILS/src/perlmods/OpenILS/Utils/PermitHold.pm
Open-ILS/src/support-scripts/test-scripts/checkout.pl

index 044674d..c2793e3 100644 (file)
@@ -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;
index beea6ad..fd5c180 100644 (file)
@@ -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 } );
 }
index a415b53..3080bde 100644 (file)
@@ -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');
index da57fa3..a498ff4 100755 (executable)
@@ -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");
+}