From 54dd7d355e5fc9cc8efd53428fbb685602d2c1f5 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 12 Apr 2021 12:23:08 -0400 Subject: [PATCH] LP1904036 checkin/checkout consolidation Signed-off-by: Bill Erickson Signed-off-by: Jane Sandberg Signed-off-by: Galen Charlton --- .../app/staff/circ/checkin/checkin.component.ts | 11 -- .../app/staff/circ/patron/checkout.component.ts | 16 +- .../eg2/src/app/staff/share/circ/circ.service.ts | 194 +++++++++++++-------- .../app/staff/share/circ/components.component.html | 10 ++ .../app/staff/share/circ/components.component.ts | 4 + 5 files changed, 144 insertions(+), 91 deletions(-) diff --git a/Open-ILS/src/eg2/src/app/staff/circ/checkin/checkin.component.ts b/Open-ILS/src/eg2/src/app/staff/circ/checkin/checkin.component.ts index 8680b09f8a..52543b52ee 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/checkin/checkin.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/circ/checkin/checkin.component.ts @@ -122,17 +122,6 @@ export class CheckinComponent implements OnInit, AfterViewInit { const entry: CheckinGridEntry = result; entry.index = this.autoIndex++; - 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.copy) { result.copy.circ_lib(this.org.get(result.copy.circ_lib())); } diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.ts index d5bdcb553e..7c7512aea2 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.ts @@ -176,7 +176,10 @@ export class CheckoutComponent implements OnInit, AfterViewInit { circ: result.circ, dueDate: null, copyAlertCount: 0, // TODO - nonCatCount: 0 + nonCatCount: 0, + title: result.title, + author: result.author, + isbn: result.isbn }; if (result.nonCatCirc) { @@ -187,17 +190,6 @@ export class CheckoutComponent implements OnInit, AfterViewInit { } else { - 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) { entry.dueDate = result.circ.due_date(); } diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/circ.service.ts b/Open-ILS/src/eg2/src/app/staff/share/circ/circ.service.ts index 829298f1ba..3c387dcc56 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/circ/circ.service.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/circ.service.ts @@ -129,17 +129,30 @@ export interface CheckoutParams { _renewal?: boolean; } -export interface CheckoutResult { +export interface CircResultCommon { index: number; firstEvent: EgEvent; allEvents: EgEvent[]; - params: CheckoutParams; success: boolean; - canceled?: boolean; copy?: IdlObject; + volume?: IdlObject; + record?: IdlObject; circ?: IdlObject; + parent_circ?: IdlObject; + hold?: IdlObject; + patron?: IdlObject; + + // Calculated values + title?: string; + author?: string; + isbn?: string; +} + + +export interface CheckoutResult extends CircResultCommon { + params: CheckoutParams; + canceled?: boolean; nonCatCirc?: IdlObject; - record?: IdlObject; } export interface CheckinParams { @@ -151,31 +164,15 @@ export interface CheckinParams { auto_print_hold_transits?: boolean; backdate?: string; - // internal tracking + // internal / local values that are moved from the API request. _override?: boolean; } -export interface CheckinResult { - index: number; - firstEvent: EgEvent; - allEvents: EgEvent[]; +export interface CheckinResult extends CircResultCommon { params: CheckinParams; - success: boolean; - copy?: IdlObject; - volume?: IdlObject; - circ?: IdlObject; - parent_circ?: IdlObject; - mbts?: IdlObject; - record?: IdlObject; - hold?: IdlObject; transit?: IdlObject; - patron?: IdlObject; - - // Calculated values + mbts?: IdlObject; routeTo?: string; // org name or in-branch destination - title?: string; - author?: string; - isbn?: string; destOrg?: IdlObject; destAddress?: IdlObject; destCourierCode?: string; @@ -348,7 +345,6 @@ export class CircService { processCheckoutResult( params: CheckoutParams, response: any): Promise { - const allEvents = Array.isArray(response) ? response.map(r => this.evt.parse(r)) : [this.evt.parse(response)]; @@ -375,6 +371,17 @@ export class CircService { nonCatCirc: payload.noncat_circ }; + if (result.record) { + result.title = result.record.title(); + result.author = result.record.author(); + result.isbn = result.record.isbn(); + + } else if (result.copy) { + result.title = result.copy.dummy_title(); + result.author = result.copy.dummy_author(); + result.isbn = result.copy.dummy_isbn(); + } + const overridable = result.params._renewal ? CAN_OVERRIDE_RENEW_EVENTS : CAN_OVERRIDE_CHECKOUT_EVENTS; @@ -532,41 +539,10 @@ export class CircService { .then(result => this.processCheckinResult(result)); } - unpackCheckinData(params: CheckinParams, response: any): Promise { - const allEvents = Array.isArray(response) ? - response.map(r => this.evt.parse(r)) : [this.evt.parse(response)]; - - console.debug('checkin returned', allEvents.map(e => e.textcode)); - - const firstEvent = allEvents[0]; - const payload = firstEvent.payload; - - if (!payload) { - this.audio.play('error.unknown.no_payload'); - return Promise.reject(); - } - - const success = - firstEvent.textcode.match(/SUCCESS|NO_CHANGE|ROUTE_ITEM/) !== null; - - const result: CheckinResult = { - index: CircService.resultIndex++, - firstEvent: firstEvent, - allEvents: allEvents, - params: params, - success: success, - circ: payload.circ, - parent_circ: payload.parent_circ, - copy: payload.copy, - volume: payload.volume, - record: payload.record, - transit: payload.transit, - hold: payload.hold - }; + collectCommonData(result: CircResultCommon): Promise { const copy = result.copy; const volume = result.volume; - const transit = result.transit; const circ = result.circ; const parent_circ = result.parent_circ; @@ -611,6 +587,49 @@ export class CircService { } } + return promise; + } + + unpackCheckinData(params: CheckinParams, response: any): Promise { + const allEvents = Array.isArray(response) ? + response.map(r => this.evt.parse(r)) : [this.evt.parse(response)]; + + console.debug('checkin returned', allEvents.map(e => e.textcode)); + + const firstEvent = allEvents[0]; + const payload = firstEvent.payload; + + if (!payload) { + this.audio.play('error.unknown.no_payload'); + return Promise.reject(); + } + + const success = + firstEvent.textcode.match(/SUCCESS|NO_CHANGE|ROUTE_ITEM/) !== null; + + const result: CheckinResult = { + index: CircService.resultIndex++, + firstEvent: firstEvent, + allEvents: allEvents, + params: params, + success: success, + circ: payload.circ, + parent_circ: payload.parent_circ, + copy: payload.copy, + volume: payload.volume, + record: payload.record, + transit: payload.transit, + hold: payload.hold + }; + + const copy = result.copy; + const volume = result.volume; + const transit = result.transit; + const circ = result.circ; + const parent_circ = result.parent_circ; + + let promise = Promise.resolve(); + if (transit) { if (typeof transit.dest() !== 'object') { transit.dest(this.org.get(transit.dest())); @@ -630,7 +649,7 @@ export class CircService { result.mbts = parent_circ.billable_transaction().summary(); } - return promise.then(_ => result); + return this.collectCommonData(result).then(_ => result); } processCheckinResult(result: CheckinResult): Promise { @@ -666,25 +685,36 @@ export class CircService { case 'ITEM_NOT_CATALOGED': this.audio.play('error.checkout.no_cataloged'); - result.routeTo = 'Cataloging'; // TODO - - if (!this.suppressCheckinPopups && !this.ignoreCheckinPrecats) { - // Tell the user its a precat and return the result. - return this.components.routeToCatalogingDialog.open() - .toPromise().then(_ => result); - } - break; + result.routeTo = this.components.catalogingStr.text; + return this.showPrecatAlert().then(_ => result); case 'ROUTE_ITEM': this.components.routeDialog.checkin = result; return this.components.routeDialog.open().toPromise() .then(_ => result); + case 'ASSET_COPY_NOT_FOUND': + this.audio.play('error.checkin.not_found'); + return this.handleCheckinUncatAlert(result); + + default: + this.audio.play('error.checkin.unknown'); + console.warn( + 'Unhandled checkin response : ' + result.firstEvent.textcode); } return Promise.resolve(result); } + showPrecatAlert(): Promise { + if (!this.suppressCheckinPopups && !this.ignoreCheckinPrecats) { + // Tell the user its a precat and return the result. + return this.components.routeToCatalogingDialog.open() + .toPromise(); + } + return Promise.resolve(null); + } + handleCheckinSuccess(result: CheckinResult): Promise { switch (result.copy.status()) { @@ -703,7 +733,7 @@ export class CircService { if (hold) { if (Number(hold.pickup_lib()) === Number(this.auth.user().ws_ou())) { - result.routeTo = 'Holds Shelf'; // TODO + result.routeTo = this.components.holdShelfStr.text; this.components.routeDialog.checkin = result; return this.components.routeDialog.open().toPromise() .then(_ => result); @@ -720,8 +750,18 @@ export class CircService { case 11: /* CATALOGING */ this.audio.play('info.checkin.cataloging'); - result.routeTo = 'Cataloging'; // TODO - // TODO more... + result.routeTo = this.components.catalogingStr.text; + return this.showPrecatAlert().then(_ => result); + + case 15: /* ON_RESERVATION_SHELF */ + this.audio.play('info.checkin.reservation'); + break; + + default: + this.audio.play('success.checkin'); + const stat = result.copy; + console.debug(`Unusual checkin copy status (may have been + set via copy alert): ${stat.id()} : ${stat.name()}`); } return Promise.resolve(result); @@ -745,6 +785,24 @@ export class CircService { }); } + handleCheckinUncatAlert(result: CheckinResult): Promise { + const copy = result.copy; + + if (this.suppressCheckinPopups) { + return Promise.resolve(result); + } + + return this.strings.interpolate( + 'staff.circ.checkin.uncat.alert', + {barcode: copy.barcode()} + ).then(str => { + this.components.uncatAlertDialog.dialogBody = str; + return this.components.uncatAlertDialog.open().toPromise() + .then(_ => result); + }); + } + + handleOverridableCheckinEvents( result: CheckinResult, events: EgEvent[]): Promise { const params = result.params; diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/components.component.html b/Open-ILS/src/eg2/src/app/staff/share/circ/components.component.html index 3032516bad..2e17a7c2aa 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/circ/components.component.html +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/components.component.html @@ -15,6 +15,12 @@ + + Item {{barcode}} was mis-scanned or is not cataloged + + + + @@ -23,5 +29,9 @@ + + + + diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/components.component.ts b/Open-ILS/src/eg2/src/app/staff/share/circ/components.component.ts index 2550ea7a5e..0736b3c8b4 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/circ/components.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/components.component.ts @@ -25,8 +25,12 @@ export class CircComponentsComponent { @ViewChild('routeToCatalogingDialog') routeToCatalogingDialog: AlertDialogComponent; @ViewChild('openCircDialog') openCircDialog: OpenCircDialogComponent; @ViewChild('locationAlertDialog') locationAlertDialog: AlertDialogComponent; + @ViewChild('uncatAlertDialog') uncatAlertDialog: AlertDialogComponent; @ViewChild('routeDialog') routeDialog: RouteDialogComponent; + @ViewChild('holdShelfStr') holdShelfStr: StringComponent; + @ViewChild('catalogingStr') catalogingStr: StringComponent; + constructor(private circ: CircService) { this.circ.components = this; } -- 2.11.0