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

loan search and cancel + list of lenders from database

tags/2.037
Patrick Sun 4 лет назад
Родитель
Сommit
ccf1dc479e
12 измененных файлов: 196 добавлений и 111 удалений
  1. +2
    -0
      src/app/app.module.ts
  2. +2
    -3
      src/app/list-all-loans/list-all-loans.component.html
  3. +84
    -82
      src/app/list-all-loans/list-all-loans.component.scss
  4. +13
    -3
      src/app/list-all-loans/list-all-loans.component.ts
  5. +1
    -1
      src/app/loan-card/loan-card.component.html
  6. +8
    -1
      src/app/loan-select/loan-select.component.html
  7. +8
    -0
      src/app/loan-select/loan-select.component.scss
  8. +12
    -2
      src/app/loan-select/loan-select.component.ts
  9. +11
    -2
      src/app/pay-in/pay-in.component.html
  10. +16
    -3
      src/app/pay-in/pay-in.component.ts
  11. +15
    -14
      src/app/service/auth.service.ts
  12. +24
    -0
      src/app/service/funder.name.service.ts

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

import { LoanSelectComponent } from './loan-select/loan-select.component'; import { LoanSelectComponent } from './loan-select/loan-select.component';
import {PopupModule} from '@progress/kendo-angular-popup'; import {PopupModule} from '@progress/kendo-angular-popup';
import { LoansAllComponent } from './loans-all/loans-all.component'; import { LoansAllComponent } from './loans-all/loans-all.component';
import {FunderNameService} from './service/funder.name.service';






