From 96951e34054e888bbba40ab34a97a092b73afcff Mon Sep 17 00:00:00 2001 From: Lebbeous Fogle-Weekley Date: Thu, 1 Mar 2012 18:06:15 -0500 Subject: [PATCH] progress Signed-off-by: Lebbeous Fogle-Weekley --- Open-ILS/src/extras/ils_events.xml | 5 + .../src/perlmods/lib/OpenILS/Application/Serial.pm | 154 +++++++++++++++++++-- 2 files changed, 144 insertions(+), 15 deletions(-) diff --git a/Open-ILS/src/extras/ils_events.xml b/Open-ILS/src/extras/ils_events.xml index 59ff421751..a1c9ac337a 100644 --- a/Open-ILS/src/extras/ils_events.xml +++ b/Open-ILS/src/extras/ils_events.xml @@ -996,6 +996,11 @@ Checkin attempted on item during minimum transit checkin interval. + + A serial pattern code has been configured + that fails to conform to MFHD standards for fields 853-855. + + diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm index 0eefc07f4e..ece120b151 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm @@ -857,6 +857,28 @@ __PACKAGE__->register_method( } ); +# This is a helper for grouped_holdings_for_summary() later. +sub _label_holding_level { + my ($pattern_code, $subfield, $value) = @_; + + return $value; # XXX TODO +} + +# This is a helper for grouped_holdings_for_summary() later. +sub _get_deepest_holding_level { + my ($display_grouping, $pattern_code) = @_; + + my $field = new MARC::Field( + "999", @{ OpenSRF::Utils::JSON->JSON2perl($pattern_code) } + ); + + my @subfields = @{ $MFHD_SUMMARIZED_SUBFIELDS{$display_grouping} }; + + my @present = grep { $field->subfield($_) } @subfields; + + return pop @present; +} + sub grouped_holdings_for_summary { my ( $self, $client, $summary_type, $summary_id, @@ -906,9 +928,8 @@ sub grouped_holdings_for_summary { # And now we know which subfields we care about from # serial.materialized_holding_code. - my @subfields = @{ - $MFHD_SUMMARIZED_SUBFIELDS{$row->[0]->{display_grouping}} - }; + my $display_grouping = $row->[0]->{display_grouping}; + my @subfields = @{ $MFHD_SUMMARIZED_SUBFIELDS{$display_grouping} }; # We look for holdings grouped at the top level once no matter what, # then we'll look deeper with additional queries for every element of @@ -917,14 +938,11 @@ sub grouped_holdings_for_summary { # potentially reuse if $expand_path has elements. my $subfield = shift @subfields; -# my %holding_leaf_select = ( -# siss => [qw/id label date_published/], - - my %deep_joins = ( - ); + my %subfield_joins = ("smhc_$subfield" => {class => "smhc"}); + my %subfield_where_clauses = ("+smhc_$subfield" => {subfield => $subfield}); # Now get the top level of holdings. - my $holdings = $e->json_query({ + my $top = $e->json_query({ select => { "smhc_$subfield" => ["value"], scap => ["pattern_code"] @@ -939,10 +957,7 @@ sub grouped_holdings_for_summary { join => { siss => { join => { - scap => {}, - "smhc_$subfield" => { - class => "smhc" - } + scap => {}, %subfield_joins } } } @@ -956,7 +971,7 @@ sub grouped_holdings_for_summary { where => { "+$summary_hint" => {id => $summary_id}, "+sitem" => {date_received => {"!=" => undef}}, - "+smhc_$subfield" => {subfield => $subfield} + %subfield_where_clauses }, distinct => 1, # sic, this goes here in json_query limit => int(shift(@$limits)), @@ -967,10 +982,119 @@ sub grouped_holdings_for_summary { ] }) or return $e->die_event; + # Unless data has been disarranged, all holdings grouped together under + # the same summary should have the same pattern code, so we can take any + # result from the set we just got. + + my $pattern_code = $top->[0]->{pattern_code}; + + # Make the tree we have so far. + my $tree = [ + map { + +{ + value => $_->{value}, + label => + _label_holding_level($pattern_code, $subfield, $_->{value}) + }; + } @$top + ]; + # Ok, that got us the top level, with nothing expanded. Now we loop through # the deeper levels of @$expand_path, issuing similar queries to get us # lower groupings and even actual specific holdings. - return $holdings; + + # This will tell us when to stop grouping and start showing actual + # holdings. + my $deepest_level = + _get_deepest_holding_level($display_grouping, $pattern_code); + if (not defined $deepest_level) { + # corrupt pattern code + my $msg = "couldn't determine deepest holding level for " . + "$summary_type summary #$summary_id"; + $logger->warn($msg); + return new OpenILS::Event("SERIAL_CORRUPT_PATTERN_CODE", note => $msg); + } + + $logger->debug( + "deepest holding level for $summary_type summary " . + "#$summary_id is $deepest_level" + ); + + my $parent = $tree; + + foreach my $value (@$expand_path) { + my $prev_subfield = $subfield; + $subfield = shift @subfields; + + # This wad of JOINs is additive over each iteration. + $subfield_joins{"smhc_$subfield"} = {class => "smhc"}; + + # The WHERE clauses also change and grow each time. + $subfield_where_clauses{"+smhc_$prev_subfield"}->{value} = $value; + $subfield_where_clauses{"+smhc_$subfield"}->{subfield} = $subfield; + + my $level = $e->json_query({ + select => { + "smhc_$subfield" => ["value"], ( + $subfield eq $deepest_level ? + (siss => [qw/id label date_published/]) : () + ) + }, + from => { + $summary_hint => { + sdist => { + join => { + sstr => { + join => { + sitem => { + join => { + siss => { + join => {%subfield_joins} + } + } + } + } + } + } + } + } + }, + where => { + "+$summary_hint" => {id => $summary_id}, + "+sitem" => {date_received => {"!=" => undef}}, + %subfield_where_clauses + }, + distinct => 1, # sic, this goes here in json_query + limit => int(shift(@$limits)), + offset => int(shift(@$offsets)), + order_by => [ + {class => "smhc_$subfield", field => "value", + direction => "descending"} + ] + }) or return $e->die_event; + + return $tree unless @$level; + + # Find attachment point for our results. + my ($point) = grep { $_->{value} eq $value } @$parent; + + # Set parent for the next iteration + $parent = $point->{children} = [ + map { + +{ + # XXX if on deepest level, show actual holdings + value => $_->{value}, + label => _label_holding_level( + $pattern_code, $subfield, $_->{value} + ) + }; + } @$level + ]; + + last if $subfield eq $deepest_level; + } + + return $tree; } __PACKAGE__->register_method( -- 2.11.0