-<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>
+
+
<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>
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,
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;
+ });
}
}
<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"/>