WebSocketService, WebSocketService,
LoanSummaryService, LoanSummaryService,
LoanSingleService, LoanSingleService,
FunderNameService,
{ {
provide: HTTP_INTERCEPTORS, provide: HTTP_INTERCEPTORS,
useClass: AuthHttpInterceptor, useClass: AuthHttpInterceptor,

+ 2
- 3
src/app/list-all-loans/list-all-loans.component.html Просмотреть файл

<span class="badge badge-info">{{MaxSelect}}</span> <span class="badge badge-info">{{MaxSelect}}</span>
</div> </div>
<button *ngIf="EnableSelectButton" kendoButton [primary]=true <button *ngIf="EnableSelectButton" kendoButton [primary]=true
class="select-loan" icon="close-circle" style="float:right;"
class="select-loan" icon="save" style="float:right;"
(click)="onFinishSelection()" (click)="onFinishSelection()"
>
Finish Selection</button>
>{{FinishButtonText}}</button>


</ng-template> </ng-template>



+ 84
- 82
src/app/list-all-loans/list-all-loans.component.scss Просмотреть файл

.fullheight_grid {
kendo-grid.fullheight_grid {
height: 100% !important; height: 100% !important;
}


.k-grid td:first-child{
vertical-align: top;
}
.k-grid td.topAlign{
vertical-align: top;
}
.k-grid td:first-child{
vertical-align: top;
}
.k-grid td.topAlign{
vertical-align: top;
}


.k-grid td.alignStatus{
vertical-align: top;
text-align: left;
}
.k-grid td.alignStatus{
vertical-align: top;
text-align: left;
}


.k-grid-header .k-header.colGroupPeople,
.k-grid-header .k-header.colClient,
.k-grid-header .k-header.colBroker,
.k-grid-header .k-header.colOtherRewarder
{
text-align:center;
}


div.selected-loans{
position: relative;
padding-right:200px;
width: calc(100% - 150px);
min-height: 60px;
overflow: auto hidden;
app-loan-card{
display: block;
.k-grid-header .k-header.colGroupLoanDetails,
.k-grid-header .k-header.colGroupLenderDetails,
.k-grid-header .k-header.colGroupIncomeDistribution{
border-left: 5px solid #ffeabe !important;
} }
}


div.selection-percentage{
float:right;
position:absolute;
right: 10px;
bottom: 1px;
}
div.selected-loans{
position: relative;
padding-right:200px;
width: calc(100% - 150px);
min-height: 60px;
overflow: auto hidden;
app-loan-card{
display: block;
}
}


div.selection-percentage{
float:right;
position:absolute;
right: 10px;
bottom: 1px;
}


button.select-loan{
position: absolute;
right: 10px;
top: 10px;
}


.customer-photo{
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
background-size: 32px 35px;
background-position: center center;
vertical-align: middle;
line-height: 32px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
margin-left: 5px;
margin-bottom: 10px;
}
button.select-loan{
position: absolute;
right: 10px;
top: 10px;
}


.customer-name {
display: inline-block;
vertical-align: middle;
line-height: 32px;
padding-left: 10px;
}
.customer-photo{
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
background-size: 32px 35px;
background-position: center center;
vertical-align: middle;
line-height: 32px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
margin-left: 5px;
margin-bottom: 10px;
}


.k-grid-header .k-header.colGroupPeople,
.k-grid-header .k-header.colClient,
.k-grid-header .k-header.colBroker,
.k-grid-header .k-header.colOtherRewarder
{
text-align:center;
}
.customer-name {
display: inline-block;
vertical-align: middle;
line-height: 32px;
padding-left: 10px;
}


.k-grid-header .k-header.colGroupLoanDetails,
.k-grid-header .k-header.colGroupLenderDetails,
.k-grid-header .k-header.colGroupIncomeDistribution{
border-left: 5px solid #ffeabe !important;
}
.colRating, .colAmount, .colPayOut{
border-left: 5px solid #ffeabe !important;
}
.colRating, .colAmount, .colPayOut{
border-left: 5px solid #ffeabe !important;
}


.colTrail{
font-width: 300;
color: green ;
//border-left: 2px solid green !important;
//border-right: 2px solid green !important;
border-bottom: 2px solid green !important;
}
.colTrail{
font-width: 300;
color: green ;
//border-left: 2px solid green !important;
//border-right: 2px solid green !important;
border-bottom: 2px solid green !important;
}


.k-grid-header .k-header.colIncomeDistribution,
.k-grid-header .k-header.colGroupLoanDetails{
background-color: #ffeabe;
}
.k-grid-header .k-header.colIncomeDistribution,
.k-grid-header .k-header.colGroupLoanDetails{
background-color: #ffeabe;
}


.red {
color: #d9534f;
}
.red {
color: #d9534f;
}


.text-bold {
font-weight: 600;
.text-bold {
font-weight: 600;
}
} }



+ 13
- 3
src/app/list-all-loans/list-all-loans.component.ts Просмотреть файл

selector: 'app-list-all-loans', selector: 'app-list-all-loans',
templateUrl: './list-all-loans.component.html', templateUrl: './list-all-loans.component.html',
styleUrls: ['./list-all-loans.component.scss'], styleUrls: ['./list-all-loans.component.scss'],
encapsulation: ViewEncapsulation.None,
encapsulation: ViewEncapsulation.Emulated,
animations: [ animations: [
trigger('fadeIn', [ trigger('fadeIn', [
transition(':enter', [ transition(':enter', [
public pageSize = 10; public pageSize = 10;
public skip = 0; public skip = 0;
@Output() LoanSelected: EventEmitter<LoanModel[]|LoanModel> = new EventEmitter<LoanModel[]|LoanModel>(); @Output() LoanSelected: EventEmitter<LoanModel[]|LoanModel> = new EventEmitter<LoanModel[]|LoanModel>();
@Output() Cancelled: EventEmitter<LoanModel[]|LoanModel> = new EventEmitter<LoanModel[]|LoanModel>();
@Output() LoanClicked: EventEmitter<LoanModel> = new EventEmitter<LoanModel>(); @Output() LoanClicked: EventEmitter<LoanModel> = new EventEmitter<LoanModel>();


@Input() EnableExportExcel = false; @Input() EnableExportExcel = false;
@Input() EnableExportPdf = false; @Input() EnableExportPdf = false;
@Input() EnableSelectButton = false; @Input() EnableSelectButton = false;
@Input() FinishButtonText = 'Finish Select';
@Input() MaxSelect = 1; @Input() MaxSelect = 1;
@Input() Preselect: LoanModel[] = []; @Input() Preselect: LoanModel[] = [];
public SelectedLoans: LoanModel[] = []; public SelectedLoans: LoanModel[] = [];
this.LoanSelected.emit(this.SelectedLoans); this.LoanSelected.emit(this.SelectedLoans);
} }


console.log('loan selected', this);
this.notifyUser('ended');
this.notifyUser('try to save');
}

public onCancelSelection(): void{
if ( this.MaxSelect === 1 ){
this.Cancelled.emit(this.SelectedLoans[0]);
}else{
this.Cancelled.emit(this.SelectedLoans);
}
this.notifyUser('cancel saving');
} }


public RemoveFromSelection(l: LoanModel): void{ public RemoveFromSelection(l: LoanModel): void{

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

<div class="card loan" (click)="onClick()" *ngIf="Loan!==undefined"> <div class="card loan" (click)="onClick()" *ngIf="Loan!==undefined">
<span class="badge badge-success">{{Loan.Item}}</span> <span class="badge badge-success">{{Loan.Item}}</span>
<span> Amount: {{Loan.Amount | currency }}</span> <span> Amount: {{Loan.Amount | currency }}</span>
<span> Settlement: {{Loan.Settlement | date:'yyyy-mm-dd' }}</span>
<span> Settlement: {{Loan.Settlement | date:'yyyy-MM-dd' }}</span>
<span *ngIf="ShowCloseButton" class="k-icon k-i-close-circle close" (click)="onClose()" size="large"></span> <span *ngIf="ShowCloseButton" class="k-icon k-i-close-circle close" (click)="onClose()" size="large"></span>
</div> </div>



+ 8
- 1
src/app/loan-select/loan-select.component.html Просмотреть файл

</div> </div>


<kendo-popup [offset]="Offset" (anchorViewportLeave)="showPopup = false" *ngIf="showPopup"> <kendo-popup [offset]="Offset" (anchorViewportLeave)="showPopup = false" *ngIf="showPopup">
<button kendoButton look="flat"
class="close-popup" icon="close-circle" style="float:right;"
(click)="onToggle()"
></button>
<div class='popup-content'> <div class='popup-content'>
<app-list-all-loans #list <app-list-all-loans #list
(LoanSelected)="onLoanSelected($event)"
[EnableSelectButton]="true" [EnableSelectButton]="true"
[SingleSelection]="true" [SingleSelection]="true"
[MaxSelect]="Max" [MaxSelect]="Max"
[Preselect]="[Loan]" [Preselect]="[Loan]"
[FinishButtonText]="FinishButtonText"
(LoanClicked)="onClickLoan($event)"
(LoanSelected)="onLoanSelected($event)"
> >
</app-list-all-loans> </app-list-all-loans>
</div> </div>

+ 8
- 0
src/app/loan-select/loan-select.component.scss Просмотреть файл

z-index: 1; z-index: 1;
} }
} }

button.close-popup{
float: right;
position: absolute;
right: 0px;
border-radius: 100%;
z-index: 1;
}

+ 12
- 2
src/app/loan-select/loan-select.component.ts Просмотреть файл

@Output() valueChange: EventEmitter<LoanModel> = new EventEmitter<LoanModel>(); @Output() valueChange: EventEmitter<LoanModel> = new EventEmitter<LoanModel>();
public Loan: LoanModel; // for multiple selection ,it has to be array; we don't support it now. public Loan: LoanModel; // for multiple selection ,it has to be array; we don't support it now.


public FinishButtonText = 'Save';
// popup // popup
public showPopup = false; public showPopup = false;
public Offset = { left: 10, top: 48 }; public Offset = { left: 10, top: 48 };
if (!this.touched) { if (!this.touched) {
this.onTouched(); this.onTouched();
this.touched = true; this.touched = true;
this.FinishButtonText = 'Save & Close';
} }
} }


onLoanSelected(loan: LoanModel): void { onLoanSelected(loan: LoanModel): void {
if (this.Loan.Id !== loan.Id){
if (loan !== undefined && this.Loan !== undefined && this.Loan.Id !== loan.Id){
this.valueChange.emit(loan); this.valueChange.emit(loan);
this.onChange(loan); this.onChange(loan);
this.Loan = loan; this.Loan = loan;
} }
this.Loan = loan;
if (loan === undefined || loan == null ){
this.Loan = new LoanModel({});
}else{
this.Loan = loan;
}

this.markAsTouched(); this.markAsTouched();
this.onTouched(); this.onTouched();


this.showPopup = false; this.showPopup = false;
} }


onClickLoan(loan: LoanModel): void {
this.markAsTouched();
}


public onToggle(): void { public onToggle(): void {
this.showPopup = !this.showPopup; this.showPopup = !this.showPopup;

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

</ng-template> </ng-template>
</kendo-grid-column> </kendo-grid-column>


<kendo-grid-column field="Lender" title="Lender" width="150" editor="string">
<kendo-grid-column field="Lender" title="Lender" width="150" >
<ng-template kendoGridEditTemplate let-dataItem>
<kendo-combobox
[formControl]="incomeFormGroup.get('Lender')"
[data]="funderListView | async"
[loading]="funderListService.loading">
</kendo-combobox>
</ng-template>
</kendo-grid-column>
<kendo-grid-column field="LoanNumber" title="Lender Loan Id" width="150" editor="string">
</kendo-grid-column> </kendo-grid-column>


<kendo-grid-column field="IncomeAmount" title="Income" width="150" format="{0:c}" editor="numeric"> <kendo-grid-column field="IncomeAmount" title="Income" width="150" format="{0:c}" editor="numeric">
</ng-template> </ng-template>
<ng-template kendoGridEditTemplate let-dataItem> <ng-template kendoGridEditTemplate let-dataItem>
<app-loan-select [formControl]="incomeFormGroup.get('Loan')" (valueChange)="onLoanChange($event)" <app-loan-select [formControl]="incomeFormGroup.get('Loan')" (valueChange)="onLoanChange($event)"
[readOnly]="this.filterLoan !== undefined && this.filterLoan.Id !==''"
[Max]="1" [readOnly]="this.filterLoan !== undefined && this.filterLoan.Id !==''"
></app-loan-select> ></app-loan-select>
</ng-template> </ng-template>
</kendo-grid-column> </kendo-grid-column>

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

import {LoanModel} from '../models/loan.model'; import {LoanModel} from '../models/loan.model';
import {LoanSingleService} from '../service/loan.single.service'; import {LoanSingleService} from '../service/loan.single.service';
import {PayInModelEx} from '../models/pay-in-ex.model'; import {PayInModelEx} from '../models/pay-in-ex.model';
import {Observable} from 'rxjs';
import {FunderNameService} from '../service/funder.name.service';






}; };


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


constructor(private pis: PayInService, private lss: LoanSingleService, private router: Router) { }

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


ngOnInit(): void { ngOnInit(): void {
this.debouncedLoadFilteredData = debounce(this.loadFilteredData, 500); this.debouncedLoadFilteredData = debounce(this.loadFilteredData, 500);
Id: new FormControl({value: dataItem.Id, disabled: true}, Validators.required), Id: new FormControl({value: dataItem.Id, disabled: true}, Validators.required),
Lender: new FormControl({value: dataItem.Lender, disabled: Loan.Id !== '' }, Validators.required), Lender: new FormControl({value: dataItem.Lender, disabled: Loan.Id !== '' }, Validators.required),
Amount: new FormControl(dataItem.Amount), Amount: new FormControl(dataItem.Amount),
LoanNumber: new FormControl(dataItem.LoanNumber, Validators.required),
LoanNumber: new FormControl({value: dataItem.LoanNumber, disabled: Loan.Id !== ''}, Validators.required),
IncomeAmount: new FormControl(dataItem.IncomeAmount, Validators.required), IncomeAmount: new FormControl(dataItem.IncomeAmount, Validators.required),
IncomeType: new FormControl(dataItem.IncomeType, Validators.required), IncomeType: new FormControl(dataItem.IncomeType, Validators.required),
Ts: new FormControl(dataItem.Ts, Validators.required), Ts: new FormControl(dataItem.Ts, Validators.required),
pi.Balance = v.Balance; pi.Balance = v.Balance;
pi.Lender = loan.Id === '' ? v.Lender : loan.Lender; pi.Lender = loan.Id === '' ? v.Lender : loan.Lender;
pi.LoanId = loan.Id; pi.LoanId = loan.Id;
pi.LoanNumber = loan.LenderLoanNumber;
pi.LoanNumber = loan.Id === '' ? v.LoanNumber : loan.LenderLoanNumber;
pi.OffsetBalance = v.OffsetBalance; pi.OffsetBalance = v.OffsetBalance;
pi.Settlement = loan.Settlement; pi.Settlement = loan.Settlement;
pi.IncomeAmount = v.IncomeAmount; pi.IncomeAmount = v.IncomeAmount;
if ( loan.Id !== '' ) { if ( loan.Id !== '' ) {
this.incomeFormGroup.get('Lender').setValue(loan.Lender); this.incomeFormGroup.get('Lender').setValue(loan.Lender);
this.incomeFormGroup.get('Lender').disable({onlySelf: true, emitEvent: false}); 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});
} }
} }
} }

