From: Lebbeous Fogle-Weekley Date: Tue, 11 Jun 2013 21:28:17 +0000 (-0400) Subject: LP#1175740 Acq: If deleting line items with copies, remove fund debits and maybe... X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=d13a3450f0f406a66eb55920f3fbee5dbb127884;p=working%2FEvergreen.git LP#1175740 Acq: If deleting line items with copies, remove fund debits and maybe copies Depending on workflow, there are times when users might delete Acq line items that have fund debits and/or real catalog copies attached to them. We should always delete such fund debits when deleting line items (since those debits otherwise become invisible and just throw off fund balances), and we should also delete copies *iff* the staff user confirms that's what they mean to do, and they have the DELETE_COPY permission, of course. This should resolve https://bugs.launchpad.net/evergreen/+bug/1175740 Signed-off-by: Lebbeous Fogle-Weekley --- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Lineitem.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Lineitem.pm index af491b6c68..abcd5d4934 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Lineitem.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Lineitem.pm @@ -230,6 +230,7 @@ __PACKAGE__->register_method( params => [ {desc => 'Authentication token', type => 'string'}, {desc => 'lineitem ID to delete', type => 'number'}, + {desc => 'Even delete associated copies', type => 'boolean'} ], return => {desc => '1 on success, Event on error'} } @@ -243,11 +244,59 @@ __PACKAGE__->register_method( params => [ {desc => 'Authentication token', type => 'string'}, {desc => 'lineitem ID to delete', type => 'number'}, + {desc => 'Even delete associated copies', type => 'boolean'} ], return => {desc => '1 on success, Event on error'} } ); + +# Deletes one fund debit given its ID ($debit_id) *iff* it's an orphan +# (i.e., it's not related to any of the tables that can point to a fund_debit, +# not including the lineitem detail with ID $lid_id). +# +# Returns nothing on success, event on failure. +sub delete_orphan_fund_debit { + my ($e, $debit_id, $lid_id) = @_; + + # Make sure the debit is orphaned first. + my $rows = $e->json_query({ + select => {acqfdeb => ["id"]}, + from => { + acqfdeb => { + acqii => { + type => "left", field => "fund_debit", fkey => "id" + }, + acqpoi => { + type => "left", field => "fund_debit", fkey => "id" + }, + acqlid => { + type => "left", field => "fund_debit", fkey => "id" + }, + acqda => { + type => "left", field => "fund_debit", fkey => "id" + } + } + }, + where => { + "+acqfdeb" => {id => $debit_id}, + "+acqii" => {id => undef}, + "+acqpoi" => {id => undef}, + "+acqda" => {id => undef}, + "+acqlid" => {id => $lid_id}, + } + }) or return $e->die_event; + + if (@$rows) { + $e->delete_acq_fund_debit( + $e->retrieve_acq_fund_debit($rows->[0]->{id}) + ) or return $e->die_event; + } + + return; # success +} + + __PACKAGE__->register_method( method => 'delete_lineitem', api_name => 'open-ils.acq.picklist.lineitem.delete', @@ -256,13 +305,14 @@ __PACKAGE__->register_method( params => [ {desc => 'Authentication token', type => 'string'}, {desc => 'lineitem ID to delete', type => 'number'}, + {desc => 'Even delete associated copies', type => 'boolean'} ], return => {desc => '1 on success, Event on error'} } ); sub delete_lineitem { - my($self, $conn, $auth, $li_id) = @_; + my($self, $conn, $auth, $li_id, $even_copies) = @_; my $e = new_editor(xact=>1, authtoken=>$auth); return $e->die_event unless $e->checkauth; @@ -295,9 +345,38 @@ sub delete_lineitem { {lineitem => $li_id}, {idlist=>1}); for my $lid_id (@$lid_ids) { - $e->delete_acq_lineitem_detail( - $e->retrieve_acq_lineitem_detail($lid_id)) - or return $e->die_event; + # Be careful not to leave orphaned fund debits hanging around when + # lineitems are deleted. + + my $lid = $e->retrieve_acq_lineitem_detail($lid_id); + + if ($lid->fund_debit) { + my $evt = delete_orphan_fund_debit($e, $lid->fund_debit, $lid->id); + return $evt if $evt; + } + + if ($lid->eg_copy_id) { + my $copies = $e->search_asset_copy([ + {id => $lid->eg_copy_id, deleted => 'f'}, + {flesh => 1, flesh_fields => {"acp" => ["call_number"]}} + ]) or return $e->die_event; + + if (@$copies) { + my $copy = $copies->[0]; + + if (not defined $even_copies) { + $e->rollback; + return new OpenILS::Event("NO_CHANGE", payload => $copy); + } elsif ($even_copies) { + $e->allowed("DELETE_COPY", $copy->call_number->owning_lib) or + return $e->die_event; + + $e->delete_asset_copy($copy) or return $e->die_event; + } # else just leave the copy alone + } + } + + $e->delete_acq_lineitem_detail($lid) or return $e->die_event; } $e->delete_acq_lineitem($li) or return $e->die_event; diff --git a/Open-ILS/src/templates/acq/common/li_table.tt2 b/Open-ILS/src/templates/acq/common/li_table.tt2 index 40546c8d07..ec5316d356 100644 --- a/Open-ILS/src/templates/acq/common/li_table.tt2 +++ b/Open-ILS/src/templates/acq/common/li_table.tt2 @@ -429,6 +429,24 @@