-import {Component, OnInit, Input, Output, ViewChild, EventEmitter, forwardRef} from '@angular/core';
+import {Component, OnInit, Input, Output, EventEmitter, forwardRef} from '@angular/core';
import {NgbDateStruct} from '@ng-bootstrap/ng-bootstrap';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {DateUtil} from '@eg/share/util/date';
</eg-staff-banner>
<div class="mb-5">
- <div>
+ <form #criteria="ngForm" egDateFieldOrderList="startDate,endDate">
<div class="row">
<div class="input-group col-lg-3">
- <div class="input-group-text" i18n>Start Date</div>
- <eg-date-select [initialDate]="today" (onChangeAsYmd)="onStartDateChange($event)"></eg-date-select>
+ <label class="input-group-text" i18n for="start-date">Start Date</label>
+ <eg-date-select [initialDate]="today" domId="start-date" name="startDate" [(ngModel)]="startDate"></eg-date-select>
</div>
<div class="input-group col-lg-3">
- <div class="input-group-text" i18n>End Date</div>
- <eg-date-select [initialDate]="today" (onChangeAsYmd)="onEndDateChange($event)"></eg-date-select>
+ <label class="input-group-text" i18n for="end-date">End Date</label>
+ <eg-date-select [initialDate]="today" domId="end-date" name="endDate" [(ngModel)]="endDate"></eg-date-select>
</div>
<div class="input-group col-lg-4">
<div class="input-group-text" i18n>View reports for</div>
<eg-org-select [applyDefault]="true" [disableOrgs]="disabledOrgs" (onChange)="onOrgChange($event)"></eg-org-select>
</div>
<div class="col-lg-2">
- <button class="btn btn-primary" (click)="searchForData(startDate, endDate)">Submit</button>
+ <button class="btn btn-primary" (click)="searchForData()" [disabled]="!criteria.valid">Submit</button>
</div>
</div>
- </div>
+ <div role="alert" class="alert alert-danger" id="dateOutOfOrderAlert" *ngIf="criteria.errors?.['datesOutOfOrder'] && (criteria.touched || criteria.dirty)">
+ <span class="material-icons" aria-hidden="true">error</span>
+ <span i18n>Start date must be before end date</span>
+ </div>
+ </form>
</div>
<ul ngbNav #cashReportsNav="ngbNav" class="nav-tabs" [keyboard]="true" [roles]="false" role="tablist"
--- /dev/null
+import { TestBed } from '@angular/core/testing';
+import { AuthService } from '@eg/core/auth.service';
+import { IdlService } from '@eg/core/idl.service';
+import { NetService } from '@eg/core/net.service';
+import { OrgService } from '@eg/core/org.service';
+import { CashReportsComponent } from './cash-reports.component';
+import { DateSelectComponent } from '@eg/share/date-select/date-select.component';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { NgbDatepickerModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { of } from 'rxjs';
+import { FormsModule } from '@angular/forms';
+import { DatesInOrderValidatorDirective } from '@eg/share/validators/dates_in_order_validator.directive';
+
+const mockIdlObject = {a: null,
+ classname: null,
+ _isfieldmapper: null,
+ id: () => {null},
+ ws_ou: () => {null}};
+const mockNet = jasmine.createSpyObj<NetService>(['request']);
+mockNet.request.and.returnValue(of());
+const mockOrg = jasmine.createSpyObj<OrgService>(['get', 'filterList']);
+const mockAuth = jasmine.createSpyObj<AuthService>(['user', 'token']);
+mockAuth.user.and.returnValue(mockIdlObject);
+
+describe('CashReportsComponent', () => {
+ it('alerts the user if end date is before start date', async () => {
+ await TestBed.configureTestingModule({
+ declarations: [
+ CashReportsComponent,
+ DateSelectComponent,
+ DatesInOrderValidatorDirective
+ ],
+ providers: [
+ {provide: IdlService, useValue: {}},
+ {provide: NetService, useValue: mockNet},
+ {provide: OrgService, useValue: mockOrg},
+ {provide: AuthService, useValue: mockAuth}
+ ],
+ imports: [
+ NgbNavModule,
+ NgbDatepickerModule,
+ FormsModule
+ ],
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
+ }).compileComponents();
+
+ const fixture = TestBed.createComponent(CashReportsComponent);
+ const component = fixture.componentInstance;
+ const element = fixture.nativeElement;
+ component.selectedOrg = mockIdlObject;
+ fixture.detectChanges();
+
+ element.querySelector('#start-date').value = '2022-01-01';
+ element.querySelector('#end-date').value = '2021-01-01';
+ component.criteria.form.setErrors({datesOutOfOrder: true});
+ component.criteria.form.markAsDirty();
+ fixture.detectChanges();
+ expect(element.querySelector('#dateOutOfOrderAlert').innerText).toContain('Start date must be before end date');
+ });
+});
import {NetService} from '@eg/core/net.service';
import {AuthService} from '@eg/core/auth.service';
import {OrgService} from '@eg/core/org.service';
+import { NgForm } from '@angular/forms';
class DeskTotals {
cash_payment = 0;
deskIdlClass = 'mwps';
userIdlClass = 'mups';
selectedOrg = this.org.get(this.auth.user().ws_ou());
- today = new Date();
- startDate = `${this.today.getFullYear()}-${String(this.today.getMonth() + 1).padStart(2, '0')}-${String(this.today.getDate()).padStart(2, '0')}`;
- endDate = `${this.today.getFullYear()}-${String(this.today.getMonth() + 1).padStart(2, '0')}-${String(this.today.getDate()).padStart(2, '0')}`;
+ startDate = new Date();
+ endDate = new Date();
deskTotals = new DeskTotals();
userTotals = new UserTotals();
disabledOrgs = [];
@ViewChild('deskPaymentGrid') deskPaymentGrid: GridComponent;
@ViewChild('userPaymentGrid') userPaymentGrid: GridComponent;
@ViewChild('userGrid') userGrid: GridComponent;
+ @ViewChild('criteria') criteria: NgForm;
constructor(
private idl: IdlService,
ngOnInit() {
this.disabledOrgs = this.getFilteredOrgList();
- this.searchForData(this.startDate, this.endDate);
+ this.searchForData();
this.cellTextGenerator = {
card: row => row.user.card()
};
}
- searchForData(start, end) {
+ searchForData() {
this.userDataSource.data = [];
this.fillGridData(this.deskIdlClass, 'deskPaymentDataSource',
this.net.request(
'open-ils.circ',
'open-ils.circ.money.org_unit.desk_payments',
- this.auth.token(), this.selectedOrg.id(), start, end));
+ this.auth.token(), this.selectedOrg.id(), this.startDate.toISOString().split('T')[0], this.endDate.toISOString().split('T')[0]));
this.fillGridData(this.userIdlClass, 'userPaymentDataSource',
this.net.request(
'open-ils.circ',
'open-ils.circ.money.org_unit.user_payments',
- this.auth.token(), this.selectedOrg.id(), start, end));
+ this.auth.token(), this.selectedOrg.id(), this.startDate.toISOString().split('T')[0], this.endDate.toISOString().split('T')[0]));
}
fillGridData(idlClass, dataSource, data) {
return this.org.filterList(orgFilter, true);
}
- onStartDateChange(date) {
- this.startDate = date;
- }
-
- onEndDateChange(date) {
- this.endDate = date;
- }
-
onOrgChange(org) {
this.selectedOrg = org;
- this.searchForData(this.startDate, this.endDate);
+ this.searchForData();
}
}