]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/share/holds/cancel-dialog.component.ts
LP2061136 - Stamping 1405 DB upgrade script
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / share / holds / cancel-dialog.component.ts
1 import {Component, Input, ViewChild} from '@angular/core';
2 import {Observable} from 'rxjs';
3 import {NetService} from '@eg/core/net.service';
4 import {EventService} from '@eg/core/event.service';
5 import {ToastService} from '@eg/share/toast/toast.service';
6 import {PcrudService} from '@eg/core/pcrud.service';
7 import {AuthService} from '@eg/core/auth.service';
8 import {DialogComponent} from '@eg/share/dialog/dialog.component';
9 import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
10 import {StringComponent} from '@eg/share/string/string.component';
11 import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
12 import {WorkLogService, WorkLogEntry} from '@eg/staff/share/worklog/worklog.service';
13
14 /**
15  * Dialog for canceling hold requests.
16  */
17
18 @Component({
19     selector: 'eg-hold-cancel-dialog',
20     templateUrl: 'cancel-dialog.component.html'
21 })
22
23 export class HoldCancelDialogComponent
24     extends DialogComponent {
25
26     @Input() holdIds: number[];
27     @ViewChild('successMsg', { static: true }) private successMsg: StringComponent;
28     @ViewChild('errorMsg', { static: true }) private errorMsg: StringComponent;
29
30     changesApplied: boolean;
31     numSucceeded: number;
32     numFailed: number;
33     cancelReason: number;
34     cancelReasons: ComboboxEntry[];
35     cancelNote: string;
36
37     constructor(
38         private modal: NgbModal, // required for passing to parent
39         private toast: ToastService,
40         private net: NetService,
41         private evt: EventService,
42         private pcrud: PcrudService,
43         private auth: AuthService,
44         private worklog: WorkLogService) {
45         super(modal); // required for subclassing
46         this.cancelReasons = [];
47     }
48
49     // Avoid fetching cancel reasons in ngOnInit becaues that causes
50     // them to load regardless of whether the dialog is ever used.
51     open(args: NgbModalOptions): Observable<boolean> {
52         this.numSucceeded = 0;
53         this.numFailed = 0;
54
55         if (this.cancelReasons.length === 0) {
56             this.pcrud.retrieveAll('ahrcc', {}, {atomic: true}).toPromise()
57                 .then(reasons => {
58                     this.cancelReasons = reasons
59                     // only display reasons for manually canceling holds
60                         .filter(r => 't' === r.manual())
61                         .map(r => ({id: r.id(), label: r.label()}));
62                 });
63         }
64
65         return super.open(args);
66     }
67
68     async cancelNext(ids: number[]): Promise<any> {
69         if (ids.length === 0) {
70             return Promise.resolve();
71         }
72
73         const holdId = ids.pop();
74
75         return this.net.request(
76             'open-ils.circ', 'open-ils.circ.hold.cancel',
77             this.auth.token(), holdId,
78             this.cancelReason, this.cancelNote
79         ).toPromise().then(
80             async(result) => {
81                 if (Number(result) === 1) {
82                     this.numSucceeded++;
83                     this.toast.success(await this.successMsg.current());
84                     await this.recordHoldCancelWorkLog(holdId);
85                 } else {
86                     this.numFailed++;
87                     console.error(this.evt.parse(result));
88                     this.toast.warning(await this.errorMsg.current());
89                 }
90                 return this.cancelNext(ids);
91             }
92         );
93     }
94
95     async recordHoldCancelWorkLog(holdId: number) {
96         try {
97             // Load work log settings first
98             await this.worklog.loadSettings();
99
100             // Request hold details
101             const details = await this.net.request(
102                 'open-ils.circ', 'open-ils.circ.hold.details.retrieve',
103                 this.auth.token(), holdId, {
104                     'suppress_notices': true,
105                     'suppress_transits': true,
106                     'suppress_mvr': true,
107                     'include_usr': true
108                 }).toPromise();
109
110             //console.log('details', details);
111             const entry: WorkLogEntry = {
112                 'action': 'canceled_hold',
113                 'hold_id': holdId,
114                 'patron_id': details.hold.usr().id(),
115                 'user': details.patron_last,
116                 'item': details.copy ? details.copy.barcode() : null,
117                 'item_id': details.copy ? details.copy.id() : null
118             };
119
120             this.worklog.record(entry);
121
122         } catch (error) {
123             console.error('Error in work log process:', error);
124         }
125     }
126
127     async cancelBatch(): Promise<any> {
128         this.numSucceeded = 0;
129         this.numFailed = 0;
130         const ids = [].concat(this.holdIds);
131         await this.cancelNext(ids);
132         this.close(this.numSucceeded > 0);
133     }
134 }
135
136
137