LP1981739 Patrons Negative Balances Angular Port
authorBill Erickson <berickxx@gmail.com>
Tue, 12 Jul 2022 17:08:50 +0000 (13:08 -0400)
committerJane Sandberg <sandbergja@gmail.com>
Fri, 30 Sep 2022 00:37:24 +0000 (17:37 -0700)
Port Admin => Local Admin => Patrons With Negative Balances to Angular.

Adds paging support to the API.

Adds support for display patrons whose home lib is a descendant of the
selected org unit.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Garry Collum <gcollum@gmail.com>
Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html
Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/list.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/list.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/negative-balances.module.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/routing.module.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/local/routing.module.ts
Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.data.negative-balance-grid.sql [new file with mode: 0644]

index 7ea6416..29e42ef 100644 (file)
@@ -55,7 +55,7 @@
     <eg-link-table-link i18n-label label="OpenAthens Sign-on"
       routerLink="/staff/admin/local/config/openathens_identity"></eg-link-table-link>
     <eg-link-table-link i18n-label label="Patrons with Negative Balances" 
-      url="/eg/staff/admin/local/circ/neg_balance_users"></eg-link-table-link>
+      routerLink="/staff/admin/local/negative-balances"></eg-link-table-link>
     <eg-link-table-link i18n-label label="Permission Tree Display Entries" 
       url="/eg/staff/admin/local/permission/grp_tree_display_entry"></eg-link-table-link>
     <eg-link-table-link i18n-label label="Search Filter Groups" 
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/list.component.html b/Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/list.component.html
new file mode 100644 (file)
index 0000000..2a12e0a
--- /dev/null
@@ -0,0 +1,40 @@
+<eg-staff-banner i18n-bannerText bannerText="Patrons with Negative Balances">
+</eg-staff-banner>
+
+<div class="row mt-2 mb-2">
+  <div class="col-lg-6 form-inline">
+    <span class="pr-2" i18n>Patron Home Library:</span>
+    <eg-org-select
+      persistKey="admin.local.negative_balances"
+      (componentLoaded)="contextOrgLoaded = true"
+      [initialOrg]="contextOrg"
+      (onChange)="orgChnaged($event)">
+    </eg-org-select>
+  </div>
+</div>
+
+<ng-template #barcodeTmpl let-user="row">
+  <a target="_blank" href="/eg/staff/circ/patron/{{user.id()}}/checkout">
+    {{user.card().barcode()}}
+  </a>
+</ng-template>
+
+<eg-grid #grid idlClass="au" [dataSource]="dataSource"
+  persistKey="admin.local.negative_balances"
+  showFields="balance_owed,last_billing_activity,barcode,family_name,first_given_name,dob,barred">
+
+  <eg-grid-column name="barcode" [cellTemplate]="barcodeTmpl"
+    i18n-label label="Barcode"></eg-grid-column>
+
+  <eg-grid-column name="balance_owed" path="_extras.balance_owed"
+    datatype="money" i18n-label label="Balance Owed"></eg-grid-column>
+
+  <eg-grid-column name="last_billing_activity" path="_extras.last_billing_activity"
+    datatype="timestamp" [datePlusTime]="true" i18n-label label="Last Billing Activity">
+  </eg-grid-column>
+</eg-grid>
+
+
+
+
+
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/list.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/list.component.ts
new file mode 100644 (file)
index 0000000..4d89675
--- /dev/null
@@ -0,0 +1,75 @@
+import {Component, Input, ViewChild, OnInit} from '@angular/core';
+import {empty} from 'rxjs';
+import {map, tap, concatMap} from 'rxjs/operators';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {NgbTabset, NgbTabChangeEvent} from '@ng-bootstrap/ng-bootstrap';
+import {OrgService} from '@eg/core/org.service';
+import {AuthService} from '@eg/core/auth.service';
+import {NetService} from '@eg/core/net.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {ToastService} from '@eg/share/toast/toast.service';
+import {StringComponent} from '@eg/share/string/string.component';
+import {StringService} from '@eg/share/string/string.service';
+import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
+import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
+import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+import {GridDataSource, GridColumn, GridRowFlairEntry, GridCellTextGenerator} from '@eg/share/grid/grid';
+import {GridComponent} from '@eg/share/grid/grid.component';
+import {Pager} from '@eg/share/util/pager';
+
+@Component({
+    templateUrl: './list.component.html'
+})
+export class NegativeBalancesComponent implements OnInit {
+
+    dataSource: GridDataSource = new GridDataSource();
+    contextOrg: IdlObject;
+    contextOrgLoaded = false;
+
+    @ViewChild('grid') private grid: GridComponent;
+
+    constructor(
+        private idl: IdlService,
+        private org: OrgService,
+        private auth: AuthService,
+        private net: NetService,
+        private pcrud: PcrudService,
+        private strings: StringService,
+        private toast: ToastService
+    ) {}
+
+    ngOnInit() {
+        this.contextOrg = this.org.get(this.auth.user().ws_ou());
+
+        this.dataSource.getRows = (pager: Pager, sort: any[]) => {
+
+            if (!this.contextOrgLoaded) {
+                // Still determining the default context org unit.
+                return empty();
+            }
+
+            return this.net.request(
+                'open-ils.actor',
+                'open-ils.actor.users.negative_balance',
+                this.auth.token(), this.contextOrg.id(),
+                {limit: pager.limit, offset: pager.offset, org_descendants: true}
+            ).pipe(map(data => {
+
+                const user = data.usr;
+                user._extras = {
+                    balance_owed: data.balance_owed,
+                    last_billing_activity: data.last_billing_activity,
+                };
+
+                return user;
+            }));
+        };
+    }
+
+    orgChnaged(org: IdlObject) {
+        if (org) {
+            this.contextOrg = org;
+            this.grid.reload();
+        }
+    }
+}
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/negative-balances.module.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/negative-balances.module.ts
new file mode 100644 (file)
index 0000000..7a55139
--- /dev/null
@@ -0,0 +1,23 @@
+import {NgModule} from '@angular/core';
+import {AdminCommonModule} from '@eg/staff/admin/common.module';
+import {NegativeBalancesRoutingModule} from './routing.module';
+import {NegativeBalancesComponent} from './list.component';
+
+@NgModule({
+  declarations: [
+    NegativeBalancesComponent
+  ],
+  imports: [
+    AdminCommonModule,
+    NegativeBalancesRoutingModule
+  ],
+  exports: [
+  ],
+  providers: [
+  ]
+})
+
+export class NegativeBalancesModule {
+}
+
+
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/routing.module.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/negative-balances/routing.module.ts
new file mode 100644 (file)
index 0000000..097184a
--- /dev/null
@@ -0,0 +1,15 @@
+import {NgModule} from '@angular/core';
+import {RouterModule, Routes} from '@angular/router';
+import {NegativeBalancesComponent} from './list.component';
+
+const routes: Routes = [{
+    path: '',
+    component: NegativeBalancesComponent
+}];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+
+export class NegativeBalancesRoutingModule {}
index a2fef17..2376260 100644 (file)
@@ -86,6 +86,10 @@ const routes: Routes = [{
     loadChildren: () => import('./field-documentation/field-documentation.module')
       .then(m => m.FieldDocumentationModule)
 }, {
+    path: 'negative-balances',
+    loadChildren: () =>
+      import('./negative-balances/negative-balances.module').then(m => m.NegativeBalancesModule)
+}, {
     path: ':schema/:table',
     component: BasicAdminPageComponent
 }];
