From f0cb658f6b7cc62a1529d7d81c42d94111f11445 Mon Sep 17 00:00:00 2001 From: Thomas Berezansky Date: Thu, 24 May 2012 11:45:36 -0400 Subject: [PATCH] Allow more granular overrides This adds a new parameter to backend override functions. In most cases the system will act like a hash with all set to 1 was passed in when nothing was passed in by the caller. The new parameter should be a hash containing zero or more of the following options: all - If true (1) override all events events - Should be an array of event textcodes to override For hold placement the "all" option is ignored for possibility checks, but is checked for other events like HOLD_EXISTS. Also included for hold placement is to always run possibility checks for the test and create batch method. Overall, the default is to act like things did previously. Signed-off-by: Thomas Berezansky Signed-off-by: Mike Rylander --- .../perlmods/lib/OpenILS/Application/Actor.pm | 10 ++- .../perlmods/lib/OpenILS/Application/Cat.pm | 59 ++++++++----- .../OpenILS/Application/Cat/AssetCommon.pm | 21 ++++- .../lib/OpenILS/Application/Cat/BibCommon.pm | 13 ++- .../perlmods/lib/OpenILS/Application/Circ.pm | 8 +- .../lib/OpenILS/Application/Circ/Circulate.pm | 30 ++++--- .../lib/OpenILS/Application/Circ/Holds.pm | 88 ++++++++++++------- .../lib/OpenILS/Application/Circ/Survey.pm | 5 +- 8 files changed, 156 insertions(+), 78 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm index 4ba9ad5f0a..77277e48f3 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm @@ -2396,16 +2396,17 @@ __PACKAGE__->register_method( ); sub register_workstation { - my( $self, $conn, $authtoken, $name, $owner ) = @_; + my( $self, $conn, $authtoken, $name, $owner, $oargs ) = @_; my $e = new_editor(authtoken=>$authtoken, xact=>1); return $e->die_event unless $e->checkauth; return $e->die_event unless $e->allowed('REGISTER_WORKSTATION', $owner); my $existing = $e->search_actor_workstation({name => $name})->[0]; + $oargs = { all => 1 } unless defined $oargs; if( $existing ) { - if( $self->api_name =~ /override/o ) { + if( $self->api_name =~ /override/o && ($oargs->{all} || grep { $_ eq 'WORKSTATION_NAME_EXISTS' } @{$oargs->{events}}) ) { # workstation with the given name exists. if($owner ne $existing->owning_lib) { @@ -3639,9 +3640,10 @@ __PACKAGE__->register_method ( ); sub really_delete_user { - my($self, $conn, $auth, $user_id, $dest_user_id) = @_; + my($self, $conn, $auth, $user_id, $dest_user_id, $oargs) = @_; my $e = new_editor(authtoken => $auth, xact => 1); return $e->die_event unless $e->checkauth; + $oargs = { all => 1 } unless defined $oargs; # Find all unclosed billings for for user $user_id, thereby, also checking for open circs my $open_bills = $e->json_query({ @@ -3658,7 +3660,7 @@ sub really_delete_user { # No deleting patrons with open billings or checked out copies, unless perm-enabled override if (@$open_bills) { return $e->die_event(OpenILS::Event->new('ACTOR_USER_DELETE_OPEN_XACTS')) - unless $self->api_name =~ /override/o + unless $self->api_name =~ /override/o && ($oargs->{all} || grep { $_ eq 'ACTOR_USER_DELETE_OPEN_XACTS' } @{$oargs->{events}}) && $e->allowed('ACTOR_USER_DELETE_OPEN_XACTS.override', $user->home_ou); } # No deleting yourself - UI is supposed to stop you first, though. diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm index e1d2c82ced..a442aff233 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm @@ -106,9 +106,10 @@ __PACKAGE__->register_method( ); sub create_record_xml { - my( $self, $client, $login, $xml, $source ) = @_; + my( $self, $client, $login, $xml, $source, $oargs ) = @_; my $override = 1 if $self->api_name =~ /override/; + $oargs = { all => 1 } unless defined $oargs; my( $user_obj, $evt ) = $U->checksesperm($login, 'CREATE_MARC'); return $evt if $evt; @@ -120,7 +121,7 @@ sub create_record_xml { $meth = $self->method_lookup( "open-ils.cat.biblio.record.xml.import.override") if $override; - my ($s) = $meth->run($login, $xml, $source); + my ($s) = $meth->run($login, $xml, $source, $oargs); return $s; } @@ -155,16 +156,20 @@ __PACKAGE__->register_method( ); sub biblio_record_replace_marc { - my( $self, $conn, $auth, $recid, $newxml, $source ) = @_; + my( $self, $conn, $auth, $recid, $newxml, $source, $oargs ) = @_; my $e = new_editor(authtoken=>$auth, xact=>1); return $e->die_event unless $e->checkauth; return $e->die_event unless $e->allowed('CREATE_MARC', $e->requestor->ws_ou); my $fix_tcn = $self->api_name =~ /replace/o; - my $override = $self->api_name =~ /override/o; + if($self->api_name =~ /override/o) { + $oargs = { all => 1 } unless defined $oargs; + } else { + $oargs = {}; + } my $res = OpenILS::Application::Cat::BibCommon->biblio_record_replace_marc( - $e, $recid, $newxml, $source, $fix_tcn, $override); + $e, $recid, $newxml, $source, $fix_tcn, $oargs); $e->commit unless $U->event_code($res); @@ -404,14 +409,18 @@ __PACKAGE__->register_method( sub biblio_record_xml_import { - my( $self, $client, $authtoken, $xml, $source, $auto_tcn) = @_; + my( $self, $client, $authtoken, $xml, $source, $auto_tcn, $oargs) = @_; my $e = new_editor(xact=>1, authtoken=>$authtoken); return $e->die_event unless $e->checkauth; return $e->die_event unless $e->allowed('IMPORT_MARC', $e->requestor->ws_ou); - my $override = $self->api_name =~ /override/; + if ($self->api_name =~ /override/) { + $oargs = { all => 1 } unless defined $oargs; + } else { + $oargs = {}; + } my $record = OpenILS::Application::Cat::BibCommon->biblio_record_xml_import( - $e, $xml, $source, $auto_tcn, $override); + $e, $xml, $source, $auto_tcn, $oargs); return $record if $U->event_code($record); @@ -718,15 +727,19 @@ __PACKAGE__->register_method( sub fleshed_copy_update { - my( $self, $conn, $auth, $copies, $delete_stats ) = @_; + my( $self, $conn, $auth, $copies, $delete_stats, $oargs ) = @_; return 1 unless ref $copies; my( $reqr, $evt ) = $U->checkses($auth); return $evt if $evt; my $editor = new_editor(requestor => $reqr, xact => 1); - my $override = $self->api_name =~ /override/; + if ($self->api_name =~ /override/) { + $oargs = { all => 1 } unless defined $oargs; + } else { + $oargs = {}; + } my $retarget_holds = []; $evt = OpenILS::Application::Cat::AssetCommon->update_fleshed_copies( - $editor, $override, undef, $copies, $delete_stats, $retarget_holds, undef); + $editor, $oargs, undef, $copies, $delete_stats, $retarget_holds, undef); if( $evt ) { $logger->info("fleshed copy update failed with event: ".OpenSRF::Utils::JSON->perl2JSON($evt)); @@ -845,12 +858,16 @@ __PACKAGE__->register_method( api_name => "open-ils.cat.asset.volume.fleshed.batch.update.override",); sub fleshed_volume_update { - my( $self, $conn, $auth, $volumes, $delete_stats, $options ) = @_; + my( $self, $conn, $auth, $volumes, $delete_stats, $options, $oargs ) = @_; my( $reqr, $evt ) = $U->checkses($auth); return $evt if $evt; $options ||= {}; - my $override = ($self->api_name =~ /override/); + if ($self->api_name =~ /override/) { + $oargs = { all => 1 } unless defined $oargs; + } else { + $oargs = {}; + } my $editor = new_editor( requestor => $reqr, xact => 1 ); my $retarget_holds = []; my $auto_merge_vols = $options->{auto_merge_vols}; @@ -873,7 +890,7 @@ sub fleshed_volume_update { return $editor->die_event unless $editor->allowed('UPDATE_VOLUME', $vol->owning_lib); - if(my $evt = $assetcom->delete_volume($editor, $vol, $override, $$options{force_delete_copies})) { + if(my $evt = $assetcom->delete_volume($editor, $vol, $oargs, $$options{force_delete_copies})) { $editor->rollback; return $evt; } @@ -883,12 +900,12 @@ sub fleshed_volume_update { } elsif( $vol->isnew ) { $logger->info("vol-update: creating volume"); - $evt = $assetcom->create_volume( $override, $editor, $vol ); + $evt = $assetcom->create_volume( $oargs, $editor, $vol ); return $evt if $evt; } elsif( $vol->ischanged ) { $logger->info("vol-update: update volume"); - my $resp = update_volume($vol, $editor, ($override or $auto_merge_vols)); + my $resp = update_volume($vol, $editor, ($oargs->{all} or grep { $_ eq 'VOLUME_LABEL_EXISTS' } @{$oargs->{events}} or $auto_merge_vols)); return $resp->{evt} if $resp->{evt}; $vol = $resp->{merge_vol}; } @@ -897,7 +914,7 @@ sub fleshed_volume_update { if( $copies and @$copies and !$vol->isdeleted ) { $_->call_number($vol->id) for @$copies; $evt = $assetcom->update_fleshed_copies( - $editor, $override, $vol, $copies, $delete_stats, $retarget_holds, undef); + $editor, $oargs, $vol, $copies, $delete_stats, $retarget_holds, undef); return $evt if $evt; } } @@ -982,7 +999,7 @@ __PACKAGE__->register_method ( sub batch_volume_transfer { - my( $self, $conn, $auth, $args ) = @_; + my( $self, $conn, $auth, $args, $oargs ) = @_; my $evt; my $rec = $$args{docid}; @@ -990,6 +1007,7 @@ sub batch_volume_transfer { my $vol_ids = $$args{volumes}; my $override = 1 if $self->api_name =~ /override/; + $oargs = { all => 1 } unless defined $oargs; $logger->info("merge: transferring volumes to lib=$o_lib and record=$rec"); @@ -1026,7 +1044,7 @@ sub batch_volume_transfer { # for each volume, see if there are any copies that have a # remote circ_lib (circ_lib != vol->owning_lib and != $o_lib ). # if so, warn them - unless( $override ) { + unless( $override && ($oargs->{all} || grep { $_ eq 'COPY_REMOTE_CIRC_LIB' } @{$oargs->{events}}) ) { for my $v (@all) { $logger->debug("merge: searching for copies with remote circ_lib for volume ".$v->id); @@ -1157,9 +1175,10 @@ __PACKAGE__->register_method( ); sub create_serial_record_xml { - my( $self, $client, $login, $source, $owning_lib, $record_id, $xml ) = @_; + my( $self, $client, $login, $source, $owning_lib, $record_id, $xml, $oargs ) = @_; my $override = 1 if $self->api_name =~ /override/; # not currently used + $oargs = { all => 1 } unless defined $oargs; # Not currently used, but here for consistency. my $e = new_editor(xact=>1, authtoken=>$login); return $e->die_event unless $e->checkauth; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm index ff750991fe..c87eb281a9 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm @@ -195,6 +195,9 @@ sub update_copy_parts { sub update_copy { my($class, $editor, $override, $vol, $copy, $retarget_holds, $force_delete_empty_bib) = @_; + $override = { all => 1 } if($override && !ref $override); + $override = { all => 0 } if(!ref $override); + my $evt; my $org = (ref $copy->circ_lib) ? $copy->circ_lib->id : $copy->circ_lib; return $evt if ( $evt = $class->org_cannot_have_vols($editor, $org) ); @@ -255,6 +258,9 @@ sub check_hold_retarget { sub update_fleshed_copies { my($class, $editor, $override, $vol, $copies, $delete_stats, $retarget_holds, $force_delete_empty_bib) = @_; + $override = { all => 1 } if($override && !ref $override); + $override = { all => 0 } if(!ref $override); + my $evt; my $fetchvol = ($vol) ? 0 : 1; @@ -322,9 +328,12 @@ sub delete_copy { return $editor->event unless $editor->allowed('DELETE_COPY', $class->copy_perm_org($vol, $copy)); + $override = { all => 1 } if($override && !ref $override); + $override = { all => 0 } if(!ref $override); + my $stat = $U->copy_status($copy->status); if ($U->is_true($stat->restrict_copy_delete)) { - if ($override) { + if ($override->{all} || grep { $_ eq 'COPY_DELETE_WARNING' } @{$override->{events}}) { return $editor->event unless $editor->allowed('COPY_DELETE_WARNING.override', $class->copy_perm_org($vol, $copy)) } else { return OpenILS::Event->new('COPY_DELETE_WARNING', payload => $copy->id ) @@ -421,6 +430,9 @@ sub create_volume { return $evt if ( $evt = $class->org_cannot_have_vols($editor, $vol->owning_lib) ); + $override = { all => 1 } if($override && !ref $override); + $override = { all => 0 } if(!ref $override); + # see if the record this volume references is marked as deleted my $rec = $editor->retrieve_biblio_record_entry($vol->record) or return $editor->die_event; @@ -441,7 +453,7 @@ sub create_volume { my $label = undef; if(@$vols) { # we've found an exising volume - if($override) { + if($override->{all} || grep { $_ eq 'VOLUME_LABEL_EXISTS' } @{$override->{events}}) { $label = $vol->label; } else { return OpenILS::Event->new( @@ -534,6 +546,9 @@ sub create_copy_note { sub remove_empty_objects { my($class, $editor, $override, $vol, $force_delete_empty_bib) = @_; + $override = { all => 1 } if($override && !ref $override); + $override = { all => 0 } if(!ref $override); + my $koe = $U->ou_ancestor_setting_value( $editor->requestor->ws_ou, 'cat.bib.keep_on_empty', $editor); my $aoe = $U->ou_ancestor_setting_value( @@ -548,7 +563,7 @@ sub remove_empty_objects { } return OpenILS::Event->new('TITLE_LAST_COPY', payload => $vol->record ) - if $aoe and not $override and not $force_delete_empty_bib; + if $aoe and not ($override->{all} || grep { $_ eq 'TITLE_LAST_COPY' } @{$override->{events}}) and not $force_delete_empty_bib; unless($koe and not $force_delete_empty_bib) { # delete the bib record if the keep-on-empty setting is not set (and we're not otherwise forcing things, say through acq settings) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/BibCommon.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/BibCommon.pm index 6a776d8158..65c3e0fabd 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/BibCommon.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/BibCommon.pm @@ -38,6 +38,9 @@ sub fetch_bib_sources { sub biblio_record_replace_marc { my($class, $e, $recid, $newxml, $source, $fixtcn, $override) = @_; + $override = { all => 1 } if($override && !ref $override); + $override = { all => 0 } if(!ref $override); + my $rec = $e->retrieve_biblio_record_entry($recid) or return $e->die_event; @@ -48,7 +51,7 @@ sub biblio_record_replace_marc { my( $tcn, $tsource, $marcdoc, $evt); - if($fixtcn or $override) { + if($fixtcn or $override->{all} or $override->{events}) { ($tcn, $tsource, $marcdoc, $evt) = _find_tcn_info($e, $newxml, $override, $recid); @@ -76,6 +79,9 @@ sub biblio_record_replace_marc { sub biblio_record_xml_import { my($class, $e, $xml, $source, $auto_tcn, $override) = @_; + $override = { all => 1 } if($override && !ref $override); + $override = { all => 0 } if(!ref $override); + my( $evt, $tcn, $tcn_source, $marcdoc ); my $use_id = $e->retrieve_config_global_flag('cat.bib.use_id_for_tcn'); @@ -171,6 +177,9 @@ sub _find_tcn_info { my $override = shift; my $existing_rec = shift || 0; + $override = { all => 1 } if($override && !ref $override); + $override = { all => 0 } if(!ref $override); + # parse the XML my $marcxml = __make_marc_doc($xml); @@ -187,7 +196,7 @@ sub _find_tcn_info { $tcn = find_free_tcn( $marcxml, $editor, $existing_rec ); # if we're overriding, try to find a different TCN to use - if( $override ) { + if( $override->{all} || grep { $_ eq 'TCN_EXISTS' } @{$override->{events}} ) { # XXX Create ALLOW_ALT_TCN permission check support diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ.pm index fba805a0a0..5c2a754a9b 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ.pm @@ -400,11 +400,13 @@ __PACKAGE__->register_method( ); sub set_circ_claims_returned { - my( $self, $conn, $auth, $args ) = @_; + my( $self, $conn, $auth, $args, $oargs ) = @_; my $e = new_editor(authtoken=>$auth, xact=>1); return $e->die_event unless $e->checkauth; + $oargs = { all => 1 } unless defined $oargs; + my $barcode = $$args{barcode}; my $backdate = $$args{backdate}; @@ -429,7 +431,7 @@ sub set_circ_claims_returned { # 0 means all attempts require an override if(defined $max_count and $patron->claims_returned_count >= $max_count) { - if($self->api_name =~ /override/) { + if($self->api_name =~ /override/ && ($oargs->{all} || grep { $_ eq 'PATRON_EXCEEDS_CLAIMS_RETURN_COUNT' } @{$oargs->{events}})) { # see if we're allowed to override return $e->die_event unless @@ -1393,7 +1395,7 @@ sub mark_item_missing_pieces { } } - my ($res) = $self->method_lookup('open-ils.circ.checkout.full.override')->run($e->authtoken,$co_params); + my ($res) = $self->method_lookup('open-ils.circ.checkout.full.override')->run($e->authtoken,$co_params,{ all => 1 }); if (ref $res ne 'ARRAY') { $res = [ $res ]; } if ( $res->[0]->{textcode} eq 'SUCCESS' ) { $logger->info('open-ils.circ.mark_item_missing_pieces: successful checkout'); diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm index 5bdb1c349c..88f7a73706 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm @@ -191,12 +191,13 @@ __PACKAGE__->register_method( sub run_method { - my( $self, $conn, $auth, $args ) = @_; + my( $self, $conn, $auth, $args, $oargs ) = @_; translate_legacy_args($args); + $oargs = { all => 1 } unless defined $oargs; my $api = $self->api_name; my $circulator = - OpenILS::Application::Circ::Circulator->new($auth, %$args); + OpenILS::Application::Circ::Circulator->new($auth, %$args, $oargs); return circ_events($circulator) if $circulator->bail_out; @@ -540,6 +541,7 @@ my @AUTOLOAD_FIELDS = qw/ hold_as_transit fake_hold_dest limit_groups + override_args /; @@ -569,12 +571,13 @@ sub AUTOLOAD { sub new { - my( $class, $auth, %args ) = @_; + my( $class, $auth, %args, $oargs ) = @_; $class = ref($class) || $class; my $self = bless( {}, $class ); $self->events([]); $self->editor(new_editor(xact => 1, authtoken => $auth)); + $self->override_args($oargs); unless( $self->editor->checkauth ) { $self->bail_on_events($self->editor->event); @@ -1367,6 +1370,7 @@ sub override_events { my $self = shift; my @events = @{$self->events}; return unless @events; + my $oargs = $self->override_args; if(!$self->override) { return $self->bail_out(1) @@ -1375,14 +1379,18 @@ sub override_events { $self->events([]); - for my $e (@events) { - my $tc = $e->{textcode}; - next if $tc eq 'SUCCESS'; - my $ov = "$tc.override"; - $logger->info("circulator: attempting to override event: $ov"); + for my $e (@events) { + my $tc = $e->{textcode}; + next if $tc eq 'SUCCESS'; + if($oargs->{all} || grep { $_ eq $tc } @{$oargs->{events}}) { + my $ov = "$tc.override"; + $logger->info("circulator: attempting to override event: $ov"); - return $self->bail_on_events($self->editor->event) - unless( $self->editor->allowed($ov) ); + return $self->bail_on_events($self->editor->event) + unless( $self->editor->allowed($ov) ); + } else { + return $self->bail_out(1); + } } } @@ -1408,7 +1416,7 @@ sub handle_claims_returned { my $evt; # - If the caller has set the override flag, we will check the item in - if($self->override) { + if($self->override && ($self->override_args->{all} || grep { $_ eq 'CIRC_CLAIMS_RETURNED' } @{$self->override_args->{events}}) ) { $CR->checkin_time('now'); $CR->checkin_scan_time('now'); 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 9fddeeb8bf..23f19a9400 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm @@ -67,9 +67,10 @@ __PACKAGE__->register_method( sub test_and_create_hold_batch { - my( $self, $conn, $auth, $params, $target_list ) = @_; + my( $self, $conn, $auth, $params, $target_list, $oargs ) = @_; my $override = 1 if $self->api_name =~ /override/; + $oargs = { all => 1 } unless defined $oargs; my $e = new_editor(authtoken=>$auth); return $e->die_event unless $e->checkauth; @@ -89,17 +90,15 @@ sub test_and_create_hold_batch { foreach (@$target_list) { $$params{$target_field} = $_; my $res; - if (! $override) { - ($res) = $self->method_lookup( - 'open-ils.circ.title_hold.is_possible')->run($auth, $params); - } - if ($override || $res->{'success'} == 1) { + ($res) = $self->method_lookup( + 'open-ils.circ.title_hold.is_possible')->run($auth, $params, $override ? $oargs : {}); + if ($res->{'success'} == 1) { my $ahr = construct_hold_request_object($params); my ($res2) = $self->method_lookup( $override ? 'open-ils.circ.holds.create.override' : 'open-ils.circ.holds.create' - )->run($auth, $ahr); + )->run($auth, $ahr, $oargs); $res2 = { 'target' => $$params{$target_field}, 'result' => $res2 @@ -166,10 +165,10 @@ __PACKAGE__->register_method( sub create_hold_batch { - my( $self, $conn, $auth, $hold_list ) = @_; + my( $self, $conn, $auth, $hold_list, $oargs ) = @_; (my $method = $self->api_name) =~ s/\.batch//og; foreach (@$hold_list) { - my ($res) = $self->method_lookup($method)->run($auth, $_); + my ($res) = $self->method_lookup($method)->run($auth, $_, $oargs); $conn->respond($res); } return undef; @@ -223,12 +222,13 @@ __PACKAGE__->register_method( ); sub create_hold { - my( $self, $conn, $auth, $hold ) = @_; + my( $self, $conn, $auth, $hold, $oargs ) = @_; return -1 unless $hold; my $e = new_editor(authtoken=>$auth, xact=>1); return $e->die_event unless $e->checkauth; my $override = 1 if $self->api_name =~ /override/; + $oargs = { all => 1 } unless defined $oargs; my @events; @@ -306,7 +306,12 @@ sub create_hold { for my $evt (@events) { next unless $evt; my $name = $evt->{textcode}; - return $e->die_event unless $e->allowed("$name.override", $porg); + if($oargs->{all} || grep { $_ eq $name } @{$oargs->{events}}) { + return $e->die_event unless $e->allowed("$name.override", $porg); + } else { + $e->rollback; + return \@events; + } } } @@ -2159,9 +2164,9 @@ __PACKAGE__->register_method( ); sub check_title_hold_batch { - my($self, $client, $authtoken, $param_list) = @_; + my($self, $client, $authtoken, $param_list, $oargs) = @_; foreach (@$param_list) { - my ($res) = $self->method_lookup('open-ils.circ.title_hold.is_possible')->run($authtoken, $_); + my ($res) = $self->method_lookup('open-ils.circ.title_hold.is_possible')->run($authtoken, $_, $oargs); $client->respond($res); } return undef; @@ -2215,9 +2220,14 @@ All key/value pairs are passed on to do_possibility_checks. # FIXME: specify proper usage/interaction of selection_ou and pickup_lib sub check_title_hold { - my( $self, $client, $authtoken, $params ) = @_; + my( $self, $client, $authtoken, $params, $oargs ) = @_; my $e = new_editor(authtoken=>$authtoken); return $e->event unless $e->checkauth; + $oargs = {} unless defined $oargs; + + if($oargs->{events}) { + @{$oargs->{events}} = grep { $e->allowed($_ . '.override', $e->requestor->ws_ou); } @{$oargs->{events}}; + } my %params = %$params; my $depth = $params{depth} || 0; @@ -2252,7 +2262,7 @@ sub check_title_hold { my $depth = $soft_boundary; while($depth >= $min_depth) { $logger->info("performing hold possibility check with soft boundary $depth"); - @status = do_possibility_checks($e, $patron, $request_lib, $depth, %params); + @status = do_possibility_checks($e, $patron, $request_lib, $depth, %params, $oargs); if ($status[0]) { $return_depth = $depth; last; @@ -2262,11 +2272,11 @@ sub check_title_hold { } elsif(defined $hard_boundary and $depth < $hard_boundary) { # there is no soft boundary, enforce the hard boundary if it exists $logger->info("performing hold possibility check with hard boundary $hard_boundary"); - @status = do_possibility_checks($e, $patron, $request_lib, $hard_boundary, %params); + @status = do_possibility_checks($e, $patron, $request_lib, $hard_boundary, %params, $oargs); } else { # no boundaries defined, fall back to user specifed boundary or no boundary $logger->info("performing hold possibility check with no boundary"); - @status = do_possibility_checks($e, $patron, $request_lib, $params{depth}, %params); + @status = do_possibility_checks($e, $patron, $request_lib, $params{depth}, %params, $oargs); } my $place_unfillable = 0; @@ -2289,7 +2299,7 @@ sub check_title_hold { sub do_possibility_checks { - my($e, $patron, $request_lib, $depth, %params) = @_; + my($e, $patron, $request_lib, $depth, %params, $oargs) = @_; my $issuanceid = $params{issuanceid} || ""; my $partid = $params{partid} || ""; @@ -2315,7 +2325,7 @@ sub do_possibility_checks { return (1, 1, []) if( $hold_type eq OILS_HOLD_TYPE_RECALL || $hold_type eq OILS_HOLD_TYPE_FORCE); return verify_copy_for_hold( - $patron, $e->requestor, $title, $copy, $pickup_lib, $request_lib + $patron, $e->requestor, $title, $copy, $pickup_lib, $request_lib, $oargs ); } elsif( $hold_type eq OILS_HOLD_TYPE_VOLUME ) { @@ -2324,25 +2334,25 @@ sub do_possibility_checks { return $e->event unless $title = $e->retrieve_biblio_record_entry($volume->record); return _check_volume_hold_is_possible( - $volume, $title, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou + $volume, $title, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou, $oargs ); } elsif( $hold_type eq OILS_HOLD_TYPE_TITLE ) { return _check_title_hold_is_possible( - $titleid, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou + $titleid, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou, $oargs ); } elsif( $hold_type eq OILS_HOLD_TYPE_ISSUANCE ) { return _check_issuance_hold_is_possible( - $issuanceid, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou + $issuanceid, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou, $oargs ); } elsif( $hold_type eq OILS_HOLD_TYPE_MONOPART ) { return _check_monopart_hold_is_possible( - $partid, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou + $partid, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou, $oargs ); } elsif( $hold_type eq OILS_HOLD_TYPE_METARECORD ) { @@ -2352,7 +2362,7 @@ sub do_possibility_checks { my @status = (); for my $rec (@recs) { @status = _check_title_hold_is_possible( - $rec, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou, $holdable_formats + $rec, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou, $holdable_formats, $oargs ); last if $status[0]; } @@ -2387,7 +2397,7 @@ sub create_ranged_org_filter { sub _check_title_hold_is_possible { - my( $titleid, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou, $holdable_formats ) = @_; + my( $titleid, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou, $holdable_formats, $oargs ) = @_; my ($types, $formats, $lang); if (defined($holdable_formats)) { @@ -2517,7 +2527,7 @@ sub _check_title_hold_is_possible { } @status = verify_copy_for_hold( - $patron, $requestor, $title, $copy, $pickup_lib, $request_lib); + $patron, $requestor, $title, $copy, $pickup_lib, $request_lib, $oargs); $age_protect_only ||= $status[3]; last OUTER if $status[0]; @@ -2529,7 +2539,7 @@ sub _check_title_hold_is_possible { } sub _check_issuance_hold_is_possible { - my( $issuanceid, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou ) = @_; + my( $issuanceid, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou, $oargs ) = @_; my $e = new_editor(); my %org_filter = create_ranged_org_filter($e, $selection_ou, $depth); @@ -2646,7 +2656,7 @@ sub _check_issuance_hold_is_possible { } @status = verify_copy_for_hold( - $patron, $requestor, $title, $copy, $pickup_lib, $request_lib); + $patron, $requestor, $title, $copy, $pickup_lib, $request_lib, $oargs); $age_protect_only ||= $status[3]; last OUTER if $status[0]; @@ -2666,7 +2676,7 @@ sub _check_issuance_hold_is_possible { } sub _check_monopart_hold_is_possible { - my( $partid, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou ) = @_; + my( $partid, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou, $oargs ) = @_; my $e = new_editor(); my %org_filter = create_ranged_org_filter($e, $selection_ou, $depth); @@ -2783,7 +2793,7 @@ sub _check_monopart_hold_is_possible { } @status = verify_copy_for_hold( - $patron, $requestor, $title, $copy, $pickup_lib, $request_lib); + $patron, $requestor, $title, $copy, $pickup_lib, $request_lib, $oargs); $age_protect_only ||= $status[3]; last OUTER if $status[0]; @@ -2804,7 +2814,7 @@ sub _check_monopart_hold_is_possible { sub _check_volume_hold_is_possible { - my( $vol, $title, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou ) = @_; + my( $vol, $title, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou, $oargs ) = @_; my %org_filter = create_ranged_org_filter(new_editor(), $selection_ou, $depth); my $copies = new_editor->search_asset_copy({call_number => $vol->id, %org_filter}); $logger->info("checking possibility of volume hold for volume ".$vol->id); @@ -2830,7 +2840,7 @@ sub _check_volume_hold_is_possible { my $age_protect_only = 0; for my $copy ( @$copies ) { @status = verify_copy_for_hold( - $patron, $requestor, $title, $copy, $pickup_lib, $request_lib ); + $patron, $requestor, $title, $copy, $pickup_lib, $request_lib, $oargs ); $age_protect_only ||= $status[3]; last if $status[0]; } @@ -2841,7 +2851,8 @@ sub _check_volume_hold_is_possible { sub verify_copy_for_hold { - my( $patron, $requestor, $title, $copy, $pickup_lib, $request_lib ) = @_; + my( $patron, $requestor, $title, $copy, $pickup_lib, $request_lib, $oargs ) = @_; + $oargs = {} unless defined $oargs; $logger->info("checking possibility of copy in hold request for copy ".$copy->id); my $permitted = OpenILS::Utils::PermitHold::permit_copy_hold( { patron => $patron, @@ -2855,6 +2866,17 @@ sub verify_copy_for_hold { show_event_list => 1 } ); + + # All overridden? + my $permit_anyway = 0; + foreach my $permit_event (@$permitted) { + if (grep { $_ eq $permit_event->{textcode} } @{$oargs->{events}}) { + $permit_anyway = 1; + last; + } + } + $permitted = [] if $permit_anyway; + my $age_protect_only = 0; if (@$permitted == 1 && @$permitted[0]->{textcode} eq 'ITEM_AGE_PROTECTED') { $age_protect_only = 1; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Survey.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Survey.pm index e09b9f611c..9c4bfc6a54 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Survey.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Survey.pm @@ -384,9 +384,10 @@ __PACKAGE__->register_method ( ); sub delete_survey { - my($self, $conn, $auth, $survey_id) = @_; + my($self, $conn, $auth, $survey_id, $oargs) = @_; my $e = new_editor(authtoken => $auth, xact => 1); return $e->die_event unless $e->checkauth; + $oargs = { all => 1 } unless defined $oargs; my $survey = $e->retrieve_action_survey($survey_id) or return $e->die_event; @@ -398,7 +399,7 @@ sub delete_survey { my $responses = $e->search_action_survey_response({survey => $survey_id}); return OpenILS::Event->new('SURVEY_RESPONSES_EXIST') - if @$responses and $self->api_name =! /override/; + if @$responses and ($self->api_name =! /override/ || !($oargs->{all} || grep { $_ eq 'SURVEY_RESPONSES_EXIST' } @{$oargs->{events}})); for my $resp (@$responses) { $e->delete_action_survey_response($resp) or return $e->die_event; -- 2.43.2