attr sets: implement provider count and view providers
authorGalen Charlton <gmc@equinoxinitiative.org>
Sat, 27 Mar 2021 22:47:49 +0000 (18:47 -0400)
committerGalen Charlton <gmc@equinoxinitiative.org>
Sat, 27 Mar 2021 22:53:26 +0000 (18:53 -0400)
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers-dialog.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers-dialog.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-sets.component.html
Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-sets.component.ts
Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-sets.module.ts

diff --git a/Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers-dialog.component.html
new file mode 100644 (file)
index 0000000..6fe8524
--- /dev/null
@@ -0,0 +1,16 @@
+<ng-template #dialogContent>
+  <div class="modal-header bg-info">
+    <h3 class="modal-title" i18n>Attribute Set {{attrSet?.label()}}: Providers</h3>
+    <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">
+    <eg-edi-attr-set-providers [attrSetId]="attrSetId"></eg-edi-attr-set-providers>
+  </div>
+  <div class="modal-footer">
+    <button type="button" class="btn btn-warning" *ngIf="!canUpdate"
+      (click)="close()" i18n>Close</button>
+  </div>
+</ng-template>
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers-dialog.component.ts
new file mode 100644 (file)
index 0000000..fad5b63
--- /dev/null
@@ -0,0 +1,41 @@
+import {Component, Input, ViewChild, TemplateRef, OnInit} from '@angular/core';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+import {NgForm} from '@angular/forms';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {EventService} from '@eg/core/event.service';
+import {NetService} from '@eg/core/net.service';
+import {AuthService} from '@eg/core/auth.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {Pager} from '@eg/share/util/pager';
+import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+import {StringComponent} from '@eg/share/string/string.component';
+import {ToastService} from '@eg/share/toast/toast.service';
+import {PermService} from '@eg/core/perm.service';
+import {EdiAttrSetProvidersComponent} from './edi-attr-set-providers.component';
+
+@Component({
+  selector: 'eg-edi-attr-set-providers-dialog',
+  templateUrl: './edi-attr-set-providers-dialog.component.html'
+})
+
+export class EdiAttrSetProvidersDialogComponent
+  extends DialogComponent implements OnInit {
+
+    @Input() attrSetId: number;
+
+    constructor(
+        private idl: IdlService,
+        private evt: EventService,
+        private net: NetService,
+        private auth: AuthService,
+        private pcrud: PcrudService,
+        private perm: PermService,
+        private toast: ToastService,
+        private modal: NgbModal
+    ) {
+        super(modal);
+    }
+
+    ngOnInit() { }
+
+}
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers.component.html b/Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers.component.html
new file mode 100644 (file)
index 0000000..ff641cb
--- /dev/null
@@ -0,0 +1,11 @@
+<eg-grid #grid [dataSource]="dataSource"
+  [sortable]="true" persistKey="disabled"
+  [filterable]="true" [stickyHeader]="true"
+  [disableSelect]="true">
+  <ng-template #nameTmpl let-row="row">
+    <a href="/eg2/staff/acq/provider/{{row.id()}}/edi_accounts" target="_blank">{{row.name()}}</a>
+  </ng-template>
+  <eg-grid-column path="name" i18n-label label="Provider Name" [cellTemplate]="nameTmpl"></eg-grid-column>
+  <eg-grid-column path="owner" i18n-label label="Owning Library" datatype="org_unit"></eg-grid-column>
+  <eg-grid-column path="id" i18n-label label="ID" [hidden]="true" [index]="true"></eg-grid-column>
+</eg-grid>
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/acq/edi_attr_set/edi-attr-set-providers.component.ts
new file mode 100644 (file)
index 0000000..ce631ec
--- /dev/null
@@ -0,0 +1,94 @@
+import {Component, Input, ViewChild, TemplateRef, OnInit} from '@angular/core';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+import {NgForm} from '@angular/forms';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {EventService} from '@eg/core/event.service';
+import {NetService} from '@eg/core/net.service';
+import {AuthService} from '@eg/core/auth.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {GridDataSource} from '@eg/share/grid/grid';
+import {GridComponent} from '@eg/share/grid/grid.component';
+import {Pager} from '@eg/share/util/pager';
+import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+import {StringComponent} from '@eg/share/string/string.component';
+import {ToastService} from '@eg/share/toast/toast.service';
+import {PermService} from '@eg/core/perm.service';
+
+@Component({
+  selector: 'eg-edi-attr-set-providers',
+  templateUrl: './edi-attr-set-providers.component.html'
+})
+
+export class EdiAttrSetProvidersComponent
+  extends DialogComponent implements OnInit {
+
+    @Input() attrSetId: number;
+    @ViewChild('grid', { static: false }) grid: GridComponent;
+    attrSet: IdlObject;
+    dataSource: GridDataSource;
+
+    constructor(
+        private idl: IdlService,
+        private evt: EventService,
+        private net: NetService,
+        private auth: AuthService,
+        private pcrud: PcrudService,
+        private perm: PermService,
+        private toast: ToastService,
+        private modal: NgbModal
+    ) {
+        super(modal);
+        this.dataSource = new GridDataSource();
+    }
+
+    ngOnInit() {
+        this.attrSet = null;
+        this._initRecord();
+    }
+
+    private _initRecord() {
+        this.attrSet = null;
+        let providerIds = [];
+        this.pcrud.retrieve('aeas', this.attrSetId, {
+            flesh: 1,
+            flesh_fields: { aeas: ['edi_accounts'] }
+        }).subscribe(res => {
+            this.attrSet = res;
+            providerIds = res.edi_accounts().map(r => r.provider());
+            this.dataSource.getRows = (pager: Pager, sort: any[]) => {
+
+                const idlClass = 'acqpro';
+                const orderBy: any = {};
+                if (sort.length) {
+                    // Sort specified from grid
+                    orderBy[idlClass] = sort[0].name + ' ' + sort[0].dir;
+                }
+
+                const searchOps = {
+                    offset: pager.offset,
+                    limit: pager.limit,
+                    order_by: orderBy,
+                    flesh: 1,
+                    flesh_fields: {
+                        acqpro: ['owner']
+                    }
+                };
+                const reqOps = { };
+
+                const search: any = new Array();
+                search.push({ id: providerIds });
+                const orgFilter: any = {};
+
+                Object.keys(this.dataSource.filters).forEach(key => {
+                    Object.keys(this.dataSource.filters[key]).forEach(key2 => {
+                        search.push(this.dataSource.filters[key][key2]);
+                    });
+                });
+
+                return this.pcrud.search(idlClass, search, searchOps, reqOps);
+            };
+            this.grid.reload();
+        });
+    }
+
+}
index c03cb68..3a36c23 100644 (file)
   </eg-grid-toolbar-action>
 
   <eg-grid-column path="label"></eg-grid-column>
