1 import {Component, Input, OnInit, AfterViewInit, ViewChild} from '@angular/core';
2 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
3 import {from, empty, range} from 'rxjs';
4 import {concatMap, tap, takeLast} from 'rxjs/operators';
5 import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
6 import {IdlObject} from '@eg/core/idl.service';
7 import {EventService} from '@eg/core/event.service';
8 import {OrgService} from '@eg/core/org.service';
9 import {NetService} from '@eg/core/net.service';
10 import {PcrudService, PcrudContext} from '@eg/core/pcrud.service';
11 import {AuthService} from '@eg/core/auth.service';
12 import {ServerStoreService} from '@eg/core/server-store.service';
13 import {PatronService} from '@eg/staff/share/patron/patron.service';
14 import {PatronContextService, BillGridEntry} from './patron.service';
15 import {GridDataSource, GridColumn, GridCellTextGenerator} from '@eg/share/grid/grid';
16 import {GridComponent} from '@eg/share/grid/grid.component';
17 import {Pager} from '@eg/share/util/pager';
18 import {CircService, CircDisplayInfo} from '@eg/staff/share/circ/circ.service';
19 import {PrintService} from '@eg/share/print/print.service';
20 import {PromptDialogComponent} from '@eg/share/dialog/prompt.component';
21 import {AlertDialogComponent} from '@eg/share/dialog/alert.component';
22 import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
23 import {CreditCardDialogComponent
24 } from '@eg/staff/share/billing/credit-card-dialog.component';
25 import {BillingService, CreditCardPaymentParams} from '@eg/staff/share/billing/billing.service';
26 import {AddBillingDialogComponent} from '@eg/staff/share/billing/billing-dialog.component';
27 import {AudioService} from '@eg/share/util/audio.service';
28 import {ToastService} from '@eg/share/toast/toast.service';
31 templateUrl: 'bill-statement.component.html',
32 selector: 'eg-patron-bill-statement'
34 export class BillStatementComponent implements OnInit {
36 @Input() patronId: number;
37 @Input() xactId: number;
39 statementTab = 'statement';
40 billingDataSource: GridDataSource = new GridDataSource();
41 paymentDataSource: GridDataSource = new GridDataSource();
42 cellTextGenerator: GridCellTextGenerator;
47 @ViewChild('billingGrid') private billingGrid: GridComponent;
48 @ViewChild('noteDialog') private noteDialog: PromptDialogComponent;
49 @ViewChild('voidBillsDialog') private voidBillsDialog: ConfirmDialogComponent;
52 private router: Router,
53 private route: ActivatedRoute,
54 private audio: AudioService,
55 private toast: ToastService,
56 private org: OrgService,
57 private evt: EventService,
58 private net: NetService,
59 private pcrud: PcrudService,
60 private auth: AuthService,
61 private printer: PrintService,
62 private serverStore: ServerStoreService,
63 private circ: CircService,
64 private billing: BillingService,
65 public patronService: PatronService,
66 public context: PatronContextService
71 this.cellTextGenerator = {
74 this.billingDataSource.getRows = (pager: Pager, sort: any[]) => {
75 const orderBy: any = {};
77 orderBy.mb = sort[0].name + ' ' + sort[0].dir;
79 return this.pcrud.search('mb', {xact: this.xactId}, {
81 flesh_fields: {mb: ['voider']},
86 this.paymentDataSource.getRows = (pager: Pager, sort: any[]) => {
87 const orderBy: any = {};
89 orderBy.mbp = sort[0].name + ' ' + sort[0].dir;
91 return this.pcrud.search('mbp', {xact: this.xactId}, {
93 flesh_fields: {mbp: ['accepting_usr']},
100 'open-ils.circ.money.statement.retrieve',
101 this.auth.token(), this.xactId
102 ).subscribe(s => this.statement = s);
105 openNoteDialog(rows: IdlObject[]) {
106 if (rows.length === 0) { return; }
108 const notes = rows.map(r => r.note() || '').join(',');
109 const ids = rows.map(r => r.id());
110 this.noteTargets = ids.join(',');
111 this.noteDialog.promptValue = notes;
113 this.noteDialog.open().subscribe(value => {
114 if (value === notes) { return; }
116 let method = 'open-ils.circ.money.billing.note.edit';
117 if (rows[0].classname === 'mbp') {
118 method = 'open-ils.circ.money.payment.note.edit';
121 this.net.requestWithParamList(
122 'open-ils.circ', method, [this.auth.token(), value].concat(ids))
123 .toPromise().then(resp => {
124 const evt = this.evt.parse(resp);
128 rows.forEach(r => r.note(value));
134 openVoidDialog(rows: IdlObject[]) {
135 rows = rows.filter(r => r.voided() === 'f');
138 rows.forEach(billing => amount += billing.amount() * 100);
140 const ids = rows.map(r => r.id());
141 this.voidAmount = amount / 100;
142 this.voidTargets = ids.join(',');
144 this.voidBillsDialog.open().subscribe(confirmed => {
145 if (!confirmed) { return; }
147 this.net.requestWithParamList(
149 'open-ils.circ.money.billing.void',
150 [this.auth.token()].concat(ids)).toPromise()
152 const evt = this.evt.parse(resp);
156 this.context.refreshPatron();
157 this.billingGrid.reload();
164 if (this.statement && this.statement.xact.circulation()) {
165 return this.statement.xact.circulation().target_copy();
169 totalBilled(): number {
170 if (!this.statement) { return 0; }
172 const billed = (this.statement.summary.billing_total || 0) * 100;
173 const voided = (this.statement.summary.void_total || 0) * 100;
175 return (billed - voided) / 100;