Add open-ils.cat.asset.copy.batch.delete as a streaming method. user/dyrcona/lp921812
authorJason Stephenson <jstephenson@mvlc.org>
Fri, 9 Mar 2012 16:01:23 +0000 (11:01 -0500)
committerJason Stephenson <jstephenson@mvlc.org>
Fri, 9 Mar 2012 16:01:23 +0000 (11:01 -0500)
Use this method with appropriate callbacks in server/cat/util.js,
server/cat/copy_buckets.js, and circ/copy_status.js. This should
improve the performance of batch deletes in the client and allow
staff to delete more items at once.

This patch requires that working/user/dyrcona/lp939535 be applied
to OpenSRF in order to function properly.

Signed-off-by: Jason Stephenson <jstephenson@mvlc.org>
Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm
Open-ILS/xul/staff_client/server/cat/copy_buckets.js
Open-ILS/xul/staff_client/server/cat/util.js
Open-ILS/xul/staff_client/server/circ/copy_status.js

index e1d2c82..8264e63 100644 (file)
@@ -1308,7 +1308,94 @@ sub acn_sms_msg {
     );
 }
 
+__PACKAGE__->register_method(
+    method => "asset_copy_batch_delete",
+    api_name => "open-ils.cat.asset.copy.batch.delete",
+    stream => 1,
+);
+
+__PACKAGE__->register_method(
+    method => "asset_copy_batch_delete",
+    api_name => "open-ils.cat.asset.copy.batch.delete.override",
+    stream => 1,
+);
+
+sub asset_copy_batch_delete {
+    my ($self, $client, $auth, $copy_ids) = @_;
+
+    my $editor = new_editor(authtoken=>$auth);
+    return $editor->die_event unless $editor->checkauth;
+
+    # diddle with the client:
+    $client->recv_timeout(300);
+    $client->max_chunk_size(0);
+    $client->max_chunk_count(0);
+
+    # Check for override.
+    my $override = $self->api_name =~ /override/;
 
+    my $count = 0;
+    my $target = scalar(@{$copy_ids});
+    my $retarget_holds = [];
+    my $copies = [];
+
+    # Tell the client we've started.
+    $client->respond({'lookup' => [0,$target]});
+
+    # Retrieve copy data.
+    my $req = OpenSRF::AppSession->create('open-ils.cstore')
+        ->request(
+            'open-ils.cstore.direct.asset.copy.search',
+            { id => $copy_ids, deleted => 'f' },
+            { flesh => 1, flesh_fields => {'acp' => ['call_number']} }
+        );
+    while (my $r = $req->recv(count=>1,timeout=>300)) {
+        my $acp = $r->content;
+        if ($acp && $U->event_code($acp)) {
+            return $acp;
+        } else {
+            push(@$copies, $acp);
+        }
+        $count++;
+        $client->respond({'lookup' => [$count,$target]})
+            if (($count % 10 == 0) || $count == $target);
+    }
+    $req->finish;
+
+    # Reset count and target:
+    $count = 0;
+    $target = scalar(@{$copies});
+    $client->respond({'delete' => [$count,$target]});
+
+    $editor->xact_begin;
+    foreach my $acp (@$copies) {
+        my $r = $assetcom->delete_copy(
+            $editor,
+            $override,
+            $acp->call_number,
+            $acp,
+            $retarget_holds,
+            1,
+            0
+        );
+        if ($r && $U->event_code($r)) {
+            $editor->rollback;
+            return $r;
+        } else {
+            $count++;
+            $client->respond({'delete' => [$count,$target]}) if ($count % 10 == 0);
+        }
+    }
+    $editor->commit;
+    $U->simplereq(
+        'open-ils.circ',
+        'open-ils.circ.hold.reset.batch',
+        $auth,
+        $retarget_holds
+    ) if (@$retarget_holds);
+    $client->respond_complete({'delete' => [$count,$target]});
+    return undef;
+}
 
 1;
 
