From be766fb0e06b946aa0eb83738a303433ed46be85 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 6 Apr 2015 11:24:33 -0400 Subject: [PATCH 1/1] LP#1436906 clean up PO direct charges on delete/cancel 1. Deleting a "direct charge" from a PO removes the linked fund_debit if the fund_debit has not been paid (i.e. it's still encumbered). If the debit has been paid, the charge cannot be removed, unless/until the debit is re-encumbered by un-invoicing the charge. 2. When a PO is canceled, fund_debits linked to PO items are removed. As above, if the debit has been paid (invoiced), the PO cannot be canceled, unless/until direct charge debits are un-invoiced. Signed-off-by: Bill Erickson Signed-off-by: Kathy Lussier Signed-off-by: Ben Shum --- .../lib/OpenILS/Application/Acq/Order.pm | 92 +++++++++++++++++++ .../web/js/ui/default/acq/po/item_table.js | 13 ++- 2 files changed, 100 insertions(+), 5 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm index 6883a0d61d..a63b948459 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm @@ -2926,6 +2926,26 @@ sub cancel_purchase_order { } } + my $po_item_ids = $mgr->editor + ->search_acq_po_item({purchase_order => $po_id}, {idlist => 1}); + + for my $po_item_id (@$po_item_ids) { + + my $po_item = $mgr->editor->retrieve_acq_po_item([ + $po_item_id, { + flesh => 1, + flesh_fields => {acqpoi => ['purchase_order', 'fund_debit']} + } + ]) or return -1; # results in rollback + + # returns undef on success + my $result = clear_po_item($mgr->editor, $po_item); + + return $result if not_cancelable($result); + return -1 if $result; # other failure events, results in rollback + } + + # TODO who/what/where/how do we indicate this change for electronic orders? # TODO return changes to encumbered/spent # TODO maybe cascade up from smaller object to container object if last @@ -3281,6 +3301,78 @@ sub cancel_lineitem_detail { return {"lid" => {$lid_id => {"cancel_reason" => $cancel_reason}}}; } +__PACKAGE__->register_method( + method => "delete_po_item_api", + api_name => "open-ils.acq.po_item.delete", + signature => { + desc => q/Deletes a po_item and removes its debit/, + params => [ + {desc => "Authentication token", type => "string"}, + {desc => "po_item ID to delete", type => "number"}, + ], + return => {desc => q/1 on success, Event on error/} + } +); + +sub delete_po_item_api { + my($self, $client, $auth, $po_item_id) = @_; + my $e = new_editor(authtoken => $auth, xact => 1); + return $e->die_event unless $e->checkauth; + + my $po_item = $e->retrieve_acq_po_item([ + $po_item_id, { + flesh => 1, + flesh_fields => {acqpoi => ['purchase_order', 'fund_debit']} + } + ]) or return $e->die_event; + + return $e->die_event unless + $e->allowed('CREATE_PURCHASE_ORDER', + $po_item->purchase_order->ordering_agency); + + # remove debit, delete item + my $result = clear_po_item($e, $po_item, 1); + + if ($result) { + $e->rollback; + return $result; + } + + $e->commit; + return 1; +} + + +# 1. Removes linked fund debit from a PO item if present and still encumbered. +# 2. Optionally also deletes the po_item object +# po_item is fleshed with purchase_order and fund_debit +sub clear_po_item { + my ($e, $po_item, $delete_item) = @_; + + if ($po_item->fund_debit) { + + if (!$U->is_true($po_item->fund_debit->encumbrance)) { + # debit has been paid. We cannot delete it. + return OpenILS::Event->new('ACQ_NOT_CANCELABLE', + note => "Debit is marked as paid: ".$po_item->fund_debit->id); + } + + # fund_debit is OK to delete. + $e->delete_acq_fund_debit($po_item->fund_debit) + or return $e->die_event; + } + + if ($delete_item) { + $e->delete_acq_po_item($po_item) or return $e->die_event; + } else { + # remove our link to the now-deleted fund_debit. + $po_item->clear_fund_debit; + $e->update_acq_po_item($po_item) or return $e->die_event; + } + + return undef; +} + __PACKAGE__->register_method( method => 'user_requests', diff --git a/Open-ILS/web/js/ui/default/acq/po/item_table.js b/Open-ILS/web/js/ui/default/acq/po/item_table.js index 4ed9a722c0..8752e34999 100644 --- a/Open-ILS/web/js/ui/default/acq/po/item_table.js +++ b/Open-ILS/web/js/ui/default/acq/po/item_table.js @@ -110,13 +110,16 @@ function PoItemTable() { this.deleteRow = function(id) { if (id > 0) { progressDialog.show(true); - pcrud.eliminate( - this.realItems[id], { - "oncomplete": function(r) { + fieldmapper.standardRequest( + ['open-ils.acq', 'open-ils.acq.po_item.delete'], + { async : true, + params: [openils.User.authtoken, id], + oncomplete : function(r) { progressDialog.hide(); r = openils.Util.readResponse(r); /* may not use */ - - self._deleteRow(id); + if (r == '1') { + self._deleteRow(id); + } } } ); -- 2.43.2