.factory('egHolds',
- ['$modal','$q','egCore','egConfirmDialog','egAlertDialog',
-function($modal , $q , egCore , egConfirmDialog , egAlertDialog) {
+ ['$uibModal','$q','egCore','egConfirmDialog','egAlertDialog',
+function($uibModal , $q , egCore , egConfirmDialog , egAlertDialog) {
var service = {};
+ service.fetch_wide_holds = function(restrictions, order_by, limit, offset) {
+ return egCore.net.request(
+ 'open-ils.circ',
+ 'open-ils.circ.hold.wide_hash.stream',
+ egCore.auth.token(),
+ restrictions, order_by, limit, offset
+ );
+ }
+
service.fetch_holds = function(hold_ids) {
var deferred = $q.defer();
- // FIXME: large batches using .authoritative result in many
- // stranded cstore backends on the server. Needs investigation.
- // For now, collect holds in a series of small batches.
- // Fetch them serially both to avoid the above problem and
- // to maintain order.
+ // Fetch hold details in batches for better UI responsiveness.
var batch_size = 5;
var index = 0;
egCore.net.request(
'open-ils.circ',
'open-ils.circ.hold.details.batch.retrieve.authoritative',
- egCore.auth.token(), ids
+ egCore.auth.token(), ids, {
+ include_current_copy : true,
+ include_usr : true,
+ include_cancel_cause : true,
+ include_requestor : true
+ }
).then(
one_batch, // kick off the next batch
service.cancel_holds = function(hold_ids) {
- return $modal.open({
+ return $uibModal.open({
templateUrl : './circ/share/t_cancel_hold_dialog',
+ backdrop: 'static',
controller :
- ['$scope', '$modalInstance', 'cancel_reasons',
- function($scope, $modalInstance, cancel_reasons) {
+ ['$scope', '$uibModalInstance', 'cancel_reasons',
+ function($scope, $uibModalInstance, cancel_reasons) {
$scope.args = {
cancel_reason : 5,
cancel_reasons : cancel_reasons,
};
$scope.cancel = function($event) {
- $modalInstance.dismiss();
+ $uibModalInstance.dismiss();
$event.preventDefault();
}
function cancel_one() {
var hold_id = hold_ids.pop();
if (!hold_id) {
- $modalInstance.close();
+ $uibModalInstance.close();
return;
}
egCore.net.request(
'open-ils.circ', 'open-ils.circ.hold.cancel',
egCore.auth.token(), hold_id,
- $scope.args.cancel_reason.id(),
+ $scope.args.cancel_reason,
$scope.args.note
).then(function(resp) {
if (evt = egCore.evt.parse(resp)) {
+ egCore.audio.play(
+ 'warning.hold.cancel_failed');
console.error('unable to cancel hold: '
+ evt.toString());
}
service.uncancel_holds = function(hold_ids) {
- return $modal.open({
+ return $uibModal.open({
templateUrl : './circ/share/t_uncancel_hold_dialog',
+ backdrop: 'static',
controller :
- ['$scope', '$modalInstance',
- function($scope, $modalInstance) {
+ ['$scope', '$uibModalInstance',
+ function($scope, $uibModalInstance) {
$scope.args = {
num_holds : hold_ids.length
};
$scope.cancel = function($event) {
- $modalInstance.dismiss();
+ $uibModalInstance.dismiss();
$event.preventDefault();
}
function uncancel_one() {
var hold_id = hold_ids.pop();
if (!hold_id) {
- $modalInstance.close();
+ $uibModalInstance.close();
return;
}
egCore.net.request(
egCore.auth.token(), hold_id
).then(function(resp) {
if (evt = egCore.evt.parse(resp)) {
+ egCore.audio.play(
+ 'warning.hold.uncancel_failed');
console.error('unable to uncancel hold: '
+ evt.toString());
}
return egCore.net.request(
'open-ils.circ',
'open-ils.circ.hold.update.batch',
- egCore.auth.token(), null, new_values);
+ egCore.auth.token(), null, new_values).then(
+ function(resp) {
+ if (evt = egCore.evt.parse(resp)) {
+ egCore.audio.play(
+ 'warning.hold.batch_update');
+ console.error('unable to batch update holds: '
+ + evt.toString());
+ } else {
+ egCore.audio.play(
+ 'success.hold.batch_update');
+ }
+ }
+ );
}
service.set_copy_quality = function(hold_ids) {
if (!hold_ids.length) return $q.when();
- return $modal.open({
+ return $uibModal.open({
templateUrl : './circ/share/t_hold_copy_quality_dialog',
+ backdrop: 'static',
controller :
- ['$scope', '$modalInstance',
- function($scope, $modalInstance) {
+ ['$scope', '$uibModalInstance',
+ function($scope, $uibModalInstance) {
function update(val) {
var vals = hold_ids.map(function(hold_id) {
return {id : hold_id, mint_condition : val}})
service.update_holds(vals).finally(function() {
- $modalInstance.close();
+ $uibModalInstance.close();
});
}
$scope.good = function() { update(true) }
$scope.any = function() { update(false) }
- $scope.cancel = function() { $modalInstance.dismiss() }
+ $scope.cancel = function() { $uibModalInstance.dismiss() }
}
]
}).result;
service.edit_pickup_lib = function(hold_ids) {
if (!hold_ids.length) return $q.when();
- return $modal.open({
+ return $uibModal.open({
templateUrl : './circ/share/t_hold_edit_pickup_lib',
+ backdrop: 'static',
controller :
- ['$scope', '$modalInstance',
- function($scope, $modalInstance) {
- $scope.can_be_pickup = egCore.org.CanHaveUsers;
+ ['$scope', '$uibModalInstance',
+ function($scope, $uibModalInstance) {
+ $scope.cant_be_pickup = function (id) { return !egCore.org.CanHaveUsers(id); };
$scope.args = {};
$scope.ok = function() {
var vals = hold_ids.map(function(hold_id) {
}
});
service.update_holds(vals).finally(function() {
- $modalInstance.close();
+ $uibModalInstance.close();
});
}
- $scope.cancel = function() { $modalInstance.dismiss() }
+ $scope.cancel = function() { $uibModalInstance.dismiss() }
}
]
}).result;
service.edit_notify_prefs = function(hold_ids) {
if (!hold_ids.length) return $q.when();
- return $modal.open({
+ return $uibModal.open({
templateUrl : './circ/share/t_hold_notification_prefs',
+ backdrop: 'static',
controller :
- ['$scope', '$modalInstance', 'sms_carriers',
- function($scope, $modalInstance, sms_carriers) {
+ ['$scope', '$uibModalInstance', 'sms_carriers',
+ function($scope, $uibModalInstance, sms_carriers) {
$scope.args = {}
$scope.sms_carriers = sms_carriers;
$scope.num_holds = hold_ids.length;
});
service.update_holds(vals).finally(function() {
- $modalInstance.close();
+ $uibModalInstance.close();
});
}
- $scope.cancel = function() { $modalInstance.dismiss() }
+ $scope.cancel = function() { $uibModalInstance.dismiss() }
}
],
resolve : {
return service.update_holds(vals);
}
- return $modal.open({
+ return $uibModal.open({
templateUrl : './circ/share/t_hold_dates',
+ backdrop: 'static',
controller :
- ['$scope', '$modalInstance',
- function($scope, $modalInstance) {
+ ['$scope', '$uibModalInstance',
+ function($scope, $uibModalInstance) {
var today = new Date();
$scope.args = {
thaw_date : today,
}
$scope.num_holds = hold_ids.length;
$scope.ok = function() {
- relay_to_update($scope).then($modalInstance.close);
+ relay_to_update($scope).then($uibModalInstance.close);
}
- $scope.cancel = function() { $modalInstance.dismiss() }
+ $scope.cancel = function() { $uibModalInstance.dismiss() }
}
],
}).result;
});
}
+ service.transfer_all_bib_holds_to_marked_title = function(bib_ids) {
+ if (!bib_ids.length) return $q.when();
+
+ var target_bib_id = egCore.hatch.getLocalItem(
+ 'eg.circ.hold.title_transfer_target');
+
+ if (!target_bib_id) {
+ // no target marked
+ return egAlertDialog.open(
+ egCore.strings.NO_HOLD_TRANSFER_TITLE_MARKED).result;
+ }
+
+ return egConfirmDialog.open(
+ egCore.strings.TRANSFER_ALL_BIB_HOLDS_TO_TITLE, '', {
+ num_bibs : bib_ids.length,
+ bib_id : target_bib_id
+ }
+ ).result.then(function() {
+ return egCore.net.request(
+ 'open-ils.circ',
+ 'open-ils.circ.hold.change_title',
+ egCore.auth.token(), target_bib_id, bib_ids);
+ });
+ }
+
// serially retargets each hold
service.retarget = function(hold_ids) {
if (!hold_ids.length) return $q.when();
|| hold_data.status;
var hold = hold_data.hold;
+ var volume = hold_data.volume;
hold.pickup_lib(egCore.org.get(hold.pickup_lib()));
hold.current_shelf_lib(egCore.org.get(hold.current_shelf_lib()));
hold_data.id = hold.id();
- if (hold.requestor() && typeof hold.requestor() != 'object')
+ // TODO: LP#1697954 fleshing calls below are deprecated in favor
+ // of API fleshing.
+
+ if (hold.requestor() && typeof hold.requestor() != 'object') {
+ console.debug('fetching hold requestor');
egCore.pcrud.retrieve('au',hold.requestor()).then(function(u) { hold.requestor(u) });
+ }
- if (hold.cancel_cause() && typeof hold.cancel_cause() != 'object')
+ if (hold.cancel_cause() && typeof hold.cancel_cause() != 'object') {
+ console.debug('fetching hold cancel cause');
egCore.pcrud.retrieve('ahrcc',hold.cancel_cause()).then(function(c) { hold.cancel_cause(c) });
+ }
- if (hold.usr() && typeof hold.usr() != 'object')
+ if (hold.usr() && typeof hold.usr() != 'object') {
+ console.debug('fetching hold user');
egCore.pcrud.retrieve('au',hold.usr()).then(function(u) { hold.usr(u) });
+ }
// current_copy is not always fleshed in the API
- if (hold.current_copy() && typeof hold.current_copy() != 'object')
+ if (hold.current_copy() && typeof hold.current_copy() != 'object') {
hold.current_copy(hold_data.copy);
+ }
+
+ if (hold.current_copy()) {
+ // likewise, current_copy's status isn't fleshed in the API
+ if(hold.current_copy().status() !== null &&
+ typeof hold.current_copy().status() != 'object')
+ egCore.pcrud.retrieve('ccs',hold.current_copy().status()
+ ).then(function(c) { hold.current_copy().status(c) });
+
+ // current_copy's shelving location position isn't always accessible
+ if (hold.current_copy().location()) {
+ //console.debug('fetching hold copy location order');
+ var location_id;
+ if (typeof hold.current_copy().location() != 'object') {
+ location_id = hold.current_copy().location();
+ } else {
+ location_id = hold.current_copy().location().id();
+ }
+ egCore.pcrud.search(
+ 'acplo',
+ {location: location_id, org: egCore.auth.user().ws_ou()},
+ null,
+ {atomic:true}
+ ).then(function(orders) {
+ if(orders[0]){
+ hold_data.hold._copy_location_position = orders[0].position();
+ } else {
+ hold_data.hold._copy_location_position = 999;
+ }
+ });
+ }
+
+ //Call number affixes are not always fleshed in the API
+ if (hold_data.volume.prefix) {
+ //console.debug('fetching call number prefix');
+ //console.log(hold_data.volume.prefix());
+ egCore.pcrud.retrieve('acnp',hold_data.volume.prefix())
+ .then(function(p) {hold_data.volume.prefix = p.label(); hold_data.volume.prefix_sortkey = p.label_sortkey()});
+ }
+ if (hold_data.volume.suffix) {
+ //console.debug('fetching call number suffix');
+ //console.log(hold_data.volume.suffix());
+ egCore.pcrud.retrieve('acns',hold_data.volume.suffix())
+ .then(function(s) {hold_data.volume.suffix = s.label(); hold_data.volume.suffix_sortkey = s.label_sortkey()});
+ }
+ }
}
return service;
* most actionis are performed.
*/
.factory('egHoldGridActions',
- ['$window','$location','egCore','egHolds','egCirc',
-function($window , $location , egCore , egHolds , egCirc) {
+ ['$window','$location','$timeout','egCore','egHolds','egCirc',
+function($window , $location , $timeout , egCore , egHolds , egCirc) {
var service = {};
return egHolds.cancel_holds(hold_ids).then(service.refresh);
}
+ service.cancel_wide_hold = function(items) {
+ var hold_ids = items.filter(function(item) {
+ return !item.hold.cancel_time;
+ }).map(function(item) {return item.hold.id});
+
+ return egHolds.cancel_holds(hold_ids).then(service.refresh);
+ }
+
service.uncancel_hold = function(items) {
var hold_ids = items.filter(function(item) {
return item.hold.cancel_time();
return egHolds.uncancel_holds(hold_ids).then(service.refresh);
}
+ service.uncancel_wide_hold = function(items) {
+ var hold_ids = items.filter(function(item) {
+ return item.hold.cancel_time;
+ }).map(function(item) {return item.hold.id});
+
+ return egHolds.uncancel_holds(hold_ids).then(service.refresh);
+ }
+
// jump to circ list for either 1) the targeted copy or
// 2) the hold target copy for copy-level holds
service.show_recent_circs = function(items) {
- if (items.length && (copy = items[0].copy)) {
- var url = $location.path(
- '/cat/item/' + copy.id() + '/circ_list').absUrl();
- $window.open(url, '_blank').focus();
- }
+ var focus = items.length == 1;
+ angular.forEach(items, function(item) {
+ if (item.copy) {
+ var url = egCore.env.basePath +
+ '/cat/item/' +
+ item.copy.id() +
+ '/circ_list';
+ $timeout(function() { var x = $window.open(url, '_blank'); if (focus) x.focus() });
+ }
+ });
+ }
+
+ // jump to circ list for either 1) the targeted copy or
+ // 2) the hold target copy for copy-level holds
+ service.show_recent_circs_wide = function(items) {
+ var focus = items.length == 1;
+ angular.forEach(items, function(item) {
+ if (item.hold.cp_id) {
+ var url = egCore.env.basePath +
+ '/cat/item/' +
+ item.hold.cp_id +
+ '/circ_list';
+ $timeout(function() { var x = $window.open(url, '_blank'); if (focus) x.focus() });
+ }
+ });
}
+ service.show_patrons = function(items) {
+ var focus = items.length == 1;
+ angular.forEach(items, function(item) {
+ var url = egCore.env.basePath +
+ 'circ/patron/' +
+ item.hold.usr().id() +
+ '/holds';
+ $timeout(function() { var x = $window.open(url, '_blank'); if (focus) x.focus() });
+ });
+ }
+
+ service.show_patrons_wide = function(items) {
+ var focus = items.length == 1;
+ angular.forEach(items, function(item) {
+ var url = egCore.env.basePath +
+ 'circ/patron/' +
+ item.hold.usr_id +
+ '/holds';
+ $timeout(function() { var x = $window.open(url, '_blank'); if (focus) x.focus() });
+ });
+ }
+
+ service.show_holds_for_title = function(items) {
+ var focus = items.length == 1;
+ angular.forEach(items, function(item) {
+ var url = egCore.env.basePath +
+ 'cat/catalog/record/' +
+ item.mvr.doc_id() +
+ '/holds';
+ $timeout(function() { var x = $window.open(url, '_blank'); if (focus) x.focus() });
+ });
+ }
+
+ service.show_holds_for_title_wide = function(items) {
+ var focus = items.length == 1;
+ angular.forEach(items, function(item) {
+ var url = egCore.env.basePath +
+ 'cat/catalog/record/' +
+ item.hold.record_id +
+ '/holds';
+ $timeout(function() { var x = $window.open(url, '_blank'); if (focus) x.focus() });
+ });
+ }
+
+
function generic_update(items, action) {
if (!items.length) return $q.when();
var hold_ids = items.map(function(item) {return item.hold.id()});
return egHolds[action](hold_ids).then(service.refresh);
}
+ function generic_update_wide(items, action) {
+ if (!items.length) return $q.when();
+ var hold_ids = items.map(function(item) {return item.hold.id});
+ return egHolds[action](hold_ids).then(service.refresh);
+ }
+
service.set_copy_quality = function(items) {
generic_update(items, 'set_copy_quality'); }
service.edit_pickup_lib = function(items) {
service.transfer_to_marked_title = function(items) {
generic_update(items, 'transfer_to_marked_title'); }
+ service.set_copy_quality_wide = function(items) {
+ generic_update_wide(items, 'set_copy_quality'); }
+ service.edit_pickup_lib_wide = function(items) {
+ generic_update_wide(items, 'edit_pickup_lib'); }
+ service.edit_notify_prefs_wide = function(items) {
+ generic_update_wide(items, 'edit_notify_prefs'); }
+ service.edit_dates_wide = function(items) {
+ generic_update_wide(items, 'edit_dates'); }
+ service.suspend_wide = function(items) {
+ generic_update_wide(items, 'suspend_holds'); }
+ service.activate_wide = function(items) {
+ generic_update_wide(items, 'activate_holds'); }
+ service.set_top_of_queue_wide = function(items) {
+ generic_update_wide(items, 'set_top_of_queue'); }
+ service.clear_top_of_queue_wide = function(items) {
+ generic_update_wide(items, 'clear_top_of_queue'); }
+ service.transfer_to_marked_title_wide = function(items) {
+ generic_update_wide(items, 'transfer_to_marked_title'); }
+
service.mark_damaged = function(items) {
+ angular.forEach(items, function(item) {
+ if (item.copy) {
+ egCirc.mark_damaged({
+ id: item.copy.id(),
+ barcode: item.copy.barcode()
+ }).then(service.refresh);
+ }
+ });
+ }
+
+ service.mark_damaged_wide = function(items) {
+ angular.forEach(items, function(item) {
+ if (item.copy) {
+ egCirc.mark_damaged({
+ id: item.hold.cp_id,
+ barcode: item.hold.cp_barcode
+ }).then(service.refresh);
+ }
+ });
+ }
+
+ service.mark_missing = function(items) {
var copy_ids = items
.filter(function(item) { return Boolean(item.copy) })
.map(function(item) { return item.copy.id() });
if (copy_ids.length)
- egCirc.mark_damaged(copy_ids).then(service.refresh);
+ egCirc.mark_missing(copy_ids).then(service.refresh);
}
- service.mark_missing = function(items) {
+ service.mark_missing_wide = function(items) {
var copy_ids = items
- .filter(function(item) { return Boolean(item.copy) })
- .map(function(item) { return item.copy.id() });
+ .filter(function(item) { return Boolean(item.hold.cp_id) })
+ .map(function(item) { return item.hold.cp_id });
if (copy_ids.length)
egCirc.mark_missing(copy_ids).then(service.refresh);
}
egHolds.retarget(hold_ids).then(service.refresh);
}
+ service.retarget_wide = function(items) {
+ var hold_ids = items.map(function(item) { return item.hold.id });
+ egHolds.retarget(hold_ids).then(service.refresh);
+ }
+
return service;
}])
showPatron : '='
},
controller : [
- '$scope','$modal','egCore','egHolds','egCirc',
- function($scope , $modal , egCore , egHolds , egCirc) {
+ '$scope','$uibModal','egCore','egHolds','egCirc',
+ function($scope , $uibModal , egCore , egHolds , egCirc) {
function draw() {
if (!$scope.holdId) return;
egCore.net.request(
'open-ils.circ',
'open-ils.circ.hold.details.retrieve.authoritative',
- egCore.auth.token(), $scope.holdId
-
+ egCore.auth.token(), $scope.holdId, {
+ include_current_copy : true,
+ include_usr : true,
+ include_cancel_cause : true,
+ include_requestor : true
+ }
).then(function(hold_data) {
egHolds.local_flesh(hold_data);
}
$scope.new_note = function() {
- return $modal.open({
+ return $uibModal.open({
templateUrl : './circ/share/t_hold_note_dialog',
+ backdrop: 'static',
controller :
- ['$scope', '$modalInstance',
- function($scope, $modalInstance) {
+ ['$scope', '$uibModalInstance',
+ function($scope, $uibModalInstance) {
$scope.args = {};
$scope.ok = function() {
- $modalInstance.close($scope.args)
+ $uibModalInstance.close($scope.args)
},
$scope.cancel = function($event) {
- $modalInstance.dismiss();
+ $uibModalInstance.dismiss();
$event.preventDefault();
}
}
}
$scope.new_notification = function() {
- return $modal.open({
+ return $uibModal.open({
templateUrl : './circ/share/t_hold_notification_dialog',
+ backdrop: 'static',
controller :
- ['$scope', '$modalInstance',
- function($scope, $modalInstance) {
+ ['$scope', '$uibModalInstance',
+ function($scope, $uibModalInstance) {
$scope.args = {};
$scope.ok = function() {
- $modalInstance.close($scope.args)
+ $uibModalInstance.close($scope.args)
},
$scope.cancel = function($event) {
- $modalInstance.dismiss();
+ $uibModalInstance.dismiss();
$event.preventDefault();
}
}