i18n-dialogBoby dialogBody="Unsaved changes will be lost. Continue navigation?">
</eg-confirm-dialog>
+<eg-confirm-dialog #purgeConfirm1
+ i18n-dialogTitle dialogTitle="Completely Purge Patron Account?"
+ i18n-dialogBody dialogBody="Completely OBLITERATE this patron
+ account, including bills, payments, bookbags, etc? This is IRREVERSIBLE.">
+</eg-confirm-dialog>
+
+<eg-confirm-dialog #purgeConfirm2
+ i18n-dialogTitle dialogTitle="Completely Purge Patron Account?"
+ i18n-dialogBody dialogBody="Last chance, are you sure you want to
+ completely delete this account?">
+</eg-confirm-dialog>
+
+<eg-confirm-dialog #purgeConfirmOverride
+ i18n-dialogTitle dialogTitle="Completely Purge Patron Account?"
+ i18n-dialogBody dialogBody="The account has open transactions
+ (circulations and/or unpaid bills). Purge anyway?">
+</eg-confirm-dialog>
+
+<eg-alert-dialog #purgeBadBarcode
+ i18n-dialogTitle dialogTitle="Bad Barcode"
+ i18n-dialogBody dialogBody="Could not retrieve a destination account
+ with the barcode provided. Aborting the purge...">
+</eg-alert-dialog>
+
+<eg-prompt-dialog #purgeStaffDialog
+ i18n-dialogTitle dialogTitle="Completely Purge Patron Account?"
+ i18n-dialogBody dialogBody="The account you are attempting to delete has
+ STAFF_LOGIN privileges. Please enter the barcode for a destination
+ account to receive miscellaneous staff artifacts (reports, etc.) from
+ the account to be deleted.">
+</eg-prompt-dialog>
+
<ng-container *ngIf="context.summary">
<eg-staff-banner i18n-bannerText bannerText="Patron:
{{context.summary.patron.family_name()}},
import {Component, ViewChild, OnInit, AfterViewInit, HostListener} from '@angular/core';
import {Router, ActivatedRoute, ParamMap} from '@angular/router';
import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
+import {Observable, throwError, empty} from 'rxjs';
+import {concatMap, tap} from 'rxjs/operators';
import {NetService} from '@eg/core/net.service';
import {AuthService} from '@eg/core/auth.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {EventService} from '@eg/core/event.service';
import {ServerStoreService} from '@eg/core/server-store.service';
import {PatronService} from '@eg/staff/share/patron/patron.service';
import {PatronContextService, BillGridEntry} from './patron.service';
import {EditToolbarComponent} from './edit-toolbar.component';
import {EditComponent} from './edit.component';
import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
+import {PromptDialogComponent} from '@eg/share/dialog/prompt.component';
+import {AlertDialogComponent} from '@eg/share/dialog/alert.component';
const MAIN_TABS =
['checkout', 'items_out', 'holds', 'bills', 'messages', 'edit', 'search'];
@ViewChild('pendingChangesDialog')
private pendingChangesDialog: ConfirmDialogComponent;
+ @ViewChild('purgeConfirm1') private purgeConfirm1: ConfirmDialogComponent;
+ @ViewChild('purgeConfirm2') private purgeConfirm2: ConfirmDialogComponent;
+ @ViewChild('purgeConfirmOverride') private purgeConfirmOverride: ConfirmDialogComponent;
+ @ViewChild('purgeStaffDialog') private purgeStaffDialog: PromptDialogComponent;
+ @ViewChild('purgeBadBarcode') private purgeBadBarcode: AlertDialogComponent;
+
constructor(
private router: Router,
private route: ActivatedRoute,
private net: NetService,
private auth: AuthService,
+ private pcrud: PcrudService,
+ private evt: EventService,
private store: ServerStoreService,
public patronService: PatronService,
public context: PatronContextService
}
purgeAccount() {
- // show scary warning, etc.
+ this.purgeConfirm1.open().toPromise()
+ .then(confirmed => {
+ if (confirmed) {
+ return this.purgeConfirm2.open().toPromise();
+ }
+ })
+ .then(confirmed => {
+ if (confirmed) {
+ return this.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.user.has_work_perm_at',
+ this.auth.token(), 'STAFF_LOGIN', this.patronId
+ ).toPromise();
+ }
+ })
+ .then(permOrgs => {
+ if (permOrgs) {
+ if (permOrgs.length === 0) { // non-staff
+ return this.doThePurge();
+ } else {
+ return this.handleStaffPurge();
+ }
+ }
+ });
+ }
+
+ handleStaffPurge(): Promise<any> {
+
+ return this.purgeStaffDialog.open().toPromise()
+ .then(barcode => {
+ if (barcode) {
+ return this.pcrud.search('ac', {barcode: barcode}).toPromise();
+ }
+ })
+ .then(card => {
+ if (card) {
+ return this.doThePurge(card.usr());
+ } else {
+ return this.purgeBadBarcode.open();
+ }
+ });
+ }
+
+ doThePurge(destUserId?: number, override?: boolean): Promise<any> {
+ let method = 'open-ils.actor.user.delete';
+ if (override) { method += '.override'; }
+
+ return this.net.request('open-ils.actor', method,
+ this.auth.token(), this.patronId, destUserId).toPromise()
+ .then(resp => {
+
+ const evt = this.evt.parse(resp);
+ if (evt) {
+ if (evt.textcode === 'ACTOR_USER_DELETE_OPEN_XACTS') {
+ return this.purgeConfirmOverride.open().toPromise()
+ .then(confirmed => {
+ if (confirmed) {
+ return this.doThePurge(destUserId, true);
+ }
+ });
+ } else {
+ alert(evt);
+ }
+ } else {
+ this.context.summary = null;
+ this.router.navigate(['/staff/circ/patron/search']);
+ }
+ });
}
counts(part: string, field: string): number {