From 4e79ea3deabf4976565c822165ab2dc734c389e9 Mon Sep 17 00:00:00 2001 From: Lebbeous Fogle-Weekley Date: Tue, 11 Jun 2013 17:28:17 -0400 Subject: [PATCH] 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 --- .../lib/OpenILS/Application/Acq/Lineitem.pm | 87 +++++++++++++++++++++- Open-ILS/src/templates/acq/common/li_table.tt2 | 18 +++++ Open-ILS/web/css/theme/default/acq.css | 1 + Open-ILS/web/js/dojo/openils/Util.js | 25 ++++--- Open-ILS/web/js/ui/default/acq/common/li_table.js | 32 ++++++-- 5 files changed, 144 insertions(+), 19 deletions(-) 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 35d46485b8..0a4f0c4d4b 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Lineitem.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Lineitem.pm @@ -195,6 +195,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'} } @@ -208,11 +209,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', @@ -221,13 +270,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; @@ -260,9 +310,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 b19e5c3309..211dcd5bcc 100644 --- a/Open-ILS/src/templates/acq/common/li_table.tt2 +++ b/Open-ILS/src/templates/acq/common/li_table.tt2 @@ -423,6 +423,24 @@