From: Mike Rylander Date: Fri, 14 Aug 2015 21:13:30 +0000 (-0400) Subject: webstaff: Vol/Copy edit (volumes ATM) X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=dbf75e0bb45d8fa60188d26eb0903b98e7d6893d;p=evergreen%2Fmasslnc.git webstaff: Vol/Copy edit (volumes ATM) Signed-off-by: Mike Rylander Signed-off-by: Galen Charlton Signed-off-by: Jason Stephenson --- diff --git a/Open-ILS/src/templates/staff/cat/volcopy/index.tt2 b/Open-ILS/src/templates/staff/cat/volcopy/index.tt2 new file mode 100644 index 0000000000..d3f3ccf454 --- /dev/null +++ b/Open-ILS/src/templates/staff/cat/volcopy/index.tt2 @@ -0,0 +1,29 @@ +[% + WRAPPER "staff/base.tt2"; + ctx.page_title = l("Volume/Copy Editor"); + ctx.page_app = "egVolCopy"; + ctx.page_ctrl = "EditCtrl"; +%] + +[% BLOCK APP_JS %] + + + + + + +[% END %] + + + +
+ +[% END %] + + diff --git a/Open-ILS/src/templates/staff/cat/volcopy/t_edit.tt2 b/Open-ILS/src/templates/staff/cat/volcopy/t_edit.tt2 new file mode 100644 index 0000000000..4889e7ca20 --- /dev/null +++ b/Open-ILS/src/templates/staff/cat/volcopy/t_edit.tt2 @@ -0,0 +1,30 @@ + + + +
+
+
[% l('Library') %]
+
[% l('Volumes') %]
+
+
+
+
[% l('Classification') %]
+
[% l('Prefix') %]
+
[% l('Call Number') %]
+
[% l('Suffix') %]
+
[% l('Copies') %]
+
+
+
+
[% l('Barcode') %]
+
[% l('Copy #') %]
+
[% l('Part') %]
+
+
+
+
+
+
+
+ +
diff --git a/Open-ILS/src/templates/staff/cat/volcopy/t_view.tt2 b/Open-ILS/src/templates/staff/cat/volcopy/t_view.tt2 new file mode 100644 index 0000000000..d31c26f302 --- /dev/null +++ b/Open-ILS/src/templates/staff/cat/volcopy/t_view.tt2 @@ -0,0 +1,35 @@ + + + +

[% l('Volume/Copy Editor') %]

