diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 71c8474..988f895 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -7,8 +7,8 @@ import { AuthGuard } from './service/auth-guard.service'; import { TransactionListComponent } from './transaction-list/transaction-list.component'; import { TransactionComponent } from './transaction/transaction.component'; import {ListAllLoansComponent} from './list-all-loans/list-all-loans.component'; -import {LoanAddNewComponent} from './loan-add-new/loan-add-new.component'; import {LoanEditComponent} from './loan-edit/loan-edit.component'; +import {LenderUploadsComponent} from './lender-uploads/lender-uploads.component'; const routes: Routes = [ @@ -21,6 +21,8 @@ const routes: Routes = [ {path : 'list-all-loans', component: ListAllLoansComponent, }, {path : 'edit-loan/:id', component: LoanEditComponent, }, {path : 'edit-loan', component: LoanEditComponent, }, + {path : 'uploads', component: LenderUploadsComponent, }, + {path : 'uploads/:id', component: LenderUploadsComponent, }, ]; @NgModule({ diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9e8bb4c..388b678 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -65,6 +65,7 @@ import {LoanSingleService} from './service/loan.single.service'; import { RatingInputComponent } from './rating-input/rating-input.component'; import { LoanEditPeopleComponent } from './loan-edit-people/loan-edit-people.component'; import { PeopleCardComponent } from './people-card/people-card.component'; +import { LenderUploadsComponent } from './lender-uploads/lender-uploads.component'; @@ -100,7 +101,8 @@ import { PeopleCardComponent } from './people-card/people-card.component'; LoanDetailComponent, RatingInputComponent, LoanEditPeopleComponent, - PeopleCardComponent + PeopleCardComponent, + LenderUploadsComponent ], imports: [ BrowserModule, diff --git a/src/app/lender-uploads/lender-uploads.component.html b/src/app/lender-uploads/lender-uploads.component.html new file mode 100644 index 0000000..34551fa --- /dev/null +++ b/src/app/lender-uploads/lender-uploads.component.html @@ -0,0 +1 @@ +

lender-uploads works!

diff --git a/src/app/lender-uploads/lender-uploads.component.scss b/src/app/lender-uploads/lender-uploads.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/lender-uploads/lender-uploads.component.spec.ts b/src/app/lender-uploads/lender-uploads.component.spec.ts new file mode 100644 index 0000000..5bf8433 --- /dev/null +++ b/src/app/lender-uploads/lender-uploads.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LenderUploadsComponent } from './lender-uploads.component'; + +describe('LenderUploadsComponent', () => { + let component: LenderUploadsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LenderUploadsComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(LenderUploadsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/lender-uploads/lender-uploads.component.ts b/src/app/lender-uploads/lender-uploads.component.ts new file mode 100644 index 0000000..b0441da --- /dev/null +++ b/src/app/lender-uploads/lender-uploads.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-lender-uploads', + templateUrl: './lender-uploads.component.html', + styleUrls: ['./lender-uploads.component.scss'] +}) +export class LenderUploadsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/loan-edit-people/loan-edit-people.component.html b/src/app/loan-edit-people/loan-edit-people.component.html index 04541f2..6e425ae 100644 --- a/src/app/loan-edit-people/loan-edit-people.component.html +++ b/src/app/loan-edit-people/loan-edit-people.component.html @@ -76,7 +76,7 @@
- +
diff --git a/src/app/loan-edit-people/loan-edit-people.component.ts b/src/app/loan-edit-people/loan-edit-people.component.ts index 8ef2921..6130c65 100644 --- a/src/app/loan-edit-people/loan-edit-people.component.ts +++ b/src/app/loan-edit-people/loan-edit-people.component.ts @@ -88,7 +88,6 @@ export class LoanEditPeopleComponent implements OnInit, AfterViewInit { return; } - console.log(this.Loan.Client, this.Loan.Broker, this.Loan.OtherRewarder, this.role); this.ps.syncPeople(this.Loan.cloneForJson()).subscribe( resp => {}); this.NotifyNext.emit(true); } diff --git a/src/app/loan-edit/basicinfo/basicinfo.component.html b/src/app/loan-edit/basicinfo/basicinfo.component.html index 2b96d09..122a7b7 100644 --- a/src/app/loan-edit/basicinfo/basicinfo.component.html +++ b/src/app/loan-edit/basicinfo/basicinfo.component.html @@ -1,5 +1,5 @@
-
+
 Basic Information {{Loan.Lender}}
@@ -94,14 +94,11 @@
- +
-
- -
diff --git a/src/app/loan-edit/loan-edit.component.html b/src/app/loan-edit/loan-edit.component.html index 0b6dbb5..afe6796 100644 --- a/src/app/loan-edit/loan-edit.component.html +++ b/src/app/loan-edit/loan-edit.component.html @@ -4,8 +4,8 @@
-
-
+
+
{ console.log(resp); this.showError('Loan' + resp + 'has been deleted'); - this.navigateTo='./#list-all-loans'; + this.navigateTo = './#list-all-loans'; }, err => { this.showError('Error Occurred, cannot delete: ' + err.toString()); @@ -89,7 +84,7 @@ export class LoanEditComponent implements OnInit { public loadLoanById(id: string): void { const self = this; - console.log('loading loan for edit ... ', id); + // console.log('loading loan for edit ... ', id); this.lss.getLoan(id).subscribe( resp => { this.Loan.Response = resp; diff --git a/src/app/loan-edit/people-reward/people-reward.component.html b/src/app/loan-edit/people-reward/people-reward.component.html index a521361..e9f39b6 100644 --- a/src/app/loan-edit/people-reward/people-reward.component.html +++ b/src/app/loan-edit/people-reward/people-reward.component.html @@ -161,7 +161,7 @@
- +
diff --git a/src/app/loan-edit/people-reward/people-reward.component.ts b/src/app/loan-edit/people-reward/people-reward.component.ts index 9a3af16..cef1b24 100644 --- a/src/app/loan-edit/people-reward/people-reward.component.ts +++ b/src/app/loan-edit/people-reward/people-reward.component.ts @@ -66,8 +66,8 @@ export class PeopleRewardComponent implements OnInit { constructor(private ls: LoanSingleService, private auth: AuthService, - private dcs: ClonerService, - private ps: PeopleService) { + private dcs: ClonerService + ) { } public ngOnInit(): void { @@ -141,6 +141,8 @@ export class PeopleRewardComponent implements OnInit { this.pendingReward[idx].Amount = reward.Amount; this.pendingReward[idx].Description = reward.Description; this.pendingReward[idx].Ts = reward.Ts; + // update Loan + this.Loan.updateReward(resp.Amount, resp.Description, resp.Id, resp.LoanId, resp.PayOutId, resp.To, resp.From, resp.Ts); } // console.log(resp); } diff --git a/src/app/loan-edit/trail-income/trail-income.component.html b/src/app/loan-edit/trail-income/trail-income.component.html index 914b68f..56e1aef 100644 --- a/src/app/loan-edit/trail-income/trail-income.component.html +++ b/src/app/loan-edit/trail-income/trail-income.component.html @@ -1,80 +1,141 @@
-
- -  Record from {{Loan.Lender}} -
- -
+ + + +  Record from {{Loan.Lender}} +
+ +
+ +
+ + + + + Unique Name for a fund provider (readonly after income data is available) + Error: Lender name is required + +
+ + + + + Unique transaction ID from Funds supplier (readonly after income data is available) + Error: the ID is required + +
-
- - - - - Unique Name for a fund provider - Error: Lender name is required - -
- - - - - Unique transaction ID from Funds supplier - Error: the ID is required - -
- - -   Monthly Income - - - - - - - - - - - - - - - - + +   Monthly Income + - - - {{ dataItem.Ts | date: 'yyyy-MM-dd' }} + + + - - - + + + + + + + + + + + + + + + + + + {{ dataItem.Ts | date: 'yyyy-MM-dd' }} + + + + + +
{{ dataItem.Balance | currency}}
+
unknown
+
+ + + + + + + + + +
+ + + + +
{{ dataItem.OffsetBalance | currency}}
+
unknown
+
+ + + + + + + + +
+ + + + +

-

+
+
- - +
- + +
- -
+
-
-
-
-
- +
+
+ + + +
-
+
diff --git a/src/app/loan-edit/trail-income/trail-income.component.scss b/src/app/loan-edit/trail-income/trail-income.component.scss index f869615..e75ae50 100644 --- a/src/app/loan-edit/trail-income/trail-income.component.scss +++ b/src/app/loan-edit/trail-income/trail-income.component.scss @@ -2,3 +2,13 @@ div.vertical-spacer { height: 10px; margin-bottom: 30px; } + +input { + width:100%; +} + +.balance { + display: inline-block; + margin-left: 0px !important; + width: calc(100% - 60px) !important; +} diff --git a/src/app/loan-edit/trail-income/trail-income.component.ts b/src/app/loan-edit/trail-income/trail-income.component.ts index 66f176a..2efa892 100644 --- a/src/app/loan-edit/trail-income/trail-income.component.ts +++ b/src/app/loan-edit/trail-income/trail-income.component.ts @@ -1,13 +1,18 @@ import {Component, Input, OnInit, Output, EventEmitter} from '@angular/core'; -import {FormControl, FormGroup, Validators} from '@angular/forms'; +import {FormControl, FormGroup, NgForm, Validators} from '@angular/forms'; import {LoanModel} from '../../models/loan.model'; +import {LoanSingleService} from '../../service/loan.single.service'; +import {AuthService} from '../../service/auth.service'; +import {PayInModel} from '../../models/pay-in.model'; +import {Router} from '@angular/router'; const createFormGroup = dataItem => new FormGroup({ - Amount : new FormControl(dataItem.Amount), - Ts: new FormControl(dataItem.Ts), - Balance: new FormControl(dataItem.Balance), - OffsetBalance: new FormControl(dataItem.OffsetBalance), + Id: new FormControl({value: dataItem.Id, disabled: true}, Validators.required), + Trail : new FormControl(dataItem.Trail, Validators.required), + Ts: new FormControl(dataItem.Ts, Validators.required), + Balance: new FormControl(dataItem.Balance, Validators.required), + OffsetBalance: new FormControl(dataItem.OffsetBalance, Validators.required), }); @Component({ @@ -17,32 +22,45 @@ const createFormGroup = dataItem => new FormGroup({ }) export class TrailIncomeComponent implements OnInit { @Input() public Loan: LoanModel; - @Input() public LenderName: string; + @Output() public NotifyNext = new EventEmitter(); @Output() public NotifyPrev = new EventEmitter(); @Output() public errorOccurred = new EventEmitter(); - public gridData: any[] = []; - public formGroup: FormGroup; private editedRowIndex: number; - public trailIncome: FormGroup = new FormGroup({ - LenderLoanNumber: new FormControl(), - Lender: new FormControl(), - }); + public trailIncome: FormGroup; + public showBalance = true; + public showOffsetBalance = true; - constructor() { } - ngOnInit(): void { } + constructor(private ls: LoanSingleService, + private auth: AuthService, + private router: Router) { } + ngOnInit(): void { + // this.Loan.PayIn + } public addHandler({ sender }): void { this.closeEditor(sender); + let balance = -1; + let offsetBalance = -1; + if ( this.Loan.PayIn.length >= 0) { + const idx = this.Loan.PayIn.length -1; + balance = this.Loan.PayIn[idx].Balance; + offsetBalance = this.Loan.PayIn[idx].OffsetBalance; + } + + this.showBalance = balance >= 0 ; + this.showOffsetBalance = offsetBalance >= 0 ; + this.formGroup = createFormGroup({ - Amount: 1000, - Ts: new Date('2020-05-20'), - Balance: 800000, - OffsetBalance: 600000 + Id: 0, + Trail: 168, + Ts: new Date(), + Balance: balance, + OffsetBalance: offsetBalance }); sender.addRow(this.formGroup); @@ -51,15 +69,11 @@ export class TrailIncomeComponent implements OnInit { public editHandler({ sender, rowIndex, dataItem }): void { this.closeEditor(sender); - if ( dataItem.Paid ) { - alert( 'cannot edit'); - }else{ - this.formGroup = createFormGroup(dataItem); - - this.editedRowIndex = rowIndex; - - sender.editRow(rowIndex, this.formGroup); - } + this.showBalance = dataItem.Balance >= 0 ; + this.showOffsetBalance = dataItem.OffsetBalance >= 0 ; + this.formGroup = createFormGroup(dataItem); + this.editedRowIndex = rowIndex; + sender.editRow(rowIndex, this.formGroup); } @@ -69,17 +83,47 @@ export class TrailIncomeComponent implements OnInit { } public saveHandler({ sender, rowIndex, formGroup, isNew }): void { - const product = formGroup.value; - - console.log('saving', product, formGroup); - // this.service.save(product, isNew); + const v = formGroup.getRawValue(); + + if ( !this.showBalance) { v.Balance = -1; } + if ( !this.showOffsetBalance) { v.OffsetBalance = -1; } + + const pi = new PayInModel( + v.Id, + this.Loan.Amount, + v.Balance, + this.Loan.Lender, + this.Loan.Id, + this.Loan.LenderLoanNumber, + v.OffsetBalance, + this.Loan.Settlement, + v.Trail, + v.Ts, + 0, + ); + + console.log('saving PayIn', pi); + this.ls.savePayIn(pi, isNew).subscribe( + (resp: PayInModel) => { + this.Loan.cuPayIn(resp); + }, + err => { + this.errorOccurred.emit('Error saving Income'); + } + ); sender.closeRow(rowIndex); } public removeHandler({ dataItem }): void { console.log(dataItem); - // this.service.remove(dataItem); + + const na = this.Loan.PayIn.filter(v => { + return v.Id !== dataItem.Id; + }); + + this.Loan.PayIn = na; + this.ls.removePayIn(dataItem.Id); } private closeEditor(grid, rowIndex = this.editedRowIndex): void{ @@ -88,11 +132,17 @@ export class TrailIncomeComponent implements OnInit { this.formGroup = undefined; } - public next(): void{ + public next(trailIncome: NgForm): void{ this.NotifyNext.emit(true); + this.router.navigate(['./list-all-loans']); } public prev(): void { this.NotifyPrev.emit(true); } + + public visitUploads(pi: PayInModel): void { + this.router.navigate(['./uploads/' + pi.Uploads]); + } + } diff --git a/src/app/main-menu-items.ts b/src/app/main-menu-items.ts index 1eef3b4..3e3f0fa 100644 --- a/src/app/main-menu-items.ts +++ b/src/app/main-menu-items.ts @@ -29,7 +29,7 @@ export const mainMenuItems: any[] = [ { text: 'List All', icon: 'table', url: '#' }, { text: 'By Broker', icon: 'table', url: '#' }, { text: '--', separator: 'true' }, - { text: 'PaidImport From ...', icon : 'upload'} + { text: 'Lender Monthly Uploads', icon: 'attachment' , url: './#uploads'} ] }, { diff --git a/src/app/models/loan.model.ts b/src/app/models/loan.model.ts index ea7e16e..8169fba 100644 --- a/src/app/models/loan.model.ts +++ b/src/app/models/loan.model.ts @@ -67,7 +67,7 @@ export class LoanModel { this.setReward(resp.Reward); this.setRewardPeople(resp.RewardPeople); this.PeopleMap = resp.PeopleMap; - this.PayIn = resp.PayIn; + this.setPayIn(resp.PayIn); } private setReward(v: any[]): void{ @@ -86,6 +86,49 @@ export class LoanModel { return; } + private setPayIn(v: any[]): void{ + this.PayIn = []; + v.forEach( pi =>{ + this.PayIn.push(new PayInModel( + pi.Id, + pi.Amount, + pi.Balance, + pi.Lender, + pi.LoanId, + pi.LoanNumber, + pi.OffsetBalance, + new Date(pi.Settlement), + pi.Trail, + new Date(pi.Ts), + pi.Uploads, + )); + }); + } + + // Create or Update PayIn + public cuPayIn(pi: PayInModel): void{ + // remove existing one + const na = this.PayIn.filter(v => v.Id !== pi.Id ); + // add the incoming one + na.unshift( + new PayInModel( + pi.Id, + pi.Amount, + pi.Balance, + pi.Lender, + pi.LoanId, + pi.LoanNumber, + pi.OffsetBalance, + new Date(pi.Settlement), + pi.Trail, + new Date(pi.Ts), + pi.Uploads, + ) + ); + // update array element + this.PayIn = na; + } + private setClient(v: any[]): void{ this.Client = []; v.forEach((c) => { @@ -140,6 +183,32 @@ export class LoanModel { return r; } + public updateReward(Amount: number, Description: string, Id: number, + LoanId: string, PayOutId: number, To: string , From: string, Ts: Date): RewardModel { + const r = new RewardModel( + Amount, + Description, + Id, + LoanId, + PayOutId, + To, + From, + new Date(Ts), + this.callBacks() + ); + r.LoanId = this.Id; // Make sure Loan Id is same + const idx = this.Reward.findIndex( v => v.Id === Id ); + this.Reward[idx].Amount = Amount; + this.Reward[idx].Description = Description; + this.Reward[idx].LoanId = r.LoanId; // Ensure Loan Id is correct + this.Reward[idx].PayOutId = PayOutId; + this.Reward[idx].To = To; + this.Reward[idx].From = From; + this.Reward[idx].Ts = new Date(Ts); + + return r; + } + public removeReward(Id: number): void { const na = this.Reward.filter(v => v.Id !== Id ); this.Reward = na; diff --git a/src/app/models/pay-in.model.ts b/src/app/models/pay-in.model.ts index e127bcb..a49a568 100644 --- a/src/app/models/pay-in.model.ts +++ b/src/app/models/pay-in.model.ts @@ -1,4 +1,16 @@ export class PayInModel { - Id: number; + constructor( + public Id: number, + public Amount: number, + public Balance: number, + public Lender: string, + public LoanId: string, + public LoanNumber: string, + public OffsetBalance: number, + public Settlement: Date, + public Trail: number, + public Ts: Date, + public Uploads: number + ){} } diff --git a/src/app/service/loan.single.service.ts b/src/app/service/loan.single.service.ts index 91a708d..e59171f 100644 --- a/src/app/service/loan.single.service.ts +++ b/src/app/service/loan.single.service.ts @@ -5,6 +5,7 @@ import {LoanModel} from '../models/loan.model'; import {Injectable} from '@angular/core'; import {RewardModel} from '../models/reward.model'; import {ClonerService} from './clone.service'; +import {PayInModel} from '../models/pay-in.model'; @Injectable() export class LoanSingleService { @@ -36,6 +37,19 @@ export class LoanSingleService { ); } + public savePayIn(payIn: PayInModel, isNew: boolean): Observable { + return this.http.post(this.auth.getUrl('payIn/'), payIn); + } + + public removePayIn(id: number): void { + this.http.delete(this.auth.getUrl('payIn/' + id)).subscribe( + resp => { + console.log(resp); + } + ); + } + + // delete means more than remove, it removes relevant data too public deleteLoan(id: string): Observable { return this.http.delete(this.auth.getUrl('loan/' + id)); }