+ 15
- 14
src/app/service/auth.service.ts Просмотреть файл





public getUrl(key: string): string{ public getUrl(key: string): string{
const s = this.apiUrl + key;
const kvPair: {key: string, value: string}[] = [
{key: 'login', value: this.apiUrl + 'login'},
{key: 'logout', value: this.apiUrl + 'logout'}
];

kvPair.forEach( item => {
if ( item.key === key) {
return item.value;
}
});

// not found if arrive here
return s;
return this.config.getUrl(key);
// const s = this.apiUrl + key;
// const kvPair: {key: string, value: string}[] = [
// {key: 'login', value: this.apiUrl + 'login'},
// {key: 'logout', value: this.apiUrl + 'logout'}
// ];
//
// kvPair.forEach( item => {
// if ( item.key === key) {
// return item.value;
// }
// });
//
// // not found if arrive here
// return s;
} }


public UpdatePeopleInfo(people: PeopleModel): void{ public UpdatePeopleInfo(people: PeopleModel): void{

+ 24
- 0
src/app/service/funder.name.service.ts Просмотреть файл

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {AppConfig} from '../app.config';
import {BehaviorSubject, Observable} from 'rxjs';
import {tap} from 'rxjs/operators';

@Injectable()
export class FunderNameService extends BehaviorSubject<string[]> {
public loading = false;
constructor( private http: HttpClient, private config: AppConfig) {
super(null);
}

public query(): void {
this.fetch().subscribe( x => super.next(x));
}

private fetch(): Observable<string[]>{
this.loading = true;
return this.http.get<string[]>(this.config.getUrl('funder-list/')).pipe(
tap(() => this.loading = false)
);
}
}

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