From f4eb326be1c4bef5b582960f0f2f087593a1c779 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Tue, 16 Mar 2021 12:10:34 -0400 Subject: [PATCH] LP1904036 Patron group details UI Signed-off-by: Bill Erickson Signed-off-by: Jane Sandberg Signed-off-by: Galen Charlton --- .../src/app/staff/circ/patron/group.component.html | 46 ++++++++ .../src/app/staff/circ/patron/group.component.ts | 125 +++++++++++++++++++++ .../app/staff/circ/patron/patron.component.html | 4 + .../eg2/src/app/staff/circ/patron/patron.module.ts | 2 + .../src/app/staff/circ/patron/patron.service.ts | 24 ++-- .../app/staff/circ/patron/summary.component.html | 2 +- 6 files changed, 194 insertions(+), 9 deletions(-) create mode 100644 Open-ILS/src/eg2/src/app/staff/circ/patron/group.component.html create mode 100644 Open-ILS/src/eg2/src/app/staff/circ/patron/group.component.ts diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/group.component.html b/Open-ILS/src/eg2/src/app/staff/circ/patron/group.component.html new file mode 100644 index 0000000000..73ceeea4f2 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/group.component.html @@ -0,0 +1,46 @@ + + + + + +

Group Member Details

+ +
+
+ Total Owed: + {{totalOwed | currency}} + Total Out: + {{totalOut}} + Total Overdue: + {{totalOverdue}} +
+
+ + +
+ + + + + + + + + + + + + + + +
+ diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/group.component.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/group.component.ts new file mode 100644 index 0000000000..af69cc64c1 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/group.component.ts @@ -0,0 +1,125 @@ +import {Component, Input, OnInit, AfterViewInit, ViewChild} from '@angular/core'; +import {Router, ActivatedRoute, ParamMap} from '@angular/router'; +import {from, empty, range} from 'rxjs'; +import {concatMap, tap, takeLast} from 'rxjs/operators'; +import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap'; +import {IdlObject} from '@eg/core/idl.service'; +import {EventService} from '@eg/core/event.service'; +import {OrgService} from '@eg/core/org.service'; +import {NetService} from '@eg/core/net.service'; +import {PcrudService, PcrudContext} from '@eg/core/pcrud.service'; +import {AuthService} from '@eg/core/auth.service'; +import {PatronService} from '@eg/staff/share/patron/patron.service'; +import {PatronContextService} from './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 {PromptDialogComponent} from '@eg/share/dialog/prompt.component'; +import {AlertDialogComponent} from '@eg/share/dialog/alert.component'; +import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component'; + +@Component({ + templateUrl: 'group.component.html', + selector: 'eg-patron-group' +}) +export class PatronGroupComponent implements OnInit { + + @Input() patronId: number; + patrons: IdlObject[] = []; + totalOwed = 0; + totalOut = 0; + totalOverdue = 0; + usergroup: number; + + dataSource: GridDataSource = new GridDataSource(); + @ViewChild('groupGrid') private groupGrid: GridComponent; + @ViewChild('moveToGroupDialog') private moveToGroupDialog: PromptDialogComponent; + @ViewChild('userNotFoundDialog') private userNotFoundDialog: AlertDialogComponent; + + constructor( + private router: Router, + private evt: EventService, + private net: NetService, + private auth: AuthService, + private org: OrgService, + private pcrud: PcrudService, + private patronService: PatronService, + private context: PatronContextService + ) {} + + ngOnInit() { + + this.dataSource.getRows = (pager: Pager, sort: any[]) => + from(this.patrons.slice(pager.offset, pager.offset + pager.limit)); + + if (this.context.patron) { + this.getGroupUsers(this.context.patron.usrgroup()); + + } else { + this.patronService.getById(this.patronId) + .then(patron => this.getGroupUsers(patron.usrgroup())); + } + } + + getGroupUsers(usergroup: number) { + this.usergroup = usergroup; + this.patrons = []; + + this.pcrud.search('au', + {usrgroup: usergroup, deleted: 'f'}, {authoritative: true}) + .pipe(concatMap(u => { + + const promise = this.context.getPatronVitalStats(u.id()) + .then(stats => { + this.totalOwed += stats.fines.balance_owed; + this.totalOut += stats.checkouts.total_out; + this.totalOverdue += stats.checkouts.overdue; + u._stats = stats; + this.patrons.push(u); + }); + + return from(promise); + + })).subscribe(null, null, () => this.groupGrid.reload()); + } + + movePatronToGroup() { + + this.moveToGroupDialog.open().subscribe(barcode => { + if (!barcode) { return null; } + + this.patronService.getByBarcode(barcode) + .then(resp => { + if (resp === null) { + this.userNotFoundDialog.open(); + return null; + } + + resp.usrgroup(this.usergroup); + resp.ischanged(true); + + return this.net.request( + 'open-ils.actor', + 'open-ils.actor.patron.update', + this.auth.token(), resp + ).toPromise(); + }) + .then(resp => { + if (resp === null) { return null; } + + const evt = this.evt.parse(resp); + if (evt) { + console.error(evt); + alert(evt); + return null; + } + + return this.getGroupUsers(this.usergroup); + }) + .then(resp => { + if (resp === null) { return null; } + this.groupGrid.reload(); + }); + }); + } +} diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.html b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.html index d13a72ff21..dc63f84d83 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.html +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.html @@ -167,6 +167,10 @@ +
+ + +
diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.module.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.module.ts index fe5f556e65..384726a633 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.module.ts @@ -25,6 +25,7 @@ import {BillStatementComponent} from './bill-statement.component'; import {TestPatronPasswordComponent} from './test-password.component'; import {PatronSurveyResponsesComponent} from './surveys.component'; import {PatronStatCatsComponent} from './statcats.component'; +import {PatronGroupComponent} from './group.component'; @NgModule({ declarations: [ @@ -41,6 +42,7 @@ import {PatronStatCatsComponent} from './statcats.component'; BillStatementComponent, TestPatronPasswordComponent, PatronSurveyResponsesComponent, + PatronGroupComponent, PatronStatCatsComponent ], imports: [ diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.service.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.service.ts index 545f09ad7a..4e9ae397d4 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.service.ts +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.service.ts @@ -135,12 +135,7 @@ export class PatronContextService { .then(_ => this.compileAlerts()); } - getPatronStats(id: number): Promise { - - // When quickly navigating patron search results it's possible - // for this.patron to be cleared right before this function - // is called. Exit early instead of making an unneeded call. - if (!this.patron) { return Promise.resolve(); } + getPatronVitalStats(id: number): Promise { return this.net.request( 'open-ils.actor', @@ -166,9 +161,22 @@ export class PatronContextService { stats.checkouts.total_out += stats.checkouts.lost; } - this.patronStats = stats; + return stats; + }); + } + + getPatronStats(id: number): Promise { + + // When quickly navigating patron search results it's possible + // for this.patron to be cleared right before this function + // is called. Exit early instead of making an unneeded call. + if (!this.patron) { return Promise.resolve(); } + + return this.getPatronVitalStats(id) + + .then(stats => this.patronStats = stats) - }).then(_ => { + .then(_ => { if (!this.patron) { return; } diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.html b/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.html index 5c2eb179ea..df7435f35e 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.html +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.html @@ -87,7 +87,7 @@
+ [ngClass]="{'alert alert-danger p-0': context.patronStats.fines.balance_owed > 0}">
Fines Owed
{{context.patronStats.fines.balance_owed | currency}}
-- 2.11.0