LPXXX Patron UI WIP
authorBill Erickson <berickxx@gmail.com>
Fri, 14 Aug 2020 21:24:31 +0000 (17:24 -0400)
committerBill Erickson <berickxx@gmail.com>
Fri, 21 Aug 2020 20:41:27 +0000 (16:41 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/circ/patron/edit.component.html
Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.html
Open-ILS/src/eg2/src/app/staff/circ/patron/patron.service.ts
Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.html

index 035f79c..139597f 100644 (file)
@@ -1,90 +1,2 @@
-<div class="{{contentPaneClass}}">
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-  <div class="row mb-5">
-    <div class="col-lg-12">
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-      ;lkjasd f;laksjdf ;aslkfjas ;flkjasf ;aslkdfjas ;flkjasf ;asdlkj
-    </div>
-  </div>
-</div>
+
+
index 3780ca4..13d1c7b 100644 (file)
       <ul ngbNav #patronNav="ngbNav" class="nav-tabs"
         [activeId]="patronTab" (navChange)="beforeTabChange($event)">
 
-        <li ngbDropdown ngbNavItem="toggle">
-          <a href class="nav-link" (click)="toggleSummaryPane(); false"
-            title="Toggle Summary Pane" i18n-title>
-            <ng-container *ngIf="showSummaryPane()">
-              <span class="material-icons">navigate_before</span>
-            </ng-container>
-            <ng-container *ngIf="!showSummaryPane()">
-              <span class="material-icons">navigate_next</span>
-            </ng-container>
-          </a>
-        </li>
+        <ng-container *ngIf="patronTab !== 'search'">
+          <li ngbDropdown ngbNavItem="toggle">
+            <a href class="nav-link" (click)="toggleSummaryPane(); false"
+              title="Toggle Summary Pane" i18n-title>
+              <ng-container *ngIf="showSummaryPane()">
+                <span class="material-icons">navigate_before</span>
+              </ng-container>
+              <ng-container *ngIf="!showSummaryPane()">
+                <span class="material-icons">navigate_next</span>
+              </ng-container>
+            </a>
+          </li>
+        </ng-container>
 
         <li ngbNavItem="checkout" [disabled]="!context.patron">
           <a ngbNavLink i18n>Checkout</a>
index 258a0e7..ef7c004 100644 (file)
@@ -5,28 +5,49 @@ import {AuthService} from '@eg/core/auth.service';
 import {PatronService} from '@eg/staff/share/patron/patron.service';
 
 const PATRON_FLESH_FIELDS = [
-       'card',
-       'cards',
-       'settings',
-       'standing_penalties',
-       'addresses',
-       'billing_address',
-       'mailing_address',
-       'stat_cat_entries',
-       'waiver_entries',
-       'usr_activity',
-       'notes',
-       'profile',
-       'net_access_level',
-       'ident_type',
-       'ident_type2',
-       'groups'
+    'card',
+    'cards',
+    'settings',
+    'standing_penalties',
+    'addresses',
+    'billing_address',
+    'mailing_address',
+    'stat_cat_entries',
+    'waiver_entries',
+    'usr_activity',
+    'notes',
+    'profile',
+    'net_access_level',
+    'ident_type',
+    'ident_type2',
+    'groups'
 ];
 
+interface PatronStats {
+    fines: {balance_owed: number};
+    checkouts: {
+        overdue: number,
+        claims_returned: number,
+        lost: number,
+        out: number,
+        total_out: number,
+        long_overdue: number
+    };
+}
+
 @Injectable()
 export class PatronManagerService {
 
     patron: IdlObject;
+    patronStats: PatronStats;
+
+    // Value for YAOUS circ.do_not_tally_claims_returned
+    noTallyClaimsReturned = false;
+
+    // Value for YAOUS circ.tally_lost
+    tallyLost = false;
+
+    loaded = false;
 
     constructor(
         private net: NetService,
@@ -34,12 +55,47 @@ export class PatronManagerService {
         public patronService: PatronService
     ) {}
 
-    loadPatron(id: number): Promise<IdlObject> {
-               return this.net.request(
+    loadPatron(id: number): Promise<any> {
+        this.loaded = false;
+        this.patron = null;
+
+        return this.net.request(
             'open-ils.actor',
             'open-ils.actor.user.fleshed.retrieve',
-            this.auth.token(), id, PATRON_FLESH_FIELDS
-        ).toPromise().then(patron => this.patron = patron);
+            this.auth.token(), id, PATRON_FLESH_FIELDS).toPromise()
+        .then(patron => this.patron = patron)
+        .then(_ => this.getPatronStats(id))
+        .then(_ => this.loaded = true);
+    }
+
+   getPatronStats(id: number): Promise<any> {
+
+        return this.net.request(
+            'open-ils.actor',
+            'open-ils.actor.user.opac.vital_stats.authoritative',
+            this.auth.token(), id).toPromise()
+
+        .then((stats: PatronStats) => {
+
+            // force numeric values
+            stats.fines.balance_owed = Number(stats.fines.balance_owed);
+
+            Object.keys(stats.checkouts).forEach(key =>
+                stats.checkouts[key] = Number(stats.checkouts[key]));
+
+            stats.checkouts.total_out = stats.checkouts.out +
+                stats.checkouts.overdue + stats.checkouts.long_overdue
+
+            if (!this.noTallyClaimsReturned) {
+                stats.checkouts.total_out += stats.checkouts.claims_returned;
+            }
+
+            if (this.tallyLost) {
+                stats.checkouts.total_out += stats.checkouts.lost
+            }
+
+            return this.patronStats = stats;
+        });
     }
 }
 
index ecba5a6..d1d0eb7 100644 (file)
 
   <hr class="m-1"/>
 
-  <div class="row mb-1">
-    <div class="col-lg-5" i18n>Fines Owed</div>
-    <div class="col-lg-7">XXXX</div>
-  </div>
-  <div class="row mb-1">
-    <div class="col-lg-5" i18n>Items Out</div>
-    <div class="col-lg-7">XXXX</div>
-  </div>
-  <div class="row mb-1">
-    <div class="col-lg-5" i18n>Overdue</div>
-    <div class="col-lg-7">XXXX</div>
-  </div>
-  <div class="row mb-1">
-    <div class="col-lg-5" i18n>Long Overdue</div>
-    <div class="col-lg-7">XXXX</div>
-  </div>
-  <div class="row mb-1">
-    <div class="col-lg-5" i18n>Claimed Returned</div>
-    <div class="col-lg-7">XXXX</div>
-  </div>
-  <div class="row mb-1">
-    <div class="col-lg-5" i18n>Lost</div>
-    <div class="col-lg-7">XXXX</div>
-  </div>
-  <div class="row mb-1">
-    <div class="col-lg-5" i18n>Non-Cataloged</div>
-    <div class="col-lg-7">XXXX</div>
-  </div>
-  <div class="row">
-    <div class="col-lg-5" i18n>Holds</div>
-    <div class="col-lg-7">XX / YY</div>
-  </div>
+  <ng-container *ngIf="context.patronStats">
 
-  <hr class="m-1"/>
+    <div class="row mb-1">
+      <div class="col-lg-5" i18n>Fines Owed</div>
+      <div class="col-lg-7">{{context.patronStats.fines.total_owed | currency}}</div>
+    </div>
+    <div class="row mb-1">
+      <div class="col-lg-5" i18n>Items Out</div>
+      <div class="col-lg-7">{{context.patronStats.checkouts.total_out}}</div>
+    </div>
+    <div class="row mb-1">
+      <div class="col-lg-5" i18n>Overdue</div>
+      <div class="col-lg-7">{{context.patronStats.checkouts.overdue}}</div>
+    </div>
+    <div class="row mb-1">
+      <div class="col-lg-5" i18n>Long Overdue</div>
+      <div class="col-lg-7">{{context.patronStats.checkouts.long_overdue}}</div>
+    </div>
+    <div class="row mb-1">
+      <div class="col-lg-5" i18n>Claimed Returned</div>
+      <div class="col-lg-7">{{context.patronStats.checkouts.claims_returned}}</div>
+    </div>
+    <div class="row mb-1">
+      <div class="col-lg-5" i18n>Lost</div>
+      <div class="col-lg-7">{{context.patronStats.checkouts.lost}}</div>
+    </div>
+    <div class="row mb-1">
+      <div class="col-lg-5" i18n>Non-Cataloged</div>
+      <div class="col-lg-7">XXXX</div>
+    </div>
+    <div class="row">
+      <div class="col-lg-5" i18n>Holds</div>
+      <div class="col-lg-7">XX / YY</div>
+    </div>
+
+    <hr class="m-1"/>
+  </ng-container>
 
   <div class="row mb-1">
     <div class="col-lg-5" i18n>Card</div>
-    <div class="col-lg-7">XXXXXXXXXX</div>
+    <div class="col-lg-7">
+      {{context.patron.card() ? context.patron.card().barcode() : ''}}
+    </div>
   </div>
   <div class="row mb-1">
     <div class="col-lg-5" i18n>Username</div>
-    <div class="col-lg-7">XXXXXXXXXX</div>
+    <div class="col-lg-7">{{context.patron.usrname()}}</div>
   </div>
   <div class="row mb-1">
     <div class="col-lg-5" i18n>Day Phone</div>
-    <div class="col-lg-7">XXXXXXXXXX</div>
+    <div class="col-lg-7">{{context.patron.day_phone()}}</div> 
   </div>
   <div class="row mb-1">
     <div class="col-lg-5" i18n>Evening Phone</div>
-    <div class="col-lg-7">XXXXXXXXXX</div>
+    <div class="col-lg-7">{{context.patron.evening_phone()}}</div> 
   </div>
   <div class="row mb-1">
     <div class="col-lg-5" i18n>Other Phone</div>
-    <div class="col-lg-7">XXXXXXXXXX</div>
+    <div class="col-lg-7">{{context.patron.other_phone()}}</div> 
   </div>
   <div class="row mb-1">
     <div class="col-lg-5" i18n>ID1 </div>
-    <div class="col-lg-7">XXXXXXXXXX</div>
+    <div class="col-lg-7">{{context.patron.ident_value()}}</div> 
   </div>
   <div class="row mb-1">
     <div class="col-lg-5" i18n>ID2</div>
-    <div class="col-lg-7">XXXXXXXXXX</div>
+    <div class="col-lg-7">{{context.patron.ident_value2()}}</div> 
   </div>
   <div class="row mb-1">
     <div class="col-lg-5" i18n>Email</div>
-    <div class="col-lg-7">XXXXXXXXXX</div>
+    <div class="col-lg-7">
+      <!-- TODO: mailto link -->
+      {{context.patron.email()}}
+    </div> 
   </div>
 
   <hr class="m-1"/>