]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/share/holdings/transfer-items.component.ts
LP1868354 Angular catalog item/call number transfer
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / share / holdings / transfer-items.component.ts
1 import {Component, OnInit, Input, ViewChild, Renderer2} from '@angular/core';
2 import {Observable} from 'rxjs';
3 import {switchMap, map, tap} from 'rxjs/operators';
4 import {IdlObject, IdlService} from '@eg/core/idl.service';
5 import {NetService} from '@eg/core/net.service';
6 import {AuthService} from '@eg/core/auth.service';
7 import {EventService} from '@eg/core/event.service';
8 import {ToastService} from '@eg/share/toast/toast.service';
9 import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
10 import {AlertDialogComponent} from '@eg/share/dialog/alert.component';
11 import {StringComponent} from '@eg/share/string/string.component';
12
13 /* Transfer items to a call number. */
14
15 @Component({
16   selector: 'eg-transfer-items',
17   templateUrl: 'transfer-items.component.html'
18 })
19
20 export class TransferItemsComponent implements OnInit {
21
22     @ViewChild('successMsg', {static: false})
23         private successMsg: StringComponent;
24
25     @ViewChild('errorMsg', {static: false})
26         private errorMsg: StringComponent;
27
28     @ViewChild('noTargetMsg', {static: false})
29         private noTargetMsg: StringComponent;
30
31     @ViewChild('confirmDialog', {static: false})
32         private confirmDialog: ConfirmDialogComponent;
33
34     @ViewChild('alertDialog', {static: false})
35         private alertDialog: AlertDialogComponent;
36
37     eventDesc: string;
38
39     constructor(
40         private toast: ToastService,
41         private idl: IdlService,
42         private net: NetService,
43         private auth: AuthService,
44         private evt: EventService) {}
45
46     ngOnInit() {}
47
48     // Transfers a set of items/copies (by ID) to the selected call
49     // number (by ID).
50     // Resolves with true if transfer completed, false otherwise.
51     transferItems(itemIds: number[],
52         cnId: number, override?: boolean): Promise<boolean> {
53
54         this.eventDesc = '';
55
56         let method = 'open-ils.cat.transfer_copies_to_volume';
57         if (override) { method += '.override'; }
58
59         return this.net.request('open-ils.cat',
60             method, this.auth.token(), cnId, itemIds)
61         .toPromise().then(resp => {
62
63             const evt = this.evt.parse(resp);
64
65             if (evt) {
66
67                 if (override) {
68                     // Override failed, no looping please.
69                     this.toast.warning(this.errorMsg.text);
70                     return false;
71                 }
72
73                 this.eventDesc = evt.desc;
74
75                 return this.confirmDialog.open().toPromise().then(ok =>
76                     ok ? this.transferItems(itemIds, cnId, true) : false);
77
78             } else { // success
79
80                 this.toast.success(this.successMsg.text);
81                 return true;
82             }
83         });
84     }
85
86     // Transfers a set of items/copies (by object with fleshed call numbers)
87     // to the selected record and org unit ID, creating new call numbers
88     // where needed.
89     // Resolves with true if transfer completed, false otherwise.
90     autoTransferItems(items: IdlObject[], // acp with fleshed call_number's
91         recId: number, orgId: number): Promise<Boolean> {
92
93         this.eventDesc = '';
94
95         const cnTransfers: any = {};
96         const itemTransfers: any = {};
97
98         items.forEach(item => {
99             const cn = item.call_number();
100
101             if (cn.owning_lib() !== orgId || cn.record() !== recId) {
102                 cn.owning_lib(orgId);
103                 cn.record(recId);
104
105                 if (cnTransfers[cn.id()]) {
106                     itemTransfers[cn.id()].push(item.id());
107
108                 } else {
109                     cnTransfers[cn.id()] = cn;
110                     itemTransfers[cn.id()] = [item.id()];
111                 }
112             }
113         });
114
115         return this.transferCallNumbers(cnTransfers, itemTransfers);
116     }
117
118     transferCallNumbers(cnTransfers, itemTransfers): Promise<boolean> {
119
120         const cnId = Object.keys(cnTransfers)[0];
121         const cn = cnTransfers[cnId];
122         delete cnTransfers[cnId];
123
124         return this.net.request('open-ils.cat',
125             'open-ils.cat.call_number.find_or_create',
126             this.auth.token(),
127             cn.label(),
128             cn.record(),     // may be new
129             cn.owning_lib(), // may be new
130             (typeof cn.prefix() === 'object' ? cn.prefix().id() : cn.prefix()),
131             (typeof cn.suffix() === 'object' ? cn.suffix().id() : cn.suffix()),
132             cn.label_class()
133
134         ).toPromise().then(resp => {
135
136             const evt = this.evt.parse(resp);
137
138             if (evt) {
139                 // Problem.  Stop processing.
140                 this.toast.warning(this.errorMsg.text);
141                 this.eventDesc = evt.desc;
142                 return this.alertDialog.open().toPromise().then(_ => false);
143             }
144
145             return this.transferItems(itemTransfers[cn.id()], resp.acn_id)
146             .then(ok => {
147
148                 if (ok && Object.keys(cnTransfers).length > 0) {
149                     // More call numbers to transfer.
150                     return this.transferCallNumbers(cnTransfers, itemTransfers);
151                 }
152
153                 return ok;
154             });
155         });
156     }
157 }
158
159
160