import {Component, EventEmitter, Input, OnInit, Output, 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 {GridComponent, PageChangeEvent, SortSettings} from '@progress/kendo-angular-grid'; import {SortDescriptor} from '@progress/kendo-data-query'; import {UploadMetaModel} from '../models/uploadMetaModel'; import {debounce} from 'ts-debounce'; import {LoanModel} from '../models/loan.model'; import {LoanSingleService} from '../service/loan.single.service'; import {PayInModelEx} from '../models/pay-in-ex.model'; import {Observable} from 'rxjs'; import {FunderNameService} from '../service/funder.name.service'; @Component({ selector: 'app-pay-in', templateUrl: './pay-in.component.html', styleUrls: ['./pay-in.component.scss'] }) export class PayInComponent implements OnInit { @Input() allowAddNew = true; @Input() allowEdit = true; @Input() showLoanColumn = true; @Input() showUploadColumn = true; private filterUploadMeta: UploadMetaModel = new UploadMetaModel({}); public filterLoan = new LoanModel({}); @Input() filter: PayInListFilterModel = new PayInListFilterModel({}); @Output() errorOccurred = new EventEmitter(); @ViewChild('filterDialog', {static: true}) filterDialog: PopupIncomeFilterComponent; @ViewChild('grid', {static: true}) grid: GridComponent; private privateLoadDataNow = false; public gridData: PayInListResult = { data: [], total: 0}; public incomeFormGroup: FormGroup; public editedRowIndex: number; public showBalance = true; public showOffsetBalance = true; @Input() public pageable = true; public gridSelection: number[] = []; public sortable: SortSettings = { mode: 'single' }; public loading = false; public funderListView: Observable; private debouncedLoadFilteredData = () => {}; constructor(private pis: PayInService, private lss: LoanSingleService, private router: Router, private funderListService: FunderNameService) { this.funderListView = this.funderListService; this.funderListService.query(); } ngOnInit(): void { this.debouncedLoadFilteredData = debounce(this.loadFilteredData, 500); if (this.privateLoadDataNow) { // not in delayed loading mode this.debouncedLoadFilteredData(); } } 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 PayInModelEx(v)); }); this.loading = false; }, err => { this.loading = false; }, () => { this.loading = false; } ); } // Upload Filter @Input() set uploadMeta(value: UploadMetaModel) { this.filterUploadMeta = value; if ( value.Id <= 0 ) { this.filter.UploadIds = []; } else{ this.filter.UploadIds = [ value.Id.toString() ]; } this.debouncedLoadFilteredData(); //console.log('upload filter changed', value, this.filter); } get uploadMeta(): UploadMetaModel { return this.filterUploadMeta; } // LoanId filter @Input() set Loan(value: LoanModel){ this.filterLoan = value; if ( value.Id === '' ) { this.filter.LoanIds = []; }else{ this.filter.LoanIds = [ value.Id ]; } this.debouncedLoadFilteredData(); // console.log('filter loanId changed', value, this.filter); } get Loan(): LoanModel { return this.filterLoan; } @Input() set LoadDataNow( value: boolean) { if ( value === true && this.privateLoadDataNow === false) { this.debouncedLoadFilteredData(); } this.privateLoadDataNow = value; } get LoadDataNow(): boolean { return this.privateLoadDataNow; } public addHandler({ sender }): void { this.closeEditor(sender); const balance = -1; const offsetBalance = -1; this.showBalance = balance >= 0 ; this.showOffsetBalance = offsetBalance >= 0 ; this.incomeFormGroup = this.createFormGroup(new PayInModelEx({})); // console.log(this.incomeFormGroup); sender.addRow(this.incomeFormGroup); } private createFormGroup(dataItem: PayInModelEx): FormGroup { const Loan = this.filterLoan.Id !== '' ? this.filterLoan : dataItem.Loan; const UploadMeta = this.filterUploadMeta.Id !== 0 ? this.filterUploadMeta : dataItem.UploadMeta ; return new FormGroup({ Id: new FormControl({value: dataItem.Id, disabled: true}, Validators.required), Lender: new FormControl({value: dataItem.Lender, disabled: Loan.Id !== '' }, Validators.required), Amount: new FormControl(dataItem.Amount), LoanNumber: new FormControl({value: dataItem.LoanNumber, disabled: Loan.Id !== ''}, Validators.required), IncomeAmount: new FormControl(dataItem.IncomeAmount, Validators.required), IncomeType: new FormControl(dataItem.IncomeType, Validators.required), Ts: new FormControl(dataItem.Ts, Validators.required), Balance: new FormControl(dataItem.Balance, Validators.required), OffsetBalance: new FormControl(dataItem.OffsetBalance, Validators.required), Loan: new FormControl(Loan), UploadMeta: new FormControl(UploadMeta) }); } public editHandler({ sender, rowIndex, dataItem }): void { this.closeEditor(sender); this.showBalance = dataItem.Balance >= 0 ; this.showOffsetBalance = dataItem.OffsetBalance >= 0 ; this.incomeFormGroup = this.createFormGroup(dataItem); this.editedRowIndex = rowIndex; sender.editRow(rowIndex, this.incomeFormGroup); } public cancelHandler({ sender, rowIndex }): void { // console.log(sender); this.closeEditor(sender, rowIndex); } public saveHandler({ sender, rowIndex, formGroup, isNew }): void { const v = formGroup.getRawValue(); if ( !this.showBalance) { v.Balance = -1; } if ( !this.showOffsetBalance) { v.OffsetBalance = -1; } const pi = this.buildPayInForSave(v, isNew); this.lss.savePayIn(pi, isNew).subscribe( (resp: PayInModelEx) => { this.Loan.cuPayIn( new PayInModel(resp)); this.updatePiInGrid(new PayInModelEx(resp)); }, err => { // TODO: this.errorOccurred.emit('Error saving Income'); } ); sender.closeRow(rowIndex); } private buildPayInForSave(v: any, isNew: boolean): PayInModel { const pi = new PayInModel({}); if ( isNew ) { pi.Id = 0; } // are we using filtered loan? let loan = v.Loan; if (loan === null || this.filterLoan !== undefined && this.filterLoan.Id !== '') { loan = this.filterLoan; } pi.Id = v.Id; pi.Amount = loan.Amount; pi.Balance = v.Balance; pi.Lender = loan.Id === '' ? v.Lender : loan.Lender; pi.LoanId = loan.Id; pi.LoanNumber = loan.Id === '' ? v.LoanNumber : loan.LenderLoanNumber; pi.OffsetBalance = v.OffsetBalance; pi.Settlement = loan.Settlement; pi.IncomeAmount = v.IncomeAmount; pi.IncomeType = v.IncomeType; pi.UploadId = this.filterUploadMeta.Id; pi.Ts = v.Ts; return pi; } private updatePiInGrid(pi: PayInModel): void { const notFound = this.gridData.data.every( v => { if ( v.Id === pi.Id ){ Object.assign(v, pi); return false; } return true; }); if ( notFound ) { this.gridData.data.unshift(pi); } } public removeHandler({ dataItem }): void { // console.log('delete', dataItem); this.Loan.PayIn = this.Loan.PayIn.filter(v => v.Id !== dataItem.Id ); this.gridData.data = this.gridData.data.filter(v => v.Id !== dataItem.Id) ; this.lss.removePayIn(dataItem.Id); } private closeEditor(grid, rowIndex = this.editedRowIndex): void{ grid.closeRow(rowIndex); this.editedRowIndex = undefined; this.incomeFormGroup = undefined; } public showUpload(id: number): void { this.router.navigate(['/upload-details', id]); } public setBalance(): void{ if ( this.showBalance ){ this.incomeFormGroup.get('Balance').setValue(0); }else{ this.incomeFormGroup.get('Balance').setValue(-1); } } public setOffsetBalance(): void{ if ( this.showOffsetBalance ){ this.incomeFormGroup.get('OffsetBalance').setValue(0); }else{ this.incomeFormGroup.get('OffsetBalance').setValue(-1); } } 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(); } public onLoanChange(loan: LoanModel): void { if ( loan.Id !== '' ) { this.incomeFormGroup.get('Lender').setValue(loan.Lender); this.incomeFormGroup.get('Lender').disable({onlySelf: true, emitEvent: false}); this.incomeFormGroup.get('LoanNumber').setValue(loan.LenderLoanNumber); this.incomeFormGroup.get('LoanNumber').disable({onlySelf: true, emitEvent: false}); } } public ScrollTo(row: number): void { this.grid.scrollTo({ row}); this.grid.focusCell(row + 1, 1 ); this.gridSelection = [row]; } }