LP1904036 Barcode completion dialog
authorBill Erickson <berickxx@gmail.com>
Wed, 17 Feb 2021 21:26:57 +0000 (16:26 -0500)
committerGalen Charlton <gmc@equinoxOLI.org>
Fri, 28 Oct 2022 00:13:23 +0000 (20:13 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Jane Sandberg <js7389@princeton.edu>
Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.html
Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.ts
Open-ILS/src/eg2/src/app/staff/circ/patron/patron.module.ts
Open-ILS/src/eg2/src/app/staff/share/barcodes/barcode-select.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/share/barcodes/barcode-select.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/share/barcodes/barcodes.module.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/share/patron/patron.service.ts

index ca96c1d..2e73da2 100644 (file)
@@ -1,5 +1,6 @@
 
 <eg-progress-dialog #progressDialog></eg-progress-dialog>
+<eg-barcode-select #barcodeSelect></eg-barcode-select>
 
 <eg-precat-checkout-dialog #precatDialog [barcode]="checkoutBarcode">
 </eg-precat-checkout-dialog>
index b4b1fdf..27baba5 100644 (file)
@@ -18,6 +18,7 @@ import {ServerStoreService} from '@eg/core/server-store.service';
 import {PrecatCheckoutDialogComponent} from './precat-dialog.component';
 import {AudioService} from '@eg/share/util/audio.service';
 import {CopyAlertsDialogComponent} from '@eg/staff/share/holdings/copy-alerts-dialog.component';
+import {BarcodeSelectComponent} from '@eg/staff/share/barcodes/barcode-select.component';
 
 const SESSION_DUE_DATE = 'eg.circ.checkout.is_until_logout';
 
@@ -45,6 +46,8 @@ export class CheckoutComponent implements OnInit {
         private precatDialog: PrecatCheckoutDialogComponent;
     @ViewChild('copyAlertsDialog')
         private copyAlertsDialog: CopyAlertsDialogComponent;
+    @ViewChild('barcodeSelect')
+        private barcodeSelect: BarcodeSelectComponent;
 
     constructor(
         private store: StoreService,
@@ -101,9 +104,17 @@ export class CheckoutComponent implements OnInit {
 
         } else if (this.checkoutBarcode) {
 
-            params.copy_barcode = this.checkoutBarcode;
             if (this.dueDateOptions > 0) { params.due_date = this.dueDate; }
-            return Promise.resolve(params);
+
+            return this.barcodeSelect.getBarcode('asset', this.checkoutBarcode)
+            .then(barcode => {
+                if (barcode) {
+                    params.copy_barcode = barcode;
+                    return params;
+                } else {
+                    return null;
+                }
+            });
         }
 
         return Promise.resolve(null);
index ced4ffc..b4403f5 100644 (file)
@@ -16,6 +16,7 @@ import {EditComponent} from './edit.component';
 import {EditToolbarComponent} from './edit-toolbar.component';
 import {BcSearchComponent} from './bcsearch.component';
 import {PrecatCheckoutDialogComponent} from './precat-dialog.component';
+import {BarcodesModule} from '@eg/staff/share/barcodes/barcodes.module';
 
 @NgModule({
   declarations: [
@@ -36,7 +37,8 @@ import {PrecatCheckoutDialogComponent} from './precat-dialog.component';
     HoldingsModule,
     BookingModule,
     PatronModule,
-    PatronRoutingModule
+    PatronRoutingModule,
+    BarcodesModule
   ],
   providers: [
     PatronManagerService
diff --git a/Open-ILS/src/eg2/src/app/staff/share/barcodes/barcode-select.component.html b/Open-ILS/src/eg2/src/app/staff/share/barcodes/barcode-select.component.html
new file mode 100644 (file)
index 0000000..9081ce8
--- /dev/null
@@ -0,0 +1,31 @@
+
+<ng-template #dialogContent>
+  <div class="modal-header bg-info">
+    <h4 class="modal-title">
+      <span i18n>Select Barcode</span>
+    </h4>
+    <button type="button" class="close" 
+      i18n-aria-label aria-label="Close" (click)="close()">
+      <span aria-hidden="true">&times;</span>
+    </button>
+  </div>
+  <div class="modal-body">
+         <ng-container *ngFor="let barcode of barcodes">
+                 <div class="form-check">
+                         <input class="form-check-input" type="checkbox" value="" 
+          id="barcode-check-{{barcode}}" [(ngModel)]="inputs[barcode]"
+          (ngModelChange)="selectionChanged()">
+                         <label class="form-check-label" for="barcode-check-{{barcode}}">
+          {{barcode}}
+                         </label>
+                 </div>
+    </ng-container>
+  </div>
+  <div class="modal-footer">
+    <button type="button" class="btn btn-success" [disabled]="!selectedBarcode"
+      (click)="close(selectedBarcode)" i18n>Apply</button>
+    <button type="button" class="btn btn-warning" 
+      (click)="close()" i18n>Cancel</button>
+  </div>
+</ng-template>
+
diff --git a/Open-ILS/src/eg2/src/app/staff/share/barcodes/barcode-select.component.ts b/Open-ILS/src/eg2/src/app/staff/share/barcodes/barcode-select.component.ts
new file mode 100644 (file)
index 0000000..5374410
--- /dev/null
@@ -0,0 +1,81 @@
+import {Component, Input, Output, OnInit, ViewChild} from '@angular/core';
+import {Observable} from 'rxjs';
+import {map, mergeMap} from 'rxjs/operators';
+import {IdlObject} from '@eg/core/idl.service';
+import {NetService} from '@eg/core/net.service';
+import {OrgService} from '@eg/core/org.service';
+import {AuthService} from '@eg/core/auth.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {EventService, EgEvent} from '@eg/core/event.service';
+import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+
+/* Suppor barcode completion for asset/actor/serial/booking data */
+
+@Component({
+  selector: 'eg-barcode-select',
+  templateUrl: './barcode-select.component.html',
+})
+
+export class BarcodeSelectComponent
+    extends DialogComponent implements OnInit {
+
+    selectedBarcode: string;
+    barcodes: string[];
+    inputs: {[barcode: string]: boolean};
+
+    constructor(
+        private modal: NgbModal,
+        private evt: EventService,
+        private org: OrgService,
+        private net: NetService,
+        private pcrud: PcrudService,
+        private auth: AuthService
+    ) { super(modal); }
+
+    ngOnInit() {
+    }
+
+    selectionChanged() {
+        this.selectedBarcode = Object.keys(this.inputs)
+            .filter(barcode => this.inputs[barcode] === true)[0];
+    }
+
+    // Returns promise of barcode
+    // When multiple barcodes match, the user is asked to select one.
+    // Returns promise of null if no match is found or the user cancels
+    // the selection process.
+    getBarcode(class_: 'asset' | 'actor', barcode: string): Promise<string> {
+        this.barcodes = [];
+        this.inputs = {};
+
+       let promise = this.net.request(
+            'open-ils.actor',
+            'open-ils.actor.get_barcodes',
+            this.auth.token(), this.auth.user().ws_ou(),
+            class_, barcode.trim()
+        ).toPromise();
+
+        promise = promise.then(results => {
+
+            if (!results) { return null; }
+
+            results.forEach(result => {
+                if (!this.evt.parse(result)) {
+                    this.barcodes.push(result.barcode);
+                }
+            });
+
+            if (this.barcodes.length === 0) {
+                return null;
+            } else if (this.barcodes.length === 1) {
+                return this.barcodes[0];
+            } else {
+                return this.open().toPromise();
+            }
+        });
+
+        return promise;
+    }
+}
+
diff --git a/Open-ILS/src/eg2/src/app/staff/share/barcodes/barcodes.module.ts b/Open-ILS/src/eg2/src/app/staff/share/barcodes/barcodes.module.ts
new file mode 100644 (file)
index 0000000..fba4c83
--- /dev/null
@@ -0,0 +1,19 @@
+import {NgModule} from '@angular/core';
+import {StaffCommonModule} from '@eg/staff/common.module';
+import {BarcodeSelectComponent} from './barcode-select.component';
+
+@NgModule({
+    declarations: [
+        BarcodeSelectComponent
+    ],
+    imports: [
+        StaffCommonModule
+    ],
+    exports: [
+        BarcodeSelectComponent
+    ],
+    providers: [
+    ]
+})
+
+export class BarcodesModule {}
index 5939cca..9487c68 100644 (file)
@@ -18,6 +18,7 @@ export class PatronService {
         private auth: AuthService
     ) {}
 
+    // TODO import barcodes.module instead
     bcSearch(barcode: string): Observable<any> {
         return this.net.request(
             'open-ils.actor',