TPAC Org unit hiding
authorBill Erickson <berick@esilibrary.com>
Fri, 21 Sep 2012 17:58:46 +0000 (13:58 -0400)
committerBill Erickson <berick@esilibrary.com>
Tue, 13 Nov 2012 21:03:02 +0000 (16:03 -0500)
Adds support for the opac.org_unit_hiding.depth org unit setting to
TPAC, which makes out-of-scope org units disappear (except when
explicitly requested).

Ui changes:

All search org unit selectors
Holds pickup lib selector
Copy summary in search results page
Copy list in search results page
Copy summary in record detail page (which controls the copy grid).

Org unit hiding is based on the physical_loc (Physical Location) param /
cookie, which is the closest analog to 'ol' (original location), from
which it was based in the JSPAC.

Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/opac/parts/misc_util.tt2
Open-ILS/src/templates/opac/parts/org_selector.tt2
Open-ILS/src/templates/opac/parts/record/copy_counts.tt2
Open-ILS/src/templates/opac/parts/result/copy_counts.tt2

index c188e97..f29ed96 100644 (file)
             );
         END;
 
+        ou_hiding_disabled = org_hiding_disabled();
+
         FOR volume IN xml.findnodes('//*[local-name()="volumes"]/*[local-name()="volume"]');
 
             # Check volume visibility - could push this into XPath
                     status = copy.findnodes('./*[local-name()="status"]');
                     NEXT IF status.getAttribute('opac_visible') == 'false';
 
+                    UNLESS ou_hiding_disabled;
+                        # extract the circ_lib id from the circ_lib node
+                        circ_lib = copy.findnodes('./*[local-name()="circ_lib"]');
+                        circ_lib_id = circ_lib.getAttribute('id').replace('.*/', '');
+                        NEXT UNLESS org_within_hiding_scope(circ_lib_id);
+                    END;
+
                     holding = {
                         label => vol.label,
                         part_label => part_label,
         loc_name = 'locg';
         loc_value = CGI.param(loc_name) || CGI.param('loc') || ctx.search_ou;
     END;
+
+    # evaluates to true if test_ou is within the same depth-
+    # scoped tree as ctx_ou. both ou's are org unit objects.
+    MACRO org_within_scope(ctx_ou, test_ou, depth) BLOCK;
+        IF ctx_ou.id == test_ou.id;
+            1;
+        ELSIF depth == 0;
+            # there's a party in my org tree and everyone's invited
+            1;
+        ELSE;
+            # start at the top of the depth-scoped tree 
+            # and search down until we find the test_ou
+
+            IF depth;
+                WHILE depth < ctx_ou.ou_type.depth AND ctx_ou.id != test_ou.id;
+                    ctx_ou = ctx.get_aou(ctx_ou.parent_ou);
+                END;
+            END;
+
+            IF ctx_ou.id == test_ou.id; # may now be a parent org
+                1;
+            ELSE;
+
+                FOR child IN ctx_ou.children;
+                    IF org_within_scope(child, test_ou);
+                        1; LAST;
+                    END;
+                END;
+            END;
+        END;
+    END;
+
+    MACRO org_within_hiding_scope(org_id) BLOCK;
+        # org unit hiding is based on the immutable physical_loc
+        # and is not meant to change as search/pref/etc libs change
+
+        IF ctx.physical_loc;
+
+            depth = ctx.get_org_setting(ctx.physical_loc, 'opac.org_unit_hiding.depth');
+            IF depth; 
+
+                org_within_scope(
+                    ctx.get_aou(ctx.physical_loc), 
+                    ctx.get_aou(org_id), 
+                    depth
+                );
+
+            ELSE; # depth is null or 0
+                1;
+            END;
+        ELSE; # no physical_loc means no org unit hiding
+            1;
+        END;
+    END;
+
+    # Evaluates to true if the context org (defaults to get_library) 
+    # is not within the hiding scope.  Also evaluates to true if the 
+    # user's pref_ou is set and it's out of hiding scope.
+    # Always evaluates to true when ctx.is_staff
+    MACRO org_hiding_disabled(ctx_org) BLOCK;
+        IF ctx.is_staff;
+            1;
+        ELSE;
+            SET ctx_org = ctx.search_ou UNLESS ctx_org;
+    
+            # beware locg values formatted as org:loc
+            ctx_org = ctx_org | replace(':.*', '');
+
+            IF !org_within_hiding_scope(ctx_org);
+                1;
+
+            ELSIF ctx.pref_ou AND ctx.pref_ou != ctx_org AND 
+                    !org_within_hiding_scope(ctx.pref_ou);
+                1;
+            END;
+        END;
+    END;
 %]
