processPending() {
const pstring = this.pending[0];
+
+ console.debug('STRING', pstring.key, pstring.ctx);
+
this.strings[pstring.key].resolver(pstring.ctx).then(
txt => {
pstring.resolve(txt);
import {AuthService, AuthWsState} from '@eg/core/auth.service';
import {NetService} from '@eg/core/net.service';
import {StoreService} from '@eg/core/store.service';
-import {SckoService} from './scko.service';
+import {SckoService, ActionContext} from './scko.service';
import {OrgService} from '@eg/core/org.service';
import {EventService, EgEvent} from '@eg/core/event.service';
import {HatchService} from '@eg/core/hatch.service';
patronUsername: string;
patronPassword: string;
- patronLoginFailed = false;
staffUsername: string;
staffPassword: string;
submitPatronLogin() {
this.patronUsername = (this.patronUsername || '').trim();
- this.patronLoginFailed = false;
- this.scko.loadPatron(this.patronUsername, this.patronPassword).finally(() => {
- this.patronUsername = '';
- this.patronPassword = '';
+ this.scko.loadPatron(this.patronUsername, this.patronPassword)
+ .finally(() => {
+
if (this.scko.patronSummary === null) {
- this.patronLoginFailed = true;
+
+ const ctx: ActionContext = {
+ username: this.patronUsername,
+ shouldPopup: true,
+ alertSound: 'error.scko.login_failed',
+ displayText: 'scko.error.login_failed'
+ };
+
+ this.scko.notifyPatron(ctx);
+
} else {
this.focusNode('item-barcode');
}
+
+ this.patronUsername = '';
+ this.patronPassword = '';
});
}
import {PcrudService} from '@eg/core/pcrud.service';
import {NetService} from '@eg/core/net.service';
import {IdlObject} from '@eg/core/idl.service';
-import {SckoService} from './scko.service';
+import {SckoService, ActionContext} from './scko.service';
import {ServerStoreService} from '@eg/core/server-store.service';
import {PrintService} from '@eg/share/print/print.service';
const renewList = this.circs.filter(c => this.selected[c.id()]);
if (renewList.length === 0) { return; }
+ const contexts: ActionContext[] = [];
+
from(renewList).pipe(switchMap(circ => {
return of(
this.scko.renew(circ.target_copy().barcode())
- .then(res => {
- if (!res.newCirc) { return; }
+ .then(ctx => {
+ contexts.push(ctx);
+
+ if (!ctx.newCirc) { return; }
// Replace the renewed circ with the new circ.
const circs = [];
this.circs.forEach(c => {
if (c.id() === circ.id()) {
- circs.push(res.newCirc);
+ circs.push(ctx.newCirc);
} else {
circs.push(c);
}
this.circs = circs;
})
);
- })).toPromise(); // run it
+ })).toPromise().then(_ => {
+
+ // Create one ActionContext to represent the batch for
+ // notification purposes. Avoid popups and audio on batch
+ // renewals.
+
+ const notifyCtx: ActionContext = {
+ displayText: 'scko.batch_renew.result',
+ renewSuccessCount: contexts.filter(c => c.newCirc).length,
+ renewFailCount: contexts.filter(c => !c.newCirc).length
+ };
+
+ this.scko.notifyPatron(notifyCtx);
+ });
}
}
<eg-string i18n-text key="scko.checkout.already_out"
text="Item is checked out to another patron"></eg-string>
-<ng-template #maxRenew>No more renewals allowed for item {{barcode}}</ng-template>
+<ng-template i18n let-ctx="ctx" #loginFailed>
+ Login for "{{ctx ? ctx.username : ''}}" failed.
+</ng-template>
+<eg-string i18n-text key="scko.error.login_failed" [template]="loginFailed"></eg-string>
+
+<ng-template i18n let-ctx="ctx" #maxRenew>
+ No more renewals allowed for item {{ctx ? ctx.barcode : ''}}
+</ng-template>
<eg-string i18n-text key="scko.error.max_renewals" [template]="maxRenew"></eg-string>
<eg-string key="scko.error.patron_fines"
text="This account has too many fines to checkout."></eg-string>
-<ng-template #itemNotCataloged>
- Item {{barcode}} was not found in the system. Try re-scanning the item.
+<ng-template i18n let-ctx="ctx" #itemNotCataloged>
+ Item {{ctx ? ctx.barcode : ctx}} was not found in the system. Try re-scanning the item.
</ng-template>
<eg-string key="scko.error.item_not_cataloged" [template]="itemNotCataloged"> </eg-string>
-<ng-template #copyCircNotAllowed>
- Item {{barcode}} is not allowed to circulate</ng-template>
+<ng-template i18n let-ctx="ctx" #copyCircNotAllowed>
+ Item {{ctx ? ctx.barcode : ''}} is not allowed to circulate</ng-template>
<eg-string key="scko.error.copy_circ_not_allowed" [template]="copyCircNotAllowed">
</eg-string>
+<ng-template let-ctx="ctx" #batchRenewResultTmpl>
+ <span class="mr-1" *ngIf="ctx && ctx.renewSuccessCount > 0" i18n>
+ {{ctx.renewSuccessCount}} item(s) successfully renewed.
+ </span>
+ <span class="mr-1" *ngIf="ctx && ctx.renewFailCount > 0" i18n>
+ {{ctx.renewFailCount}} item(s) failed to renew.
+ </span>
+</ng-template>
+<eg-string key="scko.batch_renew.result" [template]="batchRenewResultTmpl">
+</eg-string>
+
<eg-string i18n-text key="scko.error.actor_usr_barred"
text="The patron is barred"></eg-string>
<eg-string i18n-text key="scko.error.asset_copy_circulate"
import {StringService} from '@eg/share/string/string.service';
import {PcrudService} from '@eg/core/pcrud.service';
-interface CheckoutContext {
- barcode: string; // item
- result: any;
- firstEvent: EgEvent;
- payload: any;
- override: boolean;
- redo: boolean;
- renew: boolean;
- displayText: string; // string key
- alertSound: string;
- shouldPopup: boolean;
+export interface ActionContext {
+ barcode?: string; // item
+ username?: string; // patron username or barcode
+ result?: any;
+ firstEvent?: EgEvent;
+ payload?: any;
+ override?: boolean;
+ redo?: boolean;
+ renew?: boolean;
+ displayText?: string; // string key
+ alertSound?: string;
+ shouldPopup?: boolean;
previousCirc?: IdlObject;
renewalFailure?: boolean;
newCirc?: IdlObject;
external?: boolean; // not from main checkout input.
+ renewSuccessCount?: number;
+ renewFailCount?: number;
}
interface SessionCheckout {
circ: IdlObject;
- ctx: CheckoutContext;
+ ctx: ActionContext;
}
const CIRC_FLESH_DEPTH = 4;
}
renew(barcode: string,
- override?: boolean, external?: boolean): Promise<CheckoutContext> {
+ override?: boolean, external?: boolean): Promise<ActionContext> {
let method = 'open-ils.circ.renew';
if (override) { method += '.override'; }
});
}
- notifyPatron(ctx: CheckoutContext) {
+ notifyPatron(ctx: ActionContext) {
console.debug('notifyPatron(): ', ctx);
this.statusDisplayText = '';
if (!ctx.displayText) { return; }
- this.strings.interpolate(ctx.displayText, {barcode: ctx.barcode})
+ this.strings.interpolate(ctx.displayText, {ctx: ctx})
.then(str => {
this.statusDisplayText = str;
+ console.debug('Displaying text to user:', str);
if (this.alertPopup && ctx.shouldPopup && str) {
this.alertDialog.dialogBody = str;
}
handleCheckoutResult(result: any, barcode: string,
- action: string, external?: boolean): Promise<CheckoutContext> {
+ action: string, external?: boolean): Promise<ActionContext> {
if (Array.isArray(result)) {
result = result[0];
return;
}
- const ctx: CheckoutContext = {
+ const ctx: ActionContext = {
result: result,
firstEvent: evt,
payload: payload,
return this.handleEvents(ctx);
}
- handleOpenCirc(ctx: CheckoutContext): Promise<any> {
+ handleOpenCirc(ctx: ActionContext): Promise<any> {
if (ctx.payload.old_circ) {
const age = this.orgSettings['circ.checkout_auto_renew_age'];
return Promise.resolve(ctx);
}
- handleEvents(ctx: CheckoutContext): Promise<CheckoutContext> {
+ handleEvents(ctx: ActionContext): Promise<ActionContext> {
let override = true;
let abortTransit = false;
let lastErrorText = '';