1 import {Component, Input, ViewChild} from '@angular/core';
2 import {Observable, throwError, from} from 'rxjs';
3 import {switchMap} from 'rxjs/operators';
4 import {NetService} from '@eg/core/net.service';
5 import {IdlObject} from '@eg/core/idl.service';
6 import {EventService} from '@eg/core/event.service';
7 import {ToastService} from '@eg/share/toast/toast.service';
8 import {AuthService} from '@eg/core/auth.service';
9 import {PcrudService} from '@eg/core/pcrud.service';
10 import {OrgService} from '@eg/core/org.service';
11 import {StringComponent} from '@eg/share/string/string.component';
12 import {DialogComponent} from '@eg/share/dialog/dialog.component';
13 import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
14 import {BibRecordService, BibRecordSummary} from '@eg/share/catalog/bib-record.service';
15 import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
16 import {BillingService} from '@eg/staff/share/billing/billing.service';
19 * Dialog for marking items damaged and asessing related bills.
23 selector: 'eg-mark-damaged-dialog',
24 templateUrl: 'mark-damaged-dialog.component.html'
27 export class MarkDamagedDialogComponent
28 extends DialogComponent {
30 @Input() copyId: number;
32 // If the item is checked out, ask the API to check it in first.
33 @Input() handleCheckin = false;
36 bibSummary: BibRecordSummary;
37 billingTypes: ComboboxEntry[];
39 // Overide the API suggested charge amount
40 amountChangeRequested: boolean;
45 @ViewChild('successMsg', { static: true }) private successMsg: StringComponent;
46 @ViewChild('errorMsg', { static: true }) private errorMsg: StringComponent;
49 // Charge data returned from the server requesting additional charge info.
53 private modal: NgbModal, // required for passing to parent
54 private toast: ToastService,
55 private net: NetService,
56 private evt: EventService,
57 private pcrud: PcrudService,
58 private org: OrgService,
59 private billing: BillingService,
60 private bib: BibRecordService,
61 private auth: AuthService) {
62 super(modal); // required for subclassing
66 * Fetch the item/record, then open the dialog.
67 * Dialog promise resolves with true/false indicating whether
68 * the mark-damanged action occured or was dismissed.
70 open(args: NgbModalOptions): Observable<boolean> {
74 return throwError('copy ID required');
77 // Map data-loading promises to an observable
79 this.getBillingTypes().then(_ => this.getData()));
81 // Fire data loading observable and replace results with
82 // dialog opener observable.
83 return obs.pipe(switchMap(_ => super.open(args)));
86 // Fetch-cache billing types
87 getBillingTypes(): Promise<any> {
88 return this.billing.getUserBillingTypes().then(types => {
90 types.map(bt => ({id: bt.id(), label: bt.name()}));
94 getData(): Promise<any> {
95 return this.pcrud.retrieve('acp', this.copyId,
96 {flesh: 1, flesh_fields: {acp: ['call_number']}}).toPromise()
99 return this.bib.getBibSummary(
100 copy.call_number().record()).toPromise();
102 this.bibSummary = summary;
108 this.bibSummary = null;
109 this.chargeResponse = null;
110 this.newCharge = null;
112 this.amountChangeRequested = false;
115 bTypeChange(entry: ComboboxEntry) {
116 this.newBtype = entry.id;
119 markDamaged(args: any) {
120 this.chargeResponse = null;
122 if (args.apply_fines === 'apply') {
123 args.override_amount = this.newCharge;
124 args.override_btype = this.newBtype;
125 args.override_note = this.newNote;
128 if (this.handleCheckin) {
129 args.handle_checkin = true;
133 'open-ils.circ', 'open-ils.circ.mark_item_damaged',
134 this.auth.token(), this.copyId, args
137 console.debug('Mark damaged returned', result);
139 if (Number(result) === 1) {
140 this.successMsg.current().then(msg => this.toast.success(msg));
145 const evt = this.evt.parse(result);
147 if (evt.textcode === 'DAMAGE_CHARGE') {
148 // More info needed from staff on how to hangle charges.
149 this.chargeResponse = evt.payload;
150 this.newCharge = this.chargeResponse.charge;
154 this.errorMsg.current().then(m => this.toast.danger(m));