<eg-progress-dialog #progressDialog></eg-progress-dialog>
+<eg-precat-checkout-dialog #precatDialog [barcode]="checkoutBarcode">
+</eg-precat-checkout-dialog>
+
<eg-prompt-dialog #nonCatCount
promptType="number"
i18n-dialogTitle dialogTitle="Non-Cat Checkout"
<div class="flex-1"></div>
<div ngbDropdown>
<button ngbDropdownToggle class="btn mr-2" [ngClass]="{
- 'btn-outline-dark': context.dueDateOptions == 0,
- 'btn-outline-success': context.dueDateOptions > 0
+ 'btn-outline-dark': dueDateOptions == 0,
+ 'btn-outline-success': dueDateOptions > 0
}"
i18n>Date Options</button>
<div ngbDropdownMenu>
<button ngbDropdownItem (click)="toggleDateOptions(1)">
- <span *ngIf="context.dueDateOptions > 0"
+ <span *ngIf="dueDateOptions > 0"
class="badge badge-success">✓</span>
- <span *ngIf="context.dueDateOptions == 0"
+ <span *ngIf="dueDateOptions == 0"
class="badge badge-warning">✗</span>
<span class="pl-2" i18n>Specific Due Date</span>
</button>
<button ngbDropdownItem (click)="toggleDateOptions(2)">
- <span *ngIf="context.dueDateOptions == 2"
+ <span *ngIf="dueDateOptions == 2"
class="badge badge-success">✓</span>
- <span *ngIf="context.dueDateOptions < 2"
+ <span *ngIf="dueDateOptions < 2"
class="badge badge-warning">✗</span>
<span class="pl-2" i18n>Specific Due Date Until Logout</span>
</button>
</div>
</div>
- <eg-datetime-select (onChangeAsIso)="setDueDate($event)"></eg-datetime-select>
+ <eg-datetime-select [initialIso]="dueDate"
+ (onChangeAsIso)="setDueDate($event)"></eg-datetime-select>
</div>
</div>
import {GridDataSource, GridColumn, GridCellTextGenerator} from '@eg/share/grid/grid';
import {GridComponent} from '@eg/share/grid/grid.component';
import {Pager} from '@eg/share/util/pager';
+import {StoreService} from '@eg/core/store.service';
+import {ServerStoreService} from '@eg/core/server-store.service';
+import {PrecatCheckoutDialogComponent} from './precat-dialog.component';
+import {AudioService} from '@eg/share/util/audio.service';
@Component({
templateUrl: 'checkout.component.html',
cellTextGenerator: GridCellTextGenerator;
dueDate: string;
copiesInFlight: {[barcode: string]: boolean} = {};
+ dueDateOptions: 0 | 1 | 2 = 0; // auto date; specific date; session date
@ViewChild('nonCatCount') nonCatCount: PromptDialogComponent;
@ViewChild('checkoutsGrid') checkoutsGrid: GridComponent;
+ @ViewChild('precatDialog') precatDialog: PrecatCheckoutDialogComponent;
constructor(
+ private store: StoreService,
+ private serverStore: ServerStoreService,
private org: OrgService,
private net: NetService,
public circ: CircService,
public patronService: PatronService,
- public context: PatronManagerService
+ public context: PatronManagerService,
+ private audio: AudioService
) {}
ngOnInit() {
this.cellTextGenerator = {
title: row => row.title
};
+
+ if (this.store.getSessionItem('eg.circ.checkout.is_until_logout')) {
+ this.dueDate = this.store.getSessionItem('eg.circ.checkout.due_date');
+ this.toggleDateOptions(2);
+ }
}
ngAfterViewInit() {
this.focusInput();
}
- setDueDate(iso: string) {
- this.dueDate = iso;
- }
-
focusInput() {
const input = document.getElementById('barcode-input');
if (input) { input.focus(); }
this.copiesInFlight[this.checkoutBarcode] = true;
params.copy_barcode = this.checkoutBarcode;
- if (this.context.dueDateOptions > 0) { params.due_date = this.dueDate; }
+ if (this.dueDateOptions > 0) { params.due_date = this.dueDate; }
return Promise.resolve(params);
}
.then((result: CheckoutResult) => {
if (result) {
-
if (result.params.copy_barcode) {
delete this.copiesInFlight[result.params.copy_barcode];
}
-
- if (result.success) {
- this.gridifyResult(result);
- this.resetForm();
- }
+ this.dispatchResult(result);
}
});
}
+ dispatchResult(result: CheckoutResult) {
+
+ if (result.success) {
+ this.gridifyResult(result);
+ this.resetForm();
+ return;
+ }
+
+ switch (result.evt.textcode) {
+ case 'ITEM_NOT_CATALOGED':
+ this.audio.play('error.checkout.no_cataloged');
+ this.handlePrecat(result);
+ break;
+ }
+ }
+
resetForm() {
- if (this.context.dueDateOptions < 2) {
+ if (this.dueDateOptions < 2) {
// Due date is not configured to persist.
- this.context.dueDateOptions = 0;
+ this.dueDateOptions = 0;
this.dueDate = null;
}
gridifyResult(result: CheckoutResult) {
const entry: CircGridEntry = {
- title: '',
copy: result.copy,
circ: result.circ,
dueDate: null,
if (result.record) {
entry.title = result.record.title();
+ entry.author = result.record.author();
+ entry.isbn = result.record.isbn();
+
+ } else if (result.copy) {
+ entry.title = result.copy.dummy_title();
+ entry.author = result.copy.dummy_author();
+ entry.isbn = result.copy.dummy_isbn();
}
if (result.circ) {
}));
}
+ setDueDate(iso: string) {
+ this.dueDate = iso;
+ this.store.setSessionItem('eg.circ.checkout.due_date', this.dueDate);
+ }
+
+
// 0: use server due date
// 1: use specific due date once
// 2: use specific due date until the end of the session.
toggleDateOptions(value: 1 | 2) {
- if (this.context.dueDateOptions > 0) {
- if (value === 1) {
- this.context.dueDateOptions = 0;
- } else if (this.context.dueDateOptions === 1) {
- this.context.dueDateOptions = 2;
+ if (this.dueDateOptions > 0) {
+
+ if (value === 1) { // 1 or 2 -> 0
+ this.dueDateOptions = 0;
+ this.store.removeSessionItem('eg.circ.checkout.is_until_logout');
+
+ } else if (this.dueDateOptions === 1) { // 1 -> 2
+
+ this.dueDateOptions = 2;
+ this.store.setSessionItem('eg.circ.checkout.is_until_logout', true);
+
+ } else { // 2 -> 1
+
+ this.dueDateOptions = 1;
+ this.store.removeSessionItem('eg.circ.checkout.is_until_logout');
}
+
} else {
- this.context.dueDateOptions = value;
+
+ this.dueDateOptions = value;
+ if (value === 2) {
+ this.store.setSessionItem('eg.circ.checkout.is_until_logout', true);
+ }
}
}
+
+ handlePrecat(result: CheckoutResult) {
+ this.precatDialog.open({size: 'lg'}).subscribe(values => {
+ console.log('precat values', values);
+ })
+ }
}
--- /dev/null
+import {Component, OnInit, Input} from '@angular/core';
+import {Observable} from 'rxjs';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
+import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+import {PermService} from '@eg/core/perm.service';
+
+/**
+ * Precat checkout dialog
+ */
+
+@Component({
+ selector: 'eg-precat-checkout-dialog',
+ templateUrl: 'precat-dialog.component.html'
+})
+
+export class PrecatCheckoutDialogComponent extends DialogComponent implements OnInit {
+
+ @Input() barcode = '';
+
+ circModifier: ComboboxEntry;
+ hasPerm = false;
+
+ constructor(
+ private perm: PermService,
+ private modal: NgbModal) {
+ super(modal);
+ }
+
+ ngOnInit() {
+ this.perm.hasWorkPermHere('CREATE_PRECAT')
+ .then(perms => this.hasPerm = perms['CREATE_PRECAT']);
+ }
+}
+
+
+
export interface CheckoutResult {
index: number;
+ evt: EgEvent;
params: CheckoutParams,
success: boolean;
copy?: IdlObject;
).toPromise().then(types => this.nonCatTypes = types);
}
- checkout(params: CheckoutParams): Promise<CheckoutResult> {
+ checkout(params: CheckoutParams, override?: boolean): Promise<CheckoutResult> {
- console.log('checking out with', params);
+ console.debug('checking out with', params);
+
+ let method = 'open-ils.circ.checkout.full';
+ if (override) { method += '.override'; }
return this.net.request(
- 'open-ils.circ',
- 'open-ils.circ.checkout.full',
+ 'open-ils.circ', method,
this.auth.token(), params).toPromise()
.then(result => this.processCheckoutResult(params, result));
}
const result: CheckoutResult = {
index: CircService.resultIndex++,
+ evt: evt,
params: params,
- success: true,
+ success: evt.textcode === 'SUCCESS',
circ: payload.circ,
copy: payload.copy,
record: payload.record,