<option value="bills_historical">[% l('Bills, Historical') %]</option>
<option value="bill_payment">[% l('Bills, Payment') %]</option>
<option value="patron_note">[% l('Patron Note') %]</option>
+ <option value="transit_slip">[% l('Transit Slip') %]</option>
</select>
</div>
<div class="col-md-7">
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/grid.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/ui.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/user.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/services/circ.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/checkin/app.js"></script>
<script>
angular.module('egCoreMod').run(['egStrings', function(s) {
<!-- checkins list -->
<eg-grid
- id-field="id"
- features="-display,-sort,-multisort"
+ id-field="index"
+ features="-sort,-multisort"
main-label="[% l('Items Checked In') %]"
items-provider="gridDataProvider"
+ grid-controls="gridControls"
persist-key="circ.checkin">
- <eg-grid-field label="[% l('Circ ID') %]" path='payload.circ.id' visible></eg-grid-field>
- <eg-grid-field label="[% l('Barcode') %]" path='copy_barcode' visible></eg-grid-field>
- <eg-grid-field label="[% l('Due Date') %]" path='payload.circ.due_date' visible></eg-grid-field>
- <eg-grid-field label="[% l('Response') %]" path="textcode" visible></eg-grid-field>
- <eg-grid-field label="[% l('Title') %]" path="payload.record.title" visible></eg-grid-field>
- <eg-grid-field label="[% l('Author') %]" path="payload.record.author" visible></eg-grid-field>
- <eg-grid-field label="[% l('Call Number') %]" path="payload.copy.call_number.label" visible></eg-grid-field>
- <eg-grid-field label="[% l('Alert Msg') %]" path="payload.copy.alert_message" visible></eg-grid-field>
+
+ <eg-grid-field label="[% l('Circ ID') %]"
+ path='payload.circ.id'></eg-grid-field>
+
+ <eg-grid-field label="[% l('Barcode') %]" path="copy_barcode">
+ <!-- wth... ng-if / ng-disabled not working here.
+ i want to hide / disable the href when there is no copy ID -->
+ <a href="./cat/item/{{item.payload.copy.id()}}/summary" target="_self">
+ {{item.copy_barcode}}
+ </a>
+ </eg-grid-field>
+
+ <eg-grid-field label="[% l('Due Date') %]"
+ path='payload.circ.due_date' datatype="timestamp"></eg-grid-field>
+ <eg-grid-field label="[% l('Response Code') %]"
+ path="textcode"></eg-grid-field>
+ <eg-grid-field label="[% l('Title') %]"
+ path="payload.record.title"></eg-grid-field>
+ <eg-grid-field label="[% l('Author') %]"
+ path="payload.record.author"></eg-grid-field>
+ <eg-grid-field label="[% l('Call Number') %]"
+ path="payload.copy.call_number.label"></eg-grid-field>
+ <eg-grid-field label="[% l('Alert Msg') %]"
+ path="payload.copy.alert_message"></eg-grid-field>
+
+ <!-- TODO: add support for wildcard fields sans idl-class -->
</eg-grid>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/ui.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/user.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/services/billing.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/services/circ.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/patron/app.js"></script>
<!-- load the rest on demand? -->
</div>
</div>
<div class="modal-footer">
- <!--
- <input type="button" class="btn btn-primary" disabled="disabled"
+ <input type="button" class="btn btn-primary"
ng-click="print()" value="[% l('Print') %]"/>
- -->
<input type="submit" class="btn btn-warning"
ng-click="ok()" value="[% l('Do Not Print') %]"/>
</div>
--- /dev/null
+<div>
+ <div>[% l('This item needs to be routed to [_1]', '<b>{{transit.dest.shortname}}</b>') %]</div>
+ {{transit.dest.name}}<br/>
+ {{transit.dest.holds_address.street1}}
+ {{transit.dest.holds_address.street2}}<br/>
+ {{transit.dest.holds_address.city}},
+ {{transit.dest.holds_address.state}}
+ {{transit.dest.holds_address.post_code}}<br/><br/>
+ [% l('Barcode: [_1]', '{{transit.target_copy.barcode}}') %]<br/>
+ [% l('Title: [_1]', '{{title}}') %]<br/>
+ [% l('Author: [_1]', '{{author}}') %]<br/>
+ [% l('Slip Date: [_1]', '{{today | date:"short"}}') %]<br/>
+ [% l('Printed by [_1] at [_2]',
+ '{{staff.first_given_name}}', '{{current_location.shortname}}') %]<br/>
+</div>
barcode : '30393830393'
}
}
+ var seed_addr = {
+ street1 : '123 Apple Rd',
+ street2 : 'Suite B',
+ city : 'Anywhere',
+ state : 'XX',
+ country : 'US',
+ post_code : '12345'
+ }
+
+ var seed_record = {
+ title : 'Traveling Pants!!',
+ author : 'Jane Jones',
+ isbn : '1231312123'
+ };
+
+ var seed_copy = {
+ barcode : '33434322323'
+ }
+
$scope.preview_scope = {
current_location : egCore.idl.toHash(
egCore.org.get(egCore.auth.user().ws_ou())),
title : 'Test Note Title',
usr : seed_user,
value : 'This patron is super nice!'
- }
+ },
+
+ transit : {
+ dest : {
+ name : 'Library X',
+ shortname : 'LX',
+ holds_address : seed_addr
+ },
+ target_copy : seed_copy
+ },
+ title : seed_record.title,
+ author : seed_record.author,
+ staff : egCore.idl.toHash(egCore.auth.user())
}
+
$scope.preview_scope.payments = [
{amount : 1.00, xact : $scope.preview_scope.transactions[0]},
{amount : 1.00, xact : $scope.preview_scope.transactions[1]}
]
$scope.preview_scope.payments[0].xact.title = 'Hali Bote Azikaban de tao fan';
$scope.preview_scope.payments[0].xact.copy_barcode = '334343434';
- $scope.preview_scope.payments[1].xact.title = 'Traveling Pants!!';
- $scope.preview_scope.payments[1].xact.copy_barcode = '334343467';
+ $scope.preview_scope.payments[1].xact.title = seed_record.title;
+ $scope.preview_scope.payments[1].xact.copy_barcode = seed_copy.barcode;
$scope.template_changed = function() {
egCore.hatch.getPrintTemplate($scope.print.template_name)
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export
})
-/**
- * checkin service
- */
.factory('checkinSvc', [function() {
-
var service = {};
service.checkins = [];
return service;
}])
-/**
- * locally cached org unit addresses -- needed for route slips, etc.
- */
-.factory('orgAddrSvc', ['$q','egCore', function($q, egCore) {
- var service = {cache : {}};
- service.getAddr = function(org_id, addr_type) {
- if (service.cache[org_id]) {
- if (service.cache[org_id][addr_type]) {
- return $q.when(service.cache[org_id][addr_type]);
- }
- } else {
- service.cache[org_id] = {};
- }
-
- var deferred = $q.defer();
- egCore.pcrud.retrieve('aoa', egCore.org.get(org_id).holds_address())
- .then(function(addr) {
- service.cache[org_id][addr_type] = addr;
- deferred.resolve(addr);
- });
- return deferred.promise;
- }
- return service;
-}])
/**
* Manages checkin
*/
.controller('CheckinCtrl',
- ['$scope','$q','$modal','egCore','checkinSvc','egGridDataProvider',
- 'orgAddrSvc','egAlertDialog','egConfirmDialog',
-function($scope, $q, $modal, egCore, checkinSvc, egGridDataProvider,
- orgAddrSvc, egAlertDialog, egConfirmDialog) {
+ ['$scope','$q','egCore','checkinSvc','egGridDataProvider','egCirc',
+function($scope , $q , egCore , checkinSvc , egGridDataProvider , egCirc) {
// run egCore.startup here since it's not handled via resolver
egCore.startup.go().then(
$scope.focusMe = true;
$scope.checkins = checkinSvc.checkins;
+ var checkinGrid = $scope.gridControls = {};
- var provider = egGridDataProvider.instance({});
- provider.get = function(offset, count) {
- return provider.arrayNotifier(
- $scope.checkins, offset, count
- );
- }
- $scope.gridDataProvider = provider;
-
- function addCheckin(evt) {
- checkinSvc.checkins.push(evt);
- provider.refresh();
- }
-
+ $scope.gridDataProvider = egGridDataProvider.instance({
+ get : function(offset, count) {
+ return this.arrayNotifier($scope.checkins, offset, count);
+ }
+ });
$scope.checkin = function(args) {
- if (args && args.copy_barcode) {
- performCheckin(angular.copy(args));
- args.copy_barcode = ''; // reset UI
- }
-
- $scope.focusMe = true;
- }
-
- function performCheckin(args, override) {
- var method = 'open-ils.circ.checkin';
- if (override) method += '.override';
- egCore.net.request('open-ils.circ', method, egCore.auth.token(), args)
- .then(function(evt) {
+ if (args && args.copy_barcode) {
- if (!evt) {
- console.error('no checkin response received');
- return;
- }
+ egCirc.checkin(angular.copy(args))
+ .then(function(final_resp) {
+ final_resp.evt.index = checkinSvc.checkins.length;
+ checkinSvc.checkins.unshift(final_resp.evt);
+ checkinGrid.refresh();
- if (angular.isArray(evt)) evt = evt[0];
- evt.id = checkinSvc.checkins.length;
- evt.copy_barcode = args.copy_barcode;
- handleCheckinResponse(evt, args, override);
- });
- }
+ // in case we lost focus to a dialog
+ $scope.focusMe = true;
+ });
- function handleCheckinResponse(evt, args, override) {
- var copy, hold, transit;
- if (evt.payload) {
- copy = evt.payload.copy;
- hold = evt.payload.hold;
- transit = evt.payload.transit;
- }
-
- switch (evt.textcode) {
- case 'SUCCESS':
- case 'NO_CHANGE':
- addCheckin(evt);
- if (copy.status() == 8) { // on holds shelf
- if (hold &&
- hold.pickup_lib() == egCore.auth.user().ws_ou()) {
- // item should be on our holds shelf.
- // display the holds slip
- openRouteDialog(
- './circ/checkin/t_hold_shelf_dialog', evt, args);
- }
- }
- break;
-
- case 'ROUTE_ITEM':
- addCheckin(evt);
- openRouteDialog('./circ/checkin/t_transit_dialog', evt, args);
- break;
- case 'ASSET_COPY_NOT_FOUND':
- $scope.blurMe = true;
- egAlertDialog.open(egCore.strings.UNCAT_ALERT_DIALOG, args)
- .result.then(function() {$scope.focusMe = true});
- break;
- case 'COPY_ALERT_MESSAGE':
- $scope.blurMe = true;
- egConfirmDialog.open(
- egCore.strings.COPY_ALERT_MSG_DIALOG_TITLE,
- evt.payload, // payload == alert message text
- { copy_barcode : args.copy_barcode,
- ok : function() {
- // on confirm, redo checkout w/ override
- performCheckin(args, true)
- },
- cancel : function() {
- // on cancel, push the event on the list
- // to show that it happened
- addCheckin(evt);
- }
- }
- ).result.then(function() {$scope.focusMe = true})
- break;
- default:
- console.warn('unhandled checkin response : ' + evt.textcode);
- console.debug('checkin: ' + js2JSON(evt));
- // push it on the list so the user can at least see
- // something happened.
- addCheckin(evt);
- }
- }
+ args.copy_barcode = ''; // reset UI for next scan
+ }
- function openRouteDialog(tmpl, evt, args) {
- // avoid unintended checkins while the dialog is open
- $scope.blurMe = true;
- $modal.open({
- templateUrl: tmpl,
- controller: [
- '$scope', '$modalInstance', 'destAddr', 'holdUser',
- function($scope, $modalInstance, destAddr, holdUser) {
- $scope.destAddr = destAddr;
- $scope.holdUser = holdUser;
- $scope.dest = egCore.org.get(evt.org);
- $scope.evt = evt;
- $scope.now = new Date();
- $scope.ok = function() {$modalInstance.close()}
- }],
- resolve : {
- destAddr : function() {
- if (!evt.org) return $q.when();
- // TODO SERVER: response payload should flesh dest addr
- return orgAddrSvc.getAddr(evt.org, 'holds_address');
- },
- holdUser : function() {
- // TODO SERVER: response payload should flesh hold recipient
- if (!evt.payload.hold) return $q.when();
- return egCore.pcrud.retrieve('au',
- evt.payload.hold.usr(), {
- flesh : 1,
- flesh_fields : {'au' : ['card']}
- }
- );
- }
- }
- }).result.then(function() {$scope.focusMe = true});
+ $scope.focusMe = true;
}
-
}])
--- /dev/null
+/**
+ * Checkin, checkout, and renew
+ */
+
+angular.module('egCoreMod')
+
+.factory('egCirc',
+
+ ['$modal','$q','egCore','egAlertDialog','egConfirmDialog',
+function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
+
+ var service = {
+ // auto-override these events after the first override
+ checkout_overrides : {},
+ org_addr_cache : {}
+ };
+
+ service.reset = function() {
+ service.checkout_overrides = {};
+ }
+
+ // Performs a checkout.
+ // Returns a promise resolved with the original params and options
+ // and the final checkout event (e.g. in the case of override).
+ // Rejected if the checkout cannot be completed.
+ service.checkout = function(params, options) {
+ if (!options) options = {};
+
+ console.debug('egCirc.checkout() : ' + js2JSON(params));
+
+ var method = 'open-ils.circ.checkout.full';
+ if (options.override) method += '.override';
+
+ return egCore.net.request(
+ 'open-ils.circ', method, egCore.auth.token(), params
+
+ ).then(function(evt) {
+
+ if (angular.isArray(evt)) evt = evt[0];
+ return service.handle_checkout_resp(evt, args, override);
+ });
+ }
+
+ // Performs a renewal.
+ // Returns a promise resolved with the original params and options
+ // and the final checkout event (e.g. in the case of override)
+ // Rejected if the renewal cannot be completed.
+ service.renew = function(params, options) {
+ if (!options) options = {};
+
+ console.debug('egCirc.renew() : ' + js2JSON(params));
+
+ var method = 'open-ils.circ.renew';
+ if (options.override) method += '.override';
+
+ return egCore.net.request(
+ 'open-ils.circ', method, egCore.auth.token(), params
+
+ ).then(function(evt) {
+
+ if (angular.isArray(evt)) evt = evt[0];
+ return service.handle_checkout_resp(evt, args, options);
+ });
+ }
+
+ // Performs a checkin
+ // Returns a promise resolved with the original params and options,
+ // plus the final checkin event (e.g. in the case of override).
+ // Rejected if the checkin cannot be completed.
+ service.checkin = function(params, options) {
+ if (!options) options = {};
+
+ var method = 'open-ils.circ.checkin';
+ if (options.override) method += '.override';
+
+ return egCore.net.request(
+ 'open-ils.circ', method, egCore.auth.token(), params
+
+ ).then(function(evt) {
+
+ if (angular.isArray(evt)) evt = evt[0];
+ return service.handle_checkin_response(evt, params, options);
+ });
+ }
+
+ service.handle_checkout_resp = function(evt, params, options) {
+
+ var final_resp = {evt : evt, params : params, options : options};
+
+ // track the barcode regardless of whether it refers to a copy
+ evt.copy_barcode = params.copy_barcode;
+
+ switch (evt.textcode) {
+ case 'SUCCESS':
+ return $q.when(final_resp);
+
+ case 'ITEM_NOT_CATALOGED':
+ return service.precat_dialog(params, options);
+
+ case 'PATRON_EXCEEDS_OVERDUE_COUNT':
+ case 'PATRON_EXCEEDS_FINES':
+ case 'PATRON_EXCEEDS_CHECKOUT_COUNT':
+ case 'PATRON_EXCEEDS_LOST_COUNT':
+ if (options.override) {
+ // NOTE: I don't think we'll ever get here, since the
+ // override attempt should produce a perm failure...
+ console.debug('override failed: ' + evt.textcode);
+
+ } else {
+ if (service.checkout_overrides[evt.textcode]) {
+ // user has already opted to override this type
+ // of event. Re-run the checkout w/ override.
+ options.override = true;
+ return service.checkout(params, options);
+ } else {
+ // ask the user if they would like to override this
+ // event type.
+ return service.override_dialog(evt, params, options);
+ }
+ }
+ break;
+
+ case 'OPEN_CIRCULATION_EXISTS':
+ return service.circ_exists_dialog(evt, params, options);
+
+ /* stuff to consider
+ PERM_FAILURE
+ PATRON_BARRED
+ CIRC_EXCEEDS_COPY_RANGE
+ PATRON_ACCOUNT_EXPIRED
+ ITEM_DEPOSIT_REQUIRED
+ ITEM_RENTAL_FEE_REQUIRED
+ ITEM_DEPOSIT_PAID
+ ACTION_CIRCULATION_NOT_FOUND
+ PATRON_EXCEEDS_CHECKOUT_COUNT
+ COPY_CIRC_NOT_ALLOWED
+ COPY_NOT_AVAILABLE
+ COPY_IS_REFERENCE
+ COPY_NEEDED_FOR_HOLD
+ MAX_RENEWALS_REACHED
+ CIRC_CLAIMS_RETURNED
+ COPY_ALERT_MESSAGE
+ */
+
+ default:
+ console.warn('unhandled circ response : ' + evt.textcode);
+ return $q.when(final_resp);
+ }
+ }
+
+ // fetch the list of circ modifiers, from cache if available
+ service.get_circ_mods = function() {
+ if (egCore.env.ccm) {
+ return $q.when(egCore.env.ccm.list);
+ } else {
+ return egCore.pcrud.retrieveAll('ccm', null, {atomic : true})
+ .then(function(list) {
+ egCore.env.absorbList(list, 'ccm');
+ return list;
+ });
+ }
+ };
+
+ // fetch/cache for org unit addresses
+ service.get_org_addr = function(org_id, addr_type) {
+ if (service.org_addr_cache[org_id]) {
+ if (service.org_addr_cache[org_id][addr_type])
+ return $q.when(service.org_addr_cache[org_id][addr_type]);
+ } else {
+ service.org_addr_cache[org_id] = {};
+ }
+
+ return egCore.pcrud.retrieve('aoa',
+ egCore.org.get(org_id)[addr_type]()
+ ).then(function(addr) {
+ return service.org_addr_cache[org_id][addr_type] = addr;
+ });
+ }
+
+ // opens a dialog asking the user if they would like to override
+ // the returned event.
+ service.override_dialog = function(evt, params, options) {
+ return $modal.open({
+ templateUrl: './circ/share/t_event_override_dialog',
+ controller:
+ ['$scope', '$modalInstance',
+ function($scope, $modalInstance) {
+ $scope.evt = evt;
+ $scope.ok = function() { $modalInstance.close() }
+ $scope.cancel = function () { $modalInstance.dismiss() }
+ }]
+ }).result.then(
+ function() {
+ service.checkout_overrides[evt.textcode] = true;
+ options.override = true;
+ return service.checkout(params, options);
+ }
+ );
+ }
+
+
+ // opens a dialog allowing the user to fill in pre-cat copy info
+ service.precat_dialog = function(params, options) {
+
+ return $modal.open({
+ templateUrl: './circ/share/t_precat_dialog',
+ controller:
+ ['$scope', '$modalInstance', 'circMods',
+ function($scope, $modalInstance, circMods) {
+ $scope.focusMe = true;
+ $scope.precatArgs = {
+ copy_barcode : params.copy_barcode,
+ circ_modifier : circMods.length ? circMods[0].code() : null
+ };
+ $scope.circModifiers = circMods;
+ $scope.ok = function(args) { $modalInstance.close(args) }
+ $scope.cancel = function () { $modalInstance.dismiss() }
+ }],
+ resolve : {
+ circMods : function() {
+ return service.get_circ_mods();
+ }
+ }
+ }).result.then(
+ function(args) {
+ if (!args || !args.dummy_title) return $q.reject();
+ angular.forEach(args, function(val, key) {params[key] = val});
+ params.precat = true;
+ return service.checkout(params, options);
+ }
+ );
+ }
+
+ service.circ_exists_dialog = function(evt, params, options) {
+ $modal.open({
+ templateUrl: './circ/share/t_circ_exists_dialog',
+ controller:
+ ['$scope','$modalInstance','openCirc',
+ function($scope , $modalInstance , openCirc) {
+ $scope.circDate = openCirc.xact_start();
+ $scope.ok = function() { $modalInstance.close() }
+ $scope.cancel = function() { $modalInstance.dismiss() }
+ }],
+ resolve : {
+ // fetch the conflicting open circulation
+ openCirc : function() {
+ return egCore.pcrud.search('circ',
+ {target_copy : evt.payload.copy.id()},
+ {order_by : {circ : 'xact_start desc' }, limit : 1}
+ );
+ }
+ }
+ }).result.then(
+ function() {
+
+ return service.checkin(
+ {barcode : params.copy_barcode, noop : true}
+ ).then(function(checkin_resp) {
+ if (checkin_resp.evt.textcode == 'SUCCESS') {
+ return service.checkout(params, options);
+ } else {
+ alert(egCore.evt.parse(evt));
+ return $q.reject();
+ }
+ });
+ }
+ );
+ }
+
+ service.handle_checkin_response = function(evt, params, options) {
+
+ var final_resp = {evt : evt, params : params, options : options};
+
+ var copy, hold, transit;
+ if (evt.payload) {
+ copy = evt.payload.copy;
+ hold = evt.payload.hold;
+ transit = evt.payload.transit;
+ }
+
+ // track the barcode regardless of whether it refers to a copy
+ evt.copy_barcode = params.copy_barcode;
+
+ switch (evt.textcode) {
+ case 'SUCCESS':
+ case 'NO_CHANGE':
+
+ // inform user if the item is on the local holds shelf
+ if (copy.status() == 8 // on holds shelf
+ && hold
+ && hold.pickup_lib() == egCore.auth.user().ws_ou()) {
+ return service.route_dialog(
+ './circ/share/t_hold_shelf_dialog',
+ evt, params, options
+ ).then(function() { return final_resp });
+
+ } else {
+ return $q.when(final_resp);
+ }
+
+ // show the route dialog
+ case 'ROUTE_ITEM':
+ return service.route_dialog(
+ './circ/share/t_transit_dialog',
+ evt, params, options
+ ).then(function() { return final_resp });
+
+
+ // show the copy not found alert dialog
+ case 'ASSET_COPY_NOT_FOUND':
+ // FIXME: where can we put strings that don't live within
+ // a specific page?
+ return egAlertDialog.open(
+ egCore.strings.UNCAT_ALERT_DIALOG, params)
+ .result.then(function() {return final_resp});
+
+ case 'COPY_ALERT_MESSAGE':
+ // FIXME: where can we put strings that don't live within
+ // a specific page?
+
+ return egConfirmDialog.open(
+ egCore.strings.COPY_ALERT_MSG_DIALOG_TITLE,
+ evt.payload, // payload == alert message text
+ { copy_barcode : params.copy_barcode,
+ ok : function() {},
+ cancel : function() {
+ // TODO: do we return the final_resp so
+ // the user can display the copy even though
+ // the checkin did not take place?
+ }
+ }
+ ).result.then(function() {
+ options.override = true;
+ return service.checkin(params, options);
+ });
+
+ default:
+ console.warn('unhandled checkin response : ' + evt.textcode);
+ return $q.when(final_resp);
+ }
+ }
+
+ service.route_dialog = function(tmpl, evt, params, options) {
+ return $modal.open({
+ templateUrl: tmpl,
+ controller: [
+ '$scope', '$modalInstance', 'destAddr', 'holdUser',
+ function($scope, $modalInstance, destAddr, holdUser) {
+ $scope.destAddr = destAddr;
+ $scope.holdUser = holdUser;
+ $scope.dest = egCore.org.get(evt.org);
+ $scope.evt = evt;
+ $scope.now = new Date();
+ $scope.ok = function() {$modalInstance.close()}
+ $scope.print = function() {
+ $modalInstance.close();
+
+ var transit = evt.payload.transit;
+
+ // flesh data into the transit to match the print template
+ transit.target_copy(evt.payload.copy);
+ transit.dest(egCore.org.get(transit.dest()));
+ transit.dest().holds_address(destAddr);
+
+ egCore.hatch.printFromTemplate('default', 'transit_slip',
+ { transit : egCore.idl.toHash(transit),
+ title : evt.payload.record.title(),
+ author : evt.payload.record.author(),
+ staff : egCore.idl.toHash(egCore.auth.user()),
+ current_location : egCore.idl.toHash(
+ egCore.org.get(egCore.auth.user().ws_ou()))
+ }
+ );
+
+ }
+ }],
+ resolve : {
+ destAddr : function() {
+ if (!evt.org) return $q.when();
+ return service.get_org_addr(evt.org, 'holds_address');
+ },
+ holdUser : function() {
+ if (!evt.payload.hold) return $q.when();
+ return egCore.pcrud.retrieve('au',
+ evt.payload.hold.usr(), {
+ flesh : 1,
+ flesh_fields : {'au' : ['card']}
+ }
+ );
+ }
+ }
+ }).result;
+ }
+
+
+ return service;
+
+}]);
+
+
+++ /dev/null
-/**
- * Checkin, checkout, and renew
- */
-
-angular.module('egCoreMod')
-
-.factory('egCirc',
-
- ['$modal','$q','egCore',
-function($modal , $q , egCore) {
-
- var service = {
- // auto-override these events after the first override
- checkout_overrides : {},
- org_addr_cache : {}
- };
-
- service.reset = function() {
- service.checkout_overrides = {};
- }
-
- // Performs a checkout.
- // Returns a promise resolved with the original params and options
- // and the final checkout event (e.g. in the case of override).
- // Rejected if the checkout cannot be completed.
- service.checkout = function(params, options) {
- if (!options) options = {};
-
- console.debug('egCirc.checkout() : ' + js2JSON(params));
-
- var method = 'open-ils.circ.checkout.full';
- if (options.override) method += '.override';
-
- return egCore.net.request(
- 'open-ils.circ', method, egCore.auth.token(), params
-
- ).then(function(evt) {
-
- if (angular.isArray(evt)) evt = evt[0];
- return service.handle_checkout_resp(evt, args, override);
- });
- }
-
- // Performs a renewal.
- // Returns a promise resolved with the original params and options
- // and the final checkout event (e.g. in the case of override)
- // Rejected if the renewal cannot be completed.
- service.renew = function(params, options) {
- if (!options) options = {};
-
- console.debug('egCirc.renew() : ' + js2JSON(params));
-
- var method = 'open-ils.circ.renew';
- if (options.override) method += '.override';
-
- return egCore.net.request(
- 'open-ils.circ', method, egCore.auth.token(), params
-
- ).then(function(evt) {
-
- if (angular.isArray(evt)) evt = evt[0];
- return service.handle_checkout_resp(evt, args, options);
- });
- }
-
- // Performs a checkin
- // Returns a promise resolved with the original params and options,
- // plus the final checkin event (e.g. in the case of override).
- // Rejected if the checkin cannot be completed.
- service.checkin = function(params, options) {
- if (!options) options = {};
-
- var method = 'open-ils.circ.checkin';
- if (options.override) method += '.override';
-
- egCore.net.request(
- 'open-ils.circ', method, egCore.auth.token(), params
-
- ).then(function(evt) {
-
- if (angular.isArray(evt)) evt = evt[0];
- return service.handle_checkin_response(evt, params, options);
- });
- }
-
- service.handle_checkout_resp = function(evt, params, options) {
-
- var final_resp = {evt : evt, params : params, options : options};
-
- switch (evt.textcode) {
- case 'SUCCESS':
- return $q.when(final_resp);
-
- case 'ITEM_NOT_CATALOGED':
- return service.precat_dialog(params, options);
-
- case 'PATRON_EXCEEDS_OVERDUE_COUNT':
- case 'PATRON_EXCEEDS_FINES':
- case 'PATRON_EXCEEDS_CHECKOUT_COUNT':
- case 'PATRON_EXCEEDS_LOST_COUNT':
- if (options.override) {
- // NOTE: I don't think we'll ever get here, since the
- // override attempt should produce a perm failure...
- console.debug('override failed: ' + evt.textcode);
-
- } else {
- if (service.checkout_overrides[evt.textcode]) {
- // user has already opted to override this type
- // of event. Re-run the checkout w/ override.
- options.override = true;
- return service.checkout(params, options);
- } else {
- // ask the user if they would like to override this
- // event type.
- return service.override_dialog(evt, params, options);
- }
- }
- break;
-
- case 'OPEN_CIRCULATION_EXISTS':
- return service.circ_exists_dialog(evt, params, options);
-
- /* stuff to consider
- PERM_FAILURE
- PATRON_BARRED
- CIRC_EXCEEDS_COPY_RANGE
- PATRON_ACCOUNT_EXPIRED
- ITEM_DEPOSIT_REQUIRED
- ITEM_RENTAL_FEE_REQUIRED
- ITEM_DEPOSIT_PAID
- ACTION_CIRCULATION_NOT_FOUND
- PATRON_EXCEEDS_CHECKOUT_COUNT
- COPY_CIRC_NOT_ALLOWED
- COPY_NOT_AVAILABLE
- COPY_IS_REFERENCE
- COPY_NEEDED_FOR_HOLD
- MAX_RENEWALS_REACHED
- CIRC_CLAIMS_RETURNED
- COPY_ALERT_MESSAGE
- */
-
- default:
- console.warn('unhandled circ response : ' + evt.textcode);
- return $q.when(final_resp);
- }
- }
-
- // fetch the list of circ modifiers, from cache if available
- service.get_circ_mods = function() {
- if (egCore.env.ccm) {
- return $q.when(egCore.env.ccm.list);
- } else {
- return egCore.pcrud.retrieveAll('ccm', null, {atomic : true})
- .then(function(list) {
- egCore.env.absorbList(list, 'ccm');
- return list;
- });
- }
- };
-
- // fetch/cache for org unit addresses
- service.get_org_address = function(org_id, addr_type) {
- if (service.org_addr_cache[org_id]) {
- if (service.org_addr_cache[org_id][addr_type])
- return $q.when(service.org_addr_cache[org_id][addr_type]);
- } else {
- service.org_addr_cache[org_id] = {};
- }
-
- return egCore.pcrud.retrieve('aoa',
- egCore.org.get(org_id)[addr_type]()
- ).then(function(addr) {
- return service.org_addr_cache[org_id][addr_type] = addr;
- });
- }
-
- // opens a dialog asking the user if they would like to override
- // the returned event.
- service.override_dialog = function(evt, params, options) {
- return $modal.open({
- templateUrl: './circ/share/t_event_override_dialog',
- controller:
- ['$scope', '$modalInstance',
- function($scope, $modalInstance) {
- $scope.evt = evt;
- $scope.ok = function() { $modalInstance.close() }
- $scope.cancel = function () { $modalInstance.dismiss() }
- }]
- }).result.then(
- function() {
- service.checkout_overrides[evt.textcode] = true;
- options.override = true;
- return service.checkout(params, options);
- }
- );
- }
-
-
- // opens a dialog allowing the user to fill in pre-cat copy info
- service.precat_dialog = function(params, options) {
-
- return $modal.open({
- templateUrl: './circ/share/t_precat_dialog',
- controller:
- ['$scope', '$modalInstance', 'circMods',
- function($scope, $modalInstance, circMods) {
- $scope.focusMe = true;
- $scope.precatArgs = {
- copy_barcode : params.copy_barcode,
- circ_modifier : circMods.length ? circMods[0].code() : null
- };
- $scope.circModifiers = circMods;
- $scope.ok = function(args) { $modalInstance.close(args) }
- $scope.cancel = function () { $modalInstance.dismiss() }
- }],
- resolve : {
- circMods : function() {
- return service.get_circ_mods();
- }
- }
- }).result.then(
- function(args) {
- if (!args || !args.dummy_title) return $q.reject();
- angular.forEach(args, function(val, key) {params[key] = val});
- params.precat = true;
- return service.checkout(params, options);
- }
- );
- }
-
- service.circ_exists_dialog = function(evt, params, options) {
- $modal.open({
- templateUrl: './circ/share/t_circ_exists_dialog',
- controller:
- ['$scope','$modalInstance','openCirc',
- function($scope , $modalInstance , openCirc) {
- $scope.circDate = openCirc.xact_start();
- $scope.ok = function() { $modalInstance.close() }
- $scope.cancel = function() { $modalInstance.dismiss() }
- }],
- resolve : {
- // fetch the conflicting open circulation
- openCirc : function() {
- return egCore.pcrud.search('circ',
- {target_copy : evt.payload.copy.id()},
- {order_by : {circ : 'xact_start desc' }, limit : 1}
- );
- }
- }
- }).result.then(
- function() {
-
- return service.checkin(
- {barcode : params.copy_barcode, noop : true}
- ).then(function(checkin_resp) {
- if (checkin_resp.evt.textcode == 'SUCCESS') {
- return service.checkout(params, options);
- } else {
- alert(egCore.evt.parse(evt));
- return $q.reject();
- }
- });
- }
- );
- }
-
- service.handle_checkin_response = function(evt, params, options) {
-
- var final_resp = {evt : evt, params : params, options : options};
-
- var copy, hold, transit;
- if (evt.payload) {
- copy = evt.payload.copy;
- hold = evt.payload.hold;
- transit = evt.payload.transit;
- }
-
- switch (evt.textcode) {
- case 'SUCCESS':
- case 'NO_CHANGE':
- if (copy.status() == 8) { // on holds shelf
- if (hold &&
- hold.pickup_lib() == egCore.auth.user().ws_ou()) {
- // show dialog telling user the item is on the
- // local holds shelf
- return service.route_dialog(
- './circ/share/t_hold_shelf_dialog',
- evt, params, options
- ).then(function() { return final_resp });
- } else {
- return $q.when(final_resp);
- }
- }
-
- // show the route dialog
- case 'ROUTE_ITEM':
- return service.route_dialog(
- './circ/share/t_hold_shelf_dialog',
- evt, params, options
- ).then(function() { return final_resp });
-
-
- // show the copy not found alert dialog
- case 'ASSET_COPY_NOT_FOUND':
- // FIXME: where can we put strings that don't live within
- // a specific page?
- return egAlertDialog.open(
- egCore.strings.UNCAT_ALERT_DIALOG, params)
- .result.then(function() {return final_resp});
-
- case 'COPY_ALERT_MESSAGE':
- // FIXME: where can we put strings that don't live within
- // a specific page?
-
- return egConfirmDialog.open(
- egCore.strings.COPY_ALERT_MSG_DIALOG_TITLE,
- evt.payload, // payload == alert message text
- { copy_barcode : params.copy_barcode,
- ok : function() {},
- cancel : function() {
- // TODO: do we return the final_resp so
- // the user can display the copy even though
- // the checkin did not take place?
- }
- }
- ).result.then(function() {
- options.override = true;
- return service.checkin(params, options);
- });
-
- default:
- console.warn('unhandled checkin response : ' + evt.textcode);
- return $q.when(final_resp);
- }
- }
-
-}]);
-
-
service.ingestPrintContent(contentType, content, {})
.then(function() { $window.print() });
} else {
+ // HTML content is already ingested and accessible
+ // within the page to the printer.
$window.print();
}
}