Quellcode durchsuchen

loan search and cancel + list of lenders from database

tags/2.037
Patrick Sun vor 4 Jahren
Ursprung
Commit
ccf1dc479e
12 geänderte Dateien mit 196 neuen und 111 gelöschten Zeilen
  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 Datei anzeigen

@@ -100,6 +100,7 @@ import { UploadingProgressCardComponent } from './uploading-progress-card/upload
import { LoanSelectComponent } from './loan-select/loan-select.component';
import {PopupModule} from '@progress/kendo-angular-popup';
import { LoansAllComponent } from './loans-all/loans-all.component';
import {FunderNameService} from './service/funder.name.service';



@@ -214,6 +215,7 @@ export function initializeApp(appConfig: AppConfig): () => Promise<void> {
WebSocketService,
LoanSummaryService,
LoanSingleService,
FunderNameService,
{
provide: HTTP_INTERCEPTORS,
useClass: AuthHttpInterceptor,

+ 2
- 3
src/app/list-all-loans/list-all-loans.component.html Datei anzeigen

@@ -33,10 +33,9 @@
<span class="badge badge-info">{{MaxSelect}}</span>
</div>
<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()"
>
Finish Selection</button>
>{{FinishButtonText}}</button>

</ng-template>


+ 84
- 82
src/app/list-all-loans/list-all-loans.component.scss Datei anzeigen

@@ -1,100 +1,102 @@
.fullheight_grid {
kendo-grid.fullheight_grid {
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 Datei anzeigen

@@ -21,7 +21,7 @@ import {animate, style, transition, trigger} from '@angular/animations';
selector: 'app-list-all-loans',
templateUrl: './list-all-loans.component.html',
styleUrls: ['./list-all-loans.component.scss'],
encapsulation: ViewEncapsulation.None,
encapsulation: ViewEncapsulation.Emulated,
animations: [
trigger('fadeIn', [
transition(':enter', [
@@ -44,11 +44,13 @@ export class ListAllLoansComponent implements OnInit {
public pageSize = 10;
public skip = 0;
@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>();

@Input() EnableExportExcel = false;
@Input() EnableExportPdf = false;
@Input() EnableSelectButton = false;
@Input() FinishButtonText = 'Finish Select';
@Input() MaxSelect = 1;
@Input() Preselect: LoanModel[] = [];
public SelectedLoans: LoanModel[] = [];
@@ -160,8 +162,16 @@ export class ListAllLoansComponent implements OnInit {
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{

+ 1
- 1
src/app/loan-card/loan-card.component.html Datei anzeigen

@@ -1,7 +1,7 @@
<div class="card loan" (click)="onClick()" *ngIf="Loan!==undefined">
<span class="badge badge-success">{{Loan.Item}}</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>
</div>


+ 8
- 1
src/app/loan-select/loan-select.component.html Datei anzeigen

@@ -5,13 +5,20 @@
</div>

<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'>
<app-list-all-loans #list
(LoanSelected)="onLoanSelected($event)"
[EnableSelectButton]="true"
[SingleSelection]="true"
[MaxSelect]="Max"
[Preselect]="[Loan]"
[FinishButtonText]="FinishButtonText"
(LoanClicked)="onClickLoan($event)"
(LoanSelected)="onLoanSelected($event)"
>
</app-list-all-loans>
</div>

+ 8
- 0
src/app/loan-select/loan-select.component.scss Datei anzeigen

@@ -23,3 +23,11 @@ div.anchor.wrapper {
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 Datei anzeigen

@@ -22,6 +22,7 @@ export class LoanSelectComponent implements OnInit, ControlValueAccessor {
@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 FinishButtonText = 'Save';
// popup
public showPopup = false;
public Offset = { left: 10, top: 48 };
@@ -56,22 +57,31 @@ export class LoanSelectComponent implements OnInit, ControlValueAccessor {
if (!this.touched) {
this.onTouched();
this.touched = true;
this.FinishButtonText = 'Save & Close';
}
}

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.onChange(loan);
this.Loan = loan;
}
this.Loan = loan;
if (loan === undefined || loan == null ){
this.Loan = new LoanModel({});
}else{
this.Loan = loan;
}

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

this.showPopup = false;
}

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

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

+ 11
- 2
src/app/pay-in/pay-in.component.html Datei anzeigen

@@ -48,7 +48,16 @@
</ng-template>
</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 field="IncomeAmount" title="Income" width="150" format="{0:c}" editor="numeric">
@@ -133,7 +142,7 @@
</ng-template>
<ng-template kendoGridEditTemplate let-dataItem>
<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>
</ng-template>
</kendo-grid-column>

+ 16
- 3
src/app/pay-in/pay-in.component.ts Datei anzeigen

@@ -13,6 +13,8 @@ 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';



@@ -48,9 +50,17 @@ export class PayInComponent implements OnInit {
};

public loading = false;
public funderListView: Observable<string[]>;
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 {
this.debouncedLoadFilteredData = debounce(this.loadFilteredData, 500);
@@ -141,7 +151,7 @@ export class PayInComponent implements OnInit {
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(dataItem.LoanNumber, Validators.required),
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),
@@ -203,7 +213,7 @@ export class PayInComponent implements OnInit {
pi.Balance = v.Balance;
pi.Lender = loan.Id === '' ? v.Lender : loan.Lender;
pi.LoanId = loan.Id;
pi.LoanNumber = loan.LenderLoanNumber;
pi.LoanNumber = loan.Id === '' ? v.LoanNumber : loan.LenderLoanNumber;
pi.OffsetBalance = v.OffsetBalance;
pi.Settlement = loan.Settlement;
pi.IncomeAmount = v.IncomeAmount;
@@ -297,6 +307,9 @@ export class PayInComponent implements OnInit {
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});
}
}
}

+ 15
- 14
src/app/service/auth.service.ts Datei anzeigen

@@ -122,20 +122,21 @@ export class AuthService {


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{

+ 24
- 0
src/app/service/funder.name.service.ts Datei anzeigen

@@ -0,0 +1,24 @@
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)
);
}
}

Laden…
Abbrechen
Speichern