toward lazy call number vivication/updates. some refactoring
authorJason Etheridge <jason@esilibrary.com>
Wed, 9 Mar 2011 21:49:43 +0000 (16:49 -0500)
committerJason Etheridge <jason@esilibrary.com>
Wed, 9 Mar 2011 21:49:43 +0000 (16:49 -0500)
Open-ILS/xul/staff_client/server/cat/volume_copy_creator.js

index 782b99f..13d7c96 100644 (file)
@@ -260,7 +260,12 @@ g.render_callnumber_copy_count_entry = function(row,ou_id,count) {
         x.setAttribute('value',$("catStrings").getString('staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.barcodes_and_parts'));
         x.setAttribute('style','font-weight: bold');
 
-    function handle_change(call_number_column_textbox,number_of_copies_column_textbox,barcode_column_box) {
+    function handle_change_precipitating_barcode_rendering(
+        callnumber_composite_key,
+        number_of_copies_column_textbox,
+        barcode_column_box
+    ) {
+
         if (isNaN( Number( number_of_copies_column_textbox.value ) )) return;
         if ( Number( number_of_copies_column_textbox.value ) > g_max_copies_that_can_be_added_at_a_time_per_volume ) {
             g.error.yns_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.render_volume_count_entry.message', [g_max_copies_that_can_be_added_at_a_time_per_volume]),
@@ -274,7 +279,7 @@ g.render_callnumber_copy_count_entry = function(row,ou_id,count) {
         }
         g.render_barcode_entry(
             barcode_column_box,
-            call_number_column_textbox.value,
+            callnumber_composite_key,
             Number(number_of_copies_column_textbox.value),
             ou_id
         );
@@ -287,13 +292,35 @@ g.render_callnumber_copy_count_entry = function(row,ou_id,count) {
         }
     }
 
-    function handle_change_call_number_column_textbox(ev) {
+    function handle_change_to_callnumber_data(ev) {
         var _call_number_column_textbox = ev.target;
         var _call_number_column_box = _call_number_column_textbox.parentNode;
-        var _number_of_copies_column_box = _call_number_column_box.nextSibling.nextSibling; /* two over */
+
+        var _classification_column_box = _call_number_column_box.prevSibling.prevSibling; /* two over to the left */
+        var _classification_column_menulist = _call_number_column_box.firstChild;
+
+        var _prefix_column_box = _call_number_column_box.prevSibling; /* one over to the left */
+        var _prefix_column_menulist = _call_number_column_box.firstChild;
+
+        var _suffix_column_box = _call_number_column_box.nextSibling; /* one over to the right */
+        var _suffix_column_menulist = _call_number_column_box.firstChild;
+
+        var _number_of_copies_column_box = _call_number_column_box.nextSibling.nextSibling; /* two over to the right */
         var _number_of_copies_column_textbox = _number_of_copies_column_box.firstChild;
+
         var _barcode_column_box = _number_of_copies_column_box.nextSibling;
-        handle_change(_call_number_column_textbox,_number_of_copies_column_textbox,_barcode_column_box);
+
+        var acn_label = _call_number_column_textbox.value;
+        var acnc_id = _classification_column_menulist.value;
+        var acnp_id = _prefix_column_menulist.value;
+        var acns_id = _suffix_column_menulist.value;
+        var callnumber_composite_key = class_id + ':' + acnp_id + ':' + acn_label + ':' + acns_id;
+
+        handle_change_precipitating_barcode_rendering(
+            callnumber_composite_key,
+            _number_of_copies_column_textbox,
+            _barcode_column_box
+        );
     }
 
     function handle_change_number_of_copies_column_textbox(ev) {
@@ -301,8 +328,7 @@ g.render_callnumber_copy_count_entry = function(row,ou_id,count) {
         var _number_of_copies_column_box = _number_of_copies_column_textbox.parentNode;
         var _call_number_column_box = _number_of_copies_column_box.previousSibling.previousSibling; /* two over */
         var _call_number_column_textbox = _call_number_column_box.firstChild;
-        var _barcode_column_box = _number_of_copies_column_box.nextSibling;
-        handle_change(_call_number_column_textbox,_number_of_copies_column_textbox,_barcode_column_box);
+        handle_change_to_callnumber_data({'target':_call_number_column_textbox}); // let this guy do the work
     }
 
     for (var i = 0; i < count; i++) {
@@ -331,7 +357,7 @@ g.render_callnumber_copy_count_entry = function(row,ou_id,count) {
                     util.widgets.apply_vertical_tab_on_enter_handler(
                         call_number_column_textbox,
                         function() {
-                            handle_change_call_number_column_textbox({'target':call_number_column_textbox});
+                            handle_change_to_callnumber_data({'target':call_number_column_textbox});
                             setTimeout(
                                 function(){
                                     util.widgets.vertical_tab(call_number_column_textbox);
@@ -340,18 +366,31 @@ g.render_callnumber_copy_count_entry = function(row,ou_id,count) {
                         },
                         g.abort_gather_copies_soon
                     );
-                    call_number_column_textbox.addEventListener( 'change', handle_change_call_number_column_textbox, false);
+                    call_number_column_textbox.addEventListener( 'change', handle_change_to_callnumber_data, false);
                     call_number_column_textbox.addEventListener( 'change', g.gather_copies_soon, false);
                     call_number_column_textbox.addEventListener( 'focus', function(ev) { g.last_focus = ev.target; }, false );
 
                     /**** CLASSIFICATION COLUMN revisited ****/
                     var classification_column_menulist = g.render_class_menu(call_number_column_textbox);
-                    classification_column_menulist.addEventListener( 'command', g.gather_copies_soon, false);
+                    classification_column_menulist.addEventListener(
+                        'command',
+                        function() {
+                            handle_change_to_callnumber_data({'target':call_number_column_textbox});
+                        }
+                        ,false
+                    );
                     classification_column_box.appendChild(classification_column_menulist);
 
                     /**** PREFIX COLUMN revisited ****/
                     var prefix_column_menulist = g.render_prefix_menu(call_number_column_textbox);
-                    prefix_column_menulist.addEventListener( 'command', g.gather_copies_soon, false);
+                    prefix_column_menulist.addEventListener(
+                        'command',
+                        function() {
+                            handle_change_to_callnumber_data({'target':call_number_column_textbox});
+                        }
+                        ,false
+                    );
+
                     prefix_column_box.appendChild(prefix_column_menulist);
 
             /**** SUFFIX COLUMN ****/
@@ -415,7 +454,7 @@ g.render_callnumber_copy_count_entry = function(row,ou_id,count) {
                                 }
                             }
                             call_number_column_textbox.value = label;
-                            handle_change_call_number_column_textbox({'target':call_number_column_textbox});
+                            handle_change_to_callnumber_data({'target':call_number_column_textbox});
                         } else {
 
                             // if we're providing defaults, keep on rendering
@@ -514,7 +553,7 @@ g.render_part_menuitems = function(menupopup) {
 
 }
 
-g.render_barcode_entry = function(node,callnumber,count,ou_id) {
+g.render_barcode_entry = function(node,callnumber_composite_key,count,ou_id) {
     try {
         function ready_to_create(ev) {
             if (! xulG.unified_interface) {
@@ -546,7 +585,7 @@ g.render_barcode_entry = function(node,callnumber,count,ou_id) {
                 part_menu = tb_part_box.lastChild;
             }
             tb.setAttribute('ou_id',ou_id);
-            tb.setAttribute('callnumber',callnumber);
+            tb.setAttribute('callkey',callnumber_composite_key);
             tb.setAttribute('rel_vert_pos',rel_vert_pos_barcode);
             part_menu.firstChild.setAttribute('rel_vert_pos',rel_vert_pos_part);
             if (!tb.value && g.org_label_existing_copy_map[ ou_id ]) {
@@ -654,21 +693,24 @@ g.gather_copies_soon = function() {
 }
 
 g.new_acp_id = -1;
+g.new_acn_id = -1;
 
 g.gather_copies = function() {
     dump('g.gather_copies()\n');
     try {
         var nl = document.getElementsByTagName('textbox');
 
-        var volumes_hash = {};
+        g.volumes_scaffold = {};
         /*
-            volumes_hash = {
+            g.volumes_scaffold = {
                 '#ou_id' : {
-                    '#callnumber label' : {
+                    '#class_id:#prefix_id:#callnumber label:#suffix_id' : {
                         'call_number_data' : {
+                            'acn_id' : '#callnumber id',
+                            'acn_label' : '#callnumber label',
                             'acnc_id' : '#classification_id',
                             'acnp_id' : '#prefix_id',
-                            'acns_id' : '#suffix_id',
+                            'acns_id' : '#suffix_id'
                         },
                         'barcode_data' :
                             [
@@ -690,17 +732,21 @@ g.gather_copies = function() {
             if ( nl[i].getAttribute('rel_vert_pos') == rel_vert_pos_call_number )  {
                 v_count++;
                 var ou_id = nl[i].getAttribute('ou_id');
-                var acnc_id = nl[i].getAttribute('acnc_id');
-                var acnp_id = nl[i].getAttribute('acnp_id');
-                var acns_id = nl[i].getAttribute('acns_id');
+                var acn_id = nl[i].getAttribute('acn_id') || g.new_acn_node--;
+                var acnc_id = nl[i].getAttribute('acnc_id') || g.label_class;
+                var acnp_id = nl[i].getAttribute('acnp_id') || -1;
+                var acns_id = nl[i].getAttribute('acns_id') || -1;
                 var callnumber = nl[i].value;
-                if (typeof volumes_hash[ou_id] == 'undefined') {
-                    volumes_hash[ou_id] = {}
+                if (typeof g.volumes_scaffold[ou_id] == 'undefined') {
+                    g.volumes_scaffold[ou_id] = {}
                 }
-                if (typeof volumes_hash[ou_id][callnumber] == 'undefined') {
-                    volumes_hash[ou_id][callnumber] = {
+                var composite_key = acnc_id + ':' + acnp_id + ':' + callnumber + ':' + acns_id;
+                if (typeof g.volumes_scaffold[ou_id][composite_key] == 'undefined') {
+                    g.volumes_scaffold[ou_id][composite_key] = {
                         'node' : nl[i],
                         'call_number_data' : {
+                            'acn_id' : acn_id,
+                            'acn_label' : callnumber,
                             'acnc_id' : acnc_id,
                             'acnp_id' : acnp_id,
                             'acns_id' : acns_id
@@ -715,24 +761,31 @@ g.gather_copies = function() {
         for (var i = 0; i < barcodes.length; i++) {
             var acp_id = barcodes[i].getAttribute('acp_id') || g.new_acp_id--;
             var ou_id = barcodes[i].getAttribute('ou_id');
-            var callnumber = barcodes[i].getAttribute('callnumber');
+            var callnumber_composite_key = barcodes[i].getAttribute('callkey');
             var barcode = barcodes[i].value;
             var bmp_id = barcodes[i].getAttribute('bmp_id');
 
-            if (typeof volumes_hash[ou_id] == 'undefined') {
-                alert('1: I want to remove this soon, so alert me if it is getting used, ou_id = ' + ou_id);
-                volumes_hash[ou_id] = {}
+            if (typeof g.volumes_scaffold[ou_id] == 'undefined') {
+                dump('1: I want to remove this soon, so alert me if it is getting used, ou_id = ' + ou_id + '\n');
+                g.volumes_scaffold[ou_id] = {}
             }
-            if (typeof volumes_hash[ou_id][callnumber] == 'undefined') {
-                alert('2: when does this happen, and why? ou_id = ' + ou_id + ' callnumber = ' + callnumber);
-                volumes_hash[ou_id][callnumber] = {
-                    'call_number_data' : {},
+            if (typeof g.volumes_scaffold[ou_id][callnumber_composite_key] == 'undefined') {
+                dump('2: when does this happen, and why? ou_id = ' + ou_id + ' callnumber_composite_key = ' + callnumber_composite_key + '\n');
+                // one way this can happen, race condition between this function and editing a widget
+                g.volumes_scaffold[ou_id][callnumber_composite_key] = {
+                    'call_number_data' : {
+                        // not ideal, but hey...
+                        'acn_label' : callnumber_composite_key.split(/:/).slice(2,-1).join(':'),
+                        'acnc_id' : callnumber_composite_key.split(/:/)[0],
+                        'acnp_id' : callnumber_composite_key.split(/:/)[1],
+                        'acns_id' : callnumber_composite_key.split(/:/).slice(-1)[0]
+                    },
                     'barcode_data' : []
                 }
             }
 
             if (barcode != '') {
-                volumes_hash[ou_id][callnumber].barcode_data.push(
+                g.volumes_scaffold[ou_id][callnumber_composite_key].barcode_data.push(
                     {
                         'barcode' : barcode,
                         'acp_id' : acp_id,
@@ -768,78 +821,90 @@ g.gather_copies = function() {
             return copy;
         }
 
-        for (var ou_id in volumes_hash) {
-            for (var cn_label in volumes_hash[ou_id]) {
+        for (var ou_id in g.volumes_scaffold) {
+            for (var composite_key in g.volumes_scaffold[ou_id]) {
+                for (var i = 0; i < g.volumes_scaffold[ou_id][composite_key].barcode_data.length; i++) {
+                    var barcode = g.volumes_scaffold[ou_id][composite_key].barcode_data[i].barcode;
+                    var acp_id = g.volumes_scaffold[ou_id][composite_key].barcode_data[i].acp_id;
+                    var bmp_id = g.volumes_scaffold[ou_id][composite_key].barcode_data[i].bmp_id;
+                    var acn_id = g.volumes_scaffold[ou_id][composite_key].callnumber_data.acn_id;
+                    var copy = g.id_copy_map[ acp_id ];
+                    if (!copy) {
+                        copy = new_copy(acp_id,ou_id,acn_id,barcode);
+                        g.id_copy_map[ acp_id ] = copy;
+                    } else {
+                        copy.ischanged('1');
+                    }
+                    copy.barcode( barcode );
+                    if (typeof g.acn_map[ acn_id ] != 'undefined') {
+                        copy.call_number( g.acn_map[ acn_id].id() ); /* handles vivicated call numbers */
+                    } else {
+                        dump('FIXME: In volume_copy_creator.js, g.gather_copies(), using acn_id, but no g.acn_map[acn_id].  acn_id = ' + acn_id + '\n');
+                        copy.call_number( acn_id );
+                    }
+                    // FIXME - at some point we will have multi-home multi-part items, and will need to preserve foreign parts
+                    copy.parts( bmp_id ? [ g.parts_hash[ bmp_id ] ] : null );
+                    copies.push( copy );
+                }
+            }
+        }
 
-                var acn_blob = g.network.simple_request(
-                    'FM_ACN_FIND_OR_CREATE',
-                    [ ses(), cn_label, g.doc_id, ou_id ]
-                );
+        xulG.copies = copies;
+        return copies;
 
-                if (typeof acn_blob.ilsevent != 'undefined') {
-                    g.error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.stash_and_close.problem_with_volume', [cn]), acn_blob);
-                    continue;
-                }
+    } catch(E) {
+        g.error.standard_unexpected_error_alert('Error in volume_copy_creator.js, g.gather_copies():',E);
+    }
+}
+
+g.vivicate_volumes = function() {
+    try {
+        for (var ou_id in g.volumes_scaffold) {
+            for (var composite_key in g.volumes_scaffold[ou_id]) {
+
+                var callnumber_data = g.volumes_scaffold[ou_id][composite_key];
+                var acn_id = callnumber_data.acn_id;
 
-                var existed_and_first_load = acn_blob.existed;
-                var acn_id = acn_blob.acn_id;
+                if (acn_id < 0) {
 
-                var my_acn;
-                if (typeof g.acn_map[ acn_id ] == 'undefined') {
-                    my_acn = g.network.simple_request(
-                        'FM_ACN_RETRIEVE.authoritative',
-                        [ acn_id ]
+                    var acn_blob = g.network.simple_request(
+                        'FM_ACN_FIND_OR_CREATE',
+                        [ ses(), callnumber_data.acn_label, g.doc_id, ou_id ]
                     );
-                    if (typeof my_acn.ilsevent != 'undefined') {
-                        g.error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.stash_and_close.problem_with_volume', [cn]), acn_id);
+
+                    if (typeof acn_blob.ilsevent != 'undefined') {
+                        g.error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.stash_and_close.problem_with_volume', [cn]), acn_blob);
                         continue;
                     }
-                    g.acn_map[ acn_id ] = my_acn;
-                } else {
-                    existed_and_first_load = false;
-                }
-                my_acn = g.acn_map[ acn_id ];
-
-                volume_data[ acn_id ] = {
-                    'label' : cn_label,
-                    'owning_lib' : ou_id
-                };
-                for (var i in volumes_hash[ou_id][cn_label].call_number_data) {
-                    volume_data[ acn_id ][ i ] = volumes_hash[ou_id][cn_label].call_number_data[i];
+
+                    acn_id = acn_blob.acn_id;
+
+                    if (typeof g.acn_map[ acn_id ] == 'undefined') {
+                        var temp_acn = g.network.simple_request(
+                            'FM_ACN_RETRIEVE.authoritative',
+                            [ acn_id ]
+                        );
+                        if (typeof my_acn.ilsevent != 'undefined') {
+                            g.error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.stash_and_close.problem_with_volume', [cn]), acn_id);
+                            continue;
+                        }
+                        g.acn_map[ acn_id ] = temp_acn;
+                        if (callnumber_data.acn_id < 0) {
+                            g.acn_map[ callnumber_data.acn_id ] = temp_acn;
+                        }
+                    }
+
                 }
+                var my_acn = g.acn_map[ acn_id ];
 
-                var node = volumes_hash[ou_id][cn_label].node;
+                var node = g.volumes_scaffold[ou_id][composite_key].node;
                 var class_menulist = node.parentNode.previousSibling.previousSibling.firstChild;
                 var prefix_menulist = node.parentNode.previousSibling.firstChild;
                 var suffix_menulist = node.parentNode.nextSibling.firstChild;
 
-                if (existed_and_first_load) {
                     class_menulist.value = my_acn.label_class();
-                } else if (volume_data[ acn_id ][ 'acnc_id' ]) {
-                    var new_value = volume_data[ acn_id ][ 'acnc_id' ];
-                    if (Number(my_acn.label_class()) != Number(new_value)) {
-                        my_acn.label_class( Number(new_value) );
-                        my_acn.ischanged( get_db_true() );
-                    }
-                }
-                if (existed_and_first_load) {
                     prefix_menulist.value = my_acn.prefix();
-                } else if (volume_data[ acn_id ][ 'acnp_id' ]) {
-                    var new_value = volume_data[ acn_id ][ 'acnp_id' ];
-                    if (Number(my_acn.prefix()) != Number(new_value)) {
-                        my_acn.prefix( Number(new_value) );
-                        my_acn.ischanged( get_db_true() );
-                    }
-                }
-                if (existed_and_first_load) {
                     suffix_menulist.value = my_acn.suffix();
-                } else if (volume_data[ acn_id ][ 'acns_id' ]) {
-                    var new_value = volume_data[ acn_id ][ 'acns_id' ];
-                    if (Number(my_acn.suffix()) != Number(new_value)) {
-                        my_acn.suffix( Number(new_value) );
-                        my_acn.ischanged( get_db_true() );
-                    }
-                }
 
                 if (get_bool( my_acn.ischanged() )) {
                     dump('******\nPUSHING my_acn = ' + js2JSON(my_acn) + '\n',4);
@@ -847,32 +912,10 @@ g.gather_copies = function() {
                 } else {
                     dump('******\nNOT PUSHING my_acn = ' + js2JSON(my_acn) + '\n',4);
                 }
-
-                for (var i = 0; i < volumes_hash[ou_id][cn_label].barcode_data.length; i++) {
-                    var barcode = volumes_hash[ou_id][cn_label].barcode_data[i].barcode;
-                    var acp_id = volumes_hash[ou_id][cn_label].barcode_data[i].acp_id;
-                    var bmp_id = volumes_hash[ou_id][cn_label].barcode_data[i].bmp_id;
-                    var copy = g.id_copy_map[ acp_id ];
-                    if (!copy) {
-                        copy = new_copy(acp_id,ou_id,acn_id,barcode);
-                        g.id_copy_map[ acp_id ] = copy;
-                    } else {
-                        copy.ischanged('1');
-                    }
-                    copy.barcode( barcode );
-                    copy.call_number( acn_id );
-                    copy.parts( bmp_id ? [ g.parts_hash[ bmp_id ] ] : null );
-                    copies.push( copy );
-                }
             }
         }
-
-        xulG.copies = copies;
-        xulG.volumes = volumes;
-        return { 'copies' : copies, 'volumes' : volumes };
-
     } catch(E) {
-        g.error.standard_unexpected_error_alert('Error in volume_copy_creator.js, g.gather_copies():',E);
+        alert('Error in volume_copy_creator.js, vivicate_volumes(): ' + E);
     }
 }
 
@@ -884,11 +927,9 @@ g.stash_and_close = function(param) {
         var copies;
         if (xulG.unified_interface) {
             copies = xulG.copies;
-            volumes = xulG.volumes;
         } else {
-            var blob = g.gather_copies();
+            var copies = g.gather_copies();
             copies = blob.copies;
-            volumes = blob.volumes;
         }
 
         var dont_close = false;