1 angular.module('egSerialsAdmin',
2 ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'egGridMod'])
4 .config(['$routeProvider','$locationProvider','$compileProvider',
5 function($routeProvider , $locationProvider , $compileProvider) {
7 $locationProvider.html5Mode(true);
8 $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/);
9 var resolver = {delay : function(egStartup) {return egStartup.go()}};
11 $routeProvider.when('/admin/serials/templates', {
12 templateUrl: './admin/serials/t_templates',
13 controller: 'TemplatesCtrl',
18 $routeProvider.otherwise({
19 templateUrl : './admin/serials/t_splash',
25 .factory("sharedScope",function(){
29 .factory('templateSvc',
30 ['egCore','$q','$uibModal','ngToast',
31 function(egCore , $q , $uibModal , ngToast ) {
36 service.create_or_edit_template = function(id,ou,cb) {
38 template: '<eg-serials-template template_id="' + id + '" owning_lib="' + ou + '"></eg-serials-template>',
40 ['sharedScope','$uibModalInstance',
41 function(sharedScope , $uibModalInstance ) {
42 sharedScope.close_modal = function(count) { $uibModalInstance.close({}) }
44 windowClass: 'app-modal-window',
54 service.delete_template = function(id,cb) {
55 return egCore.pcrud.search('act',
58 ).then(function(resp) {
59 var evt = egCore.evt.parse(resp);
60 if (evt) { console.log(evt); }
61 if (!evt && resp && resp.length > 0) {
64 }).then(function(resp) {
65 resp.isdeleted(true); // needed?
66 return egCore.pcrud.remove(resp);
70 ngToast.success(egCore.strings.SERIALS_TEMPLATE_SUCCESS_DELETE);
73 ngToast.danger(egCore.strings.SERIALS_TEMPLATE_FAIL_DELETE);
75 ).finally(function() {
85 function(egCore , $q) {
90 service.get_locations = function(orgs) {
91 return egCore.pcrud.search('acpl',
99 'acpl' : ['owning_lib']
101 order_by : { acpl : 'name' }
106 service.get_statuses = function() {
108 return $q.when(egCore.env.ccs.list);
110 return egCore.pcrud.retrieveAll('ccs', {order_by : { ccs : 'name' }}, {atomic : true}).then(
112 egCore.env.absorbList(list, 'ccs');
119 service.get_circ_mods = function() {
121 return $q.when(egCore.env.ccm.list);
123 return egCore.pcrud.retrieveAll('ccm', {}, {atomic : true}).then(
125 egCore.env.absorbList(list, 'ccm');
132 service.get_circ_types = function() {
134 return $q.when(egCore.env.citm.list);
136 return egCore.pcrud.retrieveAll('citm', {}, {atomic : true}).then(
138 egCore.env.absorbList(list, 'citm');
145 service.get_age_protects = function() {
146 if (egCore.env.crahp)
147 return $q.when(egCore.env.crahp.list);
149 return egCore.pcrud.retrieveAll('crahp', {}, {atomic : true}).then(
151 egCore.env.absorbList(list, 'crahp');
158 service.get_floating_groups = function() {
160 return $q.when(egCore.env.cfg.list);
162 return egCore.pcrud.retrieveAll('cfg', {}, {atomic : true}).then(
164 egCore.env.absorbList(list, 'cfg');
171 service.bmp_parts = {};
172 service.get_parts = function(rec) {
173 if (service.bmp_parts[rec])
174 return $q.when(service.bmp_parts[rec]);
176 return egCore.pcrud.search('bmp',
177 {record : rec, deleted : 'f'},
178 null, {atomic : true}
179 ).then(function(list) {
180 service.bmp_parts[rec] = list;
189 .controller('TemplatesCtrl',
190 ['$scope','$q','$window','$routeParams','$location','$timeout','egCore','egNet','itemSvc','templateSvc',
191 'egGridDataProvider',
192 function($scope , $q , $window , $routeParams , $location , $timeout , egCore , egNet , itemSvc , templateSvc ,
193 egGridDataProvider ) {
195 function current_query() {
197 'owning_lib' : egCore.org.descendants($scope.context_ou.id(), true)
202 function refresh_page() {
203 $scope.grid_controls.setQuery(current_query());
206 $scope.grid_actions = {
207 create_template : function() {
208 templateSvc.create_or_edit_template(null,$scope.context_ou.id(),refresh_page);
210 edit_template : function(items) {
211 templateSvc.create_or_edit_template(items[0].id,$scope.context_ou.id(),refresh_page);
213 delete_template : function(items) {
215 angular.forEach(items,function(item) {
216 promises.push(templateSvc.delete_template(item.id));
218 $q.all(promises).then(function() {
223 $scope.grid_controls = {
224 activateItem : function(item) {
225 templateSvc.create_or_edit_template(item.id,$scope.context_ou.id(),refresh_page);
227 setQuery : function(x) { return x || current_query(); },
228 setSort : function() { return ['name','id'] }
231 $scope.need_one_selected = function() {
232 var items = $scope.grid_controls.selectedItems();
233 if (items.length == 1) return false;
237 // called after any egGridActions action occurs
238 $scope.grid_actions.refresh = refresh_page;
240 // re-draw the grid when user changes the org selector
241 $scope.context_ou = egCore.org.get(egCore.auth.user().ws_ou());
242 $scope.$watch('context_ou', function(newVal, oldVal) {
243 if (newVal && newVal != oldVal)
251 .directive("egSerialsTemplate", function () {
255 template: '<div ng-include="'+"'/eg/staff/admin/serials/t_attr_edit'"+'"></div>',
260 controller : ['$scope','$q','$window','itemSvc','egCore','ngToast','sharedScope',
261 function ( $scope , $q , $window , itemSvc , egCore , ngToast , sharedScope ) {
263 $scope.close_modal = function() {
264 if ($scope.dirty && !window.confirm(egCore.strings.CONFIRM_DIRTY_EXIT)) {
267 //console.log('unsetting dirty for close_modal');
268 $scope.dirty = false;
269 sharedScope.close_modal();
272 $scope.defaults = { // If defaults are not set at all, allow everything
275 loan_duration : true,
279 deposit_amount : true,
283 mint_condition : true,
286 circ_modifier : true,
295 $scope.fetchDefaults = function () {
296 egCore.hatch.getItem('serials.copy.defaults').then(function(t) {
302 $scope.fetchDefaults();
304 //console.log('unsetting dirty by default');
305 $scope.dirty = false;
306 $scope.$watch('dirty',
307 function(newVal, oldVal) {
308 //console.log('watching dirty');
309 //console.log('...oldVal',oldVal);
310 //console.log('...newVal',newVal);
311 //console.log('...fetching',$scope.fetching);
312 if (newVal && $scope.fetching) {
314 // so after fetchTemplate -> applyTemplate
315 // the working watches will fire and set
316 // dirty to true. We'll undo that at this
318 //console.log('unsetting dirty via kludge');
319 $scope.fetching = false;
320 $scope.dirty = false;
323 if (newVal && newVal != oldVal) {
324 $($window).on('beforeunload.template', function(){
325 return 'There is unsaved template data!'
328 $($window).off('beforeunload.template');
333 $scope.applyTemplate = function() {
334 //console.log('applying...');
335 angular.forEach($scope.hashed_template, function (v,k) {
337 if (k == 'circ_lib') {
338 $scope.working[k] = egCore.org.get(v);
339 } else if (!angular.isObject(v)) {
340 $scope.working[k] = angular.copy(v);
342 angular.forEach(v, function (sv,sk) {
343 if (!(k in $scope.working))
344 $scope.working[k] = {};
345 $scope.working[k][sk] = angular.copy(sv);
349 //console.log('unsetting dirty via applyTemplate');
350 $scope.dirty = false;
353 $scope.fetching = false;
354 $scope.fetchTemplate = function () {
355 $scope.fetching = true;
356 return egCore.pcrud.search('act',
357 {id : $scope.templateId},
358 null, {atomic : true}
359 ).then(function(resp) {
360 var evt = egCore.evt.parse(resp);
361 if (evt) { console.log(evt); }
362 if (!evt && resp && resp.length > 0) {
363 $scope.fm_template = resp[0];
364 $scope.hashed_template = egCore.idl.toHash(resp[0]);
365 $scope.applyTemplate();
367 console.log('new template');
372 $scope.saveTemplate = function() {
375 angular.forEach($scope.working, function (v,k) {
376 if (angular.isObject(v)) { // we'll use the pkey
377 if (v.id) v = v.id();
378 else if (v.code) v = v.code();
384 $scope.hashed_template = tmpl;
386 var act_obj = $scope.fm_template || new egCore.idl.act() ;
387 //console.log('consuming...');
388 angular.forEach($scope.hashed_template, function (v,k) {
390 if (typeof act_obj[k] == 'function') {
393 console.log('something wrong here',k,act_obj[k]);
396 if ($scope.fm_template) {
398 act_obj.ischanged('t');
399 act_obj.editor( egCore.auth.user().id() );
400 act_obj.edit_date( new Date() );
402 console.log('create');
404 act_obj.creator( egCore.auth.user().id() );
405 act_obj.owning_lib( $scope.owningLib );
406 act_obj.create_date( new Date() );
408 var some_failure = false;
409 var some_success = false;
411 'open-ils.cat', // worth replacing with pcrud?
412 'open-ils.cat.asset.copy_template.create_or_update',
417 var evt = egCore.evt.parse(resp);
418 if (evt) { // any way to just throw or return this to the error handler?
419 console.log('failure',resp);
421 ngToast.danger(egCore.strings.SERIALS_TEMPLATE_FAIL_SAVE);
423 console.log('success',resp);
425 ngToast.success(egCore.strings.SERIALS_TEMPLATE_SUCCESS_SAVE);
429 console.log('failure',resp);
431 ngToast.danger(egCore.strings.SERIALS_TEMPLATE_FAIL_SAVE);
434 if (some_success && !some_failure) {
435 //console.log('unsetting dirty for save');
436 $scope.dirty = false;
437 $scope.close_modal();
442 $scope.hashed_template = {};
443 $scope.imported_template = { data : '' };
444 $scope.fetchTemplate();
446 // FIXME - leaving this for now
447 $scope.$watch('imported_template.data', function(newVal, oldVal) {
448 if (newVal && newVal != oldVal) {
450 var newTemplate = JSON.parse(newVal);
451 if (!Object.keys(newTemplate).length) return;
452 $scope.hashed_template = newTemplate;
454 console.log('tried to import an invalid serials template file');
459 $scope.orgById = function (id) { return egCore.org.get(id) }
460 $scope.statusById = function (id) {
461 return $scope.status_list.filter( function (s) { return s.id() == id } )[0];
463 $scope.locationById = function (id) {
464 return $scope.location_cache[''+id];
467 createSimpleUpdateWatcher = function (field) {
468 $scope.$watch('working.' + field, function () {
469 var newval = $scope.working[field];
471 if (typeof newval != 'undefined') {
472 //console.log('setting dirty for field',field);
474 if (angular.isObject(newval)) { // we'll use the pkey
475 if (newval.id) $scope.working[field] = newval.id();
476 else if (newval.code) $scope.working[field] = newval.code();
479 if (""+newval == "" || newval == null) {
480 $scope.working[field] = undefined;
487 $scope.clearWorking = function () {
488 angular.forEach($scope.working, function (v,k,o) {
489 if (!angular.isObject(v)) {
490 if (typeof v != 'undefined')
491 $scope.working[k] = undefined;
492 } else if (k != 'circ_lib') {
493 angular.forEach(v, function (sv,sk) {
494 $scope.working[k][sk] = undefined;
498 $scope.working.circ_lib = undefined; // special
499 $scope.working.loan_duration = 2;
500 $scope.working.fine_level = 2;
501 //console.log('unsetting dirty for clearWorking');
502 $scope.dirty = false;
509 $scope.location_orgs = [];
510 $scope.location_cache = {};
512 $scope.i18n = egCore.i18n;
513 $scope.location_list = [];
514 itemSvc.get_locations(
515 egCore.org.fullPath( egCore.auth.user().ws_ou(), true )
516 ).then(function(list){
517 $scope.location_list = list;
519 createSimpleUpdateWatcher('location');
521 $scope.status_list = [];
522 itemSvc.get_statuses().then(function(list){
523 $scope.status_list = list;
525 createSimpleUpdateWatcher('status');
527 $scope.circ_modifier_list = [];
528 itemSvc.get_circ_mods().then(function(list){
529 $scope.circ_modifier_list = list;
531 createSimpleUpdateWatcher('circ_modifier');
533 $scope.circ_type_list = [];
534 itemSvc.get_circ_types().then(function(list){
535 $scope.circ_type_list = list;
537 createSimpleUpdateWatcher('circ_as_type');
539 $scope.age_protect_list = [];
540 itemSvc.get_age_protects().then(function(list){
541 $scope.age_protect_list = list;
543 createSimpleUpdateWatcher('age_protect');
545 createSimpleUpdateWatcher('circulate');
546 createSimpleUpdateWatcher('holdable');
548 $scope.loan_duration_options = [
550 v: function(){return 1;},
551 l: function(){return egCore.strings.LOAN_DURATION_SHORT;}
554 v: function(){return 2;},
555 l: function(){return egCore.strings.LOAN_DURATION_NORMAL;}
558 v: function(){return 3;},
559 l: function(){return egCore.strings.LOAN_DURATION_EXTENDED;}
562 createSimpleUpdateWatcher('loan_duration');
564 $scope.fine_level_options = [
566 v: function(){return 1;},
567 l: function(){return egCore.strings.FINE_LEVEL_LOW;}
570 v: function(){return 2;},
571 l: function(){return egCore.strings.FINE_LEVEL_NORMAL;}
574 v: function(){return 3;},
575 l: function(){return egCore.strings.FINE_LEVEL_HIGH;}
578 createSimpleUpdateWatcher('fine_level');
580 createSimpleUpdateWatcher('name');
581 createSimpleUpdateWatcher('price');
582 createSimpleUpdateWatcher('deposit');
583 createSimpleUpdateWatcher('deposit_amount');
584 createSimpleUpdateWatcher('mint_condition');
585 createSimpleUpdateWatcher('opac_visible');
586 createSimpleUpdateWatcher('ref');