index 74fd2bf..8d659a7 100644 (file)
@@ -462,7 +462,9 @@ cat.copy_buckets.prototype = {
                         ['command'],
                         function() {
                             try {
-                            
+                                var cbdata = { didoverride : false };
+                                var app = 'open-ils.cat';
+                                var name = 'open-ils.cat.asset.copy.batch.delete';
                                 obj.list2.select_all();
 
                                 JSAN.use('util.widgets'); JSAN.use('util.functional');
@@ -474,49 +476,33 @@ cat.copy_buckets.prototype = {
                                     }
                                 );
 
-                                var copies = util.functional.map_list(
-                                    list,
-                                    function (acp_id) {
-                                        return obj.network.simple_request('FM_ACP_RETRIEVE',[acp_id]);
-                                    }
-                                );
-
-                                for (var i = 0; i < copies.length; i++) {
-                                    copies[i].ischanged(1);
-                                    copies[i].isdeleted(1);
-                                }
-
-                                var robj = obj.network.simple_request(
-                                    'FM_ACP_FLESHED_BATCH_UPDATE',
-                                    [ ses(), copies, true],
-                                    null, // no callback
-                                    {
-                                        'title' : document.getElementById('catStrings').getString('staff.cat.copy_buckets.batch.error'),
-                                        'overridable_events' : [
-                                            1208 /* TITLE_LAST_COPY */,
-                                            1227 /* COPY_DELETE_WARNING */
-                                        ]
-                                    }
-                                );
-                                if (typeof robj.ilsevent != 'undefined') {
-                                    switch(Number(robj.ilsevent)) {
-                                        case 1208 /* TITLE_LAST_COPY */ :
-                                        case 1227 /* COPY_DELETE_WARNING */ :
-                                        case 5000 /* PERM_DENIED */ :
-                                            // ignore this
-                                        break;
-                                        default:
-                                            obj.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_buckets.batch.error'), robj);
-                                    }
-                                }
-
+                                function completionCallback(r,d) {
+                                    if (!d.didoverride) {
                                 obj.render_pending_copies(); // FIXME -- need a generic refresh for lists
                                 setTimeout(
                                     function() {
                                         JSAN.use('util.widgets'); 
                                         util.widgets.dispatch('change_bucket',obj.controller.view.bucket_menulist);
-                                    }, 0
-                                );
+                                            }, 0);
+                                        // Stop the throbber
+                                        if (document.getElementById('network_progress')) {
+                                            if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.dec == 'function') g.menu.network_meter.dec(app,name);
+                                        } else if (typeof xulG != 'undefined') {
+                                            if (xulG && xulG.network_meter && typeof xulG.network_meter.dec == 'function') xulG.network_meter.dec(app,name);
+                                        }
+                                    }
+                                }
+
+                                // Gentlemen! Start your throbbers!
+                                if (document.getElementById('network_progress')) {
+                                    if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.inc == 'function') g.menu.network_meter.inc(app,name);
+                                } else if (typeof xulG != 'undefined') {
+                                    if (xulG && xulG.network_meter && typeof xulG.network_meter.inc == 'function') xulG.network_meter.inc(app,name);
+                                }
+
+                                JSAN.use('cat.util');
+                                cat.util.asset_copy_batch_delete(list, false, $('catStrings').getString('staff.cat.copy_buckets.batch.error'), completionCallback, cbdata);
+
                             } catch(E) {
                                 alert( js2JSON(E) );
                             }
index 75a3704..58b90e0 100644 (file)
@@ -12,7 +12,7 @@ cat.util.EXPORT_OK    = [
     'render_loan_duration', 'mark_item_as_missing_pieces', 'render_callnumbers_for_bib_menu',
     'render_cn_prefix_menuitems', 'render_cn_suffix_menuitems', 'render_cn_class_menu',
     'render_cn_prefix_menu', 'render_cn_suffix_menu', 'transfer_specific_title_holds',
-    'request_items', 'mark_for_overlay', 'get_cbs_for_bre_id'
+    'request_items', 'mark_for_overlay', 'get_cbs_for_bre_id', 'asset_copy_batch_delete'
 ];
 cat.util.EXPORT_TAGS    = { ':all' : cat.util.EXPORT_OK };
 
