From f50b4a1a4b9990e5a643f3572c50fba2c83ac973 Mon Sep 17 00:00:00 2001 From: Adam Bowling Date: Fri, 16 Aug 2019 02:17:21 -0400 Subject: [PATCH] LP# 1811898: Fixes improper display and printing of long call numbers in the spine label print view. Signed-off-by: Adam Bowling --- .../web/js/ui/default/staff/cat/printlabels/app.js | 137 +++++++++++---------- 1 file changed, 71 insertions(+), 66 deletions(-) diff --git a/Open-ILS/web/js/ui/default/staff/cat/printlabels/app.js b/Open-ILS/web/js/ui/default/staff/cat/printlabels/app.js index 255368931f..7958f9257f 100644 --- a/Open-ILS/web/js/ui/default/staff/cat/printlabels/app.js +++ b/Open-ILS/web/js/ui/default/staff/cat/printlabels/app.js @@ -265,8 +265,9 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet, angular.forEach(data.copies, function (copy) { promises.push( - itemSvc.fetch(null, copy).then(function (res) { + itemSvc.fetch(null, copy.target_copy).then(function (res) { var flat_copy = egCore.idl.toHash(res.copy, true); + flat_copy.copy_bucket_item_id = copy.id; $scope.preview_scope.copies.push(flat_copy); $scope.record_details[flat_copy['call_number.record.id']] = 1; }) @@ -289,6 +290,8 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet, }); $q.all(promises2).then(function () { + // sort copies into the order they were entered into the bucket + $scope.preview_scope.copies.sort((a, b) => (a.copy_bucket_item_id > b.copy_bucket_item_id) ? 1 : ((b.copy_bucket_item_id > a.copy_bucket_item_id) ? -1 : 0)); // today, staff, current_location, etc. egCore.print.fleshPrintScope($scope.preview_scope); $scope.template_changed(); // load the default @@ -519,6 +522,7 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet, $scope.rendered_cn_key_by_copy_id[copy.id] = key; } } + console.log($scope.rendered_call_number_set); $scope.preview_scope.tickle = Date() + ' ' + Math.random(); }); } @@ -725,7 +729,9 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet, .filter('cn_wrap', function () { return function (input, w, h, wrap_type) { - var names; + var addedElements = 0; + /* Pattern matches for LC ([0]) and non-LC ([1]) CNs */ + var patterns = [/^([A-Z]{1,3})\s*(\d{1,4})(\.*\d{1,3})?\s*(\d[A-Z0-9]{0,3})?(\.*[A-Z]\d{1,3})?(\d[A-Z0-9]{0,3})?([A-Z]\d{1,3})?(.*)?/i, /^([A-Z]+)?\s*(\d+)(\.\d+)?\s*(.*)?$/i]; var prefix = input[0]; var callnum = input[1]; var suffix = input[2]; @@ -733,78 +739,77 @@ function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet, if (!w) { w = 8; } if (!h) { h = 9; } - /* handle spine labels differently if using LC */ - if (wrap_type == 'lc' || wrap_type == 3) { - /* Establish a pattern where every return value should be isolated on its own line - on the spine label: subclass letters, subclass numbers, cutter numbers, trailing stuff (date) */ - var patt1 = /^([A-Z]{1,3})\s*(\d+(?:\.\d+)?)\s*(\.[A-Z]\d*)\s*([A-Z]\d*)?\s*(\d\d\d\d(?:-\d\d\d\d)?)?\s*(.*)$/i; - var result = callnum.match(patt1); - if (result) { - callnum = result.slice(1).join('\t'); - } else { - callnum = callnum.split(/\s+/).join('\t'); - } - - /* If result is null, leave callnum alone. Can't parse this malformed call num */ + var cn_patt; /* <- regex from patterns to use based on wrap_type */ + var z = 3; /* <-Text match position in patterns for variable text (7th position in LC regex pattern); default to non-LC (3rd position in non-LC regex pattern) */ + if (wrap_type === 3 || wrap_type === 'lc') { + cn_patt = patterns[0]; + z = 7; } else { - callnum = callnum.split(/\s+/).join('\t'); - } - - if (prefix) { - callnum = prefix + '\t' + callnum; - } - if (suffix) { - callnum += '\t' + suffix; - } - - /* At this point, the call number pieces are separated by tab characters. This allows - * some space-containing constructs like "v. 1" to appear on one line - */ - callnum = callnum.replace(/\t\t/g, '\t'); /* Squeeze out empties */ - names = callnum.split('\t'); - var j = 0; var tb = []; - while (j < h) { - - /* spine */ - if (j < w) { - - var name = names.shift(); - if (name) { - name = String(name); - - /* if the name is greater than the label width... */ - if (name.length > w) { - /* then try to split it on periods */ - var sname = name.split(/\./); - if (sname.length > 1) { - /* if we can, then put the periods back in on each splitted element */ - if (name.match(/^\./)) sname[0] = '.' + sname[0]; - for (var k = 1; k < sname.length; k++) sname[k] = '.' + sname[k]; - /* and put all but the first one back into the names array */ - names = sname.slice(1).concat(names); - /* if the name fragment is still greater than the label width... */ - if (sname[0].length > w) { - /* then just truncate and throw the rest back into the names array */ - tb[j] = sname[0].substr(0, w); - names = [sname[0].substr(w)].concat(names); - } else { - /* otherwise we're set */ - tb[j] = sname[0]; - } + cn_patt = patterns[1]; + } + + var result = callnum.match(cn_patt); + if (result) { + result = result.slice(1); + /* Fix the variable lines of the call number that are longer than 'w'; proceed through algorithm to break up the elements in a standard spine label format (on spaces, periods, decimals, etc.) */ + if (result[z + addedElements]) { + result[z + addedElements] = result[z + addedElements].replace(/\s+$/, ""); + if (result[z + addedElements].length > w) { + var n = z + addedElements; + var sub_patt = [/^([^\.]+?)(?!\.) ([^\s]+)$/, /^(.+?) ([^\s]+)$/]; + while (n < result.length) { + var y = result[n].match(sub_patt[0]) ? 0 : result[n].match(sub_patt[1]) ? 1 : 0; + if (result[n].match(sub_patt[y]) && result[n].length > w) { + var str = result[n].match(sub_patt[y]); + result[n] = str[1]; + result.splice(n + 1, 0, str[2]); + addedElements++; } else { - /* if we can't split on periods, then just truncate and throw the rest back into the names array */ - tb[j] = name.substr(0, w); - names = [name.substr(w)].concat(names); + n++; } + } + } + } + } else { + result = []; + divideOnCharLen(callnum, result, 0, 0); + } + prefix ? result.splice(0, 0, prefix) : false; + suffix ? result.push(suffix) : false; + + /* Give each line a final check and cleanup if it exceeds width of 'w' */ + addedElements = 0; + for (var i = 0; i < result.length; i++) { + if (result[i]) { + divideOnCharLen(result[i], result, i, addedElements); + } + } + var output = []; + for (var j = 0; j < result.length; j++) { + result[j] ? result[j] = result[j].replace(/^\s*(.*?)\s*$/, "$1") : false; + result[j] ? output.push(result[j]) : false; + } + output = output.slice(0, h); /*Limit lines to height in org unit settings (or default) */ + + return output.join('\n'); + + function divideOnCharLen(val, arr, index, incr) { + var x = 1; + while ((val.length / x) > w) { + x++; + } + var charMatch = val.match(new RegExp(".{1," + Math.ceil((val.length / x)) + "}", "g")); + if (charMatch) { + for (var t = 0; t < charMatch.length; t++) { + if (t === 0) { + arr[index] = charMatch[t]; } else { - /* otherwise we're set */ - tb[j] = name; + arr.splice((index + t), 0, charMatch[t]); + incr++; } } } - j++; } - return tb.join('\n'); } }) -- 2.11.0