From 2c3ff4e4e4d2310ad8ea0ca1a1769cf93a420ab1 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Thu, 6 Oct 2011 14:34:03 -0400 Subject: [PATCH] TPac: holds placement on monographic parts Ability to place holds on monographic parts. In the holds placement form, if a record has parts, a parts selector will display in the form allowing the user to optionally specificy a monographic part for the hold. If a record has no non-part copies, the user is required to select a part, because, in such cases, the hold cannot be fulfilled without selecting a part. Signed-off-by: Bill Erickson --- .../lib/OpenILS/WWW/EGCatLoader/Account.pm | 105 +++++++++++++++++---- Open-ILS/src/templates/opac/parts/place_hold.tt2 | 34 +++---- .../src/templates/opac/parts/place_hold_result.tt2 | 18 ++++ 3 files changed, 124 insertions(+), 33 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm index b63f89a32c..c4cff3369a 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm @@ -500,12 +500,14 @@ sub load_place_hold { $self->ctx->{page} = 'place_hold'; my @targets = $cgi->param('hold_target'); + my @parts = $cgi->param('part'); + $ctx->{hold_type} = $cgi->param('hold_type'); $ctx->{default_pickup_lib} = $e->requestor->home_ou; # unless changed below return $self->post_hold_redirect unless @targets; - $logger->info("Looking at hold targets: @targets"); + $logger->info("Looking at hold_type: " . $ctx->{hold_type} . " and targets: @targets"); # if the staff client provides a patron barcode, fetch the patron if (my $bc = $self->cgi->cookie("patron_barcode")) { @@ -524,9 +526,42 @@ sub load_place_hold { my $type_dispatch = { T => sub { my $recs = $e->batch_retrieve_biblio_record_entry(\@targets, {substream => 1}); + for my $id (@targets) { # force back into the correct order my ($rec) = grep {$_->id eq $id} @$recs; - push(@hold_data, {target => $rec, record => $rec}); + + # NOTE: if tpac ever supports locked-down pickup libs, + # we'll need to pass a pickup_lib param along with the + # record to filter the set of monographic parts. + my $parts = $U->simplereq( + 'open-ils.search', + 'open-ils.search.biblio.record_hold_parts', + {record => $rec->id} + ); + + # T holds on records that have parts are OK, but if the record has + # no non-part copies, the hold will ultimately fail. When that + # happens, require the user to select a part. + my $part_required = 0; + if (@$parts) { + my $np_copies = $e->json_query({ + select => { acp => [{column => 'id', transform => 'count', alias => 'count'}]}, + from => {acp => {acn => {}, acpm => {type => 'left'}}}, + where => { + '+acp' => {deleted => 'f'}, + '+acn' => {deleted => 'f', record => $rec->id}, + '+acpm' => {id => undef} + } + }); + $part_required = 1 if $np_copies->[0]->{count} == 0; + } + + push(@hold_data, { + target => $rec, + record => $rec, + parts => $parts, + part_required => $part_required + }); } }, V => sub { @@ -594,6 +629,7 @@ sub load_place_hold { $ctx->{orig_params} = $cgi->Vars; delete $ctx->{orig_params}{submit}; delete $ctx->{orig_params}{hold_target}; + delete $ctx->{orig_params}{part}; my $usr = $e->requestor->id; @@ -611,11 +647,58 @@ sub load_place_hold { } } + # target_id is the true target_id for holds placement. + # needed for attempt_hold_placement() + # With the exception of P-type holds, target_id == target->id. + $_->{target_id} = $_->{target}->id for @hold_data; + + if ($ctx->{hold_type} eq 'T') { + + # Much like quantum wave-particles, P-type holds pop into + # and out of existence at the user's whim. For our purposes, + # we treat such holds as T(itle) holds with a selected_part + # designation. When the time comes to pass the hold information + # off for holds possibility testing and placement, make it look + # like a real P-type hold. + my (@p_holds, @t_holds); + + for my $idx (0..$#parts) { + my $hdata = $hold_data[$idx]; + if (my $part = $parts[$idx]) { + $hdata->{target_id} = $part; + $hdata->{selected_part} = $part; + push(@p_holds, $hdata); + } else { + push(@t_holds, $hdata); + } + } + + $self->attempt_hold_placement($usr, $pickup_lib, 'P', @p_holds) if @p_holds; + $self->attempt_hold_placement($usr, $pickup_lib, 'T', @t_holds) if @t_holds; + + } else { + $self->attempt_hold_placement($usr, $pickup_lib, $ctx->{hold_type}, @hold_data); + } + + # stay on the current page and display the results + return Apache2::Const::OK if + (grep {$_->{hold_failed}} @hold_data) or $ctx->{general_hold_error}; + + return $self->post_hold_redirect; +} + + +sub attempt_hold_placement { + my ($self, $usr, $pickup_lib, $hold_type, @hold_data) = @_; + my $cgi = $self->cgi; + my $ctx = $self->ctx; + my $e = $self->editor; + # First see if we should warn/block for any holds that # might have locally available items. for my $hdata (@hold_data) { my ($local_block, $local_alert) = $self->local_avail_concern( - $hdata->{target}->id, $ctx->{hold_type}, $pickup_lib); + $hdata->{target_id}, $hold_type, $pickup_lib); if ($local_block) { $hdata->{hold_failed} = 1; @@ -626,11 +709,10 @@ sub load_place_hold { } } - my $method = 'open-ils.circ.holds.test_and_create.batch'; $method .= '.override' if $cgi->param('override'); - my @create_targets = map {$_->{target}->id} (grep { !$_->{hold_failed} } @hold_data); + my @create_targets = map {$_->{target_id}} (grep { !$_->{hold_failed} } @hold_data); if(@create_targets) { @@ -640,7 +722,7 @@ sub load_place_hold { $e->authtoken, { patronid => $usr, pickup_lib => $pickup_lib, - hold_type => $ctx->{hold_type} + hold_type => $hold_type }, \@create_targets ); @@ -655,7 +737,7 @@ sub load_place_hold { last; } - my ($hdata) = grep {$_->{target}->id eq $resp->{target}} @hold_data; + my ($hdata) = grep {$_->{target_id} eq $resp->{target}} @hold_data; my $result = $resp->{result}; if ($U->event_code($result)) { @@ -681,15 +763,6 @@ sub load_place_hold { $bses->kill_me; } - - # stay on the current page and display the results - return Apache2::Const::OK if - (grep {$_->{hold_failed}} @hold_data) or $ctx->{general_hold_error}; - - # if successful, do some cleanup and return the - # user to the requesting page. - - return $self->post_hold_redirect; } sub post_hold_redirect { diff --git a/Open-ILS/src/templates/opac/parts/place_hold.tt2 b/Open-ILS/src/templates/opac/parts/place_hold.tt2 index 6da63da8fd..a94d9188dc 100644 --- a/Open-ILS/src/templates/opac/parts/place_hold.tt2 +++ b/Open-ILS/src/templates/opac/parts/place_hold.tt2 @@ -46,6 +46,23 @@
[% attrs.title_extended | html %]
+ [% IF hdata.parts %] + [% IF hdata.parts.size > 0 %] +
+ [% hdata.part_required ? l('Select a Part:') : l('Select a Part (optional):') %] + +
+ [% ELSE %] + + [% END %] + [% END %] [% END %] @@ -56,28 +73,11 @@ [% PROCESS "opac/parts/org_selector.tt2"; PROCESS build_org_selector name='pickup_lib' value=ctx.default_pickup_lib id='pickup_lib' can_have_vols_only=1 %]

-

- [% |l %]If you use the Traveling Library Center (TLC) and ABC Express - services, please select "Outreach" to have the item delivered - during your scheduled visit.[% END %] -

       -

-

- [% |l %]* If you need your item today, and it is checked in at your - library, please place your hold and then call your library to set it - aside. Placing a hold without calling the library will increase your - wait time.[% END %] -
[% l('Library phone numbers.') %] -

-

- [% |l %]* For best possible service, we recommend keeping - a printed copy of your most recent holds list.[% END %] -

diff --git a/Open-ILS/src/templates/opac/parts/place_hold_result.tt2 b/Open-ILS/src/templates/opac/parts/place_hold_result.tt2 index b83a81129c..5ca46e75a2 100644 --- a/Open-ILS/src/templates/opac/parts/place_hold_result.tt2 +++ b/Open-ILS/src/templates/opac/parts/place_hold_result.tt2 @@ -34,6 +34,24 @@
[% attrs.title_extended | html %]
+ [% IF hdata.parts %] + [% IF hdata.parts.size > 0 %] +
+ [% hdata.part_required ? l('Select a Part:') : l('Select a Part (optional):') %] + +
+ [% ELSE %] + + [% END %] + [% END %]
[% IF hdata.hold_success %] -- 2.11.0