(sitka) [rt16512] Removed incorrectly scopped 856 $9 items user/lwhalen/rt16512
authorLiam Whalen <liam.whalen@bc.libraries.coop>
Tue, 2 Jul 2013 13:15:38 +0000 (06:15 -0700)
committerLiam Whalen <liam.whalen@bc.libraries.coop>
Wed, 23 Oct 2013 06:06:48 +0000 (23:06 -0700)
When doing a search in the staff client, the search will return
all items with items with 856 and $9 that are relevant to the search.
If none of a record's 856 $9 values are in the current library search
scope or in the prefered search library scope, then these items no longer
show up in the search results.

The funciton search.query_parser_fts prepares the search results
for the user.  By using the CONTINUE statement before a result
is added to the list to be returned, you can skip that result.

So, this fix looks for 856 $9 records that are not in scope and
skips over them, thereby removing them from the search results.

(sitka) [rt16512] Updated to fix errors with the original fix

My original fix excluded some important code for ebooks that were
included in the search.  In the original fix, the code that looked at
ebooks for staff only discarded ebooks that were not in scope.  However
it should have also executed some code on ebooks that were found.

This fix makes the necessary changes to do that.  This means, clicking
on Limit to Available items in the Staff Client will show in scope
ebooks.  With the old version of the fix, it did not do that.

(sitka) [rt16512] added robbat2's optimization

robbat2 looked over my changes to make sure everything was in order
and he noticed I was executing the same query twice to no effect.
So, as he suggested, I eliminated the duplicate query, which will
improve the speed of this fix.

(sitka) [rt16512] Another opimization

I realized the function could be improved more by the ellimination
of another IF statement.  This commit does that.

(sitka) [rt16512] Kept optimizations readded limit available hiding

Supprt requested that choosing the Limit to Available option hide
ebooks.  This patch allows that while maintianing the optimizations
added earlier.  The section of code that removes ebooks when limiting to
available is the part that looks for a value in param_status.

param_status is checked against the status value in asset.copy to
determine if the item is available or not.  In order to maintain
the opitmizations and eliminate ebooks when limiting to available, I had
to move the section of code that checks for availablity above the
section of code that checks for ebooks.

By doing this, all the ebooks are removed from the results by the
section that checks for availabilty (because they have no copies and no
    copy statues) before the section that checks for ebooks is executed.

Additionally, support requested that ebooks be hidden from the consortia
and federation levels.  By default this patch does that.  However, if an
ebook has a federation short code in the $9 value of an 856, that ebook
will return for searches scoped at that federation.

Allow eBooks to show up at Sitka and Fed level searches

Moved changes from temp file to acutal file

Fixed a comment

Fixed Federation level scoping

Fed level scoping was including all Sitka items.

This returns only ebooks within the Federation.  This is ok because
the noraml method is to return all eBooks at the search_ou or higher in
the org tree, but in the case of a Federation, the only thing higher is
Sitka, so we do not want to return those items in this case.

Conflicts:

Open-ILS/src/sql/Pg/300.schema.staged_search.sql

Open-ILS/src/sql/Pg/300.schema.staged_search.sql

index c87691c..a3e73ac 100644 (file)
@@ -54,6 +54,7 @@ DECLARE
     search_org_list     INT[];
     luri_org_list       INT[];
     tmp_int_list        INT[];
+    search_ou_parents   INT[];
 
     check_limit         INT;
     core_limit          INT;
@@ -70,6 +71,8 @@ DECLARE
     visible_count       INT := 0;
     excluded_count      INT := 0;
 
+    is_top_level_ou     BOOL := FALSE;
+    is_federation_ou    BOOL := FALSE;
 BEGIN
 
     check_limit := COALESCE( param_check, 1000 );
@@ -77,6 +80,15 @@ BEGIN
     core_offset := COALESCE( param_offset, 0 );
 
     -- core_skip_chk := COALESCE( param_skip_chk, 1 );
+    -- might need to make sure param_search_ou is positive
+
+    SELECT array_accum(distinct id) INTO search_ou_parents FROM actor.org_unit_ancestors( param_search_ou );
+
+    IF array_length(search_ou_parents, 1) = 1 THEN
+        is_top_level_ou := TRUE;
+    ELSIF array_length(search_ou_parents, 1) = 2 THEN
+        is_federation_ou := TRUE;
+    END IF;
 
     IF param_search_ou > 0 THEN
         IF param_depth IS NOT NULL THEN
@@ -189,19 +201,34 @@ BEGIN
 
             END IF;
 
-            PERFORM 1
-              FROM  asset.call_number cn
-                    JOIN asset.uri_call_number_map map ON (map.call_number = cn.id)
-                    JOIN asset.uri uri ON (map.uri = uri.id)
-              WHERE NOT cn.deleted
-                    AND cn.label = '##URI##'
-                    AND uri.active
-                    AND ( param_locations IS NULL OR array_upper(param_locations, 1) IS NULL )
-                    AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
-                    AND cn.owning_lib IN ( SELECT * FROM unnest( luri_org_list ) )
-              LIMIT 1;
+            IF is_federation_ou THEN
+                PERFORM 1
+                  FROM  asset.call_number cn
+                        JOIN asset.uri_call_number_map map ON (map.call_number = cn.id)
+                        JOIN asset.uri uri ON (map.uri = uri.id)
+                  WHERE NOT cn.deleted
+                        AND cn.label = '##URI##'
+                        AND uri.active
+                        AND ( param_locations IS NULL OR array_upper(param_locations, 1) IS NULL )
+                        AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
+                        AND cn.owning_lib IN ( SELECT * FROM unnest( search_org_list ) )
+                  LIMIT 1;
+            ELSE
+                PERFORM 1
+                  FROM  asset.call_number cn
+                        JOIN asset.uri_call_number_map map ON (map.call_number = cn.id)
+                        JOIN asset.uri uri ON (map.uri = uri.id)
+                  WHERE NOT cn.deleted
+                        AND cn.label = '##URI##'
+                        AND uri.active
+                        AND ( param_locations IS NULL OR array_upper(param_locations, 1) IS NULL )
+                        AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
+                        AND cn.owning_lib IN ( SELECT * FROM unnest( luri_org_list ) )
+                  LIMIT 1;
+            END IF;
 
-            IF FOUND THEN
+            -- keep the records if this is a search scoped to Sitka or a Federation
+            IF FOUND OR is_top_level_ou THEN
                 -- RAISE NOTICE ' % have at least one URI ... ', core_result.records;
                 visible_count := visible_count + 1;
 
@@ -386,5 +413,4 @@ BEGIN
 END;
 $func$ LANGUAGE PLPGSQL;
 
 COMMIT;