From: Lebbeous Fogle-Weekley Date: Wed, 6 Mar 2013 22:11:19 +0000 (-0500) Subject: Receive/unreceive now by selected lineitem instead of whole PO X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=8a7bb5d10d1eece718e10d342ae486af3189293b;p=evergreen%2Fequinox.git Receive/unreceive now by selected lineitem instead of whole PO Signed-off-by: Lebbeous Fogle-Weekley --- 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 60e30b212a..e6ea759427 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm @@ -580,6 +580,8 @@ sub receive_lineitem { my($mgr, $li_id, $skip_complete_check) = @_; my $li = $mgr->editor->retrieve_acq_lineitem($li_id) or return 0; + return 0 unless $li->state eq 'on-order' or $li->state eq 'cancelled'; # sic + my $lid_ids = $mgr->editor->search_acq_lineitem_detail( {lineitem => $li_id, recv_time => undef}, {idlist => 1}); @@ -2097,6 +2099,56 @@ sub receive_lineitem_api { __PACKAGE__->register_method( + method => 'receive_lineitem_batch_api', + api_name => 'open-ils.acq.lineitem.receive.batch', + signature => { + desc => 'Mark lineitems as received', + params => [ + {desc => 'Authentication token', type => 'string'}, + {desc => 'lineitem ID list', type => 'array'} + ], + return => {desc => + q/On success, stream of objects describing changes to LIs and + possibly PO; onerror, Event. Any event, even after lots of other + objects, should mean general failure of whole batch operation./ + } + } +); + +sub receive_lineitem_batch_api { + my ($self, $conn, $auth, $li_idlist) = @_; + + return unless ref $li_idlist eq 'ARRAY' and @$li_idlist; + + my $e = new_editor(xact => 1, authtoken => $auth); + return $e->die_event unless $e->checkauth; + + my $mgr = new OpenILS::Application::Acq::BatchManager( + editor => $e, conn => $conn + ); + + for my $li_id (map { int $_ } @$li_idlist) { + my $li = $e->retrieve_acq_lineitem([ + $li_id, { + flesh => 1, + flesh_fields => { jub => ['purchase_order'] } + } + ]) or return $e->die_event; + + return $e->die_event unless $e->allowed( + 'RECEIVE_PURCHASE_ORDER', $li->purchase_order->ordering_agency + ); + + receive_lineitem($mgr, $li_id) or return $e->die_event; + $mgr->respond; + } + + $e->commit or return $e->die_event; + $mgr->respond_complete; + $mgr->run_post_response_hooks; +} + +__PACKAGE__->register_method( method => 'rollback_receive_po_api', api_name => 'open-ils.acq.purchase_order.receive.rollback' ); @@ -2232,6 +2284,65 @@ sub rollback_receive_lineitem_api { $e->commit and return $result or return $e->die_event; } +__PACKAGE__->register_method( + method => 'rollback_receive_lineitem_batch_api', + api_name => 'open-ils.acq.lineitem.receive.rollback.batch', + signature => { + desc => 'Mark a list of lineitems as Un-received', + params => [ + {desc => 'Authentication token', type => 'string'}, + {desc => 'lineitem ID list', type => 'array'} + ], + return => {desc => + q/on success, a stream of objects describing changes to LI and + possibly PO; on error, Event. Any event means all previously + returned objects indicate changes that didn't really happen./ + } + } +); + +sub rollback_receive_lineitem_batch_api { + my ($self, $conn, $auth, $li_idlist) = @_; + + return unless ref $li_idlist eq 'ARRAY' and @$li_idlist; + + my $e = new_editor(xact => 1, authtoken => $auth); + return $e->die_event unless $e->checkauth; + + my $mgr = new OpenILS::Application::Acq::BatchManager( + editor => $e, conn => $conn + ); + + for my $li_id (map { int $_ } @$li_idlist) { + my $li = $e->retrieve_acq_lineitem([ + $li_id, { + "flesh" => 1, + "flesh_fields" => {"jub" => ["purchase_order"]} + } + ]); + + my $po = $li->purchase_order; + + return $e->die_event unless + $e->allowed('RECEIVE_PURCHASE_ORDER', $po->ordering_agency); + + $li = rollback_receive_lineitem($mgr, $li_id) or return $e->die_event; + + my $result = {"li" => {$li->id => {"state" => $li->state}}}; + if ($po->state eq "received") { # should happen first time, not after + $po->state("on-order"); + $po = update_purchase_order($mgr, $po) or return $e->die_event; + } + $result->{"po"} = describe_affected_po($e, $po); + + $mgr->respond(%$result); + } + + $e->commit or return $e->die_event; + $mgr->respond_complete; + $mgr->run_post_response_hooks; +} + __PACKAGE__->register_method( method => 'set_lineitem_price_api', @@ -2849,6 +2960,13 @@ sub cancel_lineitem { ) ); + # XXX LFW Some users are calling for lineitems not to be cancelable + # if they're in any of these states: + # new, selector-ready, order-ready, pending-order + # + # Sounds reasonable to me, but would enforcing that now break any existing + # (if unusual?) workflows? + $li->state("cancelled"); $li->cancel_reason($cancel_reason->id); diff --git a/Open-ILS/web/js/dojo/openils/acq/nls/acq.js b/Open-ILS/web/js/dojo/openils/acq/nls/acq.js index 51100b01d1..ad82f7b155 100644 --- a/Open-ILS/web/js/dojo/openils/acq/nls/acq.js +++ b/Open-ILS/web/js/dojo/openils/acq/nls/acq.js @@ -1,6 +1,7 @@ { "CREATE_PO_ASSETS_CONFIRM" : "This will create bibliographic, call number, and copy records for this purchase order in the ILS.\n\nContinue?", "ROLLBACK_PO_RECEIVE_CONFIRM" : "This will rollback receipt of all copies for this purchase order.\n\nContinue?", + "ROLLBACK_LI_RECEIVE_CONFIRM" : "This will rollback receipt of selected line items from this purchase order.\n\nContinue?", "XUL_RECORD_DETAIL_PAGE" : "Record Details", "DELETE_LI_COPIES_CONFIRM" : "This will delete the last ${0} copies in the table. Proceed?", "NO_PO_RESULTS" : "No results", diff --git a/Open-ILS/web/js/ui/default/acq/common/li_table.js b/Open-ILS/web/js/ui/default/acq/common/li_table.js index b06ff03861..ca41ddaba7 100644 --- a/Open-ILS/web/js/ui/default/acq/common/li_table.js +++ b/Open-ILS/web/js/ui/default/acq/common/li_table.js @@ -2174,12 +2174,12 @@ function AcqLiTable() { this.batchLinkInvoice(); break; - case 'receive_po': - this.receivePO(); + case 'receive_lineitems': + this.receiveSelectedLineitems(); break; - case 'rollback_receive_po': - this.rollbackPoReceive(); + case 'rollback_receive_lineitems': + this.rollbackReceiveLineitems(); break; case 'create_assets': @@ -2445,29 +2445,33 @@ function AcqLiTable() { acqLitLinkInvoiceDialog.show(); }; - this.receivePO = function() { - if (!this.isPO) return; + this.receiveSelectedLineitems = function() { + var li_list = this.getSelected(); + + for (var i = 0; i < li_list.length; i++) { + var li = li_list[i]; - for (var id in this.liCache) { - /* assumption: liCache reflects exactly the - * set of LIs that belong to our PO */ - if (this.liCache[id].state() != "received" && - !this.checkLiAlerts(id)) return; + if (li.state() != "received" && + !this.checkLiAlerts(li.id())) return; } this.show('acq-lit-progress-numbers'); + var self = this; fieldmapper.standardRequest( - ['open-ils.acq', 'open-ils.acq.purchase_order.receive'], + ['open-ils.acq', 'open-ils.acq.lineitem.receive.batch'], { async: true, - params: [this.authtoken, this.isPO], + params: [ + this.authtoken, + li_list.map(function(li) { return li.id(); }) + ], onresponse : function(r) { var resp = openils.Util.readResponse(r); self._updateProgressNumbers(resp, true); }, } ); - } + }; this.issueReceive = function(obj, rollback) { var part = @@ -2520,22 +2524,23 @@ function AcqLiTable() { } }; - this.rollbackPoReceive = function() { - if(!this.isPO) return; - if(!confirm(localeStrings.ROLLBACK_PO_RECEIVE_CONFIRM)) return; + this.rollbackReceiveLineitems = function() { + if (!confirm(localeStrings.ROLLBACK_LI_RECEIVE_CONFIRM)) return; + this.show('acq-lit-progress-numbers'); var self = this; + fieldmapper.standardRequest( - ['open-ils.acq', 'open-ils.acq.purchase_order.receive.rollback'], + ['open-ils.acq', 'open-ils.acq.lineitem.receive.rollback.batch'], { async: true, - params: [this.authtoken, this.isPO], + params: [this.authtoken, this.getSelected(false, null, true)], onresponse : function(r) { var resp = openils.Util.readResponse(r); self._updateProgressNumbers(resp, true); }, } ); - } + }; this._updateProgressNumbers = function(resp, reloadOnComplete, onComplete) { this.vlAgent.handleResponse(resp,