Преглед изворни кода

reward edit is finished.

tags/2.037
Patrick Sun пре 4 година
родитељ
комит
03f0085ef1
10 измењених фајлова са 233 додато и 117 уклоњено
  1. +1
    -1
      src/app/loan-edit/loan-edit.component.ts
  2. +15
    -10
      src/app/loan-edit/people-reward/people-reward.component.html
  3. +41
    -27
      src/app/loan-edit/people-reward/people-reward.component.ts
  4. +4
    -0
      src/app/loan-edit/people-select/people-select.component.scss
  5. +61
    -16
      src/app/loan-edit/people-select/people-select.component.ts
  6. +19
    -15
      src/app/models/broker.model.ts
  7. +65
    -11
      src/app/models/loan.model.ts
  8. +1
    -36
      src/app/models/people.model.ts
  9. +11
    -1
      src/app/service/loan.single.service.ts
  10. +15
    -0
      src/app/service/people.service.ts

+ 1
- 1
src/app/loan-edit/loan-edit.component.ts Прегледај датотеку





ngOnInit(): void { ngOnInit(): void {
const demoId = '02ad4e5a-fb5c-4f29-bc89-381a49d77bb7';
const demoId = '049836b8-07ad-448a-b048-865e8e85f1fe';
this.loadLoanById(demoId); this.loadLoanById(demoId);
} }



+ 15
- 10
src/app/loan-edit/people-reward/people-reward.component.html Прегледај датотеку

(remove)="removeHandler($event)" (remove)="removeHandler($event)"
> >
<ng-template kendoGridToolbarTemplate> <ng-template kendoGridToolbarTemplate>
<button kendoGridAddCommand>Add new</button>
<button kendoGridAddCommand icon="plus" [primary]="true">Add new</button>
</ng-template> </ng-template>


<kendo-grid-command-column title="command" width="220">
<kendo-grid-command-column title="action" width="80">
<ng-template kendoGridCellTemplate let-isNew="isNew" let-dataItem> <ng-template kendoGridCellTemplate let-isNew="isNew" let-dataItem>
<button kendoGridEditCommand [primary]="true" *ngIf="!dataItem.Paid">Edit</button>
<button kendoGridRemoveCommand *ngIf="!dataItem.Paid" >Remove</button>
<button kendoGridSaveCommand [disabled]="formGroup?.invalid">{{ isNew ? 'Add' : 'Update' }}</button>
<button kendoGridCancelCommand>{{ isNew ? 'Discard changes' : 'Cancel' }}</button>
<button kendoGridEditCommand *ngIf="!dataItem.Paid" icon="edit"></button>
<button kendoGridRemoveCommand *ngIf="!dataItem.Paid" icon="delete"></button>
<button kendoGridSaveCommand [disabled]="formGroup?.invalid" icon="save"></button>
<button kendoGridCancelCommand icon="close"></button>
</ng-template> </ng-template>
</kendo-grid-command-column> </kendo-grid-command-column>


<kendo-grid-column field="To" title="Name" width="300">
<kendo-grid-column field="To" title="Name" width="200">
<ng-template kendoGridCellTemplate let-dataItem> <ng-template kendoGridCellTemplate let-dataItem>
<div class="customer-photo" [ngStyle]="{'background-image' : photoURL(dataItem.To) }"></div> <div class="customer-photo" [ngStyle]="{'background-image' : photoURL(dataItem.To) }"></div>
<div class="customer-name"> {{ UserName(dataItem) }}</div> <div class="customer-name"> {{ UserName(dataItem) }}</div>
</ng-template> </ng-template>
<ng-template <ng-template
kendoGridEditTemplate let-fg="formGroup" let-column="column" let-dataItem="dataItem"> kendoGridEditTemplate let-fg="formGroup" let-column="column" let-dataItem="dataItem">
<app-people-select [formControl]="formGroup.get('To')" [translateId]="true" [width]="200"></app-people-select>
<app-people-select #pps [formControl]="formGroup.get('To')" [translateId]="true" [width]="200" [initSearch]="contacts"></app-people-select>
</ng-template> </ng-template>


