From 0e540a02e5add2d918590f7c92b2e8d8dd2dc1f4 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 8 Jun 2020 14:57:37 -0400 Subject: [PATCH] LP1869898 Angular staff cat place hold from patron The place hold button in the patron holds list now takes staff to the Angular catalog for holds placement. A banner is displayed along the top of the catalog to indicate which patron the hold is for and to provide a link back to the patron's holds list. Signed-off-by: Bill Erickson Signed-off-by: Jane Sandberg Signed-off-by: Galen Charlton --- .../app/staff/catalog/catalog.component.html | 18 ++++++++ .../app/staff/catalog/catalog.component.ts | 12 +++++ .../src/app/staff/catalog/catalog.service.ts | 14 ++++++ .../app/staff/catalog/hold/hold.component.ts | 46 ++++++++----------- .../app/staff/share/patron/patron.service.ts | 28 +++++++++++ .../templates/staff/circ/patron/t_holds.tt2 | 2 + .../js/ui/default/staff/circ/patron/holds.js | 5 +- 7 files changed, 97 insertions(+), 28 deletions(-) diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.component.html b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.component.html index af1d6040c7..53c4622d85 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.component.html +++ b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.component.html @@ -1,5 +1,23 @@ + + +
+ +
+ +
+
+
+ diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.component.ts index f9fcf6dc8f..5ce37128a0 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.component.ts @@ -1,4 +1,5 @@ import {Component, OnInit} from '@angular/core'; +import {IdlObject} from '@eg/core/idl.service'; import {StaffCatalogService} from './catalog.service'; import {BasketService} from '@eg/share/catalog/basket.service'; @@ -18,5 +19,16 @@ export class CatalogComponent implements OnInit { // reset and updated as needed to apply new search parameters. this.staffCat.createContext(); } + + // Returns the 'au' object for the patron who we are + // trying to place a hold for. + holdForUser(): IdlObject { + return this.staffCat.holdForUser; + } + + clearHoldPatron() { + this.staffCat.holdForUser = null; + this.staffCat.holdForBarcode = null; + } } diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts index e46c1b4a1a..95912a4285 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts @@ -6,6 +6,7 @@ import {CatalogService} from '@eg/share/catalog/catalog.service'; import {CatalogUrlService} from '@eg/share/catalog/catalog-url.service'; import {CatalogSearchContext} from '@eg/share/catalog/search-context'; import {BibRecordSummary} from '@eg/share/catalog/bib-record.service'; +import {PatronService} from '@eg/staff/share/patron/patron.service'; /** * Shared bits needed by the staff version of the catalog. @@ -27,6 +28,11 @@ export class StaffCatalogService { // Default search tab defaultTab: string; + // Patron barcode we hope to place a hold for. + holdForBarcode: string; + // User object for above barcode. + holdForUser: IdlObject; + // Cache the currently selected detail record (i.g. catalog/record/123) // summary so the record detail component can avoid duplicate fetches // during record tab navigation. @@ -37,6 +43,7 @@ export class StaffCatalogService { private route: ActivatedRoute, private org: OrgService, private cat: CatalogService, + private patron: PatronService, private catUrl: CatalogUrlService ) { } @@ -48,6 +55,13 @@ export class StaffCatalogService { this.searchContext = this.catUrl.fromUrlParams(this.route.snapshot.queryParamMap); + this.holdForBarcode = this.route.snapshot.queryParams['holdForBarcode']; + + if (this.holdForBarcode) { + this.patron.getByBarcode(this.holdForBarcode) + .then(user => this.holdForUser = user); + } + this.searchContext.org = this.org; // service, not searchOrg this.searchContext.isStaff = true; this.applySearchDefaults(); diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.ts index c1640b0b81..687783e37a 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.ts @@ -13,6 +13,7 @@ import {StaffCatalogService} from '../catalog.service'; import {HoldsService, HoldRequest, HoldRequestTarget} from '@eg/staff/share/holds/holds.service'; import {ComboboxEntry} from '@eg/share/combobox/combobox.component'; +import {PatronService} from '@eg/staff/share/patron/patron.service'; import {PatronSearchDialogComponent } from '@eg/staff/share/patron/search-dialog.component'; @@ -81,6 +82,7 @@ export class HoldComponent implements OnInit { private cat: CatalogService, private staffCat: StaffCatalogService, private holds: HoldsService, + private patron: PatronService, private perm: PermService ) { this.holdContexts = []; @@ -93,6 +95,11 @@ export class HoldComponent implements OnInit { this.holdTargets = this.route.snapshot.queryParams['target']; this.holdFor = this.route.snapshot.queryParams['holdFor'] || 'patron'; + if (this.staffCat.holdForBarcode) { + this.holdFor = 'patron'; + this.userBarcode = this.staffCat.holdForBarcode; + } + if (!Array.isArray(this.holdTargets)) { this.holdTargets = [this.holdTargets]; } @@ -107,7 +114,7 @@ export class HoldComponent implements OnInit { return ctx; }); - if (this.holdFor === 'staff') { + if (this.holdFor === 'staff' || this.userBarcode) { this.holdForChanged(); } @@ -245,25 +252,18 @@ export class HoldComponent implements OnInit { this.user = null; this.currentUserBarcode = this.userBarcode; + this.getUser(); + } - this.net.request( - 'open-ils.actor', - 'open-ils.actor.get_barcodes', - this.auth.token(), this.auth.user().ws_ou(), - 'actor', this.userBarcode - ).subscribe(barcodes => { - - // Use the first successful barcode response. - // TODO: What happens when there are multiple responses? - // Use for-loop for early exit since we have async - // action within the loop. - for (let i = 0; i < barcodes.length; i++) { - const bc = barcodes[i]; - if (!this.evt.parse(bc)) { - this.getUser(bc.id); - break; - } - } + getUser(id?: number) { + const flesh = {flesh: 1, flesh_fields: {au: ['settings']}}; + + const promise = id ? this.patron.getById(id, flesh) : + this.patron.getByBarcode(this.userBarcode); + + promise.then(user => { + this.user = user; + this.applyUserSettings(); }); } @@ -274,14 +274,6 @@ export class HoldComponent implements OnInit { this.pickupLib = this.requestor.ws_ou(); } - getUser(id: number) { - this.pcrud.retrieve('au', id, {flesh: 1, flesh_fields: {au: ['settings']}}) - .subscribe(user => { - this.user = user; - this.applyUserSettings(); - }); - } - applyUserSettings() { if (!this.user || !this.user.settings()) { return; } diff --git a/Open-ILS/src/eg2/src/app/staff/share/patron/patron.service.ts b/Open-ILS/src/eg2/src/app/staff/share/patron/patron.service.ts index 12fd1e137b..e50fbb2422 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/patron/patron.service.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/patron/patron.service.ts @@ -1,5 +1,8 @@ import {Injectable} from '@angular/core'; +import {IdlObject} from '@eg/core/idl.service'; import {NetService} from '@eg/core/net.service'; +import {EventService} from '@eg/core/event.service'; +import {PcrudService} from '@eg/core/pcrud.service'; import {AuthService} from '@eg/core/auth.service'; import {Observable} from 'rxjs'; @@ -8,6 +11,8 @@ import {Observable} from 'rxjs'; export class PatronService { constructor( private net: NetService, + private evt: EventService, + private pcrud: PcrudService, private auth: AuthService ) {} @@ -19,5 +24,28 @@ export class PatronService { 'actor', barcode.trim()); } + getByBarcode(barcode: string, pcrudOps?: any): Promise { + return this.bcSearch(barcode).toPromise() + .then(barcodes => { + + // Use the first successful barcode response. + // TODO: What happens when there are multiple responses? + // Use for-loop for early exit since we have async + // action within the loop. + for (let i = 0; i < barcodes.length; i++) { + const bc = barcodes[i]; + if (!this.evt.parse(bc)) { + return this.getById(bc.id); + } + } + + return null; + }); + } + + getById(id: number, pcrudOps?: any): Promise { + return this.pcrud.retrieve('au', id, pcrudOps).toPromise(); + } + } diff --git a/Open-ILS/src/templates/staff/circ/patron/t_holds.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_holds.tt2 index 5ccd762a76..a5499acbbf 100644 --- a/Open-ILS/src/templates/staff/circ/patron/t_holds.tt2 +++ b/Open-ILS/src/templates/staff/circ/patron/t_holds.tt2 @@ -32,7 +32,9 @@ + diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js b/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js index c3ce75be85..798ff73d7d 100644 --- a/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js +++ b/Open-ILS/web/js/ui/default/staff/circ/patron/holds.js @@ -145,7 +145,10 @@ function($scope, $q, $routeParams, egCore, egUser, patronSvc, } $scope.place_hold = function() { - $location.path($location.path() + '/create'); + $window.location.href = '/eg2/staff/catalog?holdForBarcode=' + + encodeURIComponent(patronSvc.current.card().barcode()); + + //$location.path($location.path() + '/create'); } // when the detail hold is fetched (and updated), update the bib -- 2.43.2