| @@ -94,6 +94,7 @@ import {UploadInterceptor} from './lender-uploads/upload-status.interceptor'; | |||
| import { UploadDetailComponent } from './upload-detail/upload-detail.component'; | |||
| import {SafeUrlPipe} from './pipe/safe.url.pipe'; | |||
| import { ImagePopupDialogComponent } from './image-popup-dialog/image-popup-dialog.component'; | |||
| import { PopupIncomeFilterComponent } from './popup-income-filter/popup-income-filter.component'; | |||
| @@ -157,7 +158,8 @@ import { ImagePopupDialogComponent } from './image-popup-dialog/image-popup-dial | |||
| UploadCardsComponent, | |||
| UploadDetailComponent, | |||
| SafeUrlPipe, | |||
| ImagePopupDialogComponent | |||
| ImagePopupDialogComponent, | |||
| PopupIncomeFilterComponent | |||
| ], | |||
| imports: [ | |||
| BrowserModule, | |||
| @@ -1,12 +1,44 @@ | |||
| import {SortDescriptor} from '@progress/kendo-data-query'; | |||
| export class PayInListFilterModel { | |||
| LoanIds: string[]; | |||
| Uploads: string[]; | |||
| UploadIds: string[]; | |||
| Take: number; | |||
| Skip: number; | |||
| TsFrom: Date; | |||
| TsTo: Date; | |||
| IdFrom: number; | |||
| IdTo: number; | |||
| IncomeFrom: number; | |||
| IncomeTo: number; | |||
| TrailFrom: number; | |||
| TrailTo: number; | |||
| BalanceFrom: number; | |||
| BalanceTo: number; | |||
| AmountFrom: number; | |||
| AmountTo: number; | |||
| Sort?: SortDescriptor[]; | |||
| constructor(payload: Partial<PayInListFilterModel>) { | |||
| this.LoanIds = []; | |||
| if (payload.LoanIds !== undefined && payload.LoanIds.length > 0) { | |||
| payload.LoanIds.forEach(v => { this.LoanIds.push(v); }); | |||
| } | |||
| this.UploadIds = []; | |||
| if (payload.UploadIds !== undefined && payload.UploadIds.length > 0 ) { | |||
| payload.UploadIds.forEach(v => { this.UploadIds.push(v); }); | |||
| } | |||
| const bigNumber = 9999999999; | |||
| this.Take = payload.Take || 10; | |||
| this.Skip = payload.Skip || 0; | |||
| this.TsFrom = payload.TsFrom? new Date(payload.TsFrom) : new Date('1900-01-01'); | |||
| this.TsTo = payload.TsTo? new Date(payload.TsTo) : new Date('2038-01-01'); | |||
| this.IdFrom = payload.IdFrom || 0; | |||
| this.IdTo = payload.IdTo || bigNumber; | |||
| this.TrailFrom = payload.TrailFrom || 0; | |||
| this.TrailTo = payload.TrailTo || bigNumber; | |||
| this.BalanceFrom = payload.BalanceFrom || -1 ; | |||
| this.BalanceTo = payload.BalanceTo || bigNumber; | |||
| this.AmountFrom = payload.AmountFrom || 0; | |||
| this.AmountTo = payload.AmountTo || bigNumber; | |||
| } | |||
| } | |||
| @@ -1,9 +1,21 @@ | |||
| <kendo-grid [data]="gridData" | |||
| [pageable]="pageable" | |||
| [pageSize]="filter.Take" | |||
| [skip]="filter.Skip" | |||
| [sortable]="sortable" | |||
| [filterable]="filterable" | |||
| [loading]="loading" | |||
| [sort]="filter.Sort" | |||
| (add)="addHandler($event)" | |||
| (cancel)="cancelHandler($event)" | |||
| (save)="saveHandler($event)" | |||
| (edit)="editHandler($event)" | |||
| (remove)="removeHandler($event)" | |||
| (pageChange)="pageChange($event)" | |||
| (sortChange)="sortChange($event)" | |||
| > | |||
| <ng-template kendoGridToolbarTemplate> | |||
| <div style="width:100%; margin:0px; display:block"> | |||
| @@ -11,7 +23,7 @@ | |||
| <button kendoGridAddCommand icon="plus" >Add new Income</button> | |||
| </div> | |||
| <div [ngStyle]="{'width': allowAddNew? '70%': '100%'}" class="filter-panel-wrapper" > | |||
| <button kendoButton icon="filter" >Loan</button> | |||
| <button kendoButton icon="filter" (click)="showFilter()" >Filter</button> | |||
| <button kendoButton icon="filter" >Upload</button> | |||
| </div> | |||
| </div> | |||
| @@ -26,19 +38,28 @@ | |||
| </ng-template> | |||
| </kendo-grid-command-column> | |||
| <kendo-grid-column field="Id" title="Id" width="50" editable="false"> | |||
| <kendo-grid-column field="Id" title="Id" width="50" editable="false" > | |||
| <ng-template kendoGridFilterCellTemplate let-filter let-column="column"> | |||
| <kendo-grid-numeric-filter-cell [column]="column" [filter]="filter" [showOperators]="false" > | |||
| </kendo-grid-numeric-filter-cell> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Trail" title="Trail Received" width="200" format="{0:c}" editor="numeric"> | |||
| <kendo-grid-column field="Trail" title="Trail Received" width="150" format="{0:c}" editor="numeric"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Ts" title="Trail Date" editor="date"> | |||
| <kendo-grid-column field="Ts" title="Trail Date" editor="date" width="100"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| {{ dataItem.Ts | date: 'yyyy-MM-dd' }} | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Balance" title="Balance" width="220"> | |||
| <kendo-grid-column field="Amount" title="Loan Amount" width="150" format="{0:c}" | |||
| [editable]="false" [sortable]="false"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Balance" title="Balance" width="150"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <div *ngIf="dataItem.Balance >=0 "> {{ dataItem.Balance | currency}} </div> | |||
| <div *ngIf="dataItem.Balance < 0 "> unknown </div> | |||
| @@ -64,7 +85,7 @@ | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="OffsetBalance" title="Offset" width="200" > | |||
| <kendo-grid-column field="OffsetBalance" title="Offset" width="150" > | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <div *ngIf="dataItem.OffsetBalance >=0 "> {{ dataItem.OffsetBalance | currency}} </div> | |||
| <div *ngIf="dataItem.OffsetBalance < 0 "> unknown </div> | |||
| @@ -89,18 +110,20 @@ | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="UploadId" title="Uploads" width="100" format="{0:c}" editable="false"> | |||
| <kendo-grid-column field="UploadId" title="Uploads" width="100" format="{0:c}" [editable]="false" [sortable]="false"> | |||
| <ng-template kendoGridCellTemplate let-dataItem > | |||
| <button kendoButton *ngIf="dataItem.UploadId > 0" (click)="showUpload(dataItem.UploadId)" icon="attachment"> {{ dataItem.UploadId }} | |||
| <button kendoButton *ngIf="dataItem.UploadId > 0" | |||
| (click)="showUpload(dataItem.UploadId)" icon="attachment"> {{ dataItem.UploadId }} | |||
| </button> | |||
| <p *ngIf="dataItem.UploadId <=0" > - </p> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="LoanId" title="Loan" width="80" editable="false"> | |||
| <kendo-grid-column field="LoanId" title="Loan" width="80" [editable]="false" [sortable]="false"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <button *ngIf="dataItem.LoanId != '' && dataItem.LoanId != undefined " kendoButton [icon]="'page-properties'" (click)="gotoLoan(dataItem.LoanId)" > </button> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| </kendo-grid> | |||
| <app-popup-income-filter #filterDialog (DoFilter)="doFilter($event)"> </app-popup-income-filter> | |||
| @@ -1,10 +1,13 @@ | |||
| import {Component, Input, OnInit} from '@angular/core'; | |||
| import {Component, Input, OnInit, ViewChild} from '@angular/core'; | |||
| import {PayInModel} from '../models/pay-in.model'; | |||
| import {FormControl, FormGroup, Validators} from '@angular/forms'; | |||
| import {PayInListFilterModel} from '../models/pay-in-list.filter.model'; | |||
| import {PayInService} from '../service/pay-in.service'; | |||
| import {PayInListResult} from '../models/pay-in-list-result.model'; | |||
| import {Router} from '@angular/router'; | |||
| import {PopupIncomeFilterComponent} from '../popup-income-filter/popup-income-filter.component'; | |||
| import {PageChangeEvent, SortSettings} from '@progress/kendo-angular-grid'; | |||
| import {SortDescriptor} from '@progress/kendo-data-query'; | |||
| const createFormGroup = dataItem => new FormGroup({ | |||
| Id: new FormControl({value: dataItem.Id, disabled: true}, Validators.required), | |||
| @@ -21,14 +24,10 @@ const createFormGroup = dataItem => new FormGroup({ | |||
| styleUrls: ['./pay-in.component.scss'] | |||
| }) | |||
| export class PayInComponent implements OnInit { | |||
| @Input() loanFilter: string[] = []; | |||
| @Input() uploadsFilter: string[] = []; | |||
| @Input() allowAddNew = true; | |||
| @Input() allowEdit = true; | |||
| @Input() pageSize = 10; | |||
| @Input() skip = 0; | |||
| @Input() dateStart = new Date('1900-01-01'); | |||
| @Input() dateEnd = new Date('2038-12-31'); | |||
| @Input() filter: PayInListFilterModel = new PayInListFilterModel({}); | |||
| @ViewChild('filterDialog', {static: true}) filterDialog: PopupIncomeFilterComponent; | |||
| public gridData: PayInListResult = { data: [], total: 0}; | |||
| public incomeFormGroup: FormGroup; | |||
| @@ -37,21 +36,38 @@ export class PayInComponent implements OnInit { | |||
| public showBalance = true; | |||
| public showOffsetBalance = true; | |||
| public pageable = true; | |||
| public sortable: SortSettings = { | |||
| mode: 'single' | |||
| }; | |||
| public filterable = false; | |||
| public loading = false; | |||
| constructor(private pis: PayInService, private router: Router) { } | |||
| ngOnInit(): void { | |||
| this.pis.getPayInList(new PayInListFilterModel()).subscribe( | |||
| this.loadFilteredData(); | |||
| } | |||
| public loadFilteredData(): void{ | |||
| this.loading = true; | |||
| this.pis.getPayInList(this.filter).subscribe( | |||
| ( resp: PayInListResult) => { | |||
| this.gridData.total = resp.total; | |||
| this.gridData.data = []; | |||
| resp.data.forEach(v => { | |||
| this.gridData.data.push(new PayInModel(v)); | |||
| this.loading = false; | |||
| }); | |||
| }, err => { | |||
| this.loading = false; | |||
| }, () => { | |||
| this.loading = false; | |||
| } | |||
| ); | |||
| } | |||
| public addHandler({ sender }): void { | |||
| this.closeEditor(sender); | |||
| @@ -159,4 +175,33 @@ export class PayInComponent implements OnInit { | |||
| } | |||
| } | |||
| public showFilter(): void{ | |||
| this.filterDialog.show(); | |||
| } | |||
| public doFilter(filter: PayInListFilterModel): void { | |||
| this.filter.BalanceTo = filter.BalanceTo; | |||
| this.filter.BalanceFrom = filter.BalanceFrom; | |||
| this.filter.AmountFrom = filter.AmountFrom; | |||
| this.filter.AmountTo = filter.AmountTo; | |||
| this.filter.Take = filter.Take; | |||
| this.filter.TrailFrom = filter.TrailFrom; | |||
| this.filter.TrailTo = filter.TrailTo; | |||
| this.filter.IdFrom = filter.IdFrom; | |||
| this.filter.IdTo = filter.IdTo; | |||
| this.filter.TsFrom = filter.TsFrom; | |||
| this.filter.TsTo = filter.TsTo; | |||
| this.loadFilteredData(); | |||
| } | |||
| public pageChange(event: PageChangeEvent): void { | |||
| this.filter.Skip = event.skip; | |||
| this.loadFilteredData(); | |||
| } | |||
| public sortChange(sort: SortDescriptor[]): void { | |||
| this.filter.Sort = sort; | |||
| this.loadFilteredData(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,85 @@ | |||
| <kendo-dialog title="Filtering Data" *ngIf="opened" (close)="close('cancel')" | |||
| [minWidth]="'500px'" [minHeight]="'200px'" | |||
| [maxWidth]="'100vw'" [maxHeight]="'100vh'" | |||
| > | |||
| <form class="k-form" #filterForm="ngForm"> | |||
| <div class="range-field" > | |||
| <label> | |||
| id-from: | |||
| <kendo-numerictextbox [format]="'n'" [(value)]="filter.IdFrom"></kendo-numerictextbox> | |||
| </label> | |||
| ➜ | |||
| <label> | |||
| id-to: | |||
| <kendo-numerictextbox [format]="'n'" [(value)]="filter.IdTo"></kendo-numerictextbox> | |||
| </label> | |||
| </div> | |||
| <div class="range-field" > | |||
| <label> | |||
| Trail-from: | |||
| <kendo-numerictextbox [(value)]="filter.TrailFrom"></kendo-numerictextbox> | |||
| </label> | |||
| ➜ | |||
| <label> | |||
| Trail-to: | |||
| <kendo-numerictextbox [(value)]="filter.TrailTo"></kendo-numerictextbox> | |||
| </label> | |||
| </div> | |||
| <div class="range-field" > | |||
| <kendo-daterange> | |||
| <label> | |||
| Tail Date Start: | |||
| <kendo-dateinput kendoDateRangeStartInput [(value)]="filter.TsFrom"></kendo-dateinput> | |||
| </label> | |||
| ➜ | |||
| <label> | |||
| Tail Date End: | |||
| <kendo-dateinput kendoDateRangeEndInput [(value)]="filter.TsTo"></kendo-dateinput> | |||
| </label> | |||
| </kendo-daterange> | |||
| </div> | |||
| <div class="range-field"> | |||
| <label> | |||
| Balance-from: | |||
| <kendo-numerictextbox [(value)]="filter.BalanceFrom"></kendo-numerictextbox> | |||
| </label> | |||
| ➜ | |||
| <label> | |||
| Balance-To: | |||
| <kendo-numerictextbox [(value)]="filter.BalanceTo"></kendo-numerictextbox> | |||
| </label> | |||
| </div> | |||
| <div class="range-field"> | |||
| <label> | |||
| Loan-Amount-from: | |||
| <kendo-numerictextbox [(value)]="filter.AmountFrom"></kendo-numerictextbox> | |||
| </label> | |||
| ➜ | |||
| <label> | |||
| Loan-Amount-To: | |||
| <kendo-numerictextbox [(value)]="filter.AmountTo"></kendo-numerictextbox> | |||
| </label> | |||
| </div> | |||
| <div class="range-field"> | |||
| <label> | |||
| Record Per Page: | |||
| <kendo-dropdownlist [(value)]="filter.Take" [data]="[2,5,10,20,30,50]"> </kendo-dropdownlist> | |||
| </label> | |||
| </div> | |||
| </form> | |||
| <kendo-dialog-actions> | |||
| <button kendoButton (click)="close('no')" [disabled]="true"></button> | |||
| <button kendoButton (click)="close('no')" [disabled]="true"></button> | |||
| <button kendoButton (click)="close('no')" [icon]="'close-circle'">Close</button> | |||
| <button kendoButton (click)="close('clear')" [icon]="'filter-clear'" >Clear</button> | |||
| <button type="submit" kendoButton (click)="close('filter')" [icon]="'filter'" primary="true">Filter</button> | |||
| </kendo-dialog-actions> | |||
| </kendo-dialog> | |||
| @@ -0,0 +1,5 @@ | |||
| .range-field { | |||
| margin-top:10px; | |||
| margin-bottom:30px; | |||
| border-bottom: 1px dotted lightgrey; | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||
| import { PopupIncomeFilterComponent } from './popup-income-filter.component'; | |||
| describe('PopupIncomeFilterComponent', () => { | |||
| let component: PopupIncomeFilterComponent; | |||
| let fixture: ComponentFixture<PopupIncomeFilterComponent>; | |||
| beforeEach(async () => { | |||
| await TestBed.configureTestingModule({ | |||
| declarations: [ PopupIncomeFilterComponent ] | |||
| }) | |||
| .compileComponents(); | |||
| }); | |||
| beforeEach(() => { | |||
| fixture = TestBed.createComponent(PopupIncomeFilterComponent); | |||
| component = fixture.componentInstance; | |||
| fixture.detectChanges(); | |||
| }); | |||
| it('should create', () => { | |||
| expect(component).toBeTruthy(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,42 @@ | |||
| import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; | |||
| import {PayInListFilterModel} from '../models/pay-in-list.filter.model'; | |||
| @Component({ | |||
| selector: 'app-popup-income-filter', | |||
| templateUrl: './popup-income-filter.component.html', | |||
| styleUrls: ['./popup-income-filter.component.scss'] | |||
| }) | |||
| export class PopupIncomeFilterComponent implements OnInit { | |||
| public opened = false; | |||
| public filter: PayInListFilterModel; | |||
| @Output() public DoFilter: EventEmitter<PayInListFilterModel> = new EventEmitter<PayInListFilterModel>(); | |||
| constructor() { } | |||
| ngOnInit(): void { | |||
| if ( this.filter === undefined) { | |||
| this.filter = new PayInListFilterModel({}); | |||
| } | |||
| } | |||
| public close(status: string): void { | |||
| this.opened = false; | |||
| if (status === 'filter' ){ | |||
| this.DoFilter.emit(this.filter); | |||
| } | |||
| if (status === 'clear') { | |||
| this.clearFilter(); | |||
| this.DoFilter.emit(this.filter); | |||
| } | |||
| } | |||
| private clearFilter(): void { | |||
| this.filter = new PayInListFilterModel({}); | |||
| } | |||
| public show(): void { | |||
| this.opened = true; | |||
| } | |||
| } | |||