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>',
41 ['sharedScope','$uibModalInstance',
42 function(sharedScope , $uibModalInstance ) {
43 sharedScope.close_modal = function(count) { $uibModalInstance.close({}) }
45 windowClass: 'app-modal-window',
55 service.delete_template = function(id,cb) {
56 return egCore.pcrud.search('act',
59 ).then(function(resp) {
60 var evt = egCore.evt.parse(resp);
61 if (evt) { console.log(evt); }
62 if (!evt && resp && resp.length > 0) {
65 }).then(function(resp) {
66 resp.isdeleted(true); // needed?
67 return egCore.pcrud.remove(resp);
71 ngToast.success(egCore.strings.SERIALS_TEMPLATE_SUCCESS_DELETE);
74 ngToast.danger(egCore.strings.SERIALS_TEMPLATE_FAIL_DELETE);
76 ).finally(function() {
86 function(egCore , $q) {
91 service.get_locations = function(orgs) {
92 return egCore.pcrud.search('acpl',
100 'acpl' : ['owning_lib']
102 order_by : { acpl : 'name' }
107 service.get_statuses = function() {
109 return $q.when(egCore.env.ccs.list);
111 return egCore.pcrud.retrieveAll('ccs', {order_by : { ccs : 'name' }}, {atomic : true}).then(
113 egCore.env.absorbList(list, 'ccs');
120 service.get_circ_mods = function() {
122 return $q.when(egCore.env.ccm.list);
124 return egCore.pcrud.retrieveAll('ccm', {}, {atomic : true}).then(
126 egCore.env.absorbList(list, 'ccm');
133 service.get_circ_types = function() {
135 return $q.when(egCore.env.citm.list);
137 return egCore.pcrud.retrieveAll('citm', {}, {atomic : true}).then(
139 egCore.env.absorbList(list, 'citm');
146 service.get_age_protects = function() {
147 if (egCore.env.crahp)
148 return $q.when(egCore.env.crahp.list);
150 return egCore.pcrud.retrieveAll('crahp', {}, {atomic : true}).then(
152 egCore.env.absorbList(list, 'crahp');
159 service.get_floating_groups = function() {
161 return $q.when(egCore.env.cfg.list);
163 return egCore.pcrud.retrieveAll('cfg', {}, {atomic : true}).then(
165 egCore.env.absorbList(list, 'cfg');
172 service.bmp_parts = {};
173 service.get_parts = function(rec) {
174 if (service.bmp_parts[rec])
175 return $q.when(service.bmp_parts[rec]);
177 return egCore.pcrud.search('bmp',
178 {record : rec, deleted : 'f'},
179 null, {atomic : true}
180 ).then(function(list) {
181 service.bmp_parts[rec] = list;
190 .controller('TemplatesCtrl',
191 ['$scope','$q','$window','$routeParams','$location','$timeout','egCore','egNet','itemSvc','templateSvc',
192 'egGridDataProvider',
193 function($scope , $q , $window , $routeParams , $location , $timeout , egCore , egNet , itemSvc , templateSvc ,
194 egGridDataProvider ) {
196 function current_query() {
198 'owning_lib' : egCore.org.descendants($scope.context_ou.id(), true)
203 function refresh_page() {
204 $scope.grid_controls.setQuery(current_query());
207 $scope.grid_actions = {
208 create_template : function() {
209 templateSvc.create_or_edit_template(null,$scope.context_ou.id(),refresh_page);
211 edit_template : function(items) {
212 templateSvc.create_or_edit_template(items[0].id,$scope.context_ou.id(),refresh_page);
214 delete_template : function(items) {
216 angular.forEach(items,function(item) {
217 promises.push(templateSvc.delete_template(item.id));
219 $q.all(promises).then(function() {
224 $scope.grid_controls = {
225 activateItem : function(item) {
226 templateSvc.create_or_edit_template(item.id,$scope.context_ou.id(),refresh_page);
228 setQuery : function(x) { return x || current_query(); },
229 setSort : function() { return ['name','id'] }
232 $scope.need_one_selected = function() {
233 var items = $scope.grid_controls.selectedItems();
234 if (items.length == 1) return false;
238 // called after any egGridActions action occurs
239 $scope.grid_actions.refresh = refresh_page;
241 // re-draw the grid when user changes the org selector
242 $scope.context_ou = egCore.org.get(egCore.auth.user().ws_ou());
243 $scope.$watch('context_ou', function(newVal, oldVal) {
244 if (newVal && newVal != oldVal)
252 .directive("egSerialsTemplate", function () {
256 template: '<div ng-include="'+"'/eg/staff/admin/serials/t_attr_edit'"+'"></div>',
261 controller : ['$scope','$q','$window','itemSvc','egCore','ngToast','sharedScope',
262 function ( $scope , $q , $window , itemSvc , egCore , ngToast , sharedScope ) {
264 $scope.close_modal = function() {
265 if ($scope.dirty && !window.confirm(egCore.strings.CONFIRM_DIRTY_EXIT)) {
268 //console.log('unsetting dirty for close_modal');
269 $scope.dirty = false;
270 sharedScope.close_modal();
273 $scope.defaults = { // If defaults are not set at all, allow everything
276 loan_duration : true,
280 deposit_amount : true,
284 mint_condition : true,
287 circ_modifier : true,
296 $scope.fetchDefaults = function () {
297 egCore.hatch.getItem('serials.copy.defaults').then(function(t) {
303 $scope.fetchDefaults();
305 //console.log('unsetting dirty by default');
306 $scope.dirty = false;
307 $scope.$watch('dirty',
308 function(newVal, oldVal) {
309 //console.log('watching dirty');
310 //console.log('...oldVal',oldVal);
311 //console.log('...newVal',newVal);
312 //console.log('...fetching',$scope.fetching);
313 if (newVal && $scope.fetching) {
315 // so after fetchTemplate -> applyTemplate
316 // the working watches will fire and set
317 // dirty to true. We'll undo that at this
319 //console.log('unsetting dirty via kludge');
320 $scope.fetching = false;
321 $scope.dirty = false;
324 if (newVal && newVal != oldVal) {
325 $($window).on('beforeunload.template', function(){
326 return 'There is unsaved template data!'
329 $($window).off('beforeunload.template');
334 $scope.applyTemplate = function() {
335 //console.log('applying...');
336 angular.forEach($scope.hashed_template, function (v,k) {
338 if (k == 'circ_lib') {
339 $scope.working[k] = egCore.org.get(v);
340 } else if (!angular.isObject(v)) {
341 $scope.working[k] = angular.copy(v);
343 angular.forEach(v, function (sv,sk) {
344 if (!(k in $scope.working))
345 $scope.working[k] = {};
346 $scope.working[k][sk] = angular.copy(sv);
350 //console.log('unsetting dirty via applyTemplate');
351 $scope.dirty = false;
354 $scope.fetching = false;
355 $scope.fetchTemplate = function () {
356 $scope.fetching = true;
357 return egCore.pcrud.search('act',
358 {id : $scope.templateId},
359 null, {atomic : true}
360 ).then(function(resp) {
361 var evt = egCore.evt.parse(resp);
362 if (evt) { console.log(evt); }
363 if (!evt && resp && resp.length > 0) {
364 $scope.fm_template = resp[0];
365 $scope.hashed_template = egCore.idl.toHash(resp[0]);
366 $scope.applyTemplate();
368 console.log('new template');
373 $scope.saveTemplate = function() {
376 angular.forEach($scope.working, function (v,k) {
377 if (angular.isObject(v)) { // we'll use the pkey
378 if (v.id) v = v.id();
379 else if (v.code) v = v.code();
385 $scope.hashed_template = tmpl;
387 var act_obj = $scope.fm_template || new egCore.idl.act() ;
388 //console.log('consuming...');
389 angular.forEach($scope.hashed_template, function (v,k) {
391 if (typeof act_obj[k] == 'function') {
394 console.log('something wrong here',k,act_obj[k]);
397 if ($scope.fm_template) {
399 act_obj.ischanged('t');
400 act_obj.editor( egCore.auth.user().id() );
401 act_obj.edit_date( new Date() );
403 console.log('create');
405 act_obj.creator( egCore.auth.user().id() );
406 act_obj.owning_lib( $scope.owningLib );
407 act_obj.create_date( new Date() );
409 var some_failure = false;
410 var some_success = false;
412 'open-ils.cat', // worth replacing with pcrud?
413 'open-ils.cat.asset.copy_template.create_or_update',
418 var evt = egCore.evt.parse(resp);
419 if (evt) { // any way to just throw or return this to the error handler?
420 console.log('failure',resp);
422 ngToast.danger(egCore.strings.SERIALS_TEMPLATE_FAIL_SAVE);
424 console.log('success',resp);
426 ngToast.success(egCore.strings.SERIALS_TEMPLATE_SUCCESS_SAVE);
430 console.log('failure',resp);
432 ngToast.danger(egCore.strings.SERIALS_TEMPLATE_FAIL_SAVE);
435 if (some_success && !some_failure) {
436 //console.log('unsetting dirty for save');
437 $scope.dirty = false;
438 $scope.close_modal();
443 $scope.hashed_template = {};
444 $scope.imported_template = { data : '' };
445 $scope.fetchTemplate();
447 // FIXME - leaving this for now
448 $scope.$watch('imported_template.data', function(newVal, oldVal) {
449 if (newVal && newVal != oldVal) {
451 var newTemplate = JSON.parse(newVal);
452 if (!Object.keys(newTemplate).length) return;
453 $scope.hashed_template = newTemplate;
455 console.log('tried to import an invalid serials template file');
460 $scope.orgById = function (id) { return egCore.org.get(id) }
461 $scope.statusById = function (id) {
462 return $scope.status_list.filter( function (s) { return s.id() == id } )[0];
464 $scope.locationById = function (id) {
465 return $scope.location_cache[''+id];
468 createSimpleUpdateWatcher = function (field) {
469 $scope.$watch('working.' + field, function () {
470 var newval = $scope.working[field];
472 if (typeof newval != 'undefined') {
473 //console.log('setting dirty for field',field);
475 if (angular.isObject(newval)) { // we'll use the pkey
476 if (newval.id) $scope.working[field] = newval.id();
477 else if (newval.code) $scope.working[field] = newval.code();
480 if (""+newval == "" || newval == null) {
481 $scope.working[field] = undefined;
488 $scope.clearWorking = function () {
489 angular.forEach($scope.working, function (v,k,o) {
490 if (!angular.isObject(v)) {
491 if (typeof v != 'undefined')
492 $scope.working[k] = undefined;
493 } else if (k != 'circ_lib') {
494 angular.forEach(v, function (sv,sk) {
495 $scope.working[k][sk] = undefined;
499 $scope.working.circ_lib = undefined; // special
500 $scope.working.loan_duration = 2;
501 $scope.working.fine_level = 2;
502 //console.log('unsetting dirty for clearWorking');
503 $scope.dirty = false;
510 $scope.location_orgs = [];
511 $scope.location_cache = {};
513 $scope.i18n = egCore.i18n;
514 $scope.location_list = [];
515 itemSvc.get_locations(
516 egCore.org.fullPath( egCore.auth.user().ws_ou(), true )
517 ).then(function(list){
518 $scope.location_list = list;
520 createSimpleUpdateWatcher('location');
522 $scope.status_list = [];
523 itemSvc.get_statuses().then(function(list){
524 $scope.status_list = list;
526 createSimpleUpdateWatcher('status');
528 $scope.circ_modifier_list = [];
529 itemSvc.get_circ_mods().then(function(list){
530 $scope.circ_modifier_list = list;
532 createSimpleUpdateWatcher('circ_modifier');
534 $scope.circ_type_list = [];
535 itemSvc.get_circ_types().then(function(list){
536 $scope.circ_type_list = list;
538 createSimpleUpdateWatcher('circ_as_type');
540 $scope.age_protect_list = [];
541 itemSvc.get_age_protects().then(function(list){
542 $scope.age_protect_list = list;
544 createSimpleUpdateWatcher('age_protect');
546 createSimpleUpdateWatcher('circulate');
547 createSimpleUpdateWatcher('holdable');
549 $scope.loan_duration_options = [
551 v: function(){return 1;},
552 l: function(){return egCore.strings.LOAN_DURATION_SHORT;}
555 v: function(){return 2;},
556 l: function(){return egCore.strings.LOAN_DURATION_NORMAL;}
559 v: function(){return 3;},
560 l: function(){return egCore.strings.LOAN_DURATION_EXTENDED;}
563 createSimpleUpdateWatcher('loan_duration');
565 $scope.fine_level_options = [
567 v: function(){return 1;},
568 l: function(){return egCore.strings.FINE_LEVEL_LOW;}
571 v: function(){return 2;},
572 l: function(){return egCore.strings.FINE_LEVEL_NORMAL;}
575 v: function(){return 3;},
576 l: function(){return egCore.strings.FINE_LEVEL_HIGH;}
579 createSimpleUpdateWatcher('fine_level');
581 createSimpleUpdateWatcher('name');
582 createSimpleUpdateWatcher('price');
583 createSimpleUpdateWatcher('deposit');
584 createSimpleUpdateWatcher('deposit_amount');
585 createSimpleUpdateWatcher('mint_condition');
586 createSimpleUpdateWatcher('opac_visible');
587 createSimpleUpdateWatcher('ref');