LP1865898 Missing pieces mult-scan work flow improvements
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / cat / item / missing-pieces.component.ts
1 import {Component, Input, AfterViewInit, ViewChild} from '@angular/core';
2 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
3 import {IdlObject} from '@eg/core/idl.service';
4 import {PcrudService} from '@eg/core/pcrud.service';
5 import {AuthService} from '@eg/core/auth.service';
6 import {NetService} from '@eg/core/net.service';
7 import {PrintService} from '@eg/share/print/print.service';
8 import {HoldingsService} from '@eg/staff/share/holdings/holdings.service';
9 import {EventService} from '@eg/core/event.service';
10 import {PatronPenaltyDialogComponent} from '@eg/staff/share/patron/penalty-dialog.component';
11
12 @Component({
13   templateUrl: 'missing-pieces.component.html'
14 })
15 export class MarkItemMissingPiecesComponent implements AfterViewInit {
16
17     itemId: number;
18     itemBarcode: string;
19     item: IdlObject;
20     letter: string;
21     circNotFound = false;
22     processing = false;
23     noSuchItem = false;
24     itemProcessed = false;
25
26     @ViewChild('penaltyDialog', {static: false})
27     penaltyDialog: PatronPenaltyDialogComponent;
28
29     constructor(
30         private route: ActivatedRoute,
31         private net: NetService,
32         private printer: PrintService,
33         private pcrud: PcrudService,
34         private auth: AuthService,
35         private evt: EventService,
36         private holdings: HoldingsService
37     ) {
38         this.itemId = +this.route.snapshot.paramMap.get('id');
39     }
40
41     ngAfterViewInit() {
42         if (this.itemId) { this.getItemById(); }
43         this.selectInput();
44     }
45
46     getItemByBarcode(): Promise<any> {
47         this.itemId = null;
48         this.item = null;
49
50         if (!this.itemBarcode) { return Promise.resolve(); }
51
52         // Submitting a new barcode resets the form.
53         const bc = this.itemBarcode;
54         this.reset();
55         this.itemBarcode = bc;
56
57         return this.holdings.getItemIdFromBarcode(this.itemBarcode)
58         .then(id => {
59             this.noSuchItem = (id === null);
60             this.itemId = id;
61             return this.getItemById();
62         });
63     }
64
65     selectInput() {
66         setTimeout(() => {
67             const node: HTMLInputElement =
68                 document.getElementById('item-barcode-input') as HTMLInputElement;
69             if (node) { node.select(); }
70         });
71     }
72
73     getItemById(): Promise<any> {
74         this.circNotFound = false;
75
76         if (!this.itemId) {
77             this.selectInput();
78             return Promise.resolve();
79         }
80
81         const flesh = {
82             flesh: 3,
83             flesh_fields: {
84                 acp: ['call_number'],
85                 acn: ['record'],
86                 bre: ['flat_display_entries']
87             }
88         };
89
90         return this.pcrud.retrieve('acp', this.itemId, flesh)
91         .toPromise().then(item => {
92             this.item = item;
93             this.itemId = item.id();
94             this.itemBarcode = item.barcode();
95             this.selectInput();
96         });
97     }
98
99     display(field: string): string {
100         if (!this.item) { return ''; }
101
102         const entry = this.item.call_number().record()
103             .flat_display_entries()
104             .filter(fde => fde.name() === field)[0];
105
106         return entry ? entry.value() : '';
107     }
108
109     reset() {
110         this.item = null;
111         this.itemId = null;
112         this.letter = null;
113         this.itemBarcode = null;
114         this.circNotFound = false;
115         this.itemProcessed = false;
116     }
117
118     processItem() {
119         this.circNotFound = false;
120         this.itemProcessed = false;
121
122         if (!this.item) { return; }
123
124         this.processing = true;
125
126         this.net.request(
127             'open-ils.circ',
128             'open-ils.circ.mark_item_missing_pieces',
129             this.auth.token(), this.itemId
130         ).subscribe(resp => {
131             const evt = this.evt.parse(resp); // always returns event
132             this.processing = false;
133             this.itemProcessed = true;
134
135             if (evt.textcode === 'ACTION_CIRCULATION_NOT_FOUND') {
136                 this.circNotFound = true;
137                 this.selectInput();
138                 return;
139             }
140
141             const payload = evt.payload;
142
143             if (payload.letter) {
144                 this.letter = payload.letter.template_output().data();
145             }
146
147             if (payload.slip) {
148                 this.printer.print({
149                     printContext: 'default',
150                     contentType: 'text/html',
151                     text: payload.slip.template_output().data()
152                 });
153             }
154
155             if (payload.circ) {
156                 this.penaltyDialog.patronId = payload.circ.usr();
157                 this.penaltyDialog.open().subscribe(
158                     penId => console.debug('Applied penalty ', penId),
159                     err => {},
160                     () => this.selectInput()
161                 );
162             } else {
163                 this.selectInput();
164             }
165         });
166     }
167
168     printLetter() {
169         this.printer.print({
170             printContext: 'default',
171             contentType: 'text/plain',
172             text: this.letter
173         });
174     }
175
176     letterRowCount(): number {
177         return this.letter ? this.letter.split(/\n/).length + 2 : 20;
178     }
179 }
180
181
182