1 import {Component, Input, ViewChild} from '@angular/core';
2 import {IdlObject} from '@eg/core/idl.service';
3 import {NetService} from '@eg/core/net.service';
4 import {AuthService} from '@eg/core/auth.service';
5 import {EventService} from '@eg/core/event.service';
6 import {ToastService} from '@eg/share/toast/toast.service';
7 import {AlertDialogComponent} from '@eg/share/dialog/alert.component';
8 import {StringComponent} from '@eg/share/string/string.component';
9 import {ProgressDialogComponent} from '@eg/share/dialog/progress.component';
11 /* Transfer holdings (AKA asset.call_number) to a target bib record. */
14 selector: 'eg-transfer-holdings',
15 templateUrl: 'transfer-holdings.component.html'
18 export class TransferHoldingsComponent {
20 // Array of 'acn' objects.
21 // Assumes all acn's are children of the same bib record.
22 @Input() callNums: IdlObject[];
25 // All call numbers will be transferred to this record ID.
26 @Input() targetRecId: number;
28 // Optional. If set, all call numbers will transfer to this org
29 // unit (owning lib) in addition to transfering to the select bib
31 @Input() targetOrgId: number;
33 @ViewChild('successMsg', {static: false})
34 private successMsg: StringComponent;
36 @ViewChild('noTargetMsg', {static: false})
37 private noTargetMsg: StringComponent;
39 @ViewChild('alertDialog', {static: false})
40 private alertDialog: AlertDialogComponent;
42 @ViewChild('progressDialog', {static: false})
43 private progressDialog: ProgressDialogComponent;
48 private toast: ToastService,
49 private net: NetService,
50 private auth: AuthService,
51 private evt: EventService) {}
53 // Resolves with true if transfer completed, false otherwise.
54 // Assumes all volumes are transferred to the same bib record.
55 transferHoldings(): Promise<Boolean> {
56 if (!this.callNums || this.callNums.length === 0) {
57 return Promise.resolve(false);
60 if (!this.targetRecId) {
61 this.toast.warning(this.noTargetMsg.text);
62 return Promise.resolve(false);
67 // Group the transfers by owning library.
68 const transferVols: {[orgId: number]: number[]} = {};
70 if (this.targetOrgId) {
72 // Transfering all call numbers to the same bib record
73 // and owning library.
74 transferVols[+this.targetOrgId] = this.callNums.map(cn => cn.id());
78 // Transfering all call numbers to the same bib record
79 // while retaining existing owning library.
80 this.callNums.forEach(cn => {
81 const orgId = Number(cn.owning_lib());
82 if (!transferVols[orgId]) { transferVols[orgId] = []; }
83 transferVols[orgId].push(cn.id());
87 this.progressDialog.update({
89 max: Object.keys(transferVols).length
91 this.progressDialog.open();
93 return this.performTransfers(transferVols)
95 this.progressDialog.close();
100 performTransfers(transferVols: any): Promise<Boolean> {
101 const orgId = Object.keys(transferVols)[0];
102 const volIds = transferVols[orgId];
104 // Avoid re-processing
105 delete transferVols[orgId];
107 // Note the AngJS client also assumes .override.
108 const method = 'open-ils.cat.asset.volume.batch.transfer.override';
110 return this.net.request('open-ils.cat', method, this.auth.token(), {
111 docid: this.targetRecId,
114 }).toPromise().then(resp => {
115 const evt = this.evt.parse(resp);
117 if (evt || Number(resp) !== 1) {
119 this.eventDesc = evt ? evt.desc : '';
121 // Failure -- stop short there to avoid alert storm.
122 return this.alertDialog.open().toPromise()
123 .then(_ => { this.eventDesc = ''; return false; });
126 this.progressDialog.increment();
128 if (Object.keys(transferVols).length > 0) {
129 return this.performTransfers(transferVols);
132 return true; // All done