<field reporter:label="Status" name="status" oils_persist:virtual="true" />
<field reporter:label="Transit" name="transit" oils_persist:virtual="true" />
<field reporter:label="Capture Date/Time" name="capture_time" reporter:datatype="timestamp"/>
- <field reporter:label="Currently Targeted Copy" name="current_copy" />
+ <field reporter:label="Currently Targeted Copy" name="current_copy" reporter:datatype="link"/>
<field reporter:label="Notify by Email?" name="email_notify" reporter:datatype="bool"/>
<field reporter:label="Hold Expire Date/Time" name="expire_time" reporter:datatype="timestamp"/>
<field reporter:label="Fulfilling Library" name="fulfillment_lib" reporter:datatype="org_unit"/>
<field reporter:label="Status" name="status" oils_persist:virtual="true" />
<field reporter:label="Transit" name="transit" oils_persist:virtual="true" />
<field reporter:label="Capture Date/Time" name="capture_time" reporter:datatype="timestamp"/>
- <field reporter:label="Currently Targeted Copy" name="current_copy" />
+ <field reporter:label="Currently Targeted Copy" name="current_copy" reporter:datatype="link"/>
<field reporter:label="Notify by Email?" name="email_notify" reporter:datatype="bool"/>
<field reporter:label="Hold Expire Date/Time" name="expire_time" reporter:datatype="timestamp"/>
<field reporter:label="Fulfilling Library" name="fulfillment_lib" reporter:datatype="org_unit"/>
<field reporter:label="Status" name="status" oils_persist:virtual="true" />
<field reporter:label="Transit" name="transit" oils_persist:virtual="true" />
<field reporter:label="Capture Date/Time" name="capture_time" reporter:datatype="timestamp"/>
- <field reporter:label="Currently Targeted Copy" name="current_copy" />
+ <field reporter:label="Currently Targeted Copy" name="current_copy" reporter:datatype="link"/>
<field reporter:label="Notify by Email?" name="email_notify" reporter:datatype="bool"/>
<field reporter:label="Hold Expire Date/Time" name="expire_time" reporter:datatype="timestamp"/>
<field reporter:label="Fulfilling Library" name="fulfillment_lib" reporter:datatype="org_unit"/>
<fields oils_persist:primary="id" oils_persist:sequence="action.hold_request_id_seq">
<field reporter:label="Status" name="status" oils_persist:virtual="true" />
<field reporter:label="Capture Date/Time" name="capture_time" reporter:datatype="timestamp"/>
- <field reporter:label="Currently Targeted Copy" name="current_copy" />
+ <field reporter:label="Currently Targeted Copy" name="current_copy" reporter:datatype="link"/>
<field reporter:label="Notify by Email?" name="email_notify" reporter:datatype="bool"/>
<field reporter:label="Hold Expire Date/Time" name="expire_time" reporter:datatype="timestamp"/>
<field reporter:label="Fulfilling Library" name="fulfillment_lib" reporter:datatype="org_unit"/>
<fields oils_persist:primary="id" oils_persist:sequence="action.hold_request_id_seq">
<field reporter:label="Status" name="status" oils_persist:virtual="true" />
<field reporter:label="Capture Date/Time" name="capture_time" reporter:datatype="timestamp"/>
- <field reporter:label="Currently Targeted Copy" name="current_copy" />
+ <field reporter:label="Currently Targeted Copy" name="current_copy" reporter:datatype="link"/>
<field reporter:label="Notify by Email?" name="email_notify" reporter:datatype="bool"/>
<field reporter:label="Hold Expire Date/Time" name="expire_time" reporter:datatype="timestamp"/>
<field reporter:label="Fulfilling Library" name="fulfillment_lib" reporter:datatype="org_unit"/>
<eg-grid
id-field="id"
- features="-sort,-multisort"
- items-provider="gridDataProvider"
+ idl-class="ahopl"
+ grid-controls="gridControls"
persist-key="circ.holds.pull">
<eg-grid-menu-item handler="detail_view"
<eg-grid-action handler="grid_actions.cancel_hold"
label="[% l('Cancel Hold') %]"></eg-grid-action>
- <eg-grid-field label="[% l('Hold ID') %]" path='hold.id'></eg-grid-field>
- <eg-grid-field label="[% l('Current Copy') %]"
- path='hold.current_copy.barcode'>
- <a href="./cat/item/{{item.hold.current_copy().id()}}/summary" target="_self">
- {{item.hold.current_copy().barcode()}}
- </a>
+ <!-- Define the column using the sort-able copy location order
+ position, but display the location label in each cell -->
+ <eg-grid-field name="copy_location_order_position" required
+ label="[% l('Shelving Location') %]">
+ <span>{{item.shelving_loc}}</span>
+ </eg-grid-field>
+ <eg-grid-field name="shelving_loc" path="current_copy.location.name"
+ required hidden label="[% l('Shelving Location Label') %]">
</eg-grid-field>
- <eg-grid-field label="[% l('Part') %]" path='part.label'></eg-grid-field>
- <eg-grid-field label="[% l('Request Date') %]" path='hold.request_time'></eg-grid-field>
- <eg-grid-field label="[% l('Hold Type') %]" path='hold.hold_type'></eg-grid-field>
- <eg-grid-field label="[% l('Pickup Library') %]" path='hold.pickup_lib.shortname'></eg-grid-field>
- <eg-grid-field label="[% l('Copy Location') %]" path='copy.location.name'></eg-grid-field>
- <eg-grid-field label="[% l('Call Number') %]" path='volume.label'></eg-grid-field>
-
- <eg-grid-field label="[% l('Title') %]" path='mvr.title'>
- <a target="_self" href="[% ctx.base_path %]/staff/cat/catalog/record/{{item.mvr.doc_id()}}">
- {{item.mvr.title()}}
- </a>
+ <!-- Render the colum using the sort-able call number sort key, but
+ display the call number label, complete with prefix and suffix
+ in the cell. -->
+ <eg-grid-field name="call_number_sort_key" required
+ path="current_copy.call_number.label_sortkey"
+ label="[% l('Call Number') %]">
+ <span>{{item.cn_prefix}} {{item.call_number_label}} {{item.cn_suffix}}</span>
</eg-grid-field>
+ <eg-grid-field name="call_number_label"
+ path="call_number_label" required hidden
+ label="[% l('Call Number Label') %]"></eg-grid-field>
+ <eg-grid-field name="cn_prefix" path="current_copy.call_number.prefix.label"
+ hidden required label="[% l('Call Number Prefix') %]"></eg-grid-field>
+ <eg-grid-field name="cn_suffix" path="current_copy.call_number.suffix.label"
+ hidden required label="[% l('Call Number Suffix') %]"></eg-grid-field>
- <eg-grid-field label="[% l('Author') %]" path='mvr.author'></eg-grid-field>
- <eg-grid-field label="[% l('Potential Copies') %]" path='potential_copies'></eg-grid-field>
- <eg-grid-field label="[% l('Status') %]" path='status_string' hidden></eg-grid-field>
- <eg-grid-field label="[% l('Queue Position') %]" path='queue_position' hidden></eg-grid-field>
- <eg-grid-field path='hold.*' parent-idl-class="ahr" hidden></eg-grid-field>
- <eg-grid-field path='hold.usr.*' parent-idl-class="ahr" hidden></eg-grid-field>
- <eg-grid-field path='hold.usr.card.*' parent-idl-class="ahr" hidden></eg-grid-field>
- <eg-grid-field path='hold.requestor.*' parent-idl-class="ahr" hidden></eg-grid-field>
- <eg-grid-field path='hold.requestor.card.*' parent-idl-class="ahr" hidden></eg-grid-field>
- <eg-grid-field path='copy.*' parent-idl-class="acp" hidden></eg-grid-field>
- <eg-grid-field path='volume.*' parent-idl-class="acn" hidden></eg-grid-field>
- <eg-grid-field path='mvr.*' parent-idl-class="mvr" hidden></eg-grid-field>
+ <eg-grid-field name="author"
+ path="current_copy.call_number.record.simple_record.author"
+ label="[% l('Author') %]"></eg-grid-field>
+ <eg-grid-field name="title"
+ path="current_copy.call_number.record.simple_record.title"
+ label="[% l('Title') %]">
+ <a target="_self"
+ href="[% ctx.base_path %]/staff/cat/catalog/record/{{item.record_id}}">
+ {{item.title}}
+ </a>
+ </eg-grid-field>
+ <eg-grid-field name="record_id" label="[% l('Bib Record ID') %]"
+ required hidden path="current_copy.call_number.record.id"></eg-grid-field>
+ <eg-grid-field name="copy_id"
+ path="current_copy.id" hidden required></eg-grid-field>
+ <eg-grid-field name="barcode"
+ path="current_copy.barcode" label="[% l('Current Copy') %]">
+ <a href="./cat/item/{{item.copy_id}}/summary" target="_self">
+ {{item.barcode}}
+ </a>
+ </eg-grid-field>
+ <eg-grid-field name="parts" path="current_copy.parts.label"
+ label="[% l('Parts') %]"></eg-grid-field>
+ <eg-grid-field name="copy_status" path="current_copy.status.name"
+ label="[% l('Copy Status') %]"></eg-grid-field>
+ <eg-grid-field name="copy_circ_lib_id" path="current_copy.circ_lib.id"
+ required hidden label="[% l('Copy Circ Lib ID') %]"></eg-grid-field>
+ <eg-grid-field name="notes" path="notes.body"
+ hidden label="[% l('Hold Notes') %]"></eg-grid-field>
+ <eg-grid-field name="patron_id" path="usr.id" hidden required></eg-grid-field>
+ <eg-grid-field name="patron_barcode" path="usr.card.barcode"
+ hidden label="[% l('Patron Barcode') %]">
+ <a href="./circ/patron/{{item.patron_id}}/holds" target="_self">
+ {{item.patron_barcode}}
+ </a>
+ </eg-grid-field>
+ <eg-grid-field name="pickup_lib_name" path="pickup_lib.name"
+ hidden label="[% l('Pickup Library') %]"></eg-grid-field>
+ <eg-grid-field name="pickup_lib_shortname" path="pickup_lib.shortname"
+ hidden label="[% l('Pickup Library (Shortname)') %]"></eg-grid-field>
+ <eg-grid-field name="request_lib_name" path="request_lib.name"
+ hidden label="[% l('Request Library') %]"></eg-grid-field>
+ <eg-grid-field name="request_lib_shortname" path="request_lib.shortname"
+ hidden label="[% l('Request Library (Shortname)') %]"></eg-grid-field>
+ <eg-grid-field name="selection_ou" path="selection_ou.shortname"
+ hidden label="[% l('Selection Locus') %]"></eg-grid-field>
+ <eg-grid-field name="sms_carrier_name" path="sms_carrier.name"
+ hidden label="[% l('SMS Carrier') %]"></eg-grid-field>
+ <eg-grid-field label="[% l('Potential Copies') %]"
+ path='potential_copies'></eg-grid-field>
+ <eg-grid-field label="[% l('Queue Position') %]"
+ path='queue_position' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Hold ID') %]" path='id' required hidden>
+ </eg-grid-field>
+ <eg-grid-field label="[% l('Request Date') %]" path='request_time' hidden>
+ </eg-grid-field>
</eg-grid>
$routeProvider.otherwise({redirectTo : '/circ/holds/shelf'});
})
-.factory('holdUiSvc', function() {
- return {
- holds : [] // cache
- }
-})
.controller('HoldsShelfCtrl',
['$scope','$q','$routeParams','$window','$location','egCore','egHolds','egHoldGridActions','egCirc','egGridDataProvider',
}])
.controller('HoldsPullListCtrl',
- ['$scope','$q','$routeParams','$window','$location','egCore','egHolds','egCirc','egGridDataProvider','egHoldGridActions','holdUiSvc',
-function($scope , $q , $routeParams , $window , $location , egCore , egHolds , egCirc , egGridDataProvider , egHoldGridActions , holdUiSvc) {
- $scope.detail_hold_id = $routeParams.hold_id;
+ ['$scope','$q','$routeParams','$window','$location','egCore',
+ 'egHolds','egCirc','egHoldGridActions',
+function($scope , $q , $routeParams , $window , $location , egCore ,
+ egHolds , egCirc , egHoldGridActions) {
- var provider = egGridDataProvider.instance({});
- $scope.gridDataProvider = provider;
+ $scope.detail_hold_id = $routeParams.hold_id;
- $scope.grid_actions = egHoldGridActions;
- $scope.grid_actions.refresh = function() {
- holdUiSvc.holds = [];
- provider.refresh();
+ var cached_details = {};
+ var details_needed = {};
+
+ $scope.gridControls = {
+ setQuery : function() {
+ return {'copy_circ_lib_id' : egCore.auth.user().ws_ou()}
+ },
+ setSort : function() {
+ return ['copy_location_order_position','call_number_sort_key']
+ },
+ itemRetrieved : function(item) {
+ if (!cached_details[item.id]) {
+ details_needed[item.id] = item;
+ }
+ },
+ allItemsRetrieved : flesh_holds
}
- provider.get = function(offset, count) {
- if (holdUiSvc.holds[offset]) {
- return provider.arrayNotifier(holdUiSvc.holds, offset, count);
- }
+ // Fetches hold detail data for each hold in the grid and links
+ // the detail data to the related grid item so egHoldGridActions
+ // and friends have access to holds data they understand.
+ // Only fetch not-yet-cached data.
+ function flesh_holds() {
- var deferred = $q.defer();
- var recv_index = 0;
+ // Start by fleshing hold details from our cached data.
+ var items = $scope.gridControls.allItems();
+ angular.forEach(items, function(item) {
+ if (!cached_details[item.id]) return;
+ angular.forEach(cached_details[item.id],
+ function(val, key) { item[key] = val })
+ });
+
+ // Exit if all needed details were already cached
+ if (Object.keys(details_needed).length == 0) return;
+
+ $scope.print_list_loading = true;
+ $scope.print_list_progress = 0;
- // fetch the IDs
egCore.net.request(
'open-ils.circ',
- 'open-ils.circ.hold_pull_list.fleshed.stream',
- egCore.auth.token(), count, offset
+ 'open-ils.circ.hold.details.batch.retrieve.authoritative',
+ egCore.auth.token(), Object.keys(details_needed)
).then(
- deferred.resolve, null,
- function(hold_data) {
- egHolds.local_flesh(hold_data);
- holdUiSvc.holds[offset + recv_index++] = hold_data;
- deferred.notify(hold_data);
+ function() {
+ $scope.print_list_loading = false;
+ $scope.print_list_progress = null;
+ }, null,
+ function(hold_info) {
+ var hold_id = hold_info.hold.id();
+ cached_details[hold_id] = hold_info;
+ var item = details_needed[hold_id];
+ delete details_needed[hold_id];
+ angular.forEach(hold_info,
+ function(val, key) { item[key] = val });
+ $scope.print_list_progress++;
}
);
+ }
- return deferred.promise;
+ $scope.grid_actions = egHoldGridActions;
+ $scope.grid_actions.refresh = function() {
+ cached_details = {}; // un-cache details after edit actions.
+ $scope.gridControls.refresh();
}
$scope.detail_view = function(action, user_data, items) {
idl_parent = idl_field;
idl_field = class_obj.field_map[part];
- if (idl_field && idl_field['class'] && (
- idl_field.datatype == 'link' ||
- idl_field.datatype == 'org_unit')) {
- class_obj = egCore.idl.classes[idl_field['class']];
+ if (idl_field) {
+ if (idl_field['class'] && (
+ idl_field.datatype == 'link' ||
+ idl_field.datatype == 'org_unit')) {
+ class_obj = egCore.idl.classes[idl_field['class']];
+ }
+ } else {
+ return null;
}
- // else, path is not in the IDL, which is fine
}
- if (!idl_field) return null;
-
return {
idl_parent: idl_parent,
idl_field : idl_field,