</kendo-grid-column> </kendo-grid-column>


<kendo-grid-column field="Role" title="Role" width="200">
<kendo-grid-column field="Role" title="Role" width="100">
<ng-template <ng-template
kendoGridEditTemplate let-fg="formGroup" let-column="column" let-dataItem="dataItem"> kendoGridEditTemplate let-fg="formGroup" let-column="column" let-dataItem="dataItem">
<kendo-combobox <kendo-combobox
</ng-template> </ng-template>
</kendo-grid-column> </kendo-grid-column>


<kendo-grid-column field="Amount" title="Amount" width="200" editor="numeric" format="{0:c}"></kendo-grid-column>
<kendo-grid-column field="Amount" title="Amount" width="100" editor="numeric" format="{0:c}"></kendo-grid-column>
<kendo-grid-column field="Description" title="Description" width="200"> <kendo-grid-column field="Description" title="Description" width="200">
<ng-template <ng-template
kendoGridEditTemplate let-fg="formGroup" let-column="column" let-dataItem="dataItem"> kendoGridEditTemplate let-fg="formGroup" let-column="column" let-dataItem="dataItem">
</ng-template> </ng-template>
</kendo-grid-column> </kendo-grid-column>


<kendo-grid-column field="Ts" title="Date" width="100" editor="date" >
<ng-template kendoGridCellTemplate let-dataItem>
{{dataItem.Ts | date: 'yyyy-MM-dd'}}
</ng-template>
</kendo-grid-column>
</kendo-grid> </kendo-grid>


<bkp-divider-shadow-bottom></bkp-divider-shadow-bottom> <bkp-divider-shadow-bottom></bkp-divider-shadow-bottom>

+ 41
- 27
src/app/loan-edit/people-reward/people-reward.component.ts Прегледај датотеку

import {Component, Input, OnInit, Output, EventEmitter} from '@angular/core';
import {Component, Input, OnInit, Output, EventEmitter, ViewChild} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms'; import {FormControl, FormGroup, Validators} from '@angular/forms';
import {AuthService} from '../../service/auth.service'; import {AuthService} from '../../service/auth.service';
import {LoanModel} from '../../models/loan.model'; import {LoanModel} from '../../models/loan.model';
import {debounce} from 'ts-debounce'; import {debounce} from 'ts-debounce';
import {LoanSingleService} from '../../service/loan.single.service'; import {LoanSingleService} from '../../service/loan.single.service';
import {ClonerService} from '../../service/clone.service'; import {ClonerService} from '../../service/clone.service';
import {PeopleSelectComponent} from '../people-select/people-select.component';






Role: new FormControl(dataItem.Role, [Validators.required, Validators.minLength(2), Validators.maxLength(40)]), Role: new FormControl(dataItem.Role, [Validators.required, Validators.minLength(2), Validators.maxLength(40)]),
Amount: new FormControl(dataItem.Amount, Validators.compose([Validators.required, Validators.min(0), Validators.max(1000000)])), Amount: new FormControl(dataItem.Amount, Validators.compose([Validators.required, Validators.min(0), Validators.max(1000000)])),
Description: new FormControl(dataItem.Description, [Validators.required, Validators.maxLength(128)]), Description: new FormControl(dataItem.Description, [Validators.required, Validators.maxLength(128)]),
PayOutId: new FormControl({value: dataItem.PayOutId, disabled: dataItem.PayOutId > 0 })
Ts: new FormControl( dataItem.Ts, Validators.required)
}); });


@Component({ @Component({
'Discount', 'Discount',
'Fringe Cost', 'Fringe Cost',
'Unknown', 'Unknown',
'Trail'
]; ];


private debounceFilter: any ; private debounceFilter: any ;
} }


