]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/booking/manage-reservations.component.ts
LP1830973 Angular 8 updates
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / booking / manage-reservations.component.ts
1 import {Component, OnInit, ViewChild, OnDestroy} from '@angular/core';
2 import {FormGroup, FormControl} from '@angular/forms';
3 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
4 import {Subscription, of, from} from 'rxjs';
5 import {debounceTime, single, tap, switchMap} from 'rxjs/operators';
6 import {NgbTabset} from '@ng-bootstrap/ng-bootstrap';
7 import {AuthService} from '@eg/core/auth.service';
8 import {PcrudService} from '@eg/core/pcrud.service';
9 import {ReservationsGridComponent} from './reservations-grid.component';
10 import {ServerStoreService} from '@eg/core/server-store.service';
11 import {ToastService} from '@eg/share/toast/toast.service';
12 import {NetService} from '@eg/core/net.service';
13 import {PatronBarcodeValidator} from '@eg/share/validators/patron_barcode_validator.directive';
14 import {BookingResourceBarcodeValidator} from './booking_resource_validator.directive';
15 import {OrgFamily} from '@eg/share/org-family-select/org-family-select.component';
16
17 @Component({
18     selector: 'eg-manage-reservations',
19     templateUrl: './manage-reservations.component.html',
20 })
21 export class ManageReservationsComponent implements OnInit, OnDestroy {
22
23     patronId: number;
24     resourceId: number;
25     subscriptions: Subscription[] = [];
26     filters: FormGroup;
27     startingTab: 'patron' | 'resource' | 'type' = 'patron';
28     startingPickupOrgs: OrgFamily = {primaryOrgId: this.auth.user().ws_ou(), includeDescendants: true};
29
30     @ViewChild('filterTabs', { static: true }) filterTabs: NgbTabset;
31     @ViewChild('reservationsGrid', { static: true }) reservationsGrid: ReservationsGridComponent;
32
33     removeFilters: () => void;
34
35     constructor(
36         private route: ActivatedRoute,
37         private router: Router,
38         private auth: AuthService,
39         private net: NetService,
40         private pcrud: PcrudService,
41         private store: ServerStoreService,
42         private toast: ToastService,
43         private patronValidator: PatronBarcodeValidator,
44         private resourceValidator: BookingResourceBarcodeValidator
45     ) {
46         this.store.getItem('eg.booking.manage.selected_org_family').then((pickupLibs) => {
47             if (pickupLibs) {
48                 this.startingPickupOrgs = pickupLibs;
49             }
50         });
51     }
52
53     ngOnInit() {
54         this.filters = new FormGroup({
55             'pickupLibraries': new FormControl(this.startingPickupOrgs),
56             'patronBarcode': new FormControl('', [], [this.patronValidator.validate]),
57             'resourceBarcode': new FormControl('', [], [this.resourceValidator.validate]),
58             'resourceType': new FormControl(null),
59         });
60
61         const debouncing = 300;
62
63         this.subscriptions.push(
64             this.pickupLibraries.valueChanges.pipe(
65             ).subscribe(() => this.reservationsGrid.reloadGrid()));
66
67         this.subscriptions.push(
68             this.patronBarcode.statusChanges.pipe(
69                 debounceTime(debouncing),
70                 switchMap((status) => {
71                     if ('VALID' === status) {
72                         return this.net.request(
73                             'open-ils.actor',
74                             'open-ils.actor.get_barcodes',
75                             this.auth.token(), this.auth.user().ws_ou(),
76                            'actor', this.patronBarcode.value).pipe(
77                                single(),
78                                tap((response) =>
79                                    this.router.navigate(['/staff', 'booking', 'manage_reservations', 'by_patron', response[0].id])
80                         ));
81                     } else {
82                         this.toast.danger('No patron found with this barcode');
83                         return of();
84                     }})
85             ).subscribe());
86
87         this.subscriptions.push(
88             this.resourceBarcode.statusChanges.pipe(
89                 debounceTime(debouncing),
90                 tap((status) => {
91                     if ('VALID' === status) {
92                         if (this.resourceBarcode.value) {
93                             this.router.navigate(['/staff', 'booking', 'manage_reservations', 'by_resource', this.resourceBarcode.value]);
94                         } else {
95                             this.removeFilters();
96                         }
97                     }
98                 }
99             )).subscribe());
100
101         this.subscriptions.push(
102             this.resourceType.valueChanges.pipe(
103                 tap((value) => {
104                     if (value) {
105                         this.router.navigate(['/staff', 'booking', 'manage_reservations', 'by_resource_type', value.id]);
106                     } else {
107                         this.removeFilters();
108                     }
109                 }
110             )).subscribe());
111
112             this.subscriptions.push(
113                 this.pickupLibraries.valueChanges.pipe(
114                     tap((value) =>  this.store.setItem('eg.booking.manage.selected_org_family', value))
115                 ).subscribe());
116
117         this.removeFilters = () => {
118               this.router.navigate(['/staff', 'booking', 'manage_reservations']);
119         };
120
121
122         this.route.paramMap.pipe(
123             switchMap((params: ParamMap) => {
124                 this.patronId = params.has('patron_id') ? +params.get('patron_id') : null;
125                 this.filters.patchValue({resourceBarcode: params.get('resource_barcode')}, {emitEvent: false});
126                 this.filters.patchValue({resourceType: {id: +params.get('resource_type_id')}}, {emitEvent: false});
127
128                 if (this.patronId) {
129                     return this.pcrud.search('au', {
130                         'id': this.patronId,
131                     }, {
132                         limit: 1,
133                         flesh: 1,
134                         flesh_fields: {'au': ['card']}
135                     }).pipe(tap(
136                         (resp) => {
137                             this.filters.patchValue({patronBarcode: resp.card().barcode()}); },
138                         (err) => { console.debug(err); }
139                     ));
140                 } else if (this.resourceBarcode.value) {
141                     this.startingTab = 'resource';
142                     return this.pcrud.search('brsrc',
143                     {'barcode' : this.resourceBarcode.value}, {'limit': 1}).pipe(
144                     tap((res) => {
145                         this.resourceId = res.id();
146                     }, (err) => {
147                         this.resourceId = -1;
148                         this.toast.danger('No resource found with this barcode');
149                     }));
150                 } else if (this.resourceType.value) {
151                     this.startingTab = 'type';
152                     return of(null);
153                 } else {
154                     return of(null);
155                 }
156
157         })).subscribe();
158     }
159
160     get pickupLibraries() {
161         return this.filters.get('pickupLibraries');
162     }
163     get patronBarcode() {
164       return this.filters.get('patronBarcode');
165     }
166     get resourceBarcode() {
167         return this.filters.get('resourceBarcode');
168     }
169     get resourceType() {
170         return this.filters.get('resourceType');
171     }
172     get pickupLibrariesForGrid() {
173         return this.pickupLibraries.value ?
174             this.pickupLibraries.value.orgIds :
175             [this.auth.user().ws_ou()];
176     }
177     get resourceTypeForGrid() {
178         return this.resourceType.value ? this.resourceType.value.id : null;
179     }
180
181     ngOnDestroy(): void {
182         this.subscriptions.forEach((subscription) => {
183             subscription.unsubscribe();
184         });
185     }
186
187 }
188