From 16e8e0e59e913c551a429d1fb3f2dc1b126e2099 Mon Sep 17 00:00:00 2001 From: Mike Rylander Date: Fri, 14 Feb 2014 16:06:59 -0500 Subject: [PATCH] LP#1053397: Add optional org filter to "has holdable copies", and use that in open-ils.circ.holds.metarecord.filterd_records Signed-off-by: Mike Rylander Signed-off-by: Bill Erickson Signed-off-by: Dan Wells --- .../lib/OpenILS/Application/Circ/Holds.pm | 13 ++++- .../Application/Storage/Publisher/action.pm | 23 ++++----- Open-ILS/src/sql/Pg/040.schema.asset.sql | 6 ++- .../sql/Pg/upgrade/ZZZZ.schema.unapi-mmr.sql | 49 +++++++++++++++++++ 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm index 4f56877277..66b6391cfe 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm @@ -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', diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm index 2f98fa5532..fe1448dced 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm @@ -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( diff --git a/Open-ILS/src/sql/Pg/040.schema.asset.sql b/Open-ILS/src/sql/Pg/040.schema.asset.sql index 20dbc95837..dfe75bff89 100644 --- a/Open-ILS/src/sql/Pg/040.schema.asset.sql +++ b/Open-ILS/src/sql/Pg/040.schema.asset.sql @@ -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; diff --git a/Open-ILS/src/sql/Pg/upgrade/ZZZZ.schema.unapi-mmr.sql b/Open-ILS/src/sql/Pg/upgrade/ZZZZ.schema.unapi-mmr.sql index 89c938dbbc..20889b1c21 100644 --- a/Open-ILS/src/sql/Pg/upgrade/ZZZZ.schema.unapi-mmr.sql +++ b/Open-ILS/src/sql/Pg/upgrade/ZZZZ.schema.unapi-mmr.sql @@ -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; -- 2.43.2