more holds capturing, transits, etc.
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 20 Jul 2005 22:12:31 +0000 (22:12 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 20 Jul 2005 22:12:31 +0000 (22:12 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@1322 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/perlmods/OpenILS/Application/Actor.pm
Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm
Open-ILS/src/perlmods/OpenILS/Application/Circ/Rules.pm
Open-ILS/src/perlmods/OpenILS/EX.pm
Open-ILS/src/templates/strings/ex.ttk

index 11f6050..92fdc05 100644 (file)
@@ -868,16 +868,24 @@ sub update_password {
 __PACKAGE__->register_method(
        method  => "check_user_perms",
        api_name        => "open-ils.actor.user.perm.check",
-       notes           => <<"  NOTES"
-       Takes a user id, an org id, and an array of perm type strings.  For each
+       notes           => <<"  NOTES");
+       Takes a login session, user id, an org id, and an array of perm type strings.  For each
        perm type, if the user does *not* have the given permission it is added
        to a list which is returned from the method.  If all permissions
        are allowed, an empty list is returned
+       if the logged in user does not match 'user_id', then the logged in user must
+       have VIEW_PERMISSION priveleges.
        NOTES
-       );
 
 sub check_user_perms {
-       my( $self, $client, $user_id, $org_id, $perm_types ) = @_;
+       my( $self, $client, $login_session, $user_id, $org_id, $perm_types ) = @_;
+       my $user_obj = $apputils->check_user_session($login_session); 
+
+       if($user_obj->id ne $user_id) {
+               if($apputils->check_user_perms($user_obj->id, $org_id, "VIEW_PERMISSION")) {
+                       return OpenILS::Perm->new("VIEW_PERMISSION");
+               }
+       }
 
        my @not_allowed;
        for my $perm (@$perm_types) {
@@ -894,12 +902,11 @@ sub check_user_perms {
 __PACKAGE__->register_method(
        method  => "user_fines_summary",
        api_name        => "open-ils.actor.user.fines.summary",
-       notes           => <<"  NOTES"
+       notes           => <<"  NOTES");
        Returns a short summary of the users total open fines, excluding voided fines
        Params are login_session, user_id
        Returns a 'mus' object.
        NOTES
-       );
 
 sub user_fines_summary {
        my( $self, $client, $login_session, $user_id ) = @_;
index 9e0bac1..d5eea38 100644 (file)
@@ -20,6 +20,7 @@ use strict; use warnings;
 use OpenILS::Application::AppUtils;
 my $apputils = "OpenILS::Application::AppUtils";
 use OpenILS::EX;
+use OpenSRF::EX qw(:try);
 use OpenILS::Perm;
 
 
@@ -335,51 +336,36 @@ __PACKAGE__->register_method(
        notes           => <<"  NOTE");
        Captures a copy to fulfil a hold
        Params is login session and copy barcode
+       Optional param is 'flesh'.  If set, we also return the
+       relevant copy and title
        login mus have COPY_CHECKIN permissions (since this is essentially
        copy checkin)
        NOTE
 
 sub capture_copy {
-       my( $self, $client, $login_session, $barcode ) = @_;
+       my( $self, $client, $login_session, $barcode, $flesh ) = @_;
 
        my $user = $apputils->check_user_session($login_session);
 
        if($apputils->check_user_perms($user->id, $user->home_ou, "COPY_CHECKIN")) {
-               return OpenILS::Perm->new("COPY_CHECKIN");
-       }
+               return OpenILS::Perm->new("COPY_CHECKIN"); }
 
        my $session = $apputils->start_db_session();
+
        my $copy = $session->request(
                "open-ils.storage.direct.asset.copy.search.barcode",
                $barcode )->gather(1);
+       return OpenILS::EX->new("UNKNOWN_BARCODE")->ex unless $copy;
 
        warn "Capturing copy " . $copy->id . "\n";
 
-       # retrieve the hold copy maps for this copy
-       my $maps = $session->request(
-               "open-ils.storage.direct.action.hold_copy_map.search.target_copy.atomic",
-               $copy->id)->gather(1);
-
-       my @holdids = map { $_->hold } @$maps;
-
-       use Data::Dumper;
-       warn "Found possible holds\n" . Dumper(\@holdids) . "\n";
-
-       # retrieve sorted list of holds for the given maps and use the first
-       # if there is a hold for this lib, use that
-       my $holds = $session->request(
-               "open-ils.storage.direct.action.hold_request.search_where.atomic",
-               { id => \@holdids, current_copy => undef }, 
-               { order_by => "CASE WHEN ". $copy->circ_lib .
-                       " = (SELECT a.home_ou FROM actor.usr a where a.id = usr ) THEN 0 ELSE 1 END, request_time" }
-               )->gather(1);
-
-       my $hold = $holds->[0];
+       my $hold = _find_local_hold_for_copy($session, $copy, $user);
+       if(!$hold) {return OpenILS::EX->new("HOLD_NOT_FOUND")->ex;}
 
        warn "Found hold " . $hold->id . "\n";
 
        $hold->current_copy($copy->id);
-       $hold->capture_time("now"); # ???
+       $hold->capture_time("now"); 
 
        #update the hold
        my $stat = $session->request(
@@ -390,15 +376,7 @@ sub capture_copy {
 
        # if the staff member capturing this item is not at the pickup lib
        if( $user->home_ou ne $hold->pickup_lib ) {
-               my $trans = Fieldmapper::action::hold_transit_copy->new;
-               $trans->hold($hold->id);
-               $trans->source($user->home_ou);
-               $trans->dest($hold->pickup_lib);
-               $trans->source_send_time("now");
-               my $meth = $self->method_lookup("open-ils.circ.hold_transit.create");
-               my ($stat) = $meth->run( $login_session, $trans, $session );
-               if(!$stat) { throw OpenSRF::EX ("Error creating new hold transit"); }
-               else { $copy->status(6); } #status in transit 
+               $self->_build_hold_transit( $login_session, $session, $hold, $user, $copy );
        }
 
        $copy->editor($user->id);
@@ -407,9 +385,65 @@ sub capture_copy {
                "open-ils.storage.direct.asset.copy.update", $copy )->gather(1);
        if(!$stat) { throw OpenSRF::EX ("Error updating copy " . $copy->id); }
 
+       
+       my $title = undef;
+       if($flesh) {
+               $title = $session->request(
+                       "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
+                       $copy->id )->gather(1);
+               my $u = OpenILS::Utils::ModsParser->new();
+               $u->start_mods_batch( $title->marc() );
+               $title = $u->finish_mods_batch();
+
+       } else { $copy = undef; }
+
        $apputils->commit_db_session($session);
 
-       return { route_to => $hold->pickup_lib };
+       return { 
+               copy => $copy,
+               route_to => $hold->pickup_lib,
+               record => $title,
+       };
+
+}
+
+sub _build_hold_transit {
+       my( $self, $login_session, $session, $hold, $user, $copy ) = @_;
+       my $trans = Fieldmapper::action::hold_transit_copy->new;
+       $trans->hold($hold->id);
+       $trans->source($user->home_ou);
+       $trans->dest($hold->pickup_lib);
+       $trans->source_send_time("now");
+       $trans->target_copy($copy->id);
+       my $meth = $self->method_lookup("open-ils.circ.hold_transit.create");
+       my ($stat) = $meth->run( $login_session, $trans, $session );
+       if(!$stat) { throw OpenSRF::EX ("Error creating new hold transit"); }
+       else { $copy->status(6); } #status in transit 
+}
+
+
+sub _find_local_hold_for_copy {
+
+       my $session = shift;
+       my $copy = shift;
+       my $user = shift;
+
+       # first see if this copy has already been selected to fulfill a hold
+       my $hold  = $session->request(
+               "open-ils.storage.direct.action.hold_request.search.current_copy",
+               $copy->id )->gather(1);
+       if($hold) {return $hold;}
+
+       warn "searching for local hold at org " . $user->home_ou . " and copy " . $copy->id . "\n";
+
+       my $holdid = $session->request(
+               "open-ils.storage.action.hold_request.nearest_hold",
+               $user->home_ou, $copy->id )->gather(1);
+
+       warn "found hold id $holdid\n";
+
+       return $session->request(
+               "open-ils.storage.direct.action.hold_request.retrieve", $holdid )->gather(1);
 
 }
 
index 498848b..ff67620 100644 (file)
@@ -615,6 +615,64 @@ sub build_circ_object {
 
 }
 
+__PACKAGE__->register_method(
+       method  => "transit_receive",
+       api_name        => "open-ils.circ.transit.receive",
+       notes           => <<"  NOTES");
+       NOTES
+
+# status 3 means that this transit is destined for somewhere else
+sub transit_receive {
+       my( $self, $client, $login_session, $copyid ) = @_;
+
+       my $user = $apputils->check_user_session($login_session);
+
+       my $session = $apputils->start_db_session();
+       my $copy = _grab_copy_by_id($session, $copyid);
+       my $transit;
+
+       if(!$copy->status eq "6") {
+               throw OpenSRF::EX::ERROR ("Copy is not in transit");
+       }
+
+       $transit = $session->request(
+               "open-ils.storage.direct.action.transit_copy.search_where",
+               { target_copy => $copy->id, dest_recv_time => undef } )->gather(1);
+
+       if($transit) {
+
+               if($transit->dest ne $user->home_ou) {
+                       return { status => 3, route_to => $transit->dest };
+               }
+
+               $transit->dest_recv_time("now");
+               my $s = $session->request(
+                       "open-ils.storage.direct.action.transit_copy.update",
+                       $transit );
+
+               my $holdtransit = $session->request(
+                       "open-ils.storage.direct.action.hold_transit_copy.retrieve",
+                       $transit->id );
+
+               if($holdtransit) {
+
+                       my $hold = $session->request(
+                               "open-ils.storage.direct.action.hold_request.retrieve",
+                               $holdtransit->hold )->gather(1);
+                       $copy->status(8); #hold shelf status
+
+                       my $s = $session->request(
+                               "open-ils.storage.direct.asset.copy.update", $copy )->gather(1);
+                       if(!$s) {} # blah..
+
+                       return { status => 0, route_to => $hold->pickup_lib };
+               }
+
+       } else { } #message...
+
+}
+
+
 
 __PACKAGE__->register_method(
        method  => "checkin",
@@ -628,7 +686,7 @@ __PACKAGE__->register_method(
        NOTES
 
 sub checkin {
-       my( $self, $client, $user_session, $barcode, $isrenewal ) = @_;
+       my( $self, $client, $user_session, $barcode, $isrenewal, $backdate ) = @_;
 
        my $err;
        my $copy;
@@ -641,19 +699,15 @@ sub checkin {
                return OpenILS::Perm->new("COPY_CHECKIN");
        }
 
+       my $session = $apputils->start_db_session();
+
+
+
        try {
-               my $session = $apputils->start_db_session();
                        
                warn "retrieving copy for checkin\n";
 
-               if(!$shelving_locations) {
-                       my $sh_req = $session->request(
-                               "open-ils.storage.direct.asset.copy_location.retrieve.all.atomic");
-                       $shelving_locations = $sh_req->gather(1);
-                       $shelving_locations = 
-                               { map { (''.$_->id => $_->name) } @$shelving_locations };
-               }
-       
+                       
                my $copy_req = $session->request(
                        "open-ils.storage.direct.asset.copy.search.barcode.atomic", 
                        $barcode );
@@ -662,8 +716,21 @@ sub checkin {
                        $client->respond_complete(OpenILS::EX->new("UNKNOWN_BARCODE")->ex);
                }
 
-               
+               if($copy->status eq "6") { #copy is in transit, deal with it
+                       my $method = $self->method_lookup("open-ils.circ.transit.receive");
+                       return $method->run( $user_session, $copy->id );
+               }
 
+
+               if(!$shelving_locations) {
+                       my $sh_req = $session->request(
+                               "open-ils.storage.direct.asset.copy_location.retrieve.all.atomic");
+                       $shelving_locations = $sh_req->gather(1);
+                       $shelving_locations = 
+                               { map { (''.$_->id => $_->name) } @$shelving_locations };
+               }
+
+               
                $copy->status(0);
        
                # find circ's where the transaction is still open for the
@@ -699,7 +766,6 @@ sub checkin {
                                $circ );
                        $ci_up->gather(1);
                
-                       $apputils->commit_db_session($session);
                
                        warn "Checkin succeeded\n";
                }
@@ -718,19 +784,19 @@ sub checkin {
                my $status = "0";
                my $status_text = "OK";
 
-               # check to see if the copy is needed to fulfil a hold
-               my $r = $apputils->simple_scalar_request(
-                       "open-ils.storage", 
-                       "open-ils.storage.direct.action.hold_copy_map.search.target_copy.atomic",
-                       $copy->id );
+               # see if this copy can fulfill a hold
+               my $hold = OpenILS::Application::Circ::Holds::_find_local_hold_for_copy( $session, $copy, $user );
 
-               if(@$r != 0) { 
-                       if( $user->id ne $circ->usr ) {
-                               $status = "1";
-                               $status_text = "Copy needed to fulfill hold";
-                       }
+               my $route_to = $shelving_locations->{$copy->location} 
+
+               if($hold) { 
+                       $status = "1";
+                       $status_text = "Copy needed to fulfill hold";
+                       $route_to = $hold->pickup_lib;
                }
        
+               $apputils->commit_db_session($session);
+
                my $record = $apputils->simple_scalar_request(
                        "open-ils.storage",
                        "open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy",
@@ -746,7 +812,7 @@ sub checkin {
                        text => $status_text,
                        circ => $circ,
                        copy => $copy,
-                       route_to => $shelving_locations->{$copy->location} 
+                       route_to => $routet_to,
                };
        }
 
index 6db704d..276f517 100644 (file)
@@ -19,6 +19,7 @@ my %ex_types = (
        UNKNOWN_USER                                                    => 8, 
        MAX_RENEWALS_REACHED                                    => 9,
        COPY_NEEDED_FOR_HOLD                                    => 10,
+       NO_HOLD_FOUND                                                   => 11,
 );
 
 use overload ( '""' => sub { $_[0]->ex()->err_msg(); } );
index 68b6fa8..b2c606a 100644 (file)
@@ -42,6 +42,9 @@
        IF type == ex_types.COPY_NEEDED_FOR_HOLD;
                ret("Copy is needed to fulfill a hold"); END;
 
+       IF type == ex_types.NO_HOLD_FOUND;
+               ret("The requested hold could not be found"); END;
+
        ret("Unknown exception occured");
 
 -%]