LPXXX Item Status Angular WIP
authorBill Erickson <berickxx@gmail.com>
Mon, 21 Jun 2021 15:14:08 +0000 (11:14 -0400)
committerBill Erickson <berickxx@gmail.com>
Tue, 29 Jun 2021 20:31:33 +0000 (16:31 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/cat/item/status.component.html
Open-ILS/src/eg2/src/app/staff/cat/item/summary.component.html
Open-ILS/src/eg2/src/app/staff/cat/item/summary.component.ts

index ba0a811..9c91bd7 100644 (file)
@@ -23,7 +23,7 @@
 
 <div *ngIf="tab != 'list' && item">
 
-  <div class="mt-2 mb-2">
+  <div class="mt-2 mb-4">
     <eg-bib-summary [recordId]="item.call_number().record().id()">
     </eg-bib-summary>
   </div>
index 47c18a4..8be3f98 100644 (file)
@@ -2,7 +2,7 @@
   This item has been marked as Deleted.
 </div>
 
-<div class="well-table">
+<div class="well-table" *ngIf="item && !loading">
 
   <div class="well-row" *ngIf="item.dummy_title() || item.dummy_author()">
     <div class="well-label" *ngIf="item.dummy_title()" i18n>Precat Title</div>
     <div class="well-value">{{item.call_number().label()}}</div>
 
     <div class="well-label" i18n>Due Date</div>
-    <div class="well-value">{{circ.due_date() | date:'shortDate'}}</div>
+    <div class="well-value">
+      <ng-container *ngIf="circ">
+        {{circ.due_date() | date:'shortDate'}}
+      </ng-container>
+    </div>
   </div>
 
   <div class="well-row">
     </div>
 
     <div class="well-label" i18n>Checkout Date</div>
-    <div class="well-value">{{circSummary.start_time() | date:'shortDate'}}</div>
+    <div class="well-value">
+      <ng-container *ngIf="circ">
+        {{circSummary.start_time() | date:'shortDate'}}
+      </ng-container>
+    </div>
   </div>
 
   <div class="well-row">
 
     <div class="well-label" i18n>Renewal Type</div>
     <div class="well-value">
-      <div *ngIf="circ.opac_renewal() == 't'" i18n>OPAC</div>
-      <div *ngIf="circ.desk_renewal() == 't'" i18n>Desk</div>
-      <div *ngIf="circ.phone_renewal() == 't'" i18n>Phone</div>
-      <div *ngIf="circ.auto_renewal() == 't'" i18n>Automatic</div>
+      <ng-container *ngIf="circ">
+        <div *ngIf="circ.opac_renewal() == 't'" i18n>OPAC</div>
+        <div *ngIf="circ.desk_renewal() == 't'" i18n>Desk</div>
+        <div *ngIf="circ.phone_renewal() == 't'" i18n>Phone</div>
+        <div *ngIf="circ.auto_renewal() == 't'" i18n>Automatic</div>
+      </ng-container>
     </div>
 
     <div class="well-label" i18n>Checkout Workstation</div>
-    <div class="well-value">{{circSummary.checkout_workstation()}}</div>
+    <div class="well-value">
+      <ng-container *ngIf="circ">
+        {{circSummary.checkout_workstation()}}
+      </ng-container>
+    </div>
   </div>
 
   <div class="well-row">
     <div class="well-value">{{total_circs}}</div>
 
     <div class="well-label" i18n>Duration Rule</div>
-    <div class="well-value">{{circ.duration_rule().name()}}</div>
+    <div class="well-value">
+      <ng-container *ngIf="circ">
+        {{circ.duration_rule().name()}}
+      </ng-container>
+    </div>
   </div>
 
   <div class="well-row">
     <div class="well-value">{{item.active_date() | date:'shortDate'}}</div>
 
     <div class="well-label" i18n>Reference</div>
-    <div class="well-value">{{item.ref()}}</div>
+    <div class="well-value"><eg-bool [value]="item.ref()"></eg-bool></div>
 
     <div class="well-label" i18n>Total Circs - Current Year</div>
     <div class="well-value">{{total_circs_this_year}}</div>
 
     <div class="well-label" i18n>Recurring Fine Rule</div>
-    <div class="well-value">{{circ.recurring_fine_rule().name()}}</div>
+    <div class="well-value">
+      <ng-container *ngIf="circ">
+        {{circ.recurring_fine_rule().name()}}
+      </ng-container>
+    </div>
   </div>
 
   <div class="well-row">
     <div class="well-value">{{item.status_changed_time() | date:'shortDate'}}</div>
 
     <div class="well-label" i18n>OPAC Visible</div>
-    <div class="well-value">{{item.opac_visible()}}</div>
+    <div class="well-value"><eg-bool [value]="item.opac_visible()"></eg-bool></div>
 
     <div class="well-label" i18n>Total Circs - Prev Year</div>
     <div class="well-value">{{total_circs_prev_year}}</div>
 
     <div class="well-label" i18n>Max Fine Rule</div>
-    <div class="well-value">{{circ.max_fine_rule().name()}}</div>
+    <div class="well-value">
+      <ng-container *ngIf="circ">
+        {{circ.max_fine_rule().name()}}
+      </ng-container>
+    </div>
   </div>
 
   <div class="well-row">
     <div class="well-value">{{item.id()}}</div>
 
     <div class="well-label" i18n>Holdable</div>
-    <div class="well-value">{{item.holdable()}}</div>
+    <div class="well-value"><eg-bool [value]="item.holdable()"></eg-bool></div>
 
     <div class="well-label" i18n>In-House Uses</div>
     <div class="well-value">{{item._inHouseUseCount}}</div>
 
     <div class="well-label" i18n>Checkin Time</div>
     <div class="well-value">
-      {{circ.checkin_time() || 
-        circSummary.last_checkin_time() | date:'shortDate'}}
+      <ng-container *ngIf="circ">
+        {{circ.checkin_time() || 
+          circSummary.last_checkin_time() | date:'shortDate'}}
+      </ng-container>
     </div>
   </div>
 
   <div class="well-row">
     <div class="well-label" i18n>Circulate</div>
-    <div class="well-value">{{item.circulate()}}</div>
+    <div class="well-value"><eg-bool [value]="item.circulate()"></eg-bool></div>
 
     <div class="well-label" i18n>Renewal Workstation</div>
-    <div class="well-value">{{circSummary.last_renewal_workstation()}}</div>
+    <div class="well-value">
+      <ng-container *ngIf="circ">
+        {{circSummary.last_renewal_workstation()}}
+      </ng-container>
+    </div>
 
     <div class="well-label" i18n>Remaining Renewals</div>
-    <div class="well-value">{{circ.renewal_remaining()}}</div>
+    <div class="well-value">
+      <ng-container *ngIf="circ">
+        {{circ.renewal_remaining()}}
+      </ng-container>
+    </div>
 
     <div class="well-label" i18n>Checkin Scan Time</div>
     <div class="well-value">
-      {{circ.checkin_scan_time() || 
-        circSummary.last_checkin_scan_time() | date:'shortDate'}}
+      <ng-container *ngIf="circ">
+        {{circ.checkin_scan_time() || 
+          circSummary.last_checkin_scan_time() | date:'shortDate'}}
+      </ng-container>
     </div>
   </div>
 
 
     <div class="well-label" i18n>Checkin Workstation</div>
     <div class="well-value">
-      {{circ.checkin_workstation().name() || 
-        circSummary.last_checkin_workstation().name()}}
+      <ng-container *ngIf="circ">
+        <ng-container *ngIf="circ.checkin_workstation()">
+          {{circ.checkin_workstation().name()}}
+        </ng-container>
+        <ng-container 
+          *ngIf="!circ.checkin_workstation() && circSummary.last_checkin_workstation()">
+          {{circSummary.last_checkin_workstation().name()}}
+        </ng-container>
+      </ng-container>
     </div>
   </div>
 
   <div class="well-row">
     <div class="well-label" i18n>Inventory Date</div>
-    <div class="well-value">{{item.latest_inventory().inventory_date() | date:'shortDate'}}</div>
+    <div class="well-value">
+      <ng-container *ngIf="item.latest_inventory()">
+        {{item.latest_inventory().inventory_date() | date:'shortDate'}}
+      </ng-container>
+    </div>
 
     <div class="well-label" i18n>Inventory Workstation</div>
-    <div class="well-value">{{item.latest_inventory().inventory_workstation().name()}}</div>
+    <div class="well-value">
+      <ng-container *ngIf="item.latest_inventory()">
+        {{item.latest_inventory().inventory_workstation().name()}}
+      </ng-container>
+    </div>
 
     <div class="well-label"></div>
     <div class="well-value"></div>
   <div class="well-row">
     <div class="well-label" i18n>Item Alerts</div>
     <div class="well-value" id="item-status-alert-msg">
-      <button class="btn btn-default" ng-click="additemAlerts(item.id())"  i18n>Add</button>
-      <button class="btn btn-default" ng-disabled="!item_alert_count" ng-click="manageitemAlerts(item.id())"  i18n>Manage</button>
+      <button class="btn btn-outline-dark" (click)="addItemAlerts()" i18n>Add</button>
+      <button class="btn btn-outline-dark" [disabled]="item.copy_alerts().length == 0"
+        (click)="manageitemAlerts()"  i18n>Manage</button>
     </div>
-    <!-- hack to adjust positioning -->
+
+    <!-- maintain positioning -->
     <div class="well-label"></div>
     <div class="well-value"></div>
     <div class="well-label"></div>
index ea9e6db..8f6379e 100644 (file)
@@ -4,9 +4,11 @@ import {IdlService, IdlObject} from '@eg/core/idl.service';
 import {PcrudService} from '@eg/core/pcrud.service';
 import {AuthService} from '@eg/core/auth.service';
 import {NetService} from '@eg/core/net.service';
+import {OrgService} from '@eg/core/org.service';
 import {PrintService} from '@eg/share/print/print.service';
 import {HoldingsService} from '@eg/staff/share/holdings/holdings.service';
 import {EventService} from '@eg/core/event.service';
+import {PermService} from '@eg/core/perm.service';
 import {PatronPenaltyDialogComponent} from '@eg/staff/share/patron/penalty-dialog.component';
 import {BarcodeSelectComponent} from '@eg/staff/share/barcodes/barcode-select.component';
 import {CatalogService} from '@eg/share/catalog/catalog.service';
@@ -22,31 +24,116 @@ export class ItemSummaryComponent implements OnInit {
 
     circ: IdlObject;
     circSummary: IdlObject;
+    prevCircSummary: IdlObject;
+    prevCircUser: IdlObject;
+    maxHistoryCount: number;
+    loading = false;
 
     constructor(
         private router: Router,
         private route: ActivatedRoute,
         private net: NetService,
+        private org: OrgService,
         private printer: PrintService,
         private pcrud: PcrudService,
         private auth: AuthService,
+        private perms: PermService,
         private idl: IdlService,
         private evt: EventService,
         private cat: CatalogService,
         private holdings: HoldingsService
     ) {
-        // Create dummy objects so we can avoid a lot of *ngIf's in the template
-        this.circ = this.idl.create('circ');
-        this.circSummary = this.idl.create('accs');
-        this.circ.duration_rule(this.idl.create('crcd'));
-        this.circ.recurring_fine_rule(this.idl.create('crrf'));
-        this.circ.max_fine_rule(this.idl.create('crmf'));
     }
 
     ngOnInit() {
+        this.loading = true;
+        this.loadCircInfo()
+        .then(_ => this.loading = false);
+    }
+
+    loadCircInfo(): Promise<any> {
+
+        const copyOrg =
+            this.item.call_number().id() == -1 ?
+            this.item.circ_lib().id() :
+            this.item.call_number().owning_lib().id();
+
+        return this.perms.hasWorkPermAt(['VIEW_COPY_CHECKOUT_HISTORY'], copyOrg)
+        .then(hasPerm => {
+            if (hasPerm) {
+                return this.org.settings('circ.item_checkout_history.max')
+                .then(sets => {
+                    this.maxHistoryCount = sets['circ.item_checkout_history.max'] || 4;
+                })
+            }
+        })
+        .then(_ => {
+
+            return this.pcrud.search('aacs',
+                {target_copy : this.item.id()},
+                {   flesh: 2,
+                    flesh_fields: {
+                        aacs: [
+                            'usr',
+                            'workstation',
+                            'checkin_workstation',
+                            'duration_rule',
+                            'max_fine_rule',
+                            'recurring_fine_rule'
+                        ],
+                        au: ['card']
+                    },
+                    order_by: {aacs: 'xact_start desc'},
+                    limit:  1
+                }
+
+            ).toPromise();
+        })
+
+        .then(circ => {
+            this.circ = circ;
+
+            if (!circ) return Promise.resolve();
+
+            // load the chain for this circ
+            return this.net.request(
+                'open-ils.circ',
+                'open-ils.circ.renewal_chain.retrieve_by_circ.summary',
+                this.auth.token(), this.circ.id()
+            ).toPromise().then(summary => {
+                this.circSummary = summary
+
+                if (this.maxHistoryCount <= 1) { return; }
 
+                // load the chain for the previous circ, plus the user
+
+                return this.net.request(
+                    'open-ils.circ',
+                    'open-ils.circ.prev_renewal_chain.retrieve_by_circ.summary',
+                    this.auth.token(), this.circ.id()
+
+                ).toPromise().then(summary => {
+                    if (!summary) { return; }
+
+                    this.prevCircSummary = summary.summary;
+
+                    if (summary.usr) { // aged circs have no 'usr'.
+
+                        return this.pcrud.retrieve('au', summary.usr,
+                            {flesh : 1, flesh_fields : {au : ['card']}})
+                        .toPromise().then(user => this.prevCircUser = user);
+                    }
+                });
+            });
+        });
     }
 
 
+    addItemAlerts() {
+    }
+
+    manageItemAlerts() {
+    }
+
 }