1 import {Component, OnInit, ViewChild} from '@angular/core';
2 import {FormControl, FormGroup, Validators} from '@angular/forms';
3 import {from, Observable, of} from 'rxjs';
4 import {switchMap} from 'rxjs/operators';
5 import {AuthService} from '@eg/core/auth.service';
6 import {GridDataSource} from '@eg/share/grid/grid';
7 import {IdlObject} from '@eg/core/idl.service';
8 import {NetService} from '@eg/core/net.service';
9 import {OrgService} from '@eg/core/org.service';
10 import {PcrudService} from '@eg/core/pcrud.service';
11 import {ReservationActionsService} from './reservation-actions.service';
12 import {CancelReservationDialogComponent} from './cancel-reservation-dialog.component';
14 // The data that comes from the API, along with some fleshing
15 interface PullListRow {
17 call_number_sortkey?: string;
18 current_resource: IdlObject;
19 reservations: IdlObject[];
20 shelving_location?: string;
21 target_resource_type: IdlObject;
25 templateUrl: './pull-list.component.html'
28 export class PullListComponent implements OnInit {
29 @ViewChild('confirmCancelReservationDialog', { static: true })
30 private cancelReservationDialog: CancelReservationDialogComponent;
32 public dataSource: GridDataSource;
34 public disableOrgs: () => number[];
35 public fillGrid: (orgId?: number) => void;
36 pullListCriteria: FormGroup;
39 private auth: AuthService,
40 private net: NetService,
41 private org: OrgService,
42 private pcrud: PcrudService,
43 private actions: ReservationActionsService,
48 this.dataSource = new GridDataSource();
50 const defaultDaysHence = 5;
52 this.pullListCriteria = new FormGroup({
53 'daysHence': new FormControl(defaultDaysHence, [
58 this.pullListCriteria.valueChanges.subscribe(() => this.fillGrid() );
60 this.disableOrgs = () => this.org.filterList( { canHaveVolumes : false }, true);
62 this.fillGrid = (orgId = this.auth.user().ws_ou()) => {
63 this.dataSource.data = [];
64 const numberOfSecondsInADay = 86400;
66 'open-ils.booking', 'open-ils.booking.reservations.get_pull_list',
67 this.auth.token(), null,
68 (this.daysHence.value * numberOfSecondsInADay),
70 ).pipe(switchMap((resources) => from(resources)),
71 switchMap((resource: PullListRow) => this.fleshResource(resource))
73 .subscribe((resource) => this.dataSource.data.push(resource));
77 noSelectedRows = (rows: IdlObject[]) => (rows.length === 0);
79 notOneResourceSelected = (rows: IdlObject[]) => {
80 return this.actions.notOneUniqueSelected(
81 rows.map(row => { if (row['current_resource']) { return row['current_resource']['id']; }}));
84 notOneCatalogedItemSelected = (rows: IdlObject[]) => {
85 return this.actions.notOneUniqueSelected(
86 rows.filter(row => (row['current_resource'] && row['call_number']))
87 .map(row => row['current_resource'].id())
91 cancelSelected = (rows: IdlObject[]) => {
92 this.cancelReservationDialog.open(rows.map(row => row['reservations'][0].id()));
95 fleshResource = (resource: PullListRow): Observable<PullListRow> => {
96 if ('t' === resource['target_resource_type'].catalog_item()) {
97 return this.pcrud.search('acp', {
98 'barcode': resource['current_resource'].barcode()
102 flesh_fields: {'acp' : ['call_number', 'location' ]}
103 }).pipe(switchMap((acp) => {
104 resource['call_number'] = acp.call_number().label();
105 resource['call_number_sortkey'] = acp.call_number().label_sortkey();
106 resource['shelving_location'] = acp.location().name();
114 viewByResource = (reservations: IdlObject[]) => {
115 this.actions.manageReservationsByResource(reservations[0]['current_resource'].barcode());
118 viewItemStatus = (reservations: IdlObject[]) => {
119 this.actions.viewItemStatus(reservations[0]['current_resource'].barcode());
123 return this.pullListCriteria.get('daysHence');