}
);
+# 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,
# 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
# 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"]
join => {
siss => {
join => {
- scap => {},
- "smhc_$subfield" => {
- class => "smhc"
- }
+ scap => {}, %subfield_joins
}
}
}
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)),
]
}) 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(