Updated rebase of enhanced spine label templates enabling
authorAdam Bowling <abowling@emeralddata.net>
Thu, 14 Jan 2021 16:23:43 +0000 (11:23 -0500)
committerAdam Bowling <abowling@emeralddata.net>
Thu, 14 Jan 2021 16:23:43 +0000 (11:23 -0500)
customized printing to templates.

Signed-off-by: Adam Bowling <abowling@emeralddata.net>
Open-ILS/src/templates/staff/cat/printlabels/t_view.tt2
Open-ILS/web/js/ui/default/staff/cat/bucket/copy/app.js
Open-ILS/web/js/ui/default/staff/cat/item/app.js
Open-ILS/web/js/ui/default/staff/cat/printlabels/app.js
Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js
Open-ILS/web/js/ui/default/staff/circ/checkin/app.js

index 86fcbc9..9d7ac7a 100644 (file)
@@ -5,7 +5,7 @@
       page-break-before: always;
   }
 
-  div.print-label-toolbox input[type=number], div.print-label-toolbox input[type=text] {
+    div.print-label-toolbox input[type=number], div.print-label-toolbox input[type=text] {
   border: 1px solid #999;
   border-radius: 3px;
   margin-right: 12px;
 
 <hr/>
 
+<!-- PINES customization -->
+<div style="width:40%;border:1px dashed gray;padding:10px;text-align:center;font-weight:bold;font-style:italic;margin-bottom:15px;">
+    <a href="https://pines.georgialibraries.org/dokuwiki/doku.php?id=cat:spine-label-printing" target="_blank">
+        Instructions for setting up spine & pocket labels
+    </a>
+</div>
+
 <div class="row">
     <div class="col-md-5">
         <ul class="nav nav-tabs">
@@ -319,4 +326,4 @@ label. Use pocket label left margin to identify how much space to provide betwee
           context="preview_scope"></div>
     </div>
     <!-- col -->
-</div>
\ No newline at end of file
+</div>
index 7f0f164..7d16534 100644 (file)
@@ -568,27 +568,20 @@ function($scope,  $q , $routeParams , $timeout , $window , $uibModal , bucketSvc
         $scope.detachCopies(copies);
     }
 
-    $scope.spawnHoldingsEdit = function() {
-        $scope.spawnEdit(true, false);
-    }
-
-    $scope.spawnCallNumberEdit = function() {
-        $scope.spawnEdit(false, true);
-    }
-
-    $scope.spawnEdit = function(hide_vols,hide_copies) {
+    $scope.spawnHoldingsEdit = function (copies) {
         var cp_list = []
         angular.forEach($scope.gridControls.selectedItems(), function (i) {
             cp_list.push(i.id);
-        });
+        })
+
         egCore.net.request(
             'open-ils.actor',
             'open-ils.actor.anon_cache.set_value',
             null, 'edit-these-copies', {
                 record_id: 0, // false-y value for record_id disables record summary
                 copies: cp_list,
-                hide_vols : hide_vols,
-                hide_copies : hide_copies
+                hide_vols : true,
+                hide_copies : false
             }
         ).then(function(key) {
             if (key) {
@@ -601,40 +594,43 @@ function($scope,  $q , $routeParams , $timeout , $window , $uibModal , bucketSvc
     }
 
     $scope.print_labels = function() {
-        var cp_list = []
+        var cp_list = [];
         angular.forEach($scope.gridControls.selectedItems(), function (i) {
             cp_list.push(i.id);
         })
-
+        console.log(cp_list);
+        //var cp_full = [], promises = [];
+        //promises.push(
+        //    egCore.pcrud.search('ccbi', { bucket: bucketSvc.currentBucket.a[2], "target_copy": { "in": cp_list } }).then(
+        //        null,
+        //        null,
+        //        function (ccbi) {
+        //            cp_full.push(egCore.idl.toHash(ccbi, true));
+        //        }
+        //    )
+        //);
         egCore.net.request(
             'open-ils.actor',
             'open-ils.actor.anon_cache.set_value',
             null, 'print-labels-these-copies', {
-                copies : cp_list
+                copies : cp_list //cp_full
             }
         ).then(function(key) {
-            if (cp_list.length > 0 ) {
-                if (key) {
-                    var url = egCore.env.basePath + 'cat/printlabels/' + key;
-                    $timeout(function() { $window.open(url, '_blank') });
+            //$q.all(promises).then(function () {
+                if (cp_list.length > 0) {
+                    if (key) {
+                        var url = egCore.env.basePath + 'cat/printlabels/' + key;
+                        $timeout(function() { $window.open(url, '_blank') });
+                    } else {
+                        alert('Could not create anonymous cache key!');
+                    }
                 } else {
-                    alert('Could not create anonymous cache key!');
+                    alert('Could not print label export');
                 }
-            } else {
-                alert('Could not print label export');
-            }
+            //});
         });
     }
 
-    $scope.showItems = function() {
-        var cp_list = []
-        angular.forEach($scope.gridControls.selectedItems(), function (i) {
-            cp_list.push(i.id);
-        })
-        var url = egCore.env.basePath + '/cat/item/search/' + cp_list.join();
-        $timeout(function() { $window.open(url, '_blank') });
-    }
-
     $scope.requestItems = function() {
         var copy_list = $scope.gridControls.selectedItems().map(
             function (i) {
index f0d5e67..a16de86 100644 (file)
@@ -86,12 +86,8 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
         itemSvc.add_copies_to_bucket([$scope.args.copyId]);
     }
 
-    $scope.add_records_to_bucket = function() {
-        itemSvc.add_records_to_bucket([$scope.args.recordId], 'biblio');
-    }
-
     $scope.show_in_catalog = function() {
-        window.open('/eg2/staff/catalog/record/' + $scope.args.recordId, '_blank');
+        window.open('/eg/staff/cat/catalog/record/' + $scope.args.recordId + '/catalog', '_blank');
     }
 
     $scope.print_labels = function() {
@@ -149,6 +145,41 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
         itemSvc.manage_reservations([$scope.args.copyBarcode]);
     }
 
+    $scope.findAcquisition = function() {
+        var acqData;
+        var promises = [];
+        $scope.openAcquisitionLineItem([$scope.args.copyId]);
+    }
+
+    $scope.openAcquisitionLineItem = function (cp_list) {
+        var hasResults = false;
+        var promises = [];
+
+        angular.forEach(cp_list, function (copyId) {
+            promises.push(
+                egNet.request(
+                    'open-ils.acq',
+                    'open-ils.acq.lineitem.retrieve.by_copy_id',
+                    egCore.auth.token(),
+                    copyId
+                ).then(function (acqData) {
+                    if (acqData) {
+                        if (acqData.a) {
+                            acqData = egCore.idl.toHash(acqData);
+                            var url = '/eg/acq/po/view/' + acqData.purchase_order + '/' + acqData.id;
+                            $timeout(function () { $window.open(url, '_blank') });
+                            hasResults = true;
+                        }
+                    }
+                })
+            )
+        });
+
+        $q.all(promises).then(function () {
+            !hasResults ? alert('There is no corresponding purchase order for this item.') : false;
+        });
+    }
+
     $scope.requestItems = function() {
         itemSvc.requestItems([$scope.args.copyId],[$scope.args.recordId]);
     }
@@ -169,7 +200,7 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
     }
 
     $scope.show_record_holds = function() {
-        window.open('/eg2/staff/catalog/record/' + $scope.args.recordId + '/holds', '_blank');
+        window.open('/eg/staff/cat/catalog/record/' + $scope.args.recordId + '/holds', '_blank');
     }
 
     $scope.add_item_alerts = function() {
@@ -363,9 +394,6 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
     };
 
     $scope.$watch('barcodesFromFile', function(newVal, oldVal) {
-        $scope.context.itemsNotFound = [];
-        $scope.context.fileDoneLoading = false;
-        $scope.context.numBarcodesInFile = 0;
         if (newVal && newVal != oldVal) {
             $scope.args.barcode = '';
             var barcodes = [];
@@ -392,20 +420,13 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
                     if(itemSvc.copies[0]){  // Were any copies actually retrieved
                         copyGrid.selectItems([itemSvc.copies[0].index]);
                     }
-                    $scope.context.fileDoneLoading = true;
                     return;
                 }
 
-                itemSvc.fetch(barcode).then(function(item) {
-                    if (!item) {
-                        $scope.context.itemsNotFound.push(barcode);
-                    }
-                    fetch_next_copy();
-                })
+                itemSvc.fetch(barcode).then(fetch_next_copy);
             }
 
             if (barcodes.length) {
-                $scope.context.numBarcodesInFile = barcodes.length;
                 egProgressDialog.open({value: 0, max: barcodes.length});
                 fetch_next_copy();
             }
@@ -415,40 +436,17 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
     $scope.context.search = function(args) {
         if (!args.barcode) return;
         $scope.context.itemNotFound = false;
-
-        //check to see if there are multiple barcodes in CSV format
-        var barcodes = [];
-        //split on commas and clean up barcodes
-        angular.forEach(args.barcode.split(/,/), function(line) {
-            //remove all whitespace and commas
-            line = line.replace(/[\s,]+/g,'');
-
-            //Or remove leading/trailing whitespace
-            //line = line.replace(/(^[\s,]+|[\s,]+$/g,'');
-
-            if (!line) return;
-            barcodes.push(line);
-        });
-
-        if(barcodes.length > 1){
-            //convert to newline seperated list and send to barcodesFromFile processor
-            $scope.barcodesFromFile = barcodes.join('\n');
-            //console.log('Barcodes: ',barcodes);
-        }
-        else {
-            //Single Barcode
-            itemSvc.fetch(args.barcode).then(function(res) {
-                if (res) {
-                    copyGrid.refresh();
-                    copyGrid.selectItems([res.index]);
-                    $scope.args.barcode = '';
-                } else {
-                    $scope.context.itemNotFound = true;
-                    egCore.audio.play('warning.item_status.itemNotFound');
-                }
-                $scope.context.selectBarcode = true;
-            })
-        }
+        itemSvc.fetch(args.barcode).then(function(res) {
+            if (res) {
+                copyGrid.refresh();
+                copyGrid.selectItems([res.index]);
+                $scope.args.barcode = '';
+            } else {
+                $scope.context.itemNotFound = true;
+                egCore.audio.play('warning.item_status.itemNotFound');
+            }
+            $scope.context.selectBarcode = true;
+        })
     }
 
     var add_barcode_to_list = function (b) {
@@ -506,17 +504,6 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
         return cp_id_list;
     }
 
-    function gatherSelectedHoldingsRecords() {
-        var record_id_list = [];
-        angular.forEach(
-            copyGrid.selectedItems(),
-            function (item) {
-                record_id_list.push(item['call_number.record.id']);
-            }
-        )
-        return record_id_list;
-    }
-
     $scope.refreshGridData = function() {
         var chain = $q.when();
         var all_items = itemSvc.copies.map(function(item) {
@@ -539,11 +526,6 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
         itemSvc.add_copies_to_bucket(copy_list);
     }
 
-    $scope.add_records_to_bucket = function() {
-        var record_list = gatherSelectedHoldingsRecords();
-        itemSvc.add_copies_to_bucket(record_list, 'biblio');
-    }
-
     $scope.locateAcquisition = function() {
         if (gatherSelectedHoldingsIds) {
             var cp_list = gatherSelectedHoldingsIds();
@@ -679,7 +661,7 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
 
     $scope.showBibHolds = function () {
         angular.forEach(gatherSelectedRecordIds(), function (r) {
-            var url = '/eg2/staff/catalog/record/' + r + '/holds';
+            var url = egCore.env.basePath + 'cat/catalog/record/' + r + '/holds';
             $timeout(function() { $window.open(url, '_blank') });
         });
     }
@@ -705,8 +687,8 @@ function($scope , $q , $window , $location , $timeout , egCore , egNet , egGridD
     $scope.print_labels = function() {
         var cp_list = gatherSelectedHoldingsIds();
         !$scope.gridDataProvider.sort ? cp_list.reverse() : $scope.gridDataProvider.sort.length === 0 ? cp_list.reverse() : false;
-
-        if (cp_list.length > 0) {
+        var i = 1;
+        if (cp_list.length > 0) {        
             egCore.net.request(
                 'open-ils.actor',
                 'open-ils.actor.anon_cache.set_value',
index ba3f135..d60660f 100644 (file)
@@ -123,7 +123,7 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet,
             selected: "spine-pocket"
         },
         page: {
-            column_class: ["spine", "pocket"],
+            column_class: ["spine"],
             dimensions: {
                 columns: 2,
                 rows: 1
@@ -166,7 +166,7 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet,
                     , 'settings': {}
                     , 'toolbox_settings': toolbox_settings
                     , 'get_cn_for': function (copy) {
-                        var key = copy.id;
+                        var key = copy.id; //$scope.rendered_cn_key_by_copy_id[copy.id];
                         if (key) {
                             var manual_cn = $scope.rendered_call_number_set[key];
                             if (manual_cn && manual_cn.value) {
@@ -290,7 +290,7 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet,
 
                     $q.all(promises2).then(function () {
                         // today, staff, current_location, etc.
-                        $scope.preview_scope.copies.sort((a, b) => (data.copies.indexOf(a.id) > data.copies.indexOf(b.id)) ? 1 : ((data.copies.indexOf(b.id) > data.copies.indexOf(a.id)) ? -1 : 0));
+                       $scope.preview_scope.copies.sort((a, b) => (data.copies.indexOf(a.id) > data.copies.indexOf(b.id)) ? 1 : ((data.copies.indexOf(b.id) > data.copies.indexOf(a.id)) ? -1 : 0));
                         egCore.print.fleshPrintScope($scope.preview_scope);
                         $scope.template_changed(); // load the default
                         $scope.rebuild_cn_set();
@@ -301,7 +301,6 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet,
                                 $scope.redraw_label_table();
                             }
                         }
-
                     });
 
                 });
@@ -313,12 +312,6 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet,
 
     }
 
-    $scope.checkForToolboxCustomizations = function (tText, redraw) {
-        var re = /eg\_plt\_(\d+)/;
-        redraw ? $scope.redraw_label_table() : false;
-        return re.test(tText);
-    }
-
     $scope.fetchTemplates = function (set_default) {
         return egCore.hatch.getItem('cat.printlabels.templates').then(function (t) {
             if (t) {
@@ -375,7 +368,7 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet,
                 , context: $scope.print.template_context
                 , cn_content: $scope.print.cn_template_content
                 , settings: JSON.parse(JSON.stringify($scope.preview_scope.settings))
-                , toolbox_settings: JSON.parse(JSON.stringify($scope.preview_scope.toolbox_settings))
+                , toolbox_settings: $scope.preview_scope.toolbox_settings
             };
             $scope.template_name_list = Object.keys($scope.templates);
 
@@ -410,7 +403,8 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet,
         .then(
             function (html) {
                 $scope.print.template_content = html;
-                $scope.redraw_label_table();
+               $scope.redraw_label_table();
+                //$scope.checkForToolboxCustomizations(html, true);
             },
             function () {
                 $scope.print.template_content = '';
@@ -525,9 +519,26 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet,
                         value : rendered_cn.textContent
                     };
                     copy.rendered_cn = rendered_cn; //{ value : rendered_cn.textContent };
-                    console.log(copy.rendered_cn.textContent);
+                   console.log(copy.rendered_cn.textContent);
                 }
             }
+            console.log("brick01");
+
+
+            //for (var i = 0; i < $scope.preview_scope.copies.length; i++) {
+            //    var copy = $scope.preview_scope.copies[i];
+            //    var rendered_cn = document.getElementById('cn_for_copy_' + copy.id);
+            //    if (rendered_cn && rendered_cn.textContent) {
+            //        var key = rendered_cn.textContent;
+            //        if (typeof $scope.rendered_call_number_set[key] == 'undefined') {
+            //            $scope.rendered_call_number_set[key] = {
+            //                value: key
+            //            };
+            //        }
+            //        $scope.rendered_cn_key_by_copy_id[copy.id] = key;
+                    //copy.rendered_cn = { value : rendered_cn.textContent };
+            //    }
+            //}
             $scope.preview_scope.tickle = Date() + ' ' + Math.random();
         });
     }
@@ -947,4 +958,4 @@ function getPrintLabelOutputClass(index, settings) {
 
 function getPrintLabelStyle(index, settings) {
     return index > 0 && (index % settings.page.label.set.size === 0) ? settings.page.label.gap.size : "";
-}
\ No newline at end of file
+}
index fc96edd..c380b54 100644 (file)
@@ -127,9 +127,10 @@ function(egCore , $q) {
     service.get_statcats = function(orgs) {
         return egCore.pcrud.search('asc',
             {owner : orgs},
-            { flesh : 1,
+            { flesh : 2,
               flesh_fields : {
-                asc : ['owner','entries']
+                asc : ['owner','entries'],
+                asce : ['value']
               },
               order_by : [{'class':'asc', 'field':'owner'},{'class':'asc', 'field':'name'},{'class':'asce', 'field':'value'} ]
             },
@@ -281,121 +282,109 @@ function(egCore , $q) {
 
     };
 
-    service.get_acp_templates = function() {
-        // Already downloaded for this user? Return local copy. Changing users or logging out causes another download
-        // so users always have their own templates, and any changes made on other machines appear as expected.
-        if (egCore.hatch.getSessionItem('cat.copy.templates.usr') == egCore.auth.user().id()) {
-            return egCore.hatch.getItem('cat.copy.templates').then(function(templ) {
-                return templ;
-            });
-        } else {
-            // this can be disabled for debugging to force a re-download and translation of test templates
-            egCore.hatch.setSessionItem('cat.copy.templates.usr', egCore.auth.user().id());
-            return service.load_remote_acp_templates();
-        }
-
-    };
-
-    service.save_acp_templates = function(t) {
-        egCore.hatch.setItem('cat.copy.templates', t);
-        egCore.net.request('open-ils.actor', 'open-ils.actor.patron.settings.update',
-            egCore.auth.token(), egCore.auth.user().id(), { "webstaff.cat.copy.templates": t });
-        // console.warn('Saved ' + JSON.stringify({"webstaff.cat.copy.templates": t}));
-    };
-
-    service.load_remote_acp_templates = function() {
-        // After the XUL Client is completely removed everything related
-        // to staff_client.copy_editor.templates and convert_xul_templates
-        // can be thrown away.
-        return egCore.net.request('open-ils.actor', 'open-ils.actor.patron.settings.retrieve.authoritative',
-            egCore.auth.token(), egCore.auth.user().id(),
-            ['webstaff.cat.copy.templates','staff_client.copy_editor.templates']).then(function(settings) {
-                if (settings['webstaff.cat.copy.templates']) {
-                    egCore.hatch.setItem('cat.copy.templates', settings['webstaff.cat.copy.templates']);
-                    return settings['webstaff.cat.copy.templates'];
-                } else {
-                    if (settings['staff_client.copy_editor.templates']) {
-                        var new_templ = service.convert_xul_templates(settings['staff_client.copy_editor.templates']);
-                        egCore.hatch.setItem('cat.copy.templates', new_templ);
-                        // console.warn('Saving: ' + JSON.stringify({'webstaff.cat.copy.templates' : new_templ}));
-                        egCore.net.request('open-ils.actor', 'open-ils.actor.patron.settings.update',
-                            egCore.auth.token(), egCore.auth.user().id(), {'webstaff.cat.copy.templates' : new_templ});
-                        return new_templ;
-                    }
-                }
-                return {};
-        });
-    };
-
-    service.convert_xul_templates = function(xultempl) {
-        var conv_templ = {};
-        var templ_names = Object.keys(xultempl);
-        var name;
-        var xul_t;
-        var curr_templ;
-        var stat_cats;
-        var fields;
-        var curr_field;
-        var tmp_val;
-        var i, j;
-
-        if (templ_names) {
-            for (i=0; i < templ_names.length; i++) {
-                name = templ_names[i];
-                curr_templ = {};
-                stat_cats = {};
-                xul_t  = xultempl[name];
-                fields = Object.keys(xul_t);
-
-                if (fields.length > 0) {
-                    for (j=0; j < fields.length; j++) {
-                        curr_field = xul_t[fields[j]];
-                        var field_name = curr_field["field"];
-
-                        if ( field_name == null ) { continue; }
-                        if ( curr_field["value"] == "<HACK:KLUDGE:NULL>" ) { continue; }
-
-                        // floating changed from a boolean to an integer at one point;
-                        // take this opportunity to remove the boolean from any old templates
-                        if ( curr_field["type"] === "attribute" && field_name === "floating" ) {
-                            if ( curr_field["value"].match(/[tf]/) ) { continue; }
-                        }
-
-                        if ( curr_field["type"] === "stat_cat" ) {
-                            stat_cats[field_name] = parseInt(curr_field["value"]);
-                        } else {
-                            tmp_val = curr_field['value'];
-                            if ( tmp_val.toString().match(/^[-0-9.]+$/)) {
-                                tmp_val = parseFloat(tmp_val);
-                            }
-
-                            if (field_name.match(/^batch_.*_menulist$/)) {
-                                // special handling for volume fields
-                                if (!("callnumber" in curr_templ)) curr_templ["callnumber"] = {};
-                                if (field_name === "batch_class_menulist")  curr_templ["callnumber"]["classification"] = tmp_val;
-                                if (field_name === "batch_prefix_menulist") curr_templ["callnumber"]["prefix"] = tmp_val;
-                                if (field_name === "batch_suffix_menulist") curr_templ["callnumber"]["suffix"] = tmp_val;
-                            } else {
-                                curr_templ[field_name] = tmp_val;
-                            }
-                        }
-                    }
-
-                    if ( (Object.keys(stat_cats)).length > 0 ) {
-                        curr_templ["statcats"] = stat_cats;
-                    }
-
-                    conv_templ[name] = curr_templ;
-                }
-            }
-        }
-        return conv_templ;
-    };
+   service.get_acp_templates = function() {
+       // Already downloaded for this user? Return local copy. Changing users or logging out causes another download
+       // so users always have their own templates, and any changes made on other machines appear as expected.
+       if (egCore.hatch.getSessionItem('cat.copy.templates.usr') == egCore.auth.user().id()) {
+           return egCore.hatch.getItem('cat.copy.templates').then(function(templ) {
+               return templ;
+           });
+       } else {
+          // this can be disabled for debugging to force a re-download and translation of test templates
+          egCore.hatch.setSessionItem('cat.copy.templates.usr', egCore.auth.user().id());
+          return service.load_remote_acp_templates();
+      }
+
+   };
+
+   service.save_acp_templates = function(t) {
+       egCore.hatch.setItem('cat.copy.templates', t);
+       egCore.net.request('open-ils.actor', 'open-ils.actor.patron.settings.update',
+           egCore.auth.token(), egCore.auth.user().id(), { "webstaff.cat.copy.templates": t });
+       // console.warn('Saved ' + JSON.stringify({"webstaff.cat.copy.templates": t}));
+   };
+
+   service.load_remote_acp_templates = function() {
+       // After the XUL Client is completely removed everything related to staff_client.copy_editor.templates and convert_xul_templates can be thrown away.
+       return egCore.net.request('open-ils.actor', 'open-ils.actor.patron.settings.retrieve.authoritative',
+           egCore.auth.token(), egCore.auth.user().id(),
+           ['webstaff.cat.copy.templates','staff_client.copy_editor.templates']).then(function(settings) {
+               if (settings['webstaff.cat.copy.templates']) {
+                   egCore.hatch.setItem('cat.copy.templates', settings['webstaff.cat.copy.templates']);
+                   return settings['webstaff.cat.copy.templates'];
+               } else {
+                   if (settings['staff_client.copy_editor.templates']) {
+                      var new_templ = service.convert_xul_templates(settings['staff_client.copy_editor.templates']);
+                      egCore.hatch.setItem('cat.copy.templates', new_templ);
+                      // console.warn('Saving: ' + JSON.stringify({'webstaff.cat.copy.templates' : new_templ}));
+                      egCore.net.request('open-ils.actor', 'open-ils.actor.patron.settings.update',
+                          egCore.auth.token(), egCore.auth.user().id(), {'webstaff.cat.copy.templates' : new_templ});
+                      return new_templ;
+                   }
+               }
+               return {};
+       });
+   };
+
+   service.convert_xul_templates = function(xultempl) {
+       var conv_templ = {};
+       var templ_names = Object.keys(xultempl);
+       var name;
+       var xul_t;
+       var curr_templ;
+       var stat_cats;
+       var fields;
+       var field_name;
+       var curr_field;
+       var tmp_val;
+       var i, j;
+
+       if (templ_names){
+         for (i=0; i < templ_names.length; i++) {
+           name = templ_names[i];
+           curr_templ = {};
+           stat_cats = {};
+           xul_t  = xultempl[name];
+           fields = Object.keys(xul_t);
+
+           if (fields.length > 0) {
+             for (j=0; j < fields.length; j++) {
+               field_name = fields[j];
+               curr_field = xul_t[field_name];
+
+               if ( curr_field["field"] == null ) { continue; }
+               if ( curr_field["value"] == "<HACK:KLUDGE:NULL>" ) { continue; }
+
+               // floating changed from a boolean to an integer at one point; take this opportunity to remove the boolean from any old templates
+               if ( curr_field["type"] === "attribute" && curr_field["field"] === "floating" ) {
+                 if ( curr_field["value"].match(/[tf]/) ) { continue; }
+               }
+
+               if ( curr_field["type"] === "stat_cat" ) {
+                 stat_cats[curr_field["field"]] = parseInt(curr_field["value"]);
+               }
+               else {
+                 tmp_val = curr_field['value']; // so... some of the number fields are actually strings. Groovy.
+                 if ( tmp_val.match(/^[-0-9.]+$/) && !(curr_field["field"].match(/(?:loan_duration|fine_level)/))) { tmp_val = parseFloat(tmp_val); }
+                 curr_templ[curr_field["field"]] = tmp_val;
+               }
+             }
+
+             if ( (Object.keys(stat_cats)).length > 0 ){
+               curr_templ["statcats"] = stat_cats;
+             }
+
+             conv_templ[name] = curr_templ;
+           }
+         }
+       }
+       return conv_templ;
+   };
 
     service.flesh = {   
         flesh : 3, 
         flesh_fields : {
-            acp : ['call_number','parts','stat_cat_entries', 'notes', 'tags', 'creator', 'editor'],
+            acp : ['call_number','parts','stat_cat_entries', 'notes', 'tags'],
             acn : ['label_class','prefix','suffix'],
             acptcm : ['tag']
         }
@@ -481,13 +470,12 @@ function(egCore , $q) {
     return service;
 }])
 
-.directive("egVolCopyEdit", ['egCore', function (egCore) {
+.directive("egVolCopyEdit", function () {
     return {
         restrict: 'E',
         replace: true,
         template:
-            '<div class="row" ng-class="{'+"'new-cp'"+':is_new}">'+
-                '<span ng-if="is_new" class="sr-only">' + egCore.strings.VOL_COPY_NEW_ITEM + '</span>' +
+            '<div class="row">'+
                 '<div class="col-xs-5" ng-class="{'+"'has-error'"+':barcode_has_error}">'+
                     '<input id="{{callNumber.id()}}_{{copy.id()}}"'+
                     ' eg-enter="nextBarcode(copy.id())" class="form-control"'+
@@ -507,13 +495,11 @@ function(egCore , $q) {
                 $scope.barcode_has_error = false;
                 $scope.duplicate_barcode = false;
                 $scope.empty_barcode = false;
-                $scope.is_new = false;
                 $scope.duplicate_barcode_string = window.duplicate_barcode_string;
                 $scope.empty_barcode_string = window.empty_barcode_string;
                 var duplicate_check_count = 0;
 
                 if (!$scope.copy.barcode()) $scope.copy.empty_barcode = true;
-                if ($scope.copy.isnew() || $scope.copy.id() < 0) $scope.copy.is_new = $scope.is_new = true;
 
                 $scope.selectOnFocus = function($event) {
                     if (!$scope.copy.empty_barcode)
@@ -591,29 +577,28 @@ function(egCore , $q) {
         ]
 
     }
-}])
+})
 
-.directive("egVolRow", ['egCore', function (egCore) {
+.directive("egVolRow", function () {
     return {
         restrict: 'E',
         replace: true,
         transclude: true,
         template:
-            '<div class="row" ng-class="{'+"'new-cn'"+':!callNumber.not_ephemeral}">'+
-                '<span ng-if="!callNumber.not_ephemeral" class="sr-only">' + egCore.strings.VOL_COPY_NEW_CALL_NUMBER + '</span>' +
+            '<div class="row">'+
                 '<div class="col-xs-2">'+
                     '<button aria-label="Delete" style="margin:-5px -15px; float:left;" ng-hide="callNumber.not_ephemeral" type="button" class="close" ng-click="removeCN()">&times;</button>' +
-                    '<select class="form-control" ng-model="classification" ng-change="updateClassification()" ng-options="cl.name() for cl in classification_list"></select>'+
+                    '<select class="form-control" ng-model="classification" ng-change="updateClassification()" ng-options="cl.name() for cl in classification_list"/>'+
                 '</div>'+
                 '<div class="col-xs-1">'+
-                    '<select class="form-control" ng-model="prefix" ng-change="updatePrefix()" ng-options="p.label() for p in prefix_list"></select>'+
+                    '<select class="form-control" ng-model="prefix" ng-change="updatePrefix()" ng-options="p.label() for p in prefix_list"/>'+
                 '</div>'+
                 '<div class="col-xs-2">'+
                     '<input class="form-control" type="text" ng-change="updateLabel()" ng-model="label"/>'+
                     '<div class="label label-danger" ng-if="empty_label">{{empty_label_string}}</div>'+
                 '</div>'+
                 '<div class="col-xs-1">'+
-                    '<select class="form-control" ng-model="suffix" ng-change="updateSuffix()" ng-options="s.label() for s in suffix_list"></select>'+
+                    '<select class="form-control" ng-model="suffix" ng-change="updateSuffix()" ng-options="s.label() for s in suffix_list"/>'+
                 '</div>'+
                 '<div ng-hide="onlyVols" class="col-xs-1"><input class="form-control" type="number" ng-model="copy_count" min="{{orig_copy_count}}" ng-change="changeCPCount()"></div>'+
                 '<div ng-hide="onlyVols" class="col-xs-5">'+
@@ -840,7 +825,7 @@ function(egCore , $q) {
         ]
 
     }
-}])
+})
 
 .directive("egVolEdit", function () {
     return {
@@ -1152,8 +1137,6 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
         return true;
     }
 
-    $scope.changed_fields = [];
-
     $scope.completeToWorking = function () {
         angular.forEach( $scope.completedGridControls.selectedItems(), function (c) {
             angular.forEach( $scope.completed_copies, function (w, i) {
@@ -1190,7 +1173,6 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
                                 return;
                             }
                             if (cp[field]() !== newval) {
-                                $scope.changed_fields[cp.$$hashKey+field] = true;
                                 cp[field](newval);
                                 cp.ischanged(1);
                                 $scope.dirty = true;
@@ -1202,14 +1184,6 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
         });
     }
 
-    // determine if any of the selected copies have had changed their value for this field:
-    $scope.field_changed = function (field){
-        // if objects controlling selection don't exist, assume the fields haven't changed
-        if(!$scope.workingGridControls || !$scope.workingGridControls.selectedItems){ return false; }
-        var selected = $scope.workingGridControls.selectedItems();
-        return selected.reduce((acc, cp) => acc || $scope.changed_fields[cp.$$hashKey+field], false);
-    };
-
     $scope.working = {
         MultiMap: {},
         statcats: {},
@@ -1244,7 +1218,6 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
                 angular.forEach(
                     $scope.workingGridControls.selectedItems(),
                     function (cp) {
-                        if (!angular.isArray(cp.copy_alerts())) cp.copy_alerts([]);
                         $scope.dirty = true;
                         angular.forEach(alerts, function(alrt) {
                             var a = egCore.idl.fromHash('aca', alrt);
@@ -1269,7 +1242,6 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
             angular.forEach(
                 $scope.workingGridControls.selectedItems(),
                 function (cp) {
-                    if (!angular.isArray(cp.notes())) cp.notes([]);
                     $scope.dirty = true;
                     angular.forEach(notes, function(note) {
                         var n = egCore.idl.fromHash('acpn', note);
@@ -2325,7 +2297,6 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
                     if (typeof(copy_alert.note) != 'undefined' &&
                         copy_alert.note != '') {
                         angular.forEach(copy_list, function (cp) {
-                            if (!angular.isArray(cp.copy_alerts())) cp.copy_alerts([]);
                             var a = new egCore.idl.aca();
                             a.isnew(1);
                             a.create_staff(copy_alert.create_staff);
index 92a2949..878b0f7 100644 (file)
@@ -41,6 +41,7 @@ function($scope , $q , $window , $location , $timeout , egCore , checkinSvc , eg
     $scope.checkins = checkinSvc.checkins;
     var today = new Date();
     $scope.checkinArgs = {backdate : today}
+    $scope.using_hatch_printer = egCore.hatch.usePrinting();
     $scope.modifiers = {};
     $scope.fine_total = 0;
     $scope.is_capture = $location.path().match(/capture$/);
@@ -48,10 +49,6 @@ function($scope , $q , $window , $location , $timeout , egCore , checkinSvc , eg
     $scope.grid_persist_key = $scope.is_capture ? 
         'circ.checkin.capture' : 'circ.checkin.checkin';
 
-    egCore.hatch.usePrinting().then(function(useHatch) {
-        $scope.using_hatch_printer = useHatch;
-    });
-
     // TODO: add this to the setting batch lookup below
     egCore.hatch.getItem('circ.checkin.strict_barcode')
         .then(function(sb){ $scope.strict_barcode = sb });
@@ -380,7 +377,7 @@ function($scope , $q , $window , $location , $timeout , egCore , checkinSvc , eg
             recordIds.push(i.acn.record());
         });
         angular.forEach(recordIds, function (r) {
-            var url = '/eg2/staff/catalog/record/' + r + '/holds';
+            var url = egCore.env.basePath + 'cat/catalog/record/' + r + '/holds';
             $timeout(function() { $window.open(url, '_blank') });
         });
     }