@@ -1288,4 +1288,66 @@ cat.util.get_cbs_for_bre_id = function(doc_id) {
     }
 }
 
+cat.util.asset_copy_batch_delete = function(copy_ids, override, title, completionCallback, data) {
+    var app = 'open-ils.cat';
+    var name = 'open-ils.cat.asset.copy.batch.delete';
+    if (override) name += '.override';
+
+    var requestOverride  = function(err) {
+
+        netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
+        var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' + 
+            '<groupbox><caption label="' + $('offlineStrings').getString('network.override.exceptions') + '"/>' + 
+            '<grid><columns><column/><column flex="1"/></columns><rows>';
+
+        var t1 = String(err.code).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+        var t2 = String(err.textcode).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+        var t3 = String(err.desc).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+        
+        xml += '<row>' + 
+            '<description class="oils_event" tooltiptext="' + t1 + '">' + t2 + '</description>' + 
+            '<description>' + t3 + '</description>' + '</row>';
+
+        xml += '</rows></grid></groupbox><groupbox><caption label="' + $('offlineStrings').getString('network.override.override') +'"/><hbox>' + 
+            '<description>' + $('offlineStrings').getString('network.override.force.prompt') + '</description>' + 
+            '<button accesskey="' + $('offlineStrings').getString('common.no.accesskey') + '" label="' + $('offlineStrings').getString('common.no') + '" name="fancy_cancel"/>' + 
+            '<button id="override" accesskey="' + $('offlineStrings').getString('common.yes.accesskey') + '" label="' + $('offlineStrings').getString('common.yes') +
+            '" name="fancy_submit" value="override"/></hbox></groupbox></vbox>';
+
+        JSAN.use('util.window'); var win = new util.window();
+        var fancy_prompt_data = win.open(urls.XUL_FANCY_PROMPT, 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500', { 'xml' : xml, 'title' : title  });
+        return (fancy_prompt_data.fancy_status == 'complete');
+    }
+
+    var responseCallback = function(r,d) {
+        dojo.require('openils.Util');
+        var robj = openils.Util.readResponse(r, true);
+
+        d.didoverride = false;
+     
+        if (typeof robj.textcode != 'undefined') {
+            if (!override && (robj.textcode == 'TITLE_LAST_COPY' || robj.textcode == 'COPY_DELETE_WARNING')) {
+                if (requestOverride(robj)) {
+                    d.didoverride = true;
+                    cat.util.asset_copy_batch_delete(copy_ids, true, title, completionCallback, d);
+                }
+            } else {
+                JSAN.use('util.error');
+                var error = new util.error();
+                error.standard_unexpected_error_alert(title, robj);
+            }
+        }
+    }
+
+    fieldmapper.standardRequest([app, name],  {
+        async : true,
+        timeout : 300,
+        params : [ses(), copy_ids],
+        onresponse : responseCallback,
+        oncomplete : completionCallback,
+        callbackdata : data
+    });
+
+}
+
 dump('exiting cat/util.js\n');
index c1fbbe4..7695960 100644 (file)
@@ -25,7 +25,7 @@ circ.copy_status.prototype = {
 
         JSAN.use('circ.util');
         var columns = circ.util.columns( 
-            
+{ 
                 'barcode' : { 'hidden' : false },
                 'title' : { 'hidden' : false },
                 'location' : { 'hidden' : false },
@@ -33,17 +33,17 @@ circ.copy_status.prototype = {
                 'acp_status' : { 'hidden' : false },
                 'alert_message' : { 'hidden' : false },
                 'due_date' : { 'hidden' : false }
-            },
-            {
+},
+{
                 'except_these' : [
                     'route_to', 'message', 'uses'
                 ]
-            }
+}
         );
 
         JSAN.use('util.list'); obj.list = new util.list('copy_status_list');
         obj.list.init(
-            {
+{
                 'columns' : columns,
                 'on_select' : function(ev) {
                     try {
@@ -123,12 +123,12 @@ circ.copy_status.prototype = {
                         alert('FIXME: ' + E);
                     }
                 }
-            }
+}
         );
         
         JSAN.use('util.controller'); obj.controller = new util.controller();
         obj.controller.init(
-            {
+{
                 'control_map' : {
                     'list_actions' : [
                         ['render'],
@@ -591,38 +591,13 @@ circ.copy_status.prototype = {
 
                                 JSAN.use('util.functional');
 
+                                          var cbdata = { didoverride : false };
+                                          var app = 'open-ils.cat';
+                                          var name = 'open-ils.cat.asset.copy.batch.delete';
                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.copy_id; } );
 
-                                var copies = util.functional.map_list(
-                                    list,
-                                    function (acp_id) {
-                                        return obj.network.simple_request('FM_ACP_RETRIEVE',[acp_id]);
-                                    }
-                                );
-
-                                for (var i = 0; i < copies.length; i++) {
-                                    copies[i].ischanged(1);
-                                    copies[i].isdeleted(1);
-                                }
-
-                                if (! window.confirm(document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.del_items.confirm', [util.functional.map_list( copies, function(o) { return o.barcode(); }).join(", ")]))) {
-                                    return;
-                                }
-
-                                var robj = obj.network.simple_request('FM_ACP_FLESHED_BATCH_UPDATE',[ ses(), copies, true]);
-                                var robj = obj.network.simple_request(
-                                    'FM_ACP_FLESHED_BATCH_UPDATE', 
-                                    [ ses(), copies, true ], 
-                                    null,
-                                    {
-                                        'title' : document.getElementById('circStrings').getString('staff.circ.copy_status.del_items.title'),
-                                        'overridable_events' : [
-                                            1208 /* TITLE_LAST_COPY */,
-                                            1227 /* COPY_DELETE_WARNING */
-                                        ]
-                                    }
-                                );
-    
+                                          var completionCallback = function(robj,data) {
+                                              if (!data.didoverride) {
                                 if (typeof robj.ilsevent != 'undefined') {
                                     switch(Number(robj.ilsevent)) {
                                         case 1208 /* TITLE_LAST_COPY */:
@@ -630,10 +605,31 @@ circ.copy_status.prototype = {
                                         case 5000 /* PERM_DENIED */:
                                         break;
                                         default:
-                                            obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.copy_status.del_items.success.error'), robj);
+                                                      obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.copy_status.del_items.success.error'),
+                                                                                                robj);
                                         break;
                                     }
                                 } else { alert(document.getElementById('circStrings').getString('staff.circ.copy_status.del_items.success')); }
+                                                  // Stop the throbber
+                                                  if (document.getElementById('network_progress')) {
+                                                      if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.dec == 'function') g.menu.network_meter.dec(app,name);
+                                                  } else if (typeof xulG != 'undefined') {
+                                                      if (xulG && xulG.network_meter && typeof xulG.network_meter.dec == 'function') xulG.network_meter.dec(app,name);
+                                                  }
+                                              }
+                                          }
+
+                                // Gentlemen! Start your throbbers!
+                                if (document.getElementById('network_progress')) {
+                                    if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.inc == 'function') g.menu.network_meter.inc(app,name);
+                                } else if (typeof xulG != 'undefined') {
+                                    if (xulG && xulG.network_meter && typeof xulG.network_meter.inc == 'function') xulG.network_meter.inc(app,name);
+                                }
+
+                                JSAN.use('cat.util');
+                                cat.util.asset_copy_batch_delete(list, false, document.getElementById('circStrings').getString('staff.circ.copy_status.del_items.success.error'),
+                                                                 completionCallback, cbdata);
+
 
                             } catch(E) {
                                 obj.error.standard_unexpected_error_alert('copy status -> delete items',E);