LP#1053397: Add optional org filter to "has holdable copies", and use that in open...
authorMike Rylander <mrylander@gmail.com>
Fri, 14 Feb 2014 21:06:59 +0000 (16:06 -0500)
committerDan Wells <dbw2@calvin.edu>
Fri, 21 Feb 2014 20:38:54 +0000 (15:38 -0500)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Signed-off-by: Dan Wells <dbw2@calvin.edu>
Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
Open-ILS/src/sql/Pg/040.schema.asset.sql
Open-ILS/src/sql/Pg/upgrade/ZZZZ.schema.unapi-mmr.sql

index 4f56877..66b6391 100644 (file)
@@ -2477,7 +2477,8 @@ sub do_possibility_checks {
 
     } elsif( $hold_type eq OILS_HOLD_TYPE_METARECORD ) {
 
-        my ($recs) = __PACKAGE__->method_lookup('open-ils.circ.holds.metarecord.filterd_records')->run($mrid, $holdable_formats);
+
+        my ($recs) = __PACKAGE__->method_lookup('open-ils.circ.holds.metarecord.filterd_records')->run($mrid, $holdable_formats, $selection_ou, $depth);
         my @status = ();
         for my $rec (@$recs) {
             @status = _check_title_hold_is_possible(
@@ -2491,7 +2492,15 @@ sub do_possibility_checks {
 }
 
 sub MR_filter_records {
-    return $U->storagereq('open-ils.storage.metarecord.filtered_records.atomic', $_[2], $_[3]);
+    my $self = shift;
+    my $client = shift;
+    my $m = shift;
+    my $f = shift;
+    my $o = shift;
+    my $d = shift;
+    
+    my $org_at_depth = defined($d) ? $U->org_unit_ancestor_at_depth($o, $d) : $o;
+    return $U->storagereq('open-ils.storage.metarecord.filtered_records.atomic', $m, $f, $org_at_depth);
 }
 __PACKAGE__->register_method(
     method   => 'MR_filter_records',
index 2f98fa5..fe1448d 100644 (file)
@@ -1288,6 +1288,7 @@ sub MR_records_matching_format {
     my $client = shift;
     my $MR = shift;
     my $filter = shift;
+    my $org = shift;
 
     # find filters for MR holds
     my $mr_filter;
@@ -1301,19 +1302,19 @@ sub MR_records_matching_format {
 
     my $records = [metabib::metarecord->retrieve($MR)->source_records];
 
+    my $q = 'SELECT source FROM metabib.record_attr_vector_list WHERE source = ? AND vlist @@ ? AND asset.record_has_holdable_copy(?,?)';
+    my @args = ( $mr_filter, $org );
     if (!$mr_filter) {
-        $client->respond( $_->id ) for @$records;
-    } else {
-        for my $r ( map { isTrue($_->deleted) ?  () : ($_->id) } @$records ) {
-            $client->respond($r) if
-                @{action::hold_request->db_Main->selectcol_arrayref(
-                    'SELECT source FROM metabib.record_attr_vector_list WHERE source = ? AND vlist @@ ?',
-                    {},
-                    $r,
-                    $mr_filter
-                )};
-        }
+        $q = 'SELECT true WHERE asset.record_has_holdable_copy(?,?)';
+        @args = ( $org );
     }
+
+    for my $r ( map { isTrue($_->deleted) ?  () : ($_->id) } @$records ) {
+        # the map{} below is tricky. it puts the record ID in front of each param. see $q above
+        $client->respond($r)
+            if @{action::hold_request->db_Main->selectcol_arrayref( $q, {}, map { ( $r => $_ ) } @args )};
+    }
+
     return; # discard final l-val
 }
 __PACKAGE__->register_method(
index 20dbc95..dfe75bf 100644 (file)
@@ -656,7 +656,7 @@ BEGIN
 END;
 $f$ LANGUAGE PLPGSQL;
 
-CREATE OR REPLACE FUNCTION asset.record_has_holdable_copy ( rid BIGINT ) RETURNS BOOL AS $f$
+CREATE OR REPLACE FUNCTION asset.record_has_holdable_copy ( rid BIGINT, ou INT DEFAULT NULL) RETURNS BOOL AS $f$
 BEGIN
     PERFORM 1
         FROM
@@ -670,6 +670,7 @@ BEGIN
             AND acpl.holdable = true
             AND ccs.holdable = true
             AND acp.deleted = false
+            AND acp.circ_lib IN (SELECT id FROM actor.org_unit_descendants(COALESCE($2,(SELECT id FROM evergreen.org_top()))))
         LIMIT 1;
     IF FOUND THEN
         RETURN true;
@@ -826,7 +827,7 @@ BEGIN
 END;
 $f$ LANGUAGE PLPGSQL;
 
-CREATE OR REPLACE FUNCTION asset.metarecord_has_holdable_copy ( rid BIGINT ) RETURNS BOOL AS $f$
+CREATE OR REPLACE FUNCTION asset.metarecord_has_holdable_copy ( rid BIGINT, ou INT DEFAULT NULL) RETURNS BOOL AS $f$
 BEGIN
     PERFORM 1
         FROM
@@ -841,6 +842,7 @@ BEGIN
             AND acpl.holdable = true
             AND ccs.holdable = true
             AND acp.deleted = false
+            AND acp.circ_lib IN (SELECT id FROM actor.org_unit_descendants(COALESCE($2,(SELECT id FROM evergreen.org_top()))))
         LIMIT 1;
     IF FOUND THEN
         RETURN true;
index 89c938d..20889b1 100644 (file)
@@ -1,5 +1,54 @@
 BEGIN;
 
+DROP FUNCTION asset.record_has_holdable_copy (BIGINT);
+CREATE FUNCTION asset.record_has_holdable_copy ( rid BIGINT, ou INT DEFAULT NULL) RETURNS BOOL AS $f$
+BEGIN
+    PERFORM 1
+        FROM
+            asset.copy acp
+            JOIN asset.call_number acn ON acp.call_number = acn.id
+            JOIN asset.copy_location acpl ON acp.location = acpl.id
+            JOIN config.copy_status ccs ON acp.status = ccs.id
+        WHERE
+            acn.record = rid
+            AND acp.holdable = true
+            AND acpl.holdable = true
+            AND ccs.holdable = true
+            AND acp.deleted = false
+            AND acp.circ_lib IN (SELECT id FROM actor.org_unit_descendants(COALESCE($2,(SELECT id FROM evergreen.org_top()))))
+        LIMIT 1;
+    IF FOUND THEN
+        RETURN true;
+    END IF;
+    RETURN FALSE;
+END;
+$f$ LANGUAGE PLPGSQL;
+
+DROP FUNCTION asset.metarecord_has_holdable_copy (BIGINT);
+CREATE FUNCTION asset.metarecord_has_holdable_copy ( rid BIGINT, ou INT DEFAULT NULL) RETURNS BOOL AS $f$
+BEGIN
+    PERFORM 1
+        FROM
+            asset.copy acp
+            JOIN asset.call_number acn ON acp.call_number = acn.id
+            JOIN asset.copy_location acpl ON acp.location = acpl.id
+            JOIN config.copy_status ccs ON acp.status = ccs.id
+            JOIN metabib.metarecord_source_map mmsm ON acn.record = mmsm.source
+        WHERE
+            mmsm.metarecord = rid
+            AND acp.holdable = true
+            AND acpl.holdable = true
+            AND ccs.holdable = true
+            AND acp.deleted = false
+            AND acp.circ_lib IN (SELECT id FROM actor.org_unit_descendants(COALESCE($2,(SELECT id FROM evergreen.org_top()))))
+        LIMIT 1;
+    IF FOUND THEN
+        RETURN true;
+    END IF;
+    RETURN FALSE;
+END;
+$f$ LANGUAGE PLPGSQL;
+
 CREATE OR REPLACE FUNCTION asset.opac_ou_metarecord_copy_count (org INT, rid BIGINT) RETURNS TABLE (depth INT, org_unit INT, visible BIGINT, available BIGINT, unshadow BIGINT, transcendant INT) AS $f$
 DECLARE
     ans RECORD;