LP1840773 SCKO Angular
authorBill Erickson <berickxx@gmail.com>
Tue, 28 Jun 2022 21:53:25 +0000 (17:53 -0400)
committerBill Erickson <berickxx@gmail.com>
Tue, 28 Jun 2022 21:53:25 +0000 (17:53 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/scko/checkout.component.html
Open-ILS/src/eg2/src/app/scko/checkout.component.ts
Open-ILS/src/eg2/src/app/scko/items.component.ts
Open-ILS/src/eg2/src/app/scko/scko.component.html
Open-ILS/src/eg2/src/app/scko/scko.service.ts

index 42df0f4..a402970 100644 (file)
@@ -1,3 +1,9 @@
+<div class="d-flex">
+  <div class="flex-1"></div>
+  <div>
+    <button class="btn btn-outline-dark" (click)="printList()" i18n>Print List</button>
+  </div>
+</div>
 <div id='oils-selfck-circ-table-div'>
   <table id='oils-selfck-circ-table' class='oils-selfck-item-table'>
     <thead>
       </tr>
     </thead>
     <tbody id='oils-selfck-circ-out-tbody' class='oils-selfck-item-table'>
+           <tr *ngFor="let co of scko.sessionCheckouts">
+        <td>
+          <ng-container *ngIf="co.circ">
+            <img src="/opac/extras/ac/jacket/small/r/{{co.circ.target_copy().call_number().record().id()}}"/>
+          </ng-container>
+        </td>
+        <td><span *ngIf="co.circ">{{cocirc.target_copy().barcode()}}</span></td>
+        <td>{{getTitle(circ)}}</td>
+        <td>{{getAuthor(circ)}}</td>
+        <td><span *ngIf="co.circ">{{co.circ | egDueDate}}</span></td>
+        <td><span *ngIf="co.circ">{{co.circ.renewal_remaining()}}</span></td>
+        <td>
+          <ng-container *ngIf="co.circ">
+            <span *ngIf="co.circ.parent_circ()" i18n>Renewal</span>
+            <span *ngIf="!co.circ.parent_circ()" i18n>Checkout</span>
+          </ng-container>
+        </td>
+      </tr>
     </tbody>
   </table>
 </div>
index 89ff3d3..483978a 100644 (file)
@@ -1,6 +1,7 @@
 import {Component, OnInit, ViewEncapsulation} from '@angular/core';
 import {Router, ActivatedRoute, NavigationEnd} from '@angular/router';
 import {AuthService} from '@eg/core/auth.service';
+import {IdlObject} from '@eg/core/idl.service';
 import {SckoService} from './scko.service';
 import {ServerStoreService} from '@eg/core/server-store.service';
 
@@ -18,5 +19,25 @@ export class SckoCheckoutComponent implements OnInit {
 
     ngOnInit() {
     }
+
+    displayValue(circ: IdlObject, field: string): string {
+        const entry =
+            circ.target_copy().call_number().record().flat_display_entries()
+            .filter(e => e.name() === field)[0];
+
+        return entry ? entry.value() : '';
+    }
+
+    getTitle(circ: IdlObject): string {
+        if (!circ) { return ''; }
+        const copy = circ.target_copy();
+        return this.displayValue(circ, 'title');
+    }
+
+    getAuthor(circ: IdlObject): string {
+        if (!circ) { return ''; }
+        const copy = circ.target_copy();
+        return this.displayValue(circ, 'author');
+    }
 }
 
index a4e3d8f..bd759e8 100644 (file)
@@ -9,14 +9,6 @@ import {SckoService} from './scko.service';
 import {ServerStoreService} from '@eg/core/server-store.service';
 import {PrintService} from '@eg/share/print/print.service';
 
-const CIRC_FLESH_DEPTH = 4;
-const CIRC_FLESH_FIELDS = {
-  circ: ['target_copy'],
-  acp:  ['call_number'],
-  acn:  ['record'],
-  bre:  ['flat_display_entries']
-};
-
 @Component({
   templateUrl: 'items.component.html'
 })
@@ -51,15 +43,7 @@ export class SckoItemsComponent implements OnInit {
 
         .then(data => {
             const ids = data.out.concat(data.overdue).concat(data.long_overdue);
-
-            return this.pcrud.search('circ', {id: ids}, {
-                flesh: CIRC_FLESH_DEPTH,
-                flesh_fields: CIRC_FLESH_FIELDS,
-                order_by : {circ : 'due_date'},
-
-                select: {bre : ['id']}
-
-            }).pipe(tap(circ => {
+            return this.scko.getFleshedCircs(ids).pipe(tap(circ => {
                 this.circs.push(circ);
             })).toPromise();
         });
index 20da9a7..97098d6 100644 (file)
   text="Item was not found in the system. Try re-scanning the item."></eg-string>
 <eg-string i18n-text key="scko.checkout.already_out" 
   text="Item is checked out to another patron"></eg-string>
-<eg-string i18n-text key="scko.error.max_renewals"
-  text="No more renewals allowed for item {{barcode}}"></eg-string>
 
-<eg-string i18n-text key="scko.error.patron_fines"
+<ng-template #maxRenew>No more renewals allowed for item {{barcode}}</ng-template>
+<eg-string i18n-text key="scko.error.max_renewals" [template]="maxRenew"></eg-string>
+
+<eg-string key="scko.error.patron_fines"
   text="This account has too many fines to checkout."></eg-string>
 
-<eg-string i18n-text key="scko.error.item_not_cataloged"
-  text="Item {{barcode}} was not found in the system.  Try re-scanning the item."></eg-string>
+<ng-template #itemNotCataloged>
+  Item {{barcode}} was not found in the system.  Try re-scanning the item.
+</ng-template>
+<eg-string key="scko.error.item_not_cataloged" [template]="itemNotCataloged"> </eg-string>
+
+
+<ng-template #copyCircNotAllowed>
+  Item {{barcode}} is not allowed to circulate</ng-template>
+<eg-string key="scko.error.copy_circ_not_allowed" [template]="copyCircNotAllowed">
+</eg-string>
 
-<eg-string i18n-text key="scko.error.copy_circ_not_allowed"
-  text="Item {{barcode}} is not allowed to circulate"></eg-string>
 <eg-string i18n-text key="scko.error.actor_usr_barred" 
   text="The patron is barred"></eg-string>
 <eg-string i18n-text key="scko.error.asset_copy_circulate" 
@@ -97,5 +104,3 @@ text="The item's circulation library does not fulfill holds"></eg-string>
   text="The item cannot transit this far"></eg-string>
 
 
-
-
index 0cae316..4dfdaec 100644 (file)
@@ -1,5 +1,6 @@
 import {Injectable, EventEmitter} from '@angular/core';
 import {Router, ActivatedRoute, NavigationEnd} from '@angular/router';
+import {Observable} from 'rxjs';
 import {OrgService} from '@eg/core/org.service';
 import {NetService} from '@eg/core/net.service';
 import {AuthService} from '@eg/core/auth.service';
@@ -12,6 +13,7 @@ import {AlertDialogComponent} from '@eg/share/dialog/alert.component';
 import {PrintService} from '@eg/share/print/print.service';
 import {AudioService} from '@eg/share/util/audio.service';
 import {StringService} from '@eg/share/string/string.service';
+import {PcrudService} from '@eg/core/pcrud.service';
 
 interface CheckoutContext {
     barcode: string; // item
@@ -28,6 +30,19 @@ interface CheckoutContext {
     renewalFailure?: boolean;
 }
 
+interface SessionCheckout {
+    circ: IdlObject,
+    ctx: CheckoutContext
+}
+
+const CIRC_FLESH_DEPTH = 4;
+const CIRC_FLESH_FIELDS = {
+  circ: ['target_copy'],
+  acp:  ['call_number'],
+  acn:  ['record'],
+  bre:  ['flat_display_entries']
+};
+
 @Injectable({providedIn: 'root'})
 export class SckoService {
 
@@ -48,7 +63,7 @@ export class SckoService {
     overrideCheckoutEvents: string[] = [];
     blockStatuses: number[] = [];
 
-    sessionCheckouts: any[] = [];
+    sessionCheckouts: SessionCheckout[] = [];
 
     // We get this from the main scko component.
     logoutDialog: ConfirmDialogComponent;
@@ -62,6 +77,7 @@ export class SckoService {
         private net: NetService,
         private evt: EventService,
         public auth: AuthService,
+        private pcrud: PcrudService,
         private printer: PrintService,
         private audio: AudioService,
         private strings: StringService,
@@ -136,6 +152,19 @@ export class SckoService {
         });
     }
 
+    getFleshedCircs(circIds: number[]): Observable<IdlObject> {
+        return this.pcrud.search('circ', {id: circIds}, {
+            flesh: CIRC_FLESH_DEPTH,
+            flesh_fields: CIRC_FLESH_FIELDS,
+            order_by : {circ : 'due_date'},
+            select: {bre : ['id']}
+        });
+    }
+
+    getFleshedCirc(circId: number): Promise<IdlObject> {
+        return this.getFleshedCircs([circId]).toPromise();
+    }
+
     loadPatron(username: string, password?: string): Promise<any> {
         this.resetPatron();
 
@@ -308,7 +337,7 @@ export class SckoService {
     }
 
     notifyPatron(ctx: CheckoutContext) {
-        console.debug("notifyPatron()", ctx);
+        console.debug('notifyPatron(): ', ctx);
 
         this.statusDisplayText = '';
 
@@ -316,6 +345,8 @@ export class SckoService {
 
         this.focusBarcode.emit();
 
+        // TODO on success tell the summary to update its numbers.
+
         if (this.alertAudio && ctx.alertSound) {
             this.audio.play(ctx.alertSound);
         }
@@ -364,7 +395,13 @@ export class SckoService {
         if (evt.textcode === 'SUCCESS') {
             ctx.displayText = `scko.${action}.success`;
             ctx.alertSound = `success.scko.${action}`;
-            return Promise.resolve(ctx);
+
+            return this.getFleshedCirc(payload.circ.id()).then(
+                circ => {
+                    this.sessionCheckouts.push({circ: circ, ctx: ctx});
+                    return ctx;
+                }
+            );
         }
 
         if (evt.textcode === 'OPEN_CIRCULATION_EXISTS' && action === 'checkout') {
@@ -420,7 +457,7 @@ export class SckoService {
         [].concat(ctx.result).some(res => {
 
             if (!this.overrideCheckoutEvents.includes(res.textcode)) {
-                console.debug("We are not configured to override", res.textcode);
+                console.debug('We are not configured to override', res.textcode);
                 lastErrorText = this.getErrorDisplyText(this.evt.parse(res));
                 return override = false;
             }
@@ -481,7 +518,7 @@ export class SckoService {
             default:
                 if (evt.payload && evt.payload.fail_part) {
                     return 'scko.error.' +
-                        evt.payload.fail_part.replace(/\./g, "_");
+                        evt.payload.fail_part.replace(/\./g, '_');
                 }
         }