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>
<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"
--- /dev/null
+<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>
+
+
+
+
+
--- /dev/null
+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();
+ }
+ }
+}
--- /dev/null
+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 {
+}
+
+
--- /dev/null
+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 {}
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
}];
);
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;
}
}
},
- 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});
'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'
+ )
);
+
--- /dev/null
+
+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;