LP#1741997: bib counts in browse list now take visiblity into account
authorGalen Charlton <gmc@equinoxinitiative.org>
Mon, 8 Jan 2018 22:37:06 +0000 (17:37 -0500)
committerGalen Charlton <gmc@equinoxinitiative.org>
Mon, 8 Jan 2018 22:47:32 +0000 (17:47 -0500)
This patch ensures that bib counts reported in the headings browse
results now respects visibility with respect to whatever OU
is in scope for the search.

To test
-------
[1] Set up situation where (say) a heading is linked to a
    narrower heading that is linked to bibs that have
    items at different systems.
[2] Perform a browse scoped to one of the systems; note that
    all bibs linked to that heading are reported, even if
    they are not meant to be visible in that scope.
[3] Apply the patch and repeat step #2. This time, the number
    of bibs reported as being linked to the narrower heading
    should be correct.

Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Browse.pm
Open-ILS/src/sql/Pg/300.schema.staged_search.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.schema.bib_vis_tester.sql [new file with mode: 0644]

index d817c2c..91cf346 100644 (file)
@@ -205,7 +205,18 @@ sub map_authority_headings_to_results {
                 authority => [
                     @$auth_ids,
                     $U->unique_unnested_numbers(map { $_->{target} } @$linked)
-                ]
+                ], 
+                bib => {
+                    '=' => {
+                        transform => 'search.bib_is_visible',
+                        value => 't',
+                        params => [
+                            $self->ctx->{copy_location_group_org} || $self->ctx->{aou_tree}->()->id,
+                            $self->ctx->{copy_location_group},
+                            $self->ctx->{is_staff} ? 't' : 'f',
+                        ]
+                    }
+                }
             }
         }
     }) or return;
index 8dabef9..9d490e5 100644 (file)
@@ -1306,4 +1306,62 @@ END;
 $p$ LANGUAGE PLPGSQL ROWS 10;
 
 
+CREATE OR REPLACE FUNCTION search.bib_is_visible(rec BIGINT, context_org integer DEFAULT NULL::integer, context_loc_group integer DEFAULT NULL::integer, staff boolean DEFAULT false)
+RETURNS BOOLEAN
+AS $f$
+DECLARE
+    search_org_list INT[];
+    c_tests                 TEXT := '';
+    b_tests                 TEXT := '';
+    c_orgs                  INT[];
+BEGIN
+
+    IF NOT staff THEN
+        SELECT x.c_attrs, x.b_attrs INTO c_tests, b_tests FROM asset.patron_default_visibility_mask() x;
+    END IF;
+
+    IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
+    IF b_tests <> '' THEN b_tests := b_tests || '&'; END IF;
+
+    SELECT ARRAY_AGG(id) INTO c_orgs FROM actor.org_unit_descendants(context_org);
+
+    c_tests := c_tests || search.calculate_visibility_attribute_test('circ_lib',c_orgs)
+               || '&' || search.calculate_visibility_attribute_test('owning_lib',c_orgs);
+
+
+    PERFORM 1 FROM config.internal_flag WHERE enabled AND name = 'opac.located_uri.act_as_copy';
+    IF FOUND THEN
+        b_tests := b_tests || search.calculate_visibility_attribute_test(
+            'luri_org',
+            (SELECT ARRAY_AGG(id) FROM actor.org_unit_full_path(context_org) x)
+        );
+    ELSE
+        b_tests := b_tests || search.calculate_visibility_attribute_test(
+            'luri_org',
+            (SELECT ARRAY_AGG(id) FROM actor.org_unit_ancestors(context_org) x)
+        );
+    END IF;
+
+    IF context_loc_group THEN
+        IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
+        c_tests := c_tests || search.calculate_visibility_attribute_test('location',context_loc_group);
+    END IF;
+
+    PERFORM 1
+        FROM  biblio.record_entry b
+              JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
+        WHERE b.id = rec
+        AND (
+                acvac.vis_attr_vector @@ c_tests::query_int
+                OR b.vis_attr_vector @@ b_tests::query_int
+            );
+
+    IF FOUND THEN
+        RETURN TRUE;
+    ELSE
+        RETURN FALSE;
+    END IF;
+END;
+$f$ LANGUAGE plpgsql;
+
 COMMIT;
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.bib_vis_tester.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.bib_vis_tester.sql
new file mode 100644 (file)
index 0000000..f1222e2
--- /dev/null
@@ -0,0 +1,61 @@
+BEGIN;
+
+-- SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+CREATE OR REPLACE FUNCTION search.bib_is_visible(rec BIGINT, context_org integer DEFAULT NULL::integer, context_loc_group integer DEFAULT NULL::integer, staff boolean DEFAULT false)
+RETURNS BOOLEAN
+AS $f$
+DECLARE
+    search_org_list INT[];
+    c_tests                 TEXT := '';
+    b_tests                 TEXT := '';
+    c_orgs                  INT[];
+BEGIN
+
+    IF NOT staff THEN
+        SELECT x.c_attrs, x.b_attrs INTO c_tests, b_tests FROM asset.patron_default_visibility_mask() x;
+    END IF;
+
+    IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
+    IF b_tests <> '' THEN b_tests := b_tests || '&'; END IF;
+
+    SELECT ARRAY_AGG(id) INTO c_orgs FROM actor.org_unit_descendants(context_org);
+
+    c_tests := c_tests || search.calculate_visibility_attribute_test('circ_lib',c_orgs)
+               || '&' || search.calculate_visibility_attribute_test('owning_lib',c_orgs);
+
+
+    PERFORM 1 FROM config.internal_flag WHERE enabled AND name = 'opac.located_uri.act_as_copy';
+    IF FOUND THEN
+        b_tests := b_tests || search.calculate_visibility_attribute_test(
+            'luri_org',
+            (SELECT ARRAY_AGG(id) FROM actor.org_unit_full_path(context_org) x)
+        );
+    ELSE
+        b_tests := b_tests || search.calculate_visibility_attribute_test(
+            'luri_org',
+            (SELECT ARRAY_AGG(id) FROM actor.org_unit_ancestors(context_org) x)
+        );
+    END IF;
+
+    IF context_loc_group THEN
+        IF c_tests <> '' THEN c_tests := c_tests || '&'; END IF;
+        c_tests := c_tests || search.calculate_visibility_attribute_test('location',context_loc_group);
+    END IF;
+
+    PERFORM 1
+        FROM  biblio.record_entry b
+              JOIN asset.copy_vis_attr_cache acvac ON (acvac.record = b.id)
+        WHERE b.id = rec
+        AND (
+                acvac.vis_attr_vector @@ c_tests::query_int
+                OR b.vis_attr_vector @@ b_tests::query_int
+            );
+
+    IF FOUND THEN
+        RETURN TRUE;
+    ELSE
+        RETURN FALSE;
+    END IF;
+END;
+$f$ LANGUAGE plpgsql;