]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/share/patron/penalty-dialog.component.ts
LP1904036 Penalty dialog resets after each use
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / share / patron / penalty-dialog.component.ts
1 import {Component, OnInit, Input, Output, ViewChild} from '@angular/core';
2 import {merge, from, Observable} from 'rxjs';
3 import {tap, take, switchMap} from 'rxjs/operators';
4 import {IdlService, IdlObject} from '@eg/core/idl.service';
5 import {OrgService} from '@eg/core/org.service';
6 import {ServerStoreService} from '@eg/core/server-store.service';
7 import {AuthService} from '@eg/core/auth.service';
8 import {NetService} from '@eg/core/net.service';
9 import {EventService} from '@eg/core/event.service';
10 import {ToastService} from '@eg/share/toast/toast.service';
11 import {PcrudService} from '@eg/core/pcrud.service';
12 import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
13 import {DialogComponent} from '@eg/share/dialog/dialog.component';
14 import {StringComponent} from '@eg/share/string/string.component';
15
16
17 /**
18  * Dialog container for patron penalty/message application
19  *
20  * <eg-patron-penalty-dialog [patronId]="myPatronId">
21  * </eg-patron-penalty-dialog>
22  */
23
24 @Component({
25   selector: 'eg-patron-penalty-dialog',
26   templateUrl: 'penalty-dialog.component.html'
27 })
28
29 export class PatronPenaltyDialogComponent
30     extends DialogComponent implements OnInit {
31
32     @Input() patronId: number;
33     @Input() penaltyNote = '';
34
35     ALERT_NOTE = 20;
36     SILENT_NOTE = 21;
37     STAFF_CHR = 25;
38
39     penalty: IdlObject; // modifying an existing penalty
40     penaltyTypes: IdlObject[];
41     penaltyTypeFromSelect = '';
42     penaltyTypeFromButton: number;
43     patron: IdlObject;
44     dataLoaded = false;
45     requireInitials = false;
46     initials: string;
47     title = '';
48     noteText = '';
49
50     @ViewChild('successMsg', {static: false}) successMsg: StringComponent;
51     @ViewChild('errorMsg', {static: false}) errorMsg: StringComponent;
52
53     constructor(
54         private modal: NgbModal,
55         private idl: IdlService,
56         private org: OrgService,
57         private net: NetService,
58         private store: ServerStoreService,
59         private evt: EventService,
60         private toast: ToastService,
61         private auth: AuthService,
62         private pcrud: PcrudService) {
63         super(modal);
64     }
65
66     ngOnInit() {
67         this.onOpen$.subscribe(_ =>
68             this.init().subscribe(__ => this.dataLoaded = true));
69     }
70
71     init(): Observable<any> {
72         this.dataLoaded = false;
73
74         this.penaltyTypeFromButton = 0;
75         this.penaltyTypeFromSelect = '';
76         this.initials = '';
77         this.noteText = '';
78
79         if (this.penalty) { // Modifying an existing penalty
80             const pen = this.penalty;
81             const sp = pen.standing_penalty().id();
82             if (sp === this.ALERT_NOTE ||
83                 sp === this.SILENT_NOTE || sp === this.STAFF_CHR) {
84                 this.penaltyTypeFromButton = sp;
85             } else {
86                 this.penaltyTypeFromSelect = sp;
87             }
88
89             this.noteText = pen.note();
90
91         } else {
92             this.penaltyTypeFromButton = this.SILENT_NOTE;
93         }
94
95         this.store.getItem('ui.staff.require_initials.patron_standing_penalty')
96         .then(require => this.requireInitials = require);
97
98         const obs1 = this.pcrud.retrieve('au', this.patronId)
99             .pipe(tap(usr => this.patron = usr));
100
101         if (this.penaltyTypes) { return obs1; }
102
103         return obs1.pipe(switchMap(_ => {
104             return this.pcrud.search('csp', {id: {'>': 100}}, {}, {atomic: true})
105
106             .pipe(tap(ptypes => {
107                 this.penaltyTypes =
108                     ptypes.sort((a, b) => a.label() < b.label() ? -1 : 1);
109             }));
110         }));
111     }
112
113     modifyPenalty() {
114         this.penalty.note(this.initials ?
115             `${this.noteText} [${this.initials}]` : this.noteText);
116
117         this.penalty.standing_penalty(
118             this.penaltyTypeFromSelect || this.penaltyTypeFromButton);
119
120         this.pcrud.update(this.penalty).toPromise()
121         .then(ok => {
122             if (!ok) {
123                 this.errorMsg.current().then(msg => this.toast.danger(msg));
124                 this.error('Update failed', true);
125             } else {
126                 this.successMsg.current().then(msg => this.toast.success(msg));
127                 this.penalty = null;
128                 this.close(ok);
129             }
130         });
131     }
132
133     apply() {
134
135         if (this.penalty) {
136             this.modifyPenalty();
137             return;
138         }
139
140         const pen = this.idl.create('ausp');
141         const msg = {
142             title: this.title,
143             message: this.noteText ? this.noteText : ''
144         };
145         pen.usr(this.patronId);
146         pen.org_unit(this.auth.user().ws_ou());
147         pen.set_date('now');
148         pen.staff(this.auth.user().id());
149
150         if (this.initials) {
151             msg.message = `${this.noteText} [${this.initials}]`;
152         }
153
154         pen.standing_penalty(
155             this.penaltyTypeFromSelect || this.penaltyTypeFromButton);
156
157         this.net.request(
158             'open-ils.actor',
159             'open-ils.actor.user.penalty.apply',
160             this.auth.token(), pen, msg
161         ).subscribe(resp => {
162             const e = this.evt.parse(resp);
163             if (e) {
164                 this.errorMsg.current().then(m => this.toast.danger(m));
165                 this.error(e, true);
166             } else {
167                 // resp == penalty ID on success
168                 this.successMsg.current().then(m => this.toast.success(m));
169                 this.close(resp);
170             }
171         });
172     }
173
174     buttonClass(pType: number): string {
175         return this.penaltyTypeFromButton === pType ?
176             'btn-primary' : 'btn-light';
177     }
178 }
179
180
181