Receive/unreceive now by selected lineitem instead of whole PO
authorLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Wed, 6 Mar 2013 22:11:19 +0000 (17:11 -0500)
committerLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Mon, 11 Mar 2013 18:00:52 +0000 (14:00 -0400)
Signed-off-by: Lebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm
Open-ILS/web/js/dojo/openils/acq/nls/acq.js
Open-ILS/web/js/ui/default/acq/common/li_table.js

index da3e5c1..100fcb9 100644 (file)
@@ -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});
 
@@ -2150,6 +2152,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'
 );
@@ -2285,6 +2337,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',
@@ -2902,6 +3013,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);
 
index 51100b0..ad82f7b 100644 (file)
@@ -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",
index e727b64..c1a7018 100644 (file)
@@ -2550,12 +2550,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':
@@ -2821,29 +2821,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 =
@@ -2896,22 +2900,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,