From 74c15038fe70697c4feca0e0c225d943656a3a70 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 Signed-off-by: Jason Stephenson --- .../lib/OpenILS/WWW/EGCatLoader/Account.pm | 113 +++++++++++++++--- .../src/templates/opac/parts/place_hold.tt2 | 34 +++--- .../opac/parts/place_hold_result.tt2 | 18 +++ 3 files changed, 129 insertions(+), 36 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 48a07d8046..30d2cbaacc 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm @@ -527,12 +527,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->generic_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")) { @@ -551,9 +553,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 { @@ -621,6 +656,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; @@ -638,11 +674,63 @@ 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); + } + + # NOTE: we are leaving the staff-placed patron barcode cookie + # in place. Otherwise, it's not possible to place more than + # one hold for the patron within a staff/patron session. This + # does leave the barcode to linger longer than is ideal, but + # normal staff work flow will cause the cookie to be replaced + # with each new patron anyway. + # TODO: See about getting the staff client to clear the cookie + + # return to the place_hold page so the results of the hold + # placement attempt can be reported to the user + return Apache2::Const::OK; +} + +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; @@ -653,11 +741,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) { @@ -667,7 +754,7 @@ sub load_place_hold { $e->authtoken, { patronid => $usr, pickup_lib => $pickup_lib, - hold_type => $ctx->{hold_type} + hold_type => $hold_type }, \@create_targets ); @@ -682,7 +769,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)) { @@ -714,18 +801,6 @@ sub load_place_hold { $bses->kill_me; } - - # NOTE: we are leaving the staff-placed patron barcode cookie - # in place. Otherwise, it's not possible to place more than - # one hold for the patron within a staff/patron session. This - # does leave the barcode to linger longer than is ideal, but - # normal staff work flow will cause the cookie to be replaced - # with each new patron anyway. - # TODO: See about getting the staff client to clear the cookie - - # return to the place_hold page so the results of the hold - # placement attempt can be reported to the user - return Apache2::Const::OK; } sub fetch_user_circs { diff --git a/Open-ILS/src/templates/opac/parts/place_hold.tt2 b/Open-ILS/src/templates/opac/parts/place_hold.tt2 index 4580b9cba4..adb14837be 100644 --- a/Open-ILS/src/templates/opac/parts/place_hold.tt2 +++ b/Open-ILS/src/templates/opac/parts/place_hold.tt2 @@ -43,6 +43,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 %] @@ -53,28 +70,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 f92c38f261..7b6585923a 100644 --- a/Open-ILS/src/templates/opac/parts/place_hold_result.tt2 +++ b/Open-ILS/src/templates/opac/parts/place_hold_result.tt2 @@ -35,6 +35,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.43.2