From 4fd1049560e576b09f2a1a3fa9c3bd271a03c9ee Mon Sep 17 00:00:00 2001 From: erickson Date: Wed, 20 Jul 2005 22:12:31 +0000 Subject: [PATCH] more holds capturing, transits, etc. git-svn-id: svn://svn.open-ils.org/ILS/trunk@1322 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/src/perlmods/OpenILS/Application/Actor.pm | 19 ++-- .../src/perlmods/OpenILS/Application/Circ/Holds.pm | 102 ++++++++++++------- .../src/perlmods/OpenILS/Application/Circ/Rules.pm | 112 ++++++++++++++++----- Open-ILS/src/perlmods/OpenILS/EX.pm | 1 + Open-ILS/src/templates/strings/ex.ttk | 3 + 5 files changed, 174 insertions(+), 63 deletions(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm b/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm index 11f6050b27..92fdc05ac0 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm @@ -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 ) = @_; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm index 9e0bac125e..d5eea381cc 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm @@ -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); } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Rules.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Rules.pm index 498848bdfe..ff6762081d 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Rules.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Rules.pm @@ -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, }; } diff --git a/Open-ILS/src/perlmods/OpenILS/EX.pm b/Open-ILS/src/perlmods/OpenILS/EX.pm index 6db704d011..276f517775 100644 --- a/Open-ILS/src/perlmods/OpenILS/EX.pm +++ b/Open-ILS/src/perlmods/OpenILS/EX.pm @@ -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(); } ); diff --git a/Open-ILS/src/templates/strings/ex.ttk b/Open-ILS/src/templates/strings/ex.ttk index 68b6fa8396..b2c606a6b5 100644 --- a/Open-ILS/src/templates/strings/ex.ttk +++ b/Open-ILS/src/templates/strings/ex.ttk @@ -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"); -%] -- 2.11.0