+ +
+ + + +
+
+
+
+
+ +
+
+ diff --git a/Open-ILS/web/js/ui/default/staff/admin/workstation/app.js b/Open-ILS/web/js/ui/default/staff/admin/workstation/app.js index ae771ec60e..b313f05d8d 100644 --- a/Open-ILS/web/js/ui/default/staff/admin/workstation/app.js +++ b/Open-ILS/web/js/ui/default/staff/admin/workstation/app.js @@ -86,6 +86,7 @@ function($scope , $window , $location , egCore , egConfirmDialog) { } $scope.cant_have_users = function (id) { return !egCore.org.CanHaveUsers(id); }; + $scope.cant_have_volumes = function (id) { return !egCore.org.CanHaveVolumes(id); }; // redirect the user to the login page using the current // workstation as the workstation URL param diff --git a/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js b/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js new file mode 100644 index 0000000000..a754e3e0b2 --- /dev/null +++ b/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js @@ -0,0 +1,379 @@ +/** + * Vol/Copy Editor + */ + +angular.module('egVolCopy', + ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'egGridMod']) + +.filter('boolText', function(){ + return function (v) { + return v == 't'; + } +}) + +.config(function($routeProvider, $locationProvider, $compileProvider) { + $locationProvider.html5Mode(true); + $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export + + var resolver = { + delay : ['egStartup', function(egStartup) { return egStartup.go(); }] + }; + + $routeProvider.when('/cat/volcopy/:dataKey', { + templateUrl: './cat/volcopy/t_view', + controller: 'EditCtrl', + resolve : resolver + }); + +}) + +.factory('itemSvc', + ['egCore','$q', +function(egCore , $q) { + + var service = { + tree : {}, // holds lib->cn->copy hash stack + copies : [] // raw copy list + }; + + // returns a promise resolved with the list of circ mods + service.get_classifications = function() { + if (egCore.env.acnc) + return $q.when(egCore.env.acnc.list); + + return egCore.pcrud.retrieveAll('acnc', null, {atomic : true}) + .then(function(list) { + egCore.env.absorbList(list, 'acnc'); + return list; + }); + }; + + service.get_prefixes = function(org) { + if (egCore.env.acnp) + return $q.when(egCore.env.acnp.list); + + return egCore.pcrud.search('acnp', + {owning_lib : egCore.org.fullPath(org, true)}, + null, {atomic : true} + ).then(function(list) { + egCore.env.absorbList(list, 'acnp'); + return list; + }); + + }; + + service.get_suffixes = function(org) { + if (egCore.env.acns) + return $q.when(egCore.env.acns.list); + + return egCore.pcrud.search('acns', + {owning_lib : egCore.org.fullPath(org, true)}, + null, {atomic : true} + ).then(function(list) { + egCore.env.absorbList(list, 'acns'); + return list; + }); + + }; + + service.bmp_parts = {}; + service.get_parts = function(rec) { + if (service.bmp_parts[rec]) + return $q.when(service.bmp_parts[rec]); + + return egCore.pcrud.search('bmp', + {record : rec}, + null, {atomic : true} + ).then(function(list) { + service.bmp_parts[rec] = list; + return list; + }); + + }; + + service.flesh = { + flesh : 3, + flesh_fields : { + acp : ['call_number','parts'], + acn : ['label_class','prefix','suffix'] + }, + select : { + // avoid fleshing MARC on the bre + // note: don't add simple_record.. not sure why + bre : ['id','tcn_value','creator','editor'], + } + } + + service.addCopy = function (cp) { + + var lib = cp.call_number().owning_lib(); + var cn = cp.call_number().id(); + + // XXX need to change this data structure, likely... + if (!service.tree[lib]) service.tree[lib] = {}; + if (!service.tree[lib][cn]) service.tree[lib][cn] = []; + + service.tree[lib][cn].push(cp); + service.copies.push(cp); + } + + service.fetchIds = function(idList) { + service.tree = {}; // clear the tree on fetch + service.copies = []; // clear the copy list on fetch + return egCore.pcrud.search('acp', { 'id' : idList }, service.flesh).then(null,null, + function(copy) { + service.addCopy(copy); + } + ); + } + + return service; +}]) + +.directive("egVolCopyEdit", function () { + return { + restrict: 'E', + replace: true, + template: + '
'+ + '
'+ + '
'+ + '
'+ + '
', + + scope: { copy: "=", callNumber: "=" }, + controller : ['$scope','itemSvc', + function ( $scope , itemSvc ) { + $scope.new_part_id = 0; + + $scope.updateBarcode = function () { $scope.copy.barcode($scope.barcode) }; + $scope.updateCopyNo = function () { $scope.copy.copy_number($scope.copy_number) }; + $scope.updatePart = function () { + var p = angular.filter($scope.part_list, function (x) { + return x.label() == $scope.part + }); + if (p.length > 0) { // preexisting part + $scope.copy.parts(p) + } else { // create one... + var part = new egCore.idl.bmp(); + part.id( --$scope.new_part_id ); + part.isnew( true ); + part.label( $scope.part ); + part.record( $scope.callNumber.owning_lib() ); + $scope.copy.parts([part]); + } + } + + $scope.barcode = $scope.copy.barcode(); + $scope.copy_number = $scope.copy.copy_number(); + + if ($scope.copy.parts()) { + $scope.part = $scope.copy.parts()[0]; + if ($scope.part) $scope.part = $scope.part.label(); + }; + + $scope.parts = []; + $scope.part_list = []; + + itemSvc.get_parts($scope.callNumber.record()).then(function(list){ + $scope.part_list = list; + angular.forEach(list, function(p){ $scope.parts.push(p.label()) }); + }); + + } + ] + + } +}) + +.directive("egVolRow", function () { + return { + restrict: 'E', + replace: true, + transclude: true, + template: + '
'+ + '
'+ + ''+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + ''+ + '
'+ + '
'+ + '
', + + scope: { copies: "=" }, + controller : ['$scope','itemSvc','egCore', + function ( $scope , itemSvc , egCore ) { + $scope.new_cp_id = 0; + $scope.callNumber = $scope.copies[0].call_number(); + + $scope.idTracker = function (x) { if (x) return x.id() }; + + $scope.suffix_list = []; + itemSvc.get_suffixes($scope.callNumber.owning_lib()).then(function(list){ + $scope.suffix_list = list; + }); + $scope.updateSuffix = function () { $scope.callNumber.suffix($scope.suffix) }; + + $scope.prefix_list = []; + itemSvc.get_prefixes($scope.callNumber.owning_lib()).then(function(list){ + $scope.prefix_list = list; + }); + $scope.updatePrefix = function () { $scope.callNumber.prefix($scope.prefix) }; + + $scope.classification_list = []; + itemSvc.get_classifications().then(function(list){ + $scope.classification_list = list; + }); + $scope.updateClassification = function () { $scope.callNumber.label_class($scope.classification) }; + + $scope.classification = $scope.callNumber.label_class(); + $scope.prefix = $scope.callNumber.prefix(); + $scope.suffix = $scope.callNumber.suffix(); + + $scope.label = $scope.callNumber.label(); + $scope.updateLabel = function () { $scope.callNumber.label($scope.label) }; + + $scope.copy_count = $scope.copies.length; + $scope.orig_copy_count = $scope.copy_count; + + $scope.changeCPCount = function () { + while ($scope.copy_count > $scope.copies.length) { + var cp = new egCore.idl.acp(); + cp.id( --$scope.new_cp_id ); + cp.isnew( true ); + cp.circ_lib( $scope.lib ); + cp.call_number( $scope.callNumber ); + $scope.copies.push( cp ); + } + + var how_many = $scope.copies.length - $scope.copy_count; + if (how_many > 0) { + $scope.copies.splice($scope.copy_count,how_many); + $scope.callNumber.copies($scope.copies); + } + } + + } + ] + + } +}) + +.directive("egVolEdit", function () { + return { + restrict: 'E', + replace: true, + template: + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + ''+ + '
'+ + '
'+ + '
', + + scope: { struct: "=", lib: "@", record: "@" }, + controller : ['$scope','itemSvc','egCore', + function ( $scope , itemSvc , egCore ) { + $scope.new_cn_id = 0; + $scope.first_cn = Object.keys($scope.struct)[0]; + $scope.full_cn = $scope.struct[$scope.first_cn][0].call_number(); + + $scope.cn_count = Object.keys($scope.struct).length; + $scope.orig_cn_count = $scope.cn_count; + + $scope.owning_lib = egCore.org.get($scope.lib); + + $scope.cant_have_vols = function (id) { return !egCore.org.CanHaveVolumes(id); }; + + $scope.$watch('cn_count', function (n) { + var o = Object.keys($scope.struct).length; + if (n > o) { // adding + for (var i = o; o < n; o++) { + var cn = new egCore.idl.acn(); + cn.id( --$scope.new_cn_id ); + cn.isnew( true ); + cn.owning_lib( $scope.owning_lib ); + cn.record( $scope.full_cn.record() ); + + var cp = new egCore.idl.acp(); + cp.id( --$scope.new_cp_id ); + cp.isnew( true ); + cp.circ_lib( $scope.owning_lib ); + cp.call_number( cn ); + + $scope.struct[cn.id()] = [cp]; + } + } else if (n < o) { // removing + var how_many = o - n; + var list = Object + .keys($scope.struct) + .sort(function(a, b){return a-b}) + .reverse(); + for (var i = how_many; i > 0; i--) { + delete $scope.struct[list[i]]; + } + } + }); + } + ] + + } +}) + +/** + * Edit controller! + */ +.controller('EditCtrl', + ['$scope','$q','$routeParams','$location','$timeout','egCore','egNet','egGridDataProvider','itemSvc', +function($scope , $q , $routeParams , $location , $timeout , egCore , egNet , egGridDataProvider , itemSvc) { + + $timeout(function(){ + + var dataKey = $routeParams.dataKey; + console.debug('dataKey: ' + dataKey); + + if (dataKey && dataKey.length > 0) { + $scope.tab = 'edit'; + $scope.summaryRecord = null; + $scope.record_id = null; + $scope.data = {}; + + $scope.gridDataProvider = egGridDataProvider.instance({ + get : function(offset, count) { + //return provider.arrayNotifier(itemSvc.copies, offset, count); + return this.arrayNotifier(itemSvc.copies, offset, count); + } + }); + + egNet.request( + 'open-ils.actor', + 'open-ils.actor.anon_cache.get_value', + dataKey, 'edit-these-copies' + ).then(function (data) { + $scope.record_id = data.record_id; + return itemSvc.fetchIds(data.copies); + }).then( function() { + $scope.data = itemSvc.tree; + $scope.gridDataProvider.refresh(); + }); + } + + }); + +}]) + + diff --git a/Open-ILS/web/js/ui/default/staff/services/ui.js b/Open-ILS/web/js/ui/default/staff/services/ui.js index 25312c667c..5291d9a257 100644 --- a/Open-ILS/web/js/ui/default/staff/services/ui.js +++ b/Open-ILS/web/js/ui/default/staff/services/ui.js @@ -207,6 +207,36 @@ function($modal, $interpolate) { }; }) +.directive('egBasicComboBox', function() { + return { + restrict: 'E', + replace: true, + scope: { + list: "=", // list of strings + selected: "=" + }, + template: + '
'+ + ''+ + '
'+ + ''+ + ''+ + '
'+ + '
', + controller: ['$scope', + function($scope) { + + $scope.changeValue = function (newVal) { + $scope.selected = newVal; + } + + } + ] + }; +}) + /** * Nested org unit selector modeled as a Bootstrap dropdown button. */