public ngOnInit(): void { public ngOnInit(): void {
this.initPeople(); // make sure people has the one that we need
this.initReward(); this.initReward();


console.log(this.Loan, this.pendingReward); console.log(this.Loan, this.pendingReward);
}, 500) ; }, 500) ;
} }


public initPeople(): void{
this.contacts = this.Loan.getRelevantPeople();
}

public initReward(): void { public initReward(): void {
this.Loan.Reward.forEach((r) => { this.Loan.Reward.forEach((r) => {
const o = this.dcs.deepClone<RewardModel>(r); const o = this.dcs.deepClone<RewardModel>(r);


public editHandler({ sender, rowIndex, dataItem }): void { public editHandler({ sender, rowIndex, dataItem }): void {
this.closeEditor(sender); this.closeEditor(sender);
// console.log(sender);


if ( dataItem.Paid ) {
alert( 'cannot edit');
}else{
this.formGroup = createFormGroup(dataItem);

this.editedRowIndex = rowIndex;

sender.editRow(rowIndex, this.formGroup);
}

this.formGroup = createFormGroup(dataItem);
this.editedRowIndex = rowIndex;
sender.editRow(rowIndex, this.formGroup);
console.log('editing' , dataItem, this.contacts, this.formGroup);
} }


public cancelHandler({ sender, rowIndex }): void{ public cancelHandler({ sender, rowIndex }): void{
console.log(sender);
//console.log(sender);
this.closeEditor(sender, rowIndex); this.closeEditor(sender, rowIndex);
} }


public saveHandler({ sender, rowIndex, formGroup, isNew }): void { public saveHandler({ sender, rowIndex, formGroup, isNew }): void {
const reward = formGroup.value; const reward = formGroup.value;
reward.From = '0'; // Admin reward.From = '0'; // Admin
reward.Ts = new Date(); // Now
// reward.Ts = new Date(); // Now
reward.LoanId = this.Loan.Id; // Enforce LoanId
reward.PayOutId = 0; // make sure it is not paid reward.PayOutId = 0; // make sure it is not paid
this.ls.saveReward(reward, isNew);
this.pendingReward.push( this.Loan.addReward(
reward.Amount,
reward.Description,
reward.Id,
reward.LoanId,
reward.PayOutId,
reward.To,
reward.From,
reward.Ts
));
this.ls.saveReward(reward, isNew).subscribe(
resp => {
if ( reward.Id === 0 ) {
const r = this.Loan.addReward(resp.Amount, resp.Description, resp.Id, resp.LoanId,resp.PayOutId,resp.To,resp.From, resp.Ts);
this.pendingReward.unshift(r);
}else{
const idx = this.pendingReward.findIndex( v => v.Id === reward.Id);
// update
this.pendingReward[idx].To = reward.To;
this.pendingReward[idx].Amount = reward.Amount;
this.pendingReward[idx].Description = reward.Description;
this.pendingReward[idx].Ts = reward.Ts;
}
console.log(resp);
}

);
sender.closeRow(rowIndex); sender.closeRow(rowIndex);
} }


public removeHandler({ dataItem }): void { public removeHandler({ dataItem }): void {
console.log(dataItem);
// this.service.remove(dataItem);

const na = this.pendingReward.filter(v => {
return v.Id !== dataItem.Id;
});

this.pendingReward = na;
this.ls.removeReward(dataItem);
} }


private closeEditor(grid, rowIndex = this.editedRowIndex): void { private closeEditor(grid, rowIndex = this.editedRowIndex): void {

+ 4
- 0
src/app/loan-edit/people-select/people-select.component.scss Прегледај датотеку

margin-right: 8px; margin-right: 8px;
border-radius: 50%; border-radius: 50%;
} }

.toolbarAddNew{
padding-bottom: 20px
}

+ 61
- 16
src/app/loan-edit/people-select/people-select.component.ts Прегледај датотеку

import {Observable, of} from 'rxjs'; import {Observable, of} from 'rxjs';
import {PercentPipe} from '@angular/common'; import {PercentPipe} from '@angular/common';
import {map} from 'rxjs/operators'; import {map} from 'rxjs/operators';
import {PeopleService} from '../../service/people.service';




@Component({ @Component({
export class PeopleSelectComponent implements OnInit, ControlValueAccessor { export class PeopleSelectComponent implements OnInit, ControlValueAccessor {


@Input() disabled = false; @Input() disabled = false;
@Input() translateId: false; // true to out user Id, false output user name
@Input() translateId: true; // always tralsnate user Id, because name is not unique
@Input() width: number; @Input() width: number;
@Input() initSearch: PeopleModel[];
@Input() formControl: FormControl = new FormControl(); // this is a dummy place holder @Input() formControl: FormControl = new FormControl(); // this is a dummy place holder
@ViewChild('list', {static: true}) public text: MultiColumnComboBoxComponent; @ViewChild('list', {static: true}) public text: MultiColumnComboBoxComponent;


private onTouched = () => {}; private onTouched = () => {};




constructor(private auth: AuthService) { }
constructor(private auth: AuthService, private ps: PeopleService) { }


ngOnInit(): void { ngOnInit(): void {
this.prepareSearchPeople(); this.prepareSearchPeople();
this.initSearchResult();
}

private initSearchResult(): void {
this.initSearch.forEach( v => {
this.searchResult.push(v);
});
this.total = this.initSearch.length;
} }


private prepareSearchPeople(): void{ private prepareSearchPeople(): void{
// Allows Angular to update the model (name or ID). // Allows Angular to update the model (name or ID).
// Update the model and changes needed for the view here. // Update the model and changes needed for the view here.
writeValue(nameOrId: string): void { writeValue(nameOrId: string): void {
return;
if ( nameOrId === undefined ){ if ( nameOrId === undefined ){
console.log('who called me for write', this); console.log('who called me for write', this);
return; return;
if ( incoming === undefined || incoming === '' || incoming === this.value ) { if ( incoming === undefined || incoming === '' || incoming === this.value ) {
return false; return false;
} }
this.searchResult.forEach((person) => {
if ( this.translateId) {
if ( person.Id === this.value ) {
return false; // found in cache
}
}else{
if (person.FullName.includes(this.value)){
return false;
}
}

const idx = this.searchResult.findIndex( person => {
if ( this.translateId) {
return person.Id === incoming;
}else{
return person.FullName.includes(incoming);
}
}); });
return true;

return idx === -1; // not found need search
} }


// Search a user either based on partial name or a complete ID // Search a user either based on partial name or a complete ID
searchUser(nameOrId: string, translateId: boolean): Observable<PeopleModel>{ searchUser(nameOrId: string, translateId: boolean): Observable<PeopleModel>{
if ( translateId ) { if ( translateId ) {
return PeopleModel.searchPersonById( nameOrId) ;
return this.ps.searchById(nameOrId);
// return this.searchPersonById( nameOrId) ;
}else{ }else{
return PeopleModel.searchPersonByName(nameOrId) ;
// return this.ps.searchById(nameOrId);
// return this.searchPersonByName(nameOrId) ;
} }
} }


// searchPersonByName(name: string): Observable<PeopleModel>{
// return new Observable ( observer => {
// const dummy: PeopleModel = new PeopleModel(
// 'dummy-id',
// 'FSearch',
// 'LResult',
// '',
// 'Mr.',
// 'Display Name',
// 'Nick Name'
// );
// setTimeout(() => {
// observer.next(dummy);
// observer.complete();
// }, 1000);
// });
// }
//
// searchPersonById( id: string): Observable<PeopleModel> {
// return new Observable ( observer => {
// const dummy: PeopleModel = new PeopleModel(
// id,
// 'FSearch',
// 'LResult',
// '',
// 'Mr.',
// 'P:' + id,
// 'Nick Name'
// );
// setTimeout(() => {
// observer.next(dummy);
// observer.complete();
// }, 1000);
// });
// }

// Allows Angular to register a function to call when the model (rating) changes. // Allows Angular to register a function to call when the model (rating) changes.
// Save the function as a property to call later here. // Save the function as a property to call later here.
registerOnChange(fn: (nameOrId: string) => void): void { registerOnChange(fn: (nameOrId: string) => void): void {

+ 19
- 15
src/app/models/broker.model.ts Прегледај датотеку

import {PeopleModel} from './people.model';


export class BrokerModel{ export class BrokerModel{
Id: string;
First: string;
Last: string;
Middle: string;
Title: string;
Display: string;
Nick: string;
Login: string;
Enabled: boolean;
BSB: string;
ACC: string;
License: string;
Organization: string;
constructor(
public Id: string,
public First: string,
public Last: string,
public Middle: string,
public Title: string,
public Display: string,
public Nick: string,
public Login: string,
public Enabled: boolean,
public BSB: string,
public ACC: string,
public License: string,
public Organization: string
){}


public toPeopleModel(): PeopleModel{
return new PeopleModel( this.Id, this.First, this.Last, this.Middle, this.Title, this.Display, this.Nick );
}
} }

+ 65
- 11
src/app/models/loan.model.ts Прегледај датотеку

this.Description = resp.Description; this.Description = resp.Description;


this.Lender = resp.Lender; this.Lender = resp.Lender;
this.Client = resp.Client;
this.Broker = resp.Broker;
this.OtherRewarder = resp.OtherRewarder;

this.setClient(resp.Client);
this.setBroker(resp.Broker);
this.setOtherRewarder(resp.OtherRewarder);

this.setReward(resp.Reward); this.setReward(resp.Reward);
this.PeopleMap = resp.PeopleMap; this.PeopleMap = resp.PeopleMap;
this.PayIn = resp.PayIn; this.PayIn = resp.PayIn;
return; return;
} }


private setClient(v: any[]): void{
this.Client = [];
v.forEach((c) =>{
this.Client.push(
new PeopleModel(c.Id, c.First, c.Last, c.Middle, c.Title, c.Display, c.Nick)
);
});
}

private setOtherRewarder(v: any[]): void{
this.OtherRewarder = [];
v.forEach((c) =>{
this.OtherRewarder.push(
new PeopleModel(c.Id, c.First, c.Last, c.Middle, c.Title, c.Display, c.Nick)
);
});
}


private setBroker(v: any[]): void{
this.Broker = [];
v.forEach((b => {
this.Broker.push(new BrokerModel(
b.Id, b.First, b.Last, b.Middle, b.Title, b.Display, b.Nick, b.Login, b.Enaabled, b.BSB, b.ACC, b.License, b.Organization
)
);
}));
}

public addReward(Amount: number, Description: string, Id: number, public addReward(Amount: number, Description: string, Id: number,
LoanId: string, PayOutId: number, To: string , From: string, Ts: Date): RewardModel { LoanId: string, PayOutId: number, To: string , From: string, Ts: Date): RewardModel {
const r = new RewardModel( const r = new RewardModel(
PayOutId, PayOutId,
To, To,
From, From,
Ts,
new Date(Ts),
this.callBacks() this.callBacks()
); );
r.LoanId = this.Id; // Make sure Loan Id is same
this.Reward.push(r); this.Reward.push(r);
return r; return r;
} }
} }


public getUserName(id: string): string { public getUserName(id: string): string {
let result = 'P:' + id;
// search client // search client
this.Client.forEach(( c => { this.Client.forEach(( c => {
if ( c.Id === id ) { if ( c.Id === id ) {
return c.First + ' ' + c.Last;
result = c.First + ' ' + c.Last;
} }
})); }));


this.Broker.forEach(( c => { this.Broker.forEach(( c => {
if ( c.Id === id ) { if ( c.Id === id ) {
return c.First + ' ' + c.Last;
result = c.First + ' ' + c.Last;
} }
})); }));


this.OtherRewarder.forEach(( c => { this.OtherRewarder.forEach(( c => {
if ( c.Id === id ) { if ( c.Id === id ) {
return c.First + ' ' + c.Last;
result = c.First + ' ' + c.Last;
} }
})); }));


return 'P:' + id;
return result;
} }


public getUserPhotoUrl(id: string): string { public getUserPhotoUrl(id: string): string {
} }


public getUserRole(id: string): string { public getUserRole(id: string): string {
this.PeopleMap.forEach((row) =>{
let result = 'R:';
this.PeopleMap.forEach((row) => {
if ( row.PeopleId === id ){ if ( row.PeopleId === id ){
return row.Role;
result = row.Role;
} }
}); });
return 'R:';
return result;
}

public getRelevantPeople(): PeopleModel[] {
const result: PeopleModel[] = [];

this.Client.forEach(( c => {
result.push(c);
}));

this.Broker.forEach(( c => {
console.log(c);
result.push(c.toPeopleModel());
}));

this.OtherRewarder.forEach(( c => {
result.push(c);
}));

console.log(result);
return result;
} }


} }

+ 1
- 36
src/app/models/people.model.ts Прегледај датотеку

import {Observable} from 'rxjs'; import {Observable} from 'rxjs';
import {PeopleService} from '../service/people.service';


export class PeopleModel{ export class PeopleModel{
constructor( constructor(
return this.First + ' ' + this.Middle + ' ' + this.Last; return this.First + ' ' + this.Middle + ' ' + this.Last;
} }
} }

static searchPersonByName(name: string): Observable<PeopleModel>{
return new Observable ( observer => {
const dummy: PeopleModel = new PeopleModel(
'dummy-id',
'FSearch',
'LResult',
'',
'Mr.',
'Display Name',
'Nick Name'
);
setTimeout(() => {
observer.next(dummy);
observer.complete();
}, 1000);
});
}

static searchPersonById( id: string): Observable<PeopleModel> {
return new Observable ( observer => {
const dummy: PeopleModel = new PeopleModel(
id,
'FSearch',
'LResult',
'',
'Mr.',
'P:' + id,
'Nick Name'
);
setTimeout(() => {
observer.next(dummy);
observer.complete();
}, 1000);
});
}
} }

+ 11
- 1
src/app/service/loan.single.service.ts Прегледај датотеку

return this.auth.apiUrlFunc(); return this.auth.apiUrlFunc();
} }


public saveReward(reward: RewardModel, isNew : boolean ): void {
public saveReward(reward: RewardModel, isNew: boolean ): Observable<RewardModel> {
console.log('saving', reward, isNew, this); console.log('saving', reward, isNew, this);
return this.http.post<RewardModel>(this.auth.getUrl('reward/'), reward);
}

public removeReward(reward: RewardModel): void {
console.log('remove', reward);
this.http.delete<RewardModel>(this.auth.getUrl('reward/' + reward.Id)).subscribe(
resp => {
console.log(resp);
}
);
} }
} }

+ 15
- 0
src/app/service/people.service.ts Прегледај датотеку

import {Injectable} from '@angular/core';
import {HttpClient, HttpParams} from '@angular/common/http';
import {AuthService} from './auth.service';
import {Observable} from 'rxjs';
import {PeopleModel} from '../models/people.model';

@Injectable({providedIn: 'root'})
export class PeopleService {
constructor(private http: HttpClient, private auth: AuthService ){ }

searchById(id: string): Observable<PeopleModel> {
return this.http.get<PeopleModel>(this.auth.getUrl('people/' + id));
}

}

Loading…
Откажи
Сачувај