From: Lebbeous Fogle-Weekley Date: Tue, 6 Mar 2012 22:51:56 +0000 (-0500) Subject: Fetch data on units for holdings, if asked to do so X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=622d04fafc36dfa8c380b0b107c6ee35de8b9c3d;p=evergreen%2Fequinox.git Fetch data on units for holdings, if asked to do so So the TPAC can display them (to come) Signed-off-by: Lebbeous Fogle-Weekley --- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm index b3777c2a44..c47d51ce2b 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm @@ -1943,5 +1943,111 @@ sub bib_container_items_via_search { return [map { $ordering_hash{$_} } @$id_list]; } + +# I hate to put this here exactly, but this code needs to be shared between +# the TPAC's mod_perl module and open-ils.serial. +# +# There is a reason every part of the query *except* those parts dealing +# with scope are moved here from the code's origin in TPAC. The serials +# use case does *not* want the same scoping logic. +# +# Also, note that for the serials uses case, we may filter in OPAC visible +# status and copy/call_number deletedness, but we don't filter on any +# particular values for serial.item.status or serial.item.date_received. +# Since we're only using this *after* winnowing down the set of issuances +# that copies should be related to, I'm not sure we need any such serial.item +# filters. + +sub basic_opac_copy_query { + # Pass a defined value for $rec_id OR $iss_id, not both. + my ($self, $rec_id, $iss_id, $copy_limit, $copy_offset, $staff) = @_; + + return { + select => { + acp => ['id', 'barcode', 'circ_lib', 'create_date', + 'age_protect', 'holdable'], + acpl => [ + {column => 'name', alias => 'copy_location'}, + {column => 'holdable', alias => 'location_holdable'} + ], + ccs => [ + {column => 'name', alias => 'copy_status'}, + {column => 'holdable', alias => 'status_holdable'} + ], + acn => [ + {column => 'label', alias => 'call_number_label'}, + {column => 'id', alias => 'call_number'} + ], + circ => ['due_date'], + acnp => [ + {column => 'label', alias => 'call_number_prefix_label'}, + {column => 'id', alias => 'call_number_prefix'} + ], + acns => [ + {column => 'label', alias => 'call_number_suffix_label'}, + {column => 'id', alias => 'call_number_suffix'} + ], + bmp => [ + {column => 'label', alias => 'part_label'}, + ], + ($iss_id ? (sitem => ["issuance"]) : ()) + }, + + from => { + acp => { + ($iss_id ? ( + sitem => { + fkey => 'id', + field => 'unit', + filter => {issuance => $iss_id} + } + ) : ()), + acn => { + join => { + acnp => { fkey => 'prefix' }, + acns => { fkey => 'suffix' } + }, + filter => [ + {deleted => 'f'}, + ($rec_id ? {record => $rec_id} : ()) + ], + }, + circ => { # If the copy is circulating, retrieve the open circ + type => 'left', + filter => {checkin_time => undef} + }, + acpl => { + ($staff ? () : (filter => { opac_visible => 't' })) + }, + ccs => { + ($staff ? () : (filter => { opac_visible => 't' })) + }, + aou => {}, + acpm => { + type => 'left', + join => { + bmp => { type => 'left' } + } + } + } + }, + + where => { + '+acp' => { + deleted => 'f', + ($staff ? () : (opac_visible => 't')) + } + }, + + order_by => [ + {class => 'aou', field => 'name'}, + {class => 'acn', field => 'label'} + ], + + limit => $copy_limit, + offset => $copy_offset + }; +} + 1; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm index b1722722df..6ccf7d1cf3 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm @@ -718,8 +718,6 @@ sub _find_ou_in_holdings_tree { return; } -# XXX deprecate/replace scoped_bib_holdings_summary - sub scoped_holding_summary_tree_for_bib { my ( $self, $client, $bib, $org_unit, $depth, $limit, $offset, $ascending @@ -917,13 +915,42 @@ sub _get_deepest_holding_level { } # This is a helper for grouped_holdings_for_summary() later. +sub _opac_visible_unit_data { + my ($issuance_id_list, $staff, $e) = @_; + + my $rows = $e->json_query( + $U->basic_opac_copy_query( + undef, $issuance_id_list, + 1000, 0, # XXX no mechanism for users to page at this level yet + $staff + ) + ) or return $e->die_event; + + my $results = {}; + + # Take the list of rows returned from json_query() and sort results into + # several smaller lists stored in a hash keyed by issuance ID. + foreach my $row (@$rows) { + $results->{$row->{issuance}} = [] unless + exists $results->{$row->{issuance}}; + push @{ $results->{$row->{issuance}} }, $row; + } + + return $results; +} + +# This is a helper for grouped_holdings_for_summary() later. sub _make_grouped_holding_node { - my ($row, $subfield, $deepest_level, $pattern_field, $mfhd_cache) = @_; + my ( + $row, $subfield, $deepest_level, $pattern_field, + $unit_data, $mfhd_cache + ) = @_; return { $subfield eq $deepest_level ? ( label => $row->{label}, - holding => $row->{id} + holding => $row->{id}, + ($unit_data ? (units => ($unit_data->{$row->{id}} || [])) : ()) ) : ( value => $row->{value}, label => _label_holding_level( @@ -936,7 +963,7 @@ sub _make_grouped_holding_node { sub grouped_holdings_for_summary { my ( $self, $client, $summary_type, $summary_id, - $expand_path, $limit, $offsets, $auto_expand_first + $expand_path, $limit, $offsets, $auto_expand_first, $with_units ) = @_; # Validate input or set defaults. @@ -1104,11 +1131,22 @@ sub grouped_holdings_for_summary { # _label_holding_level() to see what I mean. my $mfhd_cache = {}; + # Prepare related unit data if appropriate. + my $unit_data; + + if ($with_units and $subfield eq $deepest_level) { + $unit_data = _opac_visible_unit_data( + [map { $_->{id} } @$top], $with_units > 1, $e + ); + return $unit_data if defined $U->event_code($unit_data); + } + # Make the tree we have so far. my $tree = [ map( _make_grouped_holding_node( - $_, $subfield, $deepest_level, $pattern_field, $mfhd_cache + $_, $subfield, $deepest_level, $pattern_field, + $unit_data, $mfhd_cache ), @$top ), ($top_more ? undef : ()) @@ -1190,11 +1228,20 @@ sub grouped_holdings_for_summary { # Find attachment point for our results. my ($point) = grep { ref $_ and $_->{value} eq $value } @$parent; + # Prepare related unit data if appropriate. + if ($with_units and $subfield eq $deepest_level) { + $unit_data = _opac_visible_unit_data( + [map { $_->{id} } @$level], $with_units > 1, $e + ); + return $unit_data if defined $U->event_code($unit_data); + } + # Set parent for the next iteration. $parent = $point->{children} = [ map( _make_grouped_holding_node( - $_, $subfield, $deepest_level, $pattern_field, $mfhd_cache + $_, $subfield, $deepest_level, $pattern_field, + $unit_data, $mfhd_cache ), @$level ), ($level_more ? undef : ()) @@ -1210,19 +1257,31 @@ __PACKAGE__->register_method( method => "grouped_holdings_for_summary", api_name => "open-ils.serial.holdings.grouped_by_summary", api_level => 1, - argc => 6, + argc => 7, signature => { desc => q/Return a tree of holdings associated with a given summary grouped by all but the last of either chron or enum units./, params => [ { name => "summary_type", type => "string" }, { name => "summary_id", type => "number" }, - { name => "expand_path", type => "array" }, + { name => "expand_path", type => "array", + desc => "In root-to-leaf order, the values of the nodes along the axis you want to expand" }, { name => "limit (default 10)", type => "number" }, { name => "offsets", type => "array", desc => "This must be exactly one element longer than expand_path" }, { name => "auto_expand_first", type => "boolean", desc => - "Only if expand_path is empty, automatically expand first top-level grouping" } + "Only if expand_path is empty, automatically expand first top-level grouping" }, + { name => "with_units", type => "number", desc => q/ + If true at all, for each holding, if there are associated units, + add some information about them to the result tree. These units + will be filtered by OPAC visibility unless you provide a value + greater than 1. + + IOW: + 0 = no units, + 1 = opac visible units, + 2 = all units (i.e. staff view) + / } ] } ); diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm index 1110a0d24f..68739d6d62 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm @@ -131,72 +131,9 @@ sub mk_copy_query { my $copy_limit = shift; my $copy_offset = shift; - my $query = { - select => { - acp => ['id', 'barcode', 'circ_lib', 'create_date', 'age_protect', 'holdable'], - acpl => [ - {column => 'name', alias => 'copy_location'}, - {column => 'holdable', alias => 'location_holdable'} - ], - ccs => [ - {column => 'name', alias => 'copy_status'}, - {column => 'holdable', alias => 'status_holdable'} - ], - acn => [ - {column => 'label', alias => 'call_number_label'}, - {column => 'id', alias => 'call_number'} - ], - circ => ['due_date'], - acnp => [ - {column => 'label', alias => 'call_number_prefix_label'}, - {column => 'id', alias => 'call_number_prefix'} - ], - acns => [ - {column => 'label', alias => 'call_number_suffix_label'}, - {column => 'id', alias => 'call_number_suffix'} - ], - bmp => [ - {column => 'label', alias => 'part_label'}, - ] - }, - - from => { - acp => { - acn => { - join => { - acnp => { fkey => 'prefix' }, - acns => { fkey => 'suffix' } - }, - filter => [{deleted => 'f'}, {record => $rec_id}], - }, - circ => { # If the copy is circulating, retrieve the open circ - type => 'left', - filter => {checkin_time => undef} - }, - acpl => {}, - ccs => {}, - aou => {}, - acpm => { - type => 'left', - join => { - bmp => { type => 'left' } - } - } - } - }, - - where => { - '+acp' => {deleted => 'f' } - }, - - order_by => [ - {class => 'aou', field => 'name'}, - {class => 'acn', field => 'label'} - ], - - limit => $copy_limit, - offset => $copy_offset - }; + my $query = $U->basic_opac_copy_query( + $rec_id, undef, $copy_limit, $copy_offset, $self->ctx->{is_staff} + ); # XXX In the future, $sort_org should be understood to be an abstration # that refers to something configurable, not necessariyl physical_loc. @@ -230,13 +167,6 @@ sub mk_copy_query { } }; - # Filter hidden items if this is the public catalog - unless($self->ctx->{is_staff}) { - $query->{where}->{'+acp'}->{opac_visible} = 't'; - $query->{from}->{'acp'}->{'acpl'}->{filter} = {opac_visible => 't'}; - $query->{from}->{'acp'}->{'ccs'}->{filter} = {opac_visible => 't'}; - } - return $query; }