index 159af59..74e848e 100644 (file)
@@ -19,6 +19,11 @@ BLOCK build_org_selector;
     IF !value;
         value = loc_value;
     END;
+
+    # if the selected org unit is out of hiding scope, 
+    # disable the ou-hide scoping altogether.
+    hiding_disabled = org_hiding_disabled(value);
+
     %]
 
     <select [% IF id %] id='[% id %]' [% END %] name='[% name %]'>
@@ -63,8 +68,11 @@ BLOCK build_org_selector;
 
             END;
 
-            # This org unit is not publicly visible (though its children may be).
+            # org is not publicly visible (though its children may be).
             NEXT UNLESS ctx.is_staff OR visible;
+            
+            # org is not within hiding scope (though its children may be).
+            NEXT UNLESS hiding_disabled OR org_within_hiding_scope(ou_id);
 
             node_value = ou_id;
             IF loc_grp;
index cd59442..a479fa6 100644 (file)
@@ -4,11 +4,13 @@
     [%- depths = ctx.copy_summary.size;
         depth = 0;
         displayed_ous = {};
+        ou_hiding_disabled = org_hiding_disabled();
         WHILE depth < depths;
             ou_avail = ctx.copy_summary.$depth.available;
             ou_id = ctx.copy_summary.$depth.org_unit;
             cp_org_unit = ctx.get_aou(ou_id);
-            IF cp_org_unit.opac_visible == 'f' AND !ctx.is_staff;
+            skip_me = !ou_hiding_disabled AND !org_within_hiding_scope(ou_id);
+            IF (cp_org_unit.opac_visible == 'f' AND !ctx.is_staff) OR skip_me;
                 depth = depth + 1;
                 NEXT;
             END;
index 1bbc357..c04bdb2 100644 (file)
@@ -1,10 +1,13 @@
 [%- depths = attrs.copy_counts.size;
     depth = 0;
     displayed_ous = {};
+    hiding_disabled = org_hiding_disabled();
     WHILE depth < depths;
-        ou_name = ctx.get_aou(attrs.copy_counts.$depth.org_unit).name;
+        org_unit = ctx.get_aou(attrs.copy_counts.$depth.org_unit);
+        ou_name = org_unit.name;
         displayed_ous.$ou_name = 1;
-        IF attrs.copy_counts.$depth.count > 0;
+        IF attrs.copy_counts.$depth.count > 0 AND (
+            hiding_disabled OR org_within_hiding_scope(org_unit.id));
 %]
 <div class="result_count">
 [% IF ctx.get_aou(attrs.copy_counts.$depth.org_unit).opac_visible == 't' %]
     END;
 
     depth = attrs.plib_copy_counts.size - 1;
-    ou_name = ctx.get_aou(attrs.plib_copy_counts.$depth.org_unit).name;
+    org_unit = ctx.get_aou(attrs.plib_copy_counts.$depth.org_unit);
+    ou_name = org_unit.name;
     UNLESS displayed_ous.exists(ou_name);
     
 %]
-[%- IF attrs.plib_copy_counts.$depth.count > 0; %]
+[%- IF attrs.plib_copy_counts.$depth.count > 0 AND (
+        hiding_disabled OR org_within_hiding_scope(org_unit.id)) %]
 <div class="result_count preferred">[%
      l('[_1] of [quant,_2,copy,copies] available at [_3].',
         attrs.plib_copy_counts.$depth.available,