+  <eg-grid-column i18n-label label="# Providers Using Attribute Set" path="num_providers" name="num_providers"></eg-grid-column>
+  <ng-template #ediAttrSetProvidersTmpl let-attrSet="row">
+    <button class="btn btn-outline-secondary" (click)="openEdiAttrSetProvidersDialog(attrSet.id())" [disabled]="attrSet.num_providers < 1" i18n>View Providers</button>
+  </ng-template>
+  <eg-grid-column i18n-label label="View Providers" name="view_providers" [cellTemplate]="ediAttrSetProvidersTmpl"></eg-grid-column>
   <eg-grid-column path="id" [hidden]="true"></eg-grid-column>
 
 
@@ -74,3 +79,5 @@
     [preloadLinkedValues]="true"
     [readonlyFields]="readonlyFields">
 </eg-fm-record-editor>
+
+<eg-edi-attr-set-providers-dialog #ediAttrSetProvidersDialog></eg-edi-attr-set-providers-dialog>
index 6deea86..22b662b 100644 (file)
@@ -13,7 +13,9 @@ import {OrgService} from '@eg/core/org.service';
 import {PermService} from '@eg/core/perm.service';
 import {AuthService} from '@eg/core/auth.service';
 import {NetService} from '@eg/core/net.service';
-import {StringComponent} from '@eg/share/string/string.component';
+import {Observable, of} from 'rxjs';
+import {map, mergeMap} from 'rxjs/operators';
+import {EdiAttrSetProvidersDialogComponent} from './edi-attr-set-providers-dialog.component';
 
 @Component({
     templateUrl: './edi-attr-sets.component.html'
@@ -24,6 +26,7 @@ export class EdiAttrSetsComponent extends AdminPageComponent implements OnInit {
     classLabel: string;
 
     @ViewChild('grid', { static: true }) grid: GridComponent;
+    @ViewChild('ediAttrSetProvidersDialog', { static: false }) ediAttrSetProvidersDialog: EdiAttrSetProvidersDialogComponent;
 
     cellTextGenerator: GridCellTextGenerator;
 
@@ -45,9 +48,11 @@ export class EdiAttrSetsComponent extends AdminPageComponent implements OnInit {
 
     ngOnInit() {
         this.cellTextGenerator = {
-            name: row => row.name()
+            name: row => row.name(),
+            view_providers: row => '',
+            num_providers: row => '',
         };
-        this.fieldOrder = 'name,code,year,org,active,currency_type,balance_stop_percentage,balance_warning_percentage,propagate,rollover';
+        this.fieldOrder = 'label';
         this.defaultNewRecord = this.idl.create('aeas');
 
         this.dataSource.getRows = (pager: Pager, sort: any[]) => {
@@ -63,16 +68,19 @@ export class EdiAttrSetsComponent extends AdminPageComponent implements OnInit {
             const searchOps = {
                 offset: pager.offset,
                 limit: pager.limit,
-                order_by: orderBy
-            };
-            const reqOps = {
-                fleshSelectors: true,
+                order_by: orderBy,
+                flesh: 1,
+                flesh_fields: {
+                    aeas: ['edi_accounts']
+                }
             };
+            const reqOps = { };
 
             if (!this.contextOrg && !Object.keys(this.dataSource.filters).length) {
                 // No org filter -- fetch all rows
                 return this.pcrud.retrieveAll(
-                    this.idlClass, searchOps, reqOps);
+                    this.idlClass, searchOps, reqOps)
+                   .pipe(mergeMap((row) => this.countProviders(row)));
             }
 
             const search: any = new Array();
@@ -90,8 +98,8 @@ export class EdiAttrSetsComponent extends AdminPageComponent implements OnInit {
                 });
             });
 
-            return this.pcrud.search(
-                this.idlClass, search, searchOps, reqOps);
+            return this.pcrud.search(this.idlClass, search, searchOps, reqOps)
+                   .pipe(mergeMap((row) => this.countProviders(row)));
         };
 
         super.ngOnInit();
@@ -100,4 +108,14 @@ export class EdiAttrSetsComponent extends AdminPageComponent implements OnInit {
         this.includeOrgDescendants = true;
     }
 
+    countProviders(row: IdlObject): Observable<IdlObject> {
+        row['num_providers'] = (new Set( row.edi_accounts().map(r => r.provider()) )).size;
+        return of(row);
+    }
+
+    openEdiAttrSetProvidersDialog(id: number) {
+        this.ediAttrSetProvidersDialog.attrSetId = id;
+        this.ediAttrSetProvidersDialog.open({size: 'lg'});
+    }
+
 }
index 0804e4b..e5fb854 100644 (file)
@@ -3,10 +3,14 @@ import {StaffCommonModule} from '@eg/staff/common.module';
 import {AdminCommonModule} from '@eg/staff/admin/common.module';
 import {EdiAttrSetsRoutingModule} from './routing.module';
 import {EdiAttrSetsComponent} from './edi-attr-sets.component';
+import {EdiAttrSetProvidersDialogComponent} from './edi-attr-set-providers-dialog.component';
+import {EdiAttrSetProvidersComponent} from './edi-attr-set-providers.component';
 
 @NgModule({
   declarations: [
-    EdiAttrSetsComponent
+    EdiAttrSetsComponent,
+    EdiAttrSetProvidersDialogComponent,
+    EdiAttrSetProvidersComponent
   ],
   imports: [
     StaffCommonModule,