From a4686537b6cd50e0f450c04e4e5123cfebc45257 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Thu, 15 Apr 2021 17:39:11 -0400 Subject: [PATCH] LP1904036 checkin grid actions Signed-off-by: Bill Erickson Signed-off-by: Jane Sandberg Signed-off-by: Galen Charlton --- .../app/staff/circ/checkin/checkin.component.html | 49 ++++++++--- .../app/staff/circ/checkin/checkin.component.ts | 97 +++++++++++++++++++++- .../share/circ/backdate-dialog.component.html | 38 +++++++++ .../staff/share/circ/backdate-dialog.component.ts | 47 +++++++++++ .../eg2/src/app/staff/share/circ/circ.module.ts | 3 + .../eg2/src/app/staff/share/circ/circ.service.ts | 7 ++ 6 files changed, 228 insertions(+), 13 deletions(-) create mode 100644 Open-ILS/src/eg2/src/app/staff/share/circ/backdate-dialog.component.html create mode 100644 Open-ILS/src/eg2/src/app/staff/share/circ/backdate-dialog.component.ts diff --git a/Open-ILS/src/eg2/src/app/staff/circ/checkin/checkin.component.html b/Open-ILS/src/eg2/src/app/staff/circ/checkin/checkin.component.html index 8ce201bc1c..b424e80d03 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/checkin/checkin.component.html +++ b/Open-ILS/src/eg2/src/app/staff/circ/checkin/checkin.component.html @@ -3,6 +3,10 @@ + + +
@@ -85,18 +89,39 @@ [useLocalSort]="true" [cellTextGenerator]="cellTextGenerator" [disablePaging]="true" persistKey="circ.checkin"> - + + + + + + + + + + + + + + + + + + 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 f8be484750..af8ef2e5f7 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 @@ -1,6 +1,8 @@ import {Component, ViewChild, OnInit, AfterViewInit, HostListener} from '@angular/core'; import {Router, ActivatedRoute, ParamMap} from '@angular/router'; import {from} from 'rxjs'; +import {concatMap} from 'rxjs/operators'; +import {IdlObject, IdlService} from '@eg/core/idl.service'; import {NetService} from '@eg/core/net.service'; import {OrgService} from '@eg/core/org.service'; import {AuthService} from '@eg/core/auth.service'; @@ -8,12 +10,21 @@ import {ServerStoreService} from '@eg/core/server-store.service'; import {PatronService} from '@eg/staff/share/patron/patron.service'; 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 {CircService, CircDisplayInfo, CheckinParams, CheckinResult } from '@eg/staff/share/circ/circ.service'; -import {Pager} from '@eg/share/util/pager'; import {BarcodeSelectComponent } from '@eg/staff/share/barcodes/barcode-select.component'; import {PrintService} from '@eg/share/print/print.service'; +import {MarkDamagedDialogComponent + } from '@eg/staff/share/holdings/mark-damaged-dialog.component'; +import {CopyAlertsDialogComponent + } from '@eg/staff/share/holdings/copy-alerts-dialog.component'; +import {BucketDialogComponent + } from '@eg/staff/share/buckets/bucket-dialog.component'; +import {ToastService} from '@eg/share/toast/toast.service'; +import {StringComponent} from '@eg/share/string/string.component'; +import {BackdateDialogComponent} from '@eg/staff/share/circ/backdate-dialog.component'; interface CheckinGridEntry extends CheckinResult { // May need to extend... @@ -51,6 +62,7 @@ export class CheckinComponent implements OnInit, AfterViewInit { isHoldCapture = false; strictBarcode = false; trimList = false; + itemNeverCirced: string; gridDataSource: GridDataSource = new GridDataSource(); cellTextGenerator: GridCellTextGenerator; @@ -61,6 +73,11 @@ export class CheckinComponent implements OnInit, AfterViewInit { @ViewChild('grid') private grid: GridComponent; @ViewChild('barcodeSelect') private barcodeSelect: BarcodeSelectComponent; + @ViewChild('markDamagedDialog') private markDamagedDialog: MarkDamagedDialogComponent; + @ViewChild('copyAlertsDialog') private copyAlertsDialog: CopyAlertsDialogComponent; + @ViewChild('bucketDialog') private bucketDialog: BucketDialogComponent; + @ViewChild('itemNeverCircedStr') private itemNeverCircedStr: StringComponent; + @ViewChild('backdateDialog') private backdateDialog: BackdateDialogComponent; constructor( private router: Router, @@ -70,6 +87,7 @@ export class CheckinComponent implements OnInit, AfterViewInit { private auth: AuthService, private store: ServerStoreService, private circ: CircService, + private toast: ToastService, private printer: PrintService, public patronService: PatronService ) {} @@ -223,5 +241,82 @@ export class CheckinComponent implements OnInit, AfterViewInit { this.modifiers.auto_print_holds_transits ); } + + getCopyIds(rows: CheckinGridEntry[], skipStatus?: number): number[] { + return this.getCopies(rows, skipStatus).map(c => Number(c.id())); + } + + getCopies(rows: CheckinGridEntry[], skipStatus?: number): IdlObject[] { + let copies = rows.filter(r => r.copy).map(r => r.copy); + if (skipStatus) { + copies = copies.filter( + c => Number(c.status().id()) !== Number(skipStatus)); + } + return copies; + } + + + markDamaged(rows: CheckinGridEntry[]) { + const copyIds = this.getCopyIds(rows, 14 /* ignore damaged */); + if (copyIds.length === 0) { return; } + + from(copyIds).pipe(concatMap(id => { + this.markDamagedDialog.copyId = id; + return this.markDamagedDialog.open({size: 'lg'}); + })); + } + + addItemAlerts(rows: CheckinGridEntry[]) { + const copyIds = this.getCopyIds(rows); + if (copyIds.length === 0) { return; } + + this.copyAlertsDialog.copyIds = copyIds; + this.copyAlertsDialog.mode = 'create' + this.copyAlertsDialog.open({size: 'lg'}).subscribe(); + } + + manageItemAlerts(rows: CheckinGridEntry[]) { + const copyIds = this.getCopyIds(rows); + if (copyIds.length === 0) { return; } + + this.copyAlertsDialog.copyIds = copyIds; + this.copyAlertsDialog.mode = 'manage'; + this.copyAlertsDialog.open({size: 'lg'}).subscribe(); + } + + openBucketDialog(rows: CheckinGridEntry[]) { + const copyIds = this.getCopyIds(rows); + if (copyIds.length > 0) { + this.bucketDialog.bucketClass = 'copy'; + this.bucketDialog.itemIds = copyIds; + this.bucketDialog.open({size: 'lg'}); + } + } + + retrieveLastPatron(rows: CheckinGridEntry[]) { + const copy = this.getCopies(rows).pop(); + if (!copy) { return; } + + this.circ.lastCopyCirc(copy.id()).then(circ => { + if (circ) { + this.router.navigate(['/staff/circ/patron', circ.usr(), 'checkout']); + } else { + this.itemNeverCirced = copy.barcode(); + setTimeout(() => this.toast.danger(this.itemNeverCircedStr.text)); + } + }); + } + + backdatePostCheckin(rows: CheckinGridEntry[]) { + const circs = rows.map(r => r.circ).filter(circ => Boolean(circ)); + if (circs.length === 0) { return; } + + this.backdateDialog.circIds = circs.map(c => c.id()); + this.backdateDialog.open().subscribe(backdate => { + if (backdate) { + circs.forEach(circ => circ.checkin_time(backdate)); + } + }); + } } diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/backdate-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/share/circ/backdate-dialog.component.html new file mode 100644 index 0000000000..d4dc7e3b82 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/backdate-dialog.component.html @@ -0,0 +1,38 @@ + + + + + + + + + diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/backdate-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/share/circ/backdate-dialog.component.ts new file mode 100644 index 0000000000..4c7e8ebc27 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/backdate-dialog.component.ts @@ -0,0 +1,47 @@ +import {Component, OnInit, Output, Input, ViewChild, EventEmitter} from '@angular/core'; +import {Observable, empty, of, from, throwError} from 'rxjs'; +import {concatMap, mergeMap, map} from 'rxjs/operators'; +import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap'; +import {DialogComponent} from '@eg/share/dialog/dialog.component'; +import {NetService} from '@eg/core/net.service'; +import {AuthService} from '@eg/core/auth.service'; +import {EventService} from '@eg/core/event.service'; + +@Component({ + templateUrl: 'backdate-dialog.component.html', + selector: 'eg-backdate-dialog' +}) +export class BackdateDialogComponent extends DialogComponent implements OnInit { + + circIds: number[]; + backdate: string; + updateCount = 0; + + constructor( + private modal: NgbModal, + private net: NetService, + private auth: AuthService, + private evt: EventService + ) { super(modal); } + + ngOnInit() { + this.onOpen$.subscribe(_ => { + this.updateCount = 0; + this.backdate = new Date().toISOString(); + }); + } + + modifyBatch() { + this.net.request( + 'open-ils.circ', + 'open-ils.circ.post_checkin_backdate.batch', + this.auth.token(), this.circIds, this.backdate + ).subscribe( + res => this.updateCount++, + err => console.error(err), + () => this.close(this.backdate) + ); + } +} + + diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/circ.module.ts b/Open-ILS/src/eg2/src/app/staff/share/circ/circ.module.ts index 8c8fef8549..b712fdd7fb 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/circ/circ.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/circ.module.ts @@ -12,6 +12,7 @@ import {CircEventsComponent} from './events-dialog.component'; import {OpenCircDialogComponent} from './open-circ-dialog.component'; import {RouteDialogComponent} from './route-dialog.component'; import {CopyInTransitDialogComponent} from './in-transit-dialog.component'; +import {BackdateDialogComponent} from './backdate-dialog.component'; @NgModule({ declarations: [ @@ -22,6 +23,7 @@ import {CopyInTransitDialogComponent} from './in-transit-dialog.component'; ClaimsReturnedDialogComponent, CircEventsComponent, RouteDialogComponent, + BackdateDialogComponent, CopyInTransitDialogComponent, OpenCircDialogComponent ], @@ -32,6 +34,7 @@ import {CopyInTransitDialogComponent} from './in-transit-dialog.component'; ], exports: [ CircGridComponent, + BackdateDialogComponent, CircComponentsComponent ], providers: [ 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 348515288a..ae558ef137 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 @@ -1038,5 +1038,12 @@ export class CircService { return Promise.resolve(); }); } + + lastCopyCirc(copyId: number): Promise { + return this.pcrud.search('circ', + {target_copy : copyId}, + {order_by : {circ : 'xact_start desc' }, limit : 1} + ).toPromise(); + } } -- 2.11.0