LP#1549505: Teach QP and its caller how to use badges
authorMike Rylander <mrylander@gmail.com>
Fri, 22 Jan 2016 22:13:25 +0000 (17:13 -0500)
committerGalen Charlton <gmc@esilibrary.com>
Wed, 24 Feb 2016 22:37:58 +0000 (17:37 -0500)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm

index f08b1e5..3af02b5 100644 (file)
@@ -642,6 +642,7 @@ __PACKAGE__->add_search_filter( 'statuses' );
 __PACKAGE__->add_search_filter( 'locations' );
 __PACKAGE__->add_search_filter( 'location_groups' );
 __PACKAGE__->add_search_filter( 'bib_source' );
+__PACKAGE__->add_search_filter( 'badge_orgs' );
 __PACKAGE__->add_search_filter( 'site' );
 __PACKAGE__->add_search_filter( 'pref_ou' );
 __PACKAGE__->add_search_filter( 'lasso' );
@@ -830,12 +831,39 @@ sub toSQL {
     my $nullpos = 'NULLS LAST';
     $nullpos = 'NULLS FIRST' if ($self->find_modifier('nullsfirst'));
 
+    my $pop_join = '';
     if (grep {$_ eq $sort_filter} @{$self->QueryParser->dynamic_sorters}) {
         $rank = "FIRST((SELECT value FROM metabib.record_sorter rbr WHERE rbr.source = m.source and attr = '$sort_filter'))"
     } elsif ($sort_filter eq 'create_date') {
         $rank = "FIRST((SELECT create_date FROM biblio.record_entry rbr WHERE rbr.id = m.source))";
     } elsif ($sort_filter eq 'edit_date') {
         $rank = "FIRST((SELECT edit_date FROM biblio.record_entry rbr WHERE rbr.id = m.source))";
+    } elsif ($sort_filter =~ /^pop/) {
+        my ($bo_filter) = $self->find_filter('badge_orgs');
+        if ($bo_filter && @{$bo_filter->args}) {
+            my $borgs = join (',', grep /^\d+$/ @{$bo_filter->args});
+            if ($borgs) {
+                $pop_join = <<"                JOIN";
+                    LEFT JOIN (
+                        rating.badge rb
+                        JOIN rating.record_badge_score rbs ON (
+                            m.source = rbs.record
+                            AND rbs.badge = rb.id
+                            AND rb.scope = ANY ('{$borgs}')
+                        )
+                    )
+                JOIN
+                if ($sort_filter eq 'poprel') {
+                    $rank = $rel . ' * (1 + AVG(COALESCE(rbs.value::NUMERIC,0.0)) / 5.0)';
+                } else {
+                    $rank = 'AVG(COALESCE(rbs.value::NUMERIC,0.0))';
+                }
+            } else {
+                $rank = $rel;
+            }
+        } else {
+            $rank = $rel;
+        }
     } else {
         # default to rel ranking
         $rank = $rel;
@@ -876,6 +904,7 @@ SELECT  $key AS id,
         $mrv_join
         $bre_join
         $lang_join
+        $pop_join
   WHERE 1=1
         $flat_where
   GROUP BY 1
index fad6ef3..13886a6 100644 (file)
@@ -3144,7 +3144,50 @@ sub query_parser_fts_wrapper {
         if ($args{preferred_language_weight} and !$base_plan->parse_tree->find_filter('preferred_language_weight') and !$base_plan->parse_tree->find_filter('preferred_language_multiplier'));
 
 
+    my $borgs = undef;
+    my ($site_filter) = $base_plan->parse_tree->find_filter('site');
+    if ($site_filter && @{$site_filter->args}) {
+        my $cstore = OpenSRF::AppSession->create( 'open-ils.cstore' );
+        my $site;
+        $site = $cstore->request(
+            'open-ils.cstore.direct.actor.org_unit.search',
+            { parent_ou => undef }
+        )->gather(1) if ($site_filter->args->[0] eq '-');
+
+        $site = $cstore->request(
+            'open-ils.cstore.direct.actor.org_unit.search',
+            { shortname => $site_filter->args->[0] }
+        )->gather(1) unless ($site);
+
+        $site = $cstore->request(
+            'open-ils.cstore.direct.actor.org_unit.retrieve',
+            $args{org_unit}
+        )->gather(1) if (!$site and $args{org_unit});
+
+        if ($site) {
+            my ($depth_filter) = $base_plan->parse_tree->find_filter('depth');
+            if ($depth_filter && $depth_filter->args->[0] =~ /^\d+$/) {
+                $borgs = $cstore->request(
+                    'open-ils.cstore.json_query.atomic',
+                    { from => [ 'actor.org_unit_descendants', $site->id, $depth_filter->args->[0] ] }
+                )->gather(1);
+            } else {
+                $borgs = $cstore->request(
+                    'open-ils.cstore.json_query.atomic',
+                    { from => [ 'actor.org_unit_descendants', $site->id ] }
+                )->gather(1);
+            }
+
+            if (ref $borgs && @$borgs) {
+                $borgs = join(',', map { $_->{'actor.org_unit_descendants'} } @$borgs);
+            } else {
+                $borgs = undef;
+            }
+        }
+    }
+
     $query = "estimation_strategy($args{estimation_strategy}) $query" if ($args{estimation_strategy});
+    $query = "badge_orgs($borgs) $query" if ($borgs);
     $query = "site($args{org_unit}) $query" if ($args{org_unit});
     $query = "depth($args{depth}) $query" if (defined($args{depth}));
     $query = "sort($args{sort}) $query" if ($args{sort});