index c0d9851..3adc2a3 100644 (file)
@@ -4182,7 +4182,11 @@ __PACKAGE__->register_method (
 );
 
 sub negative_balance_users {
-    my($self, $conn, $auth, $org_id) = @_;
+    my($self, $conn, $auth, $org_id, $options) = @_;
+
+    $options ||= {};
+    $options->{limit} = 1000 unless $options->{limit};
+    $options->{offset} = 0 unless $options->{offset};
 
     my $e = new_editor(authtoken => $auth);
     return $e->die_event unless $e->checkauth;
@@ -4211,9 +4215,14 @@ sub negative_balance_users {
                 }
             }
         },
-        where => {'+mous' => {balance_owed => {'<' => 0}}}
+        where => {'+mous' => {balance_owed => {'<' => 0}}},
+        offset => $options->{offset},
+        limit => $options->{limit},
+        order_by => [{class => 'mous', field => 'usr'}]
     };
 
+    $org_id = $U->get_org_descendants($org_id) if $options->{org_descendants};
+
     $query->{from}->{mous}->{au}->{filter}->{home_ou} = $org_id if $org_id;
 
     my $list = $e->json_query($query, {timeout => 600});
index ae6cdd3..de0629b 100644 (file)
@@ -22193,4 +22193,19 @@ VALUES (
         'Library Selector Show Combined Names',
         'cwst', 'label'
     )
+), (
+    'eg.grid.admin.local.negative_balances', 'gui', 'object', 
+    oils_i18n_gettext(
+        'eg.grid.admin.local.negative_balances',
+        'Patrons With Negative Balances Grid Settings',
+        'cwst', 'label'
+    )
+), (
+    'eg.orgselect.admin.local.negative_balances', 'gui', 'integer',
+    oils_i18n_gettext(
+        'eg.orgselect.admin.local.negative_balances',
+        'Default org unit for patron negative balances interface',
+        'cwst', 'label'
+    )
 );
+
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.negative-balance-grid.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.negative-balance-grid.sql
new file mode 100644 (file)
index 0000000..a0407f5
--- /dev/null
@@ -0,0 +1,23 @@
+
+BEGIN;
+
+-- SELECT evergreen.upgrade_deps_block_check('TODO', :eg_version);
+
+INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
+VALUES (
+    'eg.grid.admin.local.negative_balances', 'gui', 'object', 
+    oils_i18n_gettext(
+        'eg.grid.admin.local.negative_balances',
+        'Patrons With Negative Balances Grid Settings',
+        'cwst', 'label'
+    )
+), (
+    'eg.orgselect.admin.local.negative_balances', 'gui', 'integer',
+    oils_i18n_gettext(
+        'eg.orgselect.admin.local.negative_balances',
+        'Default org unit for patron negative balances interface',
+        'cwst', 'label'
+    )
+);
+
+COMMIT;