Просмотр исходного кода

upload lender automatically if there is already a match.

tags/2.037
Patrick Sun 4 лет назад
Родитель
Сommit
fed8bbfca7
14 измененных файлов: 210 добавлений и 32 удалений
  1. +3
    -1
      src/app/app.module.ts
  2. +0
    -7
      src/app/lender-uploads/lender-uploads.component.html
  3. +21
    -0
      src/app/models/Pay.In.AAA.Row.model.ts
  4. +1
    -0
      src/app/models/pay-in.model.ts
  5. +2
    -2
      src/app/models/upload.analysis.model.ts
  6. +13
    -0
      src/app/observable/pay.in.observable.ts
  7. +18
    -0
      src/app/pay-in/lender-aaa-income/lender-aaa-income.component.html
  8. +0
    -0
      src/app/pay-in/lender-aaa-income/lender-aaa-income.component.scss
  9. +25
    -0
      src/app/pay-in/lender-aaa-income/lender-aaa-income.component.spec.ts
  10. +77
    -0
      src/app/pay-in/lender-aaa-income/lender-aaa-income.component.ts
  11. +2
    -2
      src/app/pay-in/pay-in.component.html
  12. +28
    -8
      src/app/pay-in/pay-in.component.ts
  13. +7
    -1
      src/app/upload-detail/upload-detail.component.html
  14. +13
    -11
      src/app/upload-detail/upload-detail.component.ts

+ 3
- 1
src/app/app.module.ts Просмотреть файл

@@ -101,6 +101,7 @@ import { LoanSelectComponent } from './loan-select/loan-select.component';
import {PopupModule} from '@progress/kendo-angular-popup';
import { LoansAllComponent } from './loans-all/loans-all.component';
import {LenderNameService} from './service/lender-name.service';
import { LenderAaaIncomeComponent } from './pay-in/lender-aaa-income/lender-aaa-income.component';



@@ -170,7 +171,8 @@ export function initializeApp(appConfig: AppConfig): () => Promise<void> {
LoanCardComponent,
UploadingProgressCardComponent,
LoanSelectComponent,
LoansAllComponent
LoansAllComponent,
LenderAaaIncomeComponent
],
imports: [
BrowserModule,

+ 0
- 7
src/app/lender-uploads/lender-uploads.component.html Просмотреть файл

@@ -9,13 +9,6 @@
(uploadProgress)="uploadProgress($event)"
[showFileList]="false"
[saveUrl]="uploadSaveUrl">
<!-- <ng-template kendoUploadFileInfoTemplate let-files>-->
<!-- <div *ngIf="files!==undefined && files!== null && files[0] !== null">-->
<!-- <div (click)="onClick(files)">Name: {{ files[0].name }}</div>-->
<!-- <div *ngIf="files[0].validationErrors !== undefined"> Cannot upload this file {{files[0]}}</div>-->
<!-- <div *ngIf="map.get(files[0].uid) !== undefined"> fuck all {{map.get(files[0].uid).response.body.Funder}} </div>-->
<!-- </div>-->
<!-- </ng-template>-->
</kendo-upload>
</div>
<div class="search-area">

+ 21
- 0
src/app/models/Pay.In.AAA.Row.model.ts Просмотреть файл

@@ -1,6 +1,8 @@
import {PayInModel} from './pay-in.model';


export class PayInAAARowModel {
private Lender = 'AAA';
public Period: Date;
public LoanNumber: string;
public Settlement: Date;
@@ -8,6 +10,8 @@ export class PayInAAARowModel {
public Balance: number;
public InTrail: number;

public matchedPayIn?: PayInModel | -1;

constructor(payload: Partial<PayInAAARowModel>){
this.Period = new Date(payload.Period);
this.LoanNumber = payload.LoanNumber || '';
@@ -15,5 +19,22 @@ export class PayInAAARowModel {
this.LoanAmount = payload.LoanAmount || 0;
this.Balance = payload.Balance || 0;
this.InTrail = payload.InTrail || 0;
this.matchedPayIn = payload.matchedPayIn || -1;
}

public asPayIn(): PayInModel {
if ( this.matchedPayIn !== undefined && this.matchedPayIn !== -1 ) {
return this.matchedPayIn;
}
const pi = new PayInModel({});
pi.Lender = this.Lender;
pi.LoanNumber = this.LoanNumber;
pi.Amount = this.LoanAmount;
pi.Settlement = this.Settlement;
pi.IncomeAmount = this.InTrail;
pi.IncomeType = 'Trail';
pi.Ts = this.Period;

return pi;
}
}

+ 1
- 0
src/app/models/pay-in.model.ts Просмотреть файл

@@ -40,6 +40,7 @@ export class PayInModel {
}
this.UploadId = payload.UploadId;
}

}



+ 2
- 2
src/app/models/upload.analysis.model.ts Просмотреть файл

@@ -6,7 +6,7 @@ import {PayInAAARowModel} from './Pay.In.AAA.Row.model';

export class UploadAnalysisModel {
public Id: number;
public Funders: string[];
public Lender: string;
public Mime: string;
public PayIn: PayInModel[];

@@ -18,7 +18,7 @@ export class UploadAnalysisModel {

constructor(payload: Partial<UploadAnalysisModel>){
this.Id = payload.Id || 0 ;
this.Funders = payload.Funders || [];
this.Lender = payload.Lender || '';
this.Mime = payload.Mime || '';
if ( payload.PayIn && payload.PayIn.length > 0 ) {
this.PayIn = [];

+ 13
- 0
src/app/observable/pay.in.observable.ts Просмотреть файл

@@ -0,0 +1,13 @@
import {BehaviorSubject} from 'rxjs';
import {PayInModel} from '../models/pay-in.model';


export class PayInObservable extends BehaviorSubject<PayInModel[]> {
constructor() {
super(null);
}

Next(pis: PayInModel[]): void {
super.next(pis);
}
}

+ 18
- 0
src/app/pay-in/lender-aaa-income/lender-aaa-income.component.html Просмотреть файл

@@ -0,0 +1,18 @@
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<kendo-grid [data]="data" (cellClick)="onCellClick($event)">
<ng-template kendoGridToolbarTemplate>
AAA
</ng-template>
<kendo-grid-column field="Period" format='{0:yyyy MMMM}'> </kendo-grid-column>
<kendo-grid-column field="LoanNumber"> </kendo-grid-column>
<kendo-grid-column field="Settlement" format='{0:MM/dd/yyyy h:mm a}'> </kendo-grid-column>
<kendo-grid-column field="LoanAmount" format='{0:c}' > </kendo-grid-column>
<kendo-grid-column field="Balance" format='{0:c}' > </kendo-grid-column>
<kendo-grid-column field="InTrail" format='{0:c}'> </kendo-grid-column>
<kendo-grid-column field="matchedPayIn" title="Matched" format='{0:c}'>
<ng-template kendoGridCellTemplate let-dataItem>
<button kendoButton iconClass="fa fa-calendar fa-fw"></button>
{{ dataItem.matchedPayIn === -1? 'Not matched': dataItem.matchedPayIn.Id}}
</ng-template>
</kendo-grid-column>
</kendo-grid>

+ 0
- 0
src/app/pay-in/lender-aaa-income/lender-aaa-income.component.scss Просмотреть файл


+ 25
- 0
src/app/pay-in/lender-aaa-income/lender-aaa-income.component.spec.ts Просмотреть файл

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { LenderAaaIncomeComponent } from './lender-aaa-income.component';

describe('LenderAaaIncomeComponent', () => {
let component: LenderAaaIncomeComponent;
let fixture: ComponentFixture<LenderAaaIncomeComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ LenderAaaIncomeComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(LenderAaaIncomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 77
- 0
src/app/pay-in/lender-aaa-income/lender-aaa-income.component.ts Просмотреть файл

@@ -0,0 +1,77 @@
import {Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output} from '@angular/core';
import {UploadAnalysisModel} from '../../models/upload.analysis.model';
import {CellCloseEvent} from '@progress/kendo-angular-grid';
import {PayInAAARowModel} from '../../models/Pay.In.AAA.Row.model';
import {PayInModel} from '../../models/pay-in.model';
import {Subject} from 'rxjs';


@Component({
selector: 'app-lender-aaa-income',
templateUrl: './lender-aaa-income.component.html',
styleUrls: ['./lender-aaa-income.component.scss']
})
export class LenderAaaIncomeComponent implements OnInit, OnChanges {
private Lender = 'AAA';
@Input() public analysis = new UploadAnalysisModel({});
@Input() newPayInUpdate: PayInModel;
@Output() Selected: EventEmitter<PayInModel> = new EventEmitter<PayInModel>();
public data: PayInAAARowModel[] = [];
private payInCandidates: PayInModel[] = [];
constructor() { }

ngOnInit(): void {
this.analysis.AAA.forEach(v => {
v.matchedPayIn = this.matchPayIn(v);
this.data.push(new PayInAAARowModel(v));
v.InTrail = 20;
this.data.push(new PayInAAARowModel(v));
});
console.log(this);
}

ngOnChanges(changes): void {
if (changes.newPayInUpdate){
this.data.forEach(v => {
if ( this.isMatch(v, changes.newPayInUpdate.currentValue) ){
v.matchedPayIn = changes.newPayInUpdate.currentValue;
}
});
}
}

public onCellClick(event: CellCloseEvent): void{
this.Selected.emit(event.dataItem.asPayIn());
}

private matchPayIn(v: PayInAAARowModel): PayInModel | -1 {
const idx = this.payInCandidates.findIndex( pi => this.isMatch(v, pi) );
if ( idx === -1 ) { return -1; }
return this.payInCandidates[idx];
}

private isMatch( v: PayInAAARowModel, pi: PayInModel): boolean {
if ( v === null || pi === null ){
return false;
}
return v.LoanNumber === pi.LoanNumber &&
this.Lender === pi.Lender &&
v.InTrail === pi.IncomeAmount &&
'Trail' === pi.IncomeType;
}

@Input() set payIn(pis: PayInModel[]) {
this.payInCandidates = [];
pis.forEach( v => this.payInCandidates.push(new PayInModel(v)));

this.data.forEach( v => {
v.matchedPayIn = this.matchPayIn(v);
});

console.log ('new payin comes in');
}

get PayIn(): PayInModel[] {
return this.payInCandidates;
}
}

+ 2
- 2
src/app/pay-in/pay-in.component.html Просмотреть файл

@@ -58,8 +58,8 @@
<ng-template kendoGridEditTemplate let-dataItem>
<kendo-combobox
[formControl]="incomeFormGroup.get('Lender')"
[data]="funderListView | async"
[loading]="funderListService.loading">
[data]="lenderListView | async"
[loading]="lenderNameService.loading">
</kendo-combobox>
</ng-template>
</kendo-grid-column>

+ 28
- 8
src/app/pay-in/pay-in.component.ts Просмотреть файл

@@ -14,7 +14,7 @@ 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';
import {LenderNameService} from '../service/lender-name.service';



@@ -33,6 +33,7 @@ export class PayInComponent implements OnInit {
public filterLoan = new LoanModel({});
@Input() filter: PayInListFilterModel = new PayInListFilterModel({});
@Output() errorOccurred = new EventEmitter<string>();
@Output() Updated = new EventEmitter<PayInModel>();
@ViewChild('filterDialog', {static: true}) filterDialog: PopupIncomeFilterComponent;
@ViewChild('grid', {static: true}) grid: GridComponent;
private privateLoadDataNow = false;
@@ -53,16 +54,16 @@ export class PayInComponent implements OnInit {
};

public loading = false;
public funderListView: Observable<string[]>;
public lenderListView: Observable<string[]>;
private debouncedLoadFilteredData = () => {};


constructor(private pis: PayInService,
private lss: LoanSingleService,
private router: Router,
private funderListService: FunderNameService) {
this.funderListView = this.funderListService;
this.funderListService.query();
private lenderNameService: LenderNameService) {
this.lenderListView = this.lenderNameService;
this.lenderNameService.query();
}

ngOnInit(): void {
@@ -190,8 +191,10 @@ export class PayInComponent implements OnInit {
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));
const model = new PayInModelEx(resp);
this.Loan.cuPayIn( model);
this.updatePiInGrid(model);
this.Updated.emit(model);
},
err => {
// TODO: this.errorOccurred.emit('Error saving Income');
@@ -316,9 +319,26 @@ export class PayInComponent implements OnInit {
}
}

public ScrollTo(row: number): void {
private ScrollTo(row: number): void {
this.grid.scrollTo({ row});
this.grid.focusCell(row + 1, 1 );
this.gridSelection = [row];
}

public selectOrAddPayIn(pi: PayInModel): void{
const row = this.gridData.data.findIndex( v => {
return v.LoanNumber === pi.LoanNumber &&
v.Lender === pi.Lender &&
v.IncomeAmount === pi.IncomeAmount &&
v.IncomeType === pi.IncomeType;
});

if ( row >= 0 ) { // we found it
this.ScrollTo(row);
} else{
this.incomeFormGroup = this.createFormGroup(new PayInModelEx(pi));
// this.closeEditor(this.grid);
this.grid.addRow(this.incomeFormGroup);
}
}
}

+ 7
- 1
src/app/upload-detail/upload-detail.component.html Просмотреть файл

@@ -52,7 +52,12 @@
</div>
</div>
<div *ngIf="scanDone" class="analysis-result">
<div *ngIf="ua.Funders === undefined || ua.Funders.length == 0"> No result analyzed </div>
<div *ngIf="ua.Lender === undefined || ua.Lender == ''"> AI has no results </div>
<app-lender-aaa-income *ngIf="ua.Lender === 'AAA'" [analysis]="ua"
[payIn]="payIn.gridData.data"
[newPayInUpdate]="newPayInUpdateSubject | async"
(Selected)="onSelected($event)">
</app-lender-aaa-income>

</div>

@@ -74,6 +79,7 @@
[showLoanColumn]="true"
[LoadDataNow] = "true"
[pageable]="false"
(Updated)="onNewPayInUpdate($event)"
>
</app-pay-in>
</div>

+ 13
- 11
src/app/upload-detail/upload-detail.component.ts Просмотреть файл

@@ -5,9 +5,9 @@ import {UploadAnalysisModel} from '../models/upload.analysis.model';
import {UploadMetaModel} from '../models/uploadMetaModel';
import {FloatingActionButtonComponent} from '@progress/kendo-angular-buttons';
import {DrawerSelectEvent, TabStripComponent} from '@progress/kendo-angular-layout';
import {PayInAAARowModel} from '../models/Pay.In.AAA.Row.model';
import {CellCloseEvent} from '@progress/kendo-angular-grid';
import {PayInComponent} from '../pay-in/pay-in.component';
import {PayInModel} from '../models/pay-in.model';
import {Subject} from 'rxjs';



@@ -25,8 +25,9 @@ export class UploadDetailComponent implements OnInit, AfterViewInit {
@ViewChild('tabs', {static: true}) tab: TabStripComponent;
@ViewChild('PayIn', {static: false}) payIn: PayInComponent;

// 'http://africau.edu/images/default/sample.pdf';
public uploadAsPicUrl = '';
public newPayInUpdateSubject = new Subject<PayInModel>();

public uploadAsPicUrl = ''; // 'http://africau.edu/images/default/sample.pdf';
public uploadAsPdfUrl = '';
public initAnimation = false;
public iframeLoaded = false;
@@ -45,7 +46,7 @@ export class UploadDetailComponent implements OnInit, AfterViewInit {
public tabText: string[] = ['Preview', 'Content', 'Analysis'];
public tabTitle: string[] = this.tabText;

public analysisAAA: PayInAAARowModel[] = [];

constructor(private us: UploadAttachService, private actRoute: ActivatedRoute, private router: Router) {
this.uploadAsPicUrl = location.origin + 'assets/img/no_preview.jpg';
@@ -79,9 +80,6 @@ export class UploadDetailComponent implements OnInit, AfterViewInit {
this.us.getUploadAnalysis(this.uploadId).subscribe(
resp => {
this.ua = new UploadAnalysisModel(resp);
this.ua.AAA.forEach(v => {
this.analysisAAA.push(new PayInAAARowModel(v));
});
this.uploadId = this.ua.Id;
this.analysisIsDone = true;
}, err => {
@@ -172,8 +170,12 @@ export class UploadDetailComponent implements OnInit, AfterViewInit {
this.fabOffset = {x: '10px', y: s};
}

public onCellClick(event: CellCloseEvent): void{
console.log('cell-click', event.dataItem, event, this.payIn);
this.payIn.ScrollTo(2);
public onSelected(pi: PayInModel): void{
this.payIn.selectOrAddPayIn(pi);
}

public onNewPayInUpdate( pi: PayInModel): void {
this.newPayInUpdateSubject.next(pi);
}

}

Загрузка…
Отмена
Сохранить