+<div class="d-flex">
+ <div class="flex-1"></div>
+ <div>
+ <button class="btn btn-outline-dark" (click)="printList()" i18n>Print List</button>
+ </div>
+</div>
<div id='oils-selfck-circ-table-div'>
<table id='oils-selfck-circ-table' class='oils-selfck-item-table'>
<thead>
</tr>
</thead>
<tbody id='oils-selfck-circ-out-tbody' class='oils-selfck-item-table'>
+ <tr *ngFor="let co of scko.sessionCheckouts">
+ <td>
+ <ng-container *ngIf="co.circ">
+ <img src="/opac/extras/ac/jacket/small/r/{{co.circ.target_copy().call_number().record().id()}}"/>
+ </ng-container>
+ </td>
+ <td><span *ngIf="co.circ">{{cocirc.target_copy().barcode()}}</span></td>
+ <td>{{getTitle(circ)}}</td>
+ <td>{{getAuthor(circ)}}</td>
+ <td><span *ngIf="co.circ">{{co.circ | egDueDate}}</span></td>
+ <td><span *ngIf="co.circ">{{co.circ.renewal_remaining()}}</span></td>
+ <td>
+ <ng-container *ngIf="co.circ">
+ <span *ngIf="co.circ.parent_circ()" i18n>Renewal</span>
+ <span *ngIf="!co.circ.parent_circ()" i18n>Checkout</span>
+ </ng-container>
+ </td>
+ </tr>
</tbody>
</table>
</div>
import {Component, OnInit, ViewEncapsulation} from '@angular/core';
import {Router, ActivatedRoute, NavigationEnd} from '@angular/router';
import {AuthService} from '@eg/core/auth.service';
+import {IdlObject} from '@eg/core/idl.service';
import {SckoService} from './scko.service';
import {ServerStoreService} from '@eg/core/server-store.service';
ngOnInit() {
}
+
+ displayValue(circ: IdlObject, field: string): string {
+ const entry =
+ circ.target_copy().call_number().record().flat_display_entries()
+ .filter(e => e.name() === field)[0];
+
+ return entry ? entry.value() : '';
+ }
+
+ getTitle(circ: IdlObject): string {
+ if (!circ) { return ''; }
+ const copy = circ.target_copy();
+ return this.displayValue(circ, 'title');
+ }
+
+ getAuthor(circ: IdlObject): string {
+ if (!circ) { return ''; }
+ const copy = circ.target_copy();
+ return this.displayValue(circ, 'author');
+ }
}
import {ServerStoreService} from '@eg/core/server-store.service';
import {PrintService} from '@eg/share/print/print.service';
-const CIRC_FLESH_DEPTH = 4;
-const CIRC_FLESH_FIELDS = {
- circ: ['target_copy'],
- acp: ['call_number'],
- acn: ['record'],
- bre: ['flat_display_entries']
-};
-
@Component({
templateUrl: 'items.component.html'
})
.then(data => {
const ids = data.out.concat(data.overdue).concat(data.long_overdue);
-
- return this.pcrud.search('circ', {id: ids}, {
- flesh: CIRC_FLESH_DEPTH,
- flesh_fields: CIRC_FLESH_FIELDS,
- order_by : {circ : 'due_date'},
-
- select: {bre : ['id']}
-
- }).pipe(tap(circ => {
+ return this.scko.getFleshedCircs(ids).pipe(tap(circ => {
this.circs.push(circ);
})).toPromise();
});
text="Item was not found in the system. Try re-scanning the item."></eg-string>
<eg-string i18n-text key="scko.checkout.already_out"
text="Item is checked out to another patron"></eg-string>
-<eg-string i18n-text key="scko.error.max_renewals"
- text="No more renewals allowed for item {{barcode}}"></eg-string>
-<eg-string i18n-text key="scko.error.patron_fines"
+<ng-template #maxRenew>No more renewals allowed for item {{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>
-<eg-string i18n-text key="scko.error.item_not_cataloged"
- text="Item {{barcode}} was not found in the system. Try re-scanning the item."></eg-string>
+<ng-template #itemNotCataloged>
+ Item {{barcode}} 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>
+<eg-string key="scko.error.copy_circ_not_allowed" [template]="copyCircNotAllowed">
+</eg-string>
-<eg-string i18n-text key="scko.error.copy_circ_not_allowed"
- text="Item {{barcode}} is not allowed to circulate"></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"
text="The item cannot transit this far"></eg-string>
-
-
import {Injectable, EventEmitter} from '@angular/core';
import {Router, ActivatedRoute, NavigationEnd} from '@angular/router';
+import {Observable} from 'rxjs';
import {OrgService} from '@eg/core/org.service';
import {NetService} from '@eg/core/net.service';
import {AuthService} from '@eg/core/auth.service';
import {PrintService} from '@eg/share/print/print.service';
import {AudioService} from '@eg/share/util/audio.service';
import {StringService} from '@eg/share/string/string.service';
+import {PcrudService} from '@eg/core/pcrud.service';
interface CheckoutContext {
barcode: string; // item
renewalFailure?: boolean;
}
+interface SessionCheckout {
+ circ: IdlObject,
+ ctx: CheckoutContext
+}
+
+const CIRC_FLESH_DEPTH = 4;
+const CIRC_FLESH_FIELDS = {
+ circ: ['target_copy'],
+ acp: ['call_number'],
+ acn: ['record'],
+ bre: ['flat_display_entries']
+};
+
@Injectable({providedIn: 'root'})
export class SckoService {
overrideCheckoutEvents: string[] = [];
blockStatuses: number[] = [];
- sessionCheckouts: any[] = [];
+ sessionCheckouts: SessionCheckout[] = [];
// We get this from the main scko component.
logoutDialog: ConfirmDialogComponent;
private net: NetService,
private evt: EventService,
public auth: AuthService,
+ private pcrud: PcrudService,
private printer: PrintService,
private audio: AudioService,
private strings: StringService,
});
}
+ getFleshedCircs(circIds: number[]): Observable<IdlObject> {
+ return this.pcrud.search('circ', {id: circIds}, {
+ flesh: CIRC_FLESH_DEPTH,
+ flesh_fields: CIRC_FLESH_FIELDS,
+ order_by : {circ : 'due_date'},
+ select: {bre : ['id']}
+ });
+ }
+
+ getFleshedCirc(circId: number): Promise<IdlObject> {
+ return this.getFleshedCircs([circId]).toPromise();
+ }
+
loadPatron(username: string, password?: string): Promise<any> {
this.resetPatron();
}
notifyPatron(ctx: CheckoutContext) {
- console.debug("notifyPatron()", ctx);
+ console.debug('notifyPatron(): ', ctx);
this.statusDisplayText = '';
this.focusBarcode.emit();
+ // TODO on success tell the summary to update its numbers.
+
if (this.alertAudio && ctx.alertSound) {
this.audio.play(ctx.alertSound);
}
if (evt.textcode === 'SUCCESS') {
ctx.displayText = `scko.${action}.success`;
ctx.alertSound = `success.scko.${action}`;
- return Promise.resolve(ctx);
+
+ return this.getFleshedCirc(payload.circ.id()).then(
+ circ => {
+ this.sessionCheckouts.push({circ: circ, ctx: ctx});
+ return ctx;
+ }
+ );
}
if (evt.textcode === 'OPEN_CIRCULATION_EXISTS' && action === 'checkout') {
[].concat(ctx.result).some(res => {
if (!this.overrideCheckoutEvents.includes(res.textcode)) {
- console.debug("We are not configured to override", res.textcode);
+ console.debug('We are not configured to override', res.textcode);
lastErrorText = this.getErrorDisplyText(this.evt.parse(res));
return override = false;
}
default:
if (evt.payload && evt.payload.fail_part) {
return 'scko.error.' +
- evt.payload.fail_part.replace(/\./g, "_");
+ evt.payload.fail_part.replace(/\./g, '_');
}
}