浏览代码

added deep clone service and make people reward ready to commit to database.

tags/2.037
Patrick Sun 4 年前
父节点
当前提交
1e10a93e8c
共有 10 个文件被更改,包括 176 次插入152 次删除
  1. +65
    -2
      src/app/loan-edit/people-reward/people-reward.component.html
  2. +48
    -109
      src/app/loan-edit/people-reward/people-reward.component.ts
  3. +1
    -1
      src/app/loan-edit/people-select/people-select.component.html
  4. +9
    -4
      src/app/loan-edit/people-select/people-select.component.ts
  5. +26
    -7
      src/app/models/loan.model.ts
  6. +5
    -1
      src/app/models/people-map.model.ts
  7. +6
    -0
      src/app/rating-input/rating-input.component.scss
  8. +11
    -0
      src/app/service/clone.service.ts
  9. +5
    -0
      src/app/service/loan.single.service.ts
  10. +0
    -28
      src/app/service/loan_summary.service.ts

+ 65
- 2
src/app/loan-edit/people-reward/people-reward.component.html 查看文件

<div class="vertical-spacer"></div> <div class="vertical-spacer"></div>
<bkp-divider-shadow-bottom></bkp-divider-shadow-bottom> <bkp-divider-shadow-bottom></bkp-divider-shadow-bottom>


<kendo-grid [data]="gridData"
<kendo-grid [data]="pendingReward"
[height]="410" [height]="410"
(add)="addHandler($event)" (add)="addHandler($event)"
(cancel)="cancelHandler($event)" (cancel)="cancelHandler($event)"


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


<kendo-grid-column field="Description" title="Description" width="200"></kendo-grid-column>
<kendo-grid-column field="Role" title="Role" width="200">
<ng-template
kendoGridEditTemplate let-fg="formGroup" let-column="column" let-dataItem="dataItem">
<kendo-combobox
name="existingRoles"
[data]="existingRoles"
[valuePrimitive]="true"
[formControl]="formGroup.get(column.field)"
>
</kendo-combobox>
</ng-template>
</kendo-grid-column>

<kendo-grid-column field="Amount" title="Amount" width="200" editor="numeric" format="{0:c}"></kendo-grid-column>
<kendo-grid-column field="Description" title="Description" width="200">
<ng-template
kendoGridEditTemplate let-fg="formGroup" let-column="column" let-dataItem="dataItem">
<kendo-combobox
name="existingPayDescription"
[data]="existingPayDescription"
[valuePrimitive]="true"
[formControl]="formGroup.get(column.field)"
>
</kendo-combobox>
</ng-template>
</kendo-grid-column>


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


<bkp-divider-shadow-bottom></bkp-divider-shadow-bottom>
<div class="vertical-spacer"></div>

Paid Reward (casted into stone, cannot be undone )

<kendo-grid [data]="paidReward"
[height]="410"
(add)="addHandler($event)"
(cancel)="cancelHandler($event)"
(save)="saveHandler($event)"
(edit)="editHandler($event)"
(remove)="removeHandler($event)"
>
<kendo-grid-column field="Id" title="Id" width="80"> </kendo-grid-column>

<kendo-grid-column field="To" title="Name" width="300">
<ng-template kendoGridCellTemplate let-dataItem>
<div class="customer-photo" [ngStyle]="{'background-image' : photoURL(dataItem.To) }"></div>
<div class="customer-name"> {{ UserName(dataItem) }}</div>
</ng-template>
</kendo-grid-column>


<kendo-grid-column field="Role" title="Role" width="200">
</kendo-grid-column>

<kendo-grid-column field="Amount" title="Amount" width="200" format="{0:c}"></kendo-grid-column>
<kendo-grid-column field="Description" title="Description" width="200">
</kendo-grid-column>
<kendo-grid-column field="Ts" title="Date" width="200">
<ng-template kendoGridCellTemplate let-dataItem>
{{dataItem.Ts | date: 'yyyy-MM-dd'}}
</ng-template>
</kendo-grid-column>

<kendo-grid-column field="PayOutId" title="Payment Info" width="180"> </kendo-grid-column>

</kendo-grid>


<bkp-divider-shadow-bottom></bkp-divider-shadow-bottom> <bkp-divider-shadow-bottom></bkp-divider-shadow-bottom>
<div class="vertical-spacer"></div> <div class="vertical-spacer"></div>


</fieldset> </fieldset>
</ng-container> </ng-container>



+ 48
- 109
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} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms'; import {FormControl, FormGroup, Validators} from '@angular/forms';
import {LoanSummaryService} from '../../service/loan_summary.service';
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 {Observable} from 'rxjs';
import {RewardModel} from '../../models/reward.model'; import {RewardModel} from '../../models/reward.model';
import {PeopleModel} from '../../models/people.model'; import {PeopleModel} from '../../models/people.model';
import {debounce} from 'ts-debounce'; import {debounce} from 'ts-debounce';
import {LoanSingleService} from '../../service/loan.single.service';
import {ClonerService} from '../../service/clone.service';






const createFormGroup = dataItem => new FormGroup({ const createFormGroup = dataItem => new FormGroup({
Id: new FormControl(dataItem.Id), Id: new FormControl(dataItem.Id),
To: new FormControl(dataItem.To, Validators.required),
To: new FormControl(dataItem.To, [Validators.required, Validators.maxLength(128), Validators.minLength(1)]),
From: new FormControl(dataItem.From), From: new FormControl(dataItem.From),
Role: new FormControl(dataItem.Role),
Amount: new FormControl(dataItem.Amount, Validators.compose([Validators.required, Validators.pattern('^[0-9]{1,3}')])),
Description: new FormControl(dataItem.Description),
PayOutId: new FormControl({value: dataItem.PaidOutId, disabled: dataItem.PayOutId > 0 })
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)])),
Description: new FormControl(dataItem.Description, [Validators.required, Validators.maxLength(128)]),
PayOutId: new FormControl({value: dataItem.PayOutId, disabled: dataItem.PayOutId > 0 })
}); });


@Component({ @Component({
public contacts: PeopleModel[] = []; public contacts: PeopleModel[] = [];
public total = 0; public total = 0;


public gridData: RewardModel[] = [];
public data = [

{
RewardId: 14,
UserName: 'Alina Cox',
PeopleId: 'df743325-810d-4d25-bb52-91a1a0c3ba22',
Role: 'broker',
RewardDescription: 'Trail',
RewardAmount: 100,
Paid: false,
},

{
RewardId: 13,
UserName: 'Alina Cox',
PeopleId: 'df743325-810d-4d25-bb52-91a1a0c3ba22',
Role: 'broker',
RewardDescription: 'Trail',
RewardAmount: 100,
Paid: false,
},

{
RewardId: 12,
UserName: 'Alina Cox',
PeopleId: 'df743325-810d-4d25-bb52-91a1a0c3ba22',
Role: 'broker',
RewardDescription: 'broker fee',
RewardAmount: 100,
Paid: true,
},
{
RewardId: 11,
UserName: 'Helen Morgan',
PeopleId: '92dd6e14-10da-47ae-89ac-3a52d6567e61',
Role: 'Referral',
RewardDescription: 'no fee',
RewardAmount: 500,
Paid: true,
},
{
RewardId: 10,
UserName: 'Oscar Coudors',
PeopleId: '09aa4151-7744-422e-9f2c-90b4871018f3',
Role: 'Upfront',
RewardDescription: 'no fee',
RewardAmount: 3000,
Paid: true,
}

public pendingReward: RewardModel[] = [];
public paidReward: RewardModel[] = [];


];
public formGroup: FormGroup; public formGroup: FormGroup;
private editedRowIndex: number; private editedRowIndex: number;


'Admin' 'Admin'
]; ];


public existingPayDescription: string[] = [
'Upfront',
'Broker Fee',
'SFM Incentive',
'Special Reward',
'Discount',
'Fringe Cost',
'Unknown',
];

private debounceFilter: any ; private debounceFilter: any ;


constructor(private ls: LoanSummaryService, private auth: AuthService) {
constructor(private ls: LoanSingleService, private auth: AuthService, private dcs: ClonerService) {
} }


public ngOnInit(): void { public ngOnInit(): void {
// this.gridData = this.service.products();
Object.assign(this.gridData, this.Loan.Reward);
console.log(this.Loan, this.gridData);
this.initReward();
console.log(this.Loan, this.pendingReward);


this.debounceFilter = debounce( (filter: string): void => { this.debounceFilter = debounce( (filter: string): void => {
this.auth.getPeopleList(filter).subscribe( this.auth.getPeopleList(filter).subscribe(
}, 500) ; }, 500) ;
} }


public initReward(): void {
this.Loan.Reward.forEach((r) => {
const o = this.dcs.deepClone<RewardModel>(r);
if ( r.PayOutId > 0 ){
this.paidReward.push(o);
}else{
this.pendingReward.push(o);
}
});
}


public addHandler({ sender }): void { public addHandler({ sender }): void {
this.closeEditor(sender); this.closeEditor(sender);
} }


public saveHandler({ sender, rowIndex, formGroup, isNew }): void { public saveHandler({ sender, rowIndex, formGroup, isNew }): void {
const product = formGroup.value;

console.log('"saving', product, formGroup);
// this.service.save(product, isNew);

const reward = formGroup.value;
reward.From = '0'; // Admin
reward.Ts = new Date(); // Now
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
));
sender.closeRow(rowIndex); sender.closeRow(rowIndex);
} }


this.formGroup = undefined; this.formGroup = undefined;
} }


public onUserNameChanged(event: any, dataItem: any): void {
console.log(event, dataItem);
dataItem.UserId = 'fuck this user id';
// debounce
// console.log(event);
}

private photoURL(peopleId: string): string { private photoURL(peopleId: string): string {
const url = this.auth.getUrl('avatar/') + peopleId; const url = this.auth.getUrl('avatar/') + peopleId;
return 'url("' + url + '")'; return 'url("' + url + '")';
this.NotifyPrev.emit(true); this.NotifyPrev.emit(true);
} }


filterChange(filter: string): void {
if (filter.length > 1 ) {
this.debounceFilter(filter);
}
}


public getContactImageUrl(contactId: string): string {
return this.auth.getUrl('avatar/' + contactId);
}

public valueChange(value: any): void {
console.log('valueChange', value);
}

public selectionChange(value: any): void {
console.log('selectionChange', value);
}

public open(): void {
console.log('open');
}

public close(): void {
console.log('close');
}

public focus(): void {
console.log('focus');
}

public blur(): void {
console.log('blur');
}
} }

+ 1
- 1
src/app/loan-edit/people-select/people-select.component.html 查看文件

<kendo-multicolumncombobox <kendo-multicolumncombobox
#list #list
[data]="searchResult" [data]="searchResult"
[(ngModel)]="value"
[textField]="'Display'" [textField]="'Display'"
[valueField]="getEffectiveField()" [valueField]="getEffectiveField()"
[valuePrimitive]="true" [valuePrimitive]="true"
[allowCustom]="false" [allowCustom]="false"




[formControl]="formControl"
(filterChange)="filterChange($event)" (filterChange)="filterChange($event)"
(valueChange)="valueChange($event)" (valueChange)="valueChange($event)"
> >

+ 9
- 4
src/app/loan-edit/people-select/people-select.component.ts 查看文件

@ViewChild('list', {static: true}) public text: MultiColumnComboBoxComponent; @ViewChild('list', {static: true}) public text: MultiColumnComboBoxComponent;


public searchResult: PeopleModel[] = []; public searchResult: PeopleModel[] = [];
public value = ''; // selecting the default and only empty contact element
public value = ''; // selecting the default and only empty contact element // TODO: remove ngModel
public total = 0; public total = 0;


private debounceFilter: any ; private debounceFilter: any ;


// ComboBox emit event on value change // ComboBox emit event on value change
public valueChange(str: string): void { public valueChange(str: string): void {
return;
console.log('value change', str); console.log('value change', str);
this.onChange(this.value); this.onChange(this.value);
} }
// 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;
} }
const changed = nameOrId !== this.value; const changed = nameOrId !== this.value;
if (this.needSearch() ){
if (this.needSearch(nameOrId) ){
this.text.loading = true; this.text.loading = true;
console.log('searching ... ', nameOrId, this.translateId? 'by id' : 'by name');
console.log('searching ... ', nameOrId, this.translateId ? 'by id' : 'by name');
this.searchUser(nameOrId, this.translateId).subscribe( this.searchUser(nameOrId, this.translateId).subscribe(
ppl => { ppl => {
const person = new PeopleModel( const person = new PeopleModel(
} }
} }


needSearch(): boolean {
needSearch(incoming: string ): boolean {
if ( incoming === undefined || incoming === '' || incoming === this.value ) {
return false;
}
this.searchResult.forEach((person) => { this.searchResult.forEach((person) => {
if ( this.translateId) { if ( this.translateId) {
if ( person.Id === this.value ) { if ( person.Id === this.value ) {

+ 26
- 7
src/app/models/loan.model.ts 查看文件

import { PeopleModel } from "./people.model";
import { PeopleModel } from './people.model';
import {PeopleMapModel} from './people-map.model'; import {PeopleMapModel} from './people-map.model';
import {BrokerModel} from './broker.model'; import {BrokerModel} from './broker.model';
import {PayInModel} from './pay-in.model'; import {PayInModel} from './pay-in.model';
private setReward(v: any[]): void{ private setReward(v: any[]): void{
this.Reward = []; this.Reward = [];
v.forEach((reward) => { v.forEach((reward) => {
const r = new RewardModel(
this.addReward(
reward.Amount, reward.Amount,
reward.Description, reward.Description,
reward.Id, reward.Id,
reward.PayOutId, reward.PayOutId,
reward.To, reward.To,
reward.From, reward.From,
reward.Ts,
this.callBacks()
);
this.Reward.push(r);
reward.Ts);
}); });
return; return;
} }


public addReward(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,
Ts,
this.callBacks()
);
this.Reward.push(r);
return r;
}

public emptyReward(): RewardModel { public emptyReward(): RewardModel {
return new RewardModel( return new RewardModel(
0, '', 0, this.Id, 0, '', 0, this.Id,
} }


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


} }

+ 5
- 1
src/app/models/people-map.model.ts 查看文件

export class PeopleMapModel { export class PeopleMapModel {

constructor(
public LoanId: string,
public Role: string,
public PeopleId: string
){}
} }

+ 6
- 0
src/app/rating-input/rating-input.component.scss 查看文件

.yellow { .yellow {
color: #ffa600; color: #ffa600;
} }


:host .ng-dirty {
border-style: solid;
border-color: red;
}

+ 11
- 0
src/app/service/clone.service.ts 查看文件

import {Injectable} from '@angular/core';
import * as clone from 'clone';

@Injectable({providedIn: 'root'})
export class ClonerService {

deepClone<T>(value): T {
return clone<T>(value);
}

}

+ 5
- 0
src/app/service/loan.single.service.ts 查看文件

import {Observable} from 'rxjs'; import {Observable} from 'rxjs';
import {LoanModel} from '../models/loan.model'; import {LoanModel} from '../models/loan.model';
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {RewardModel} from '../models/reward.model';


@Injectable() @Injectable()
export class LoanSingleService { export class LoanSingleService {
public apiUrlFunc(): ApiUrL { public apiUrlFunc(): ApiUrL {
return this.auth.apiUrlFunc(); return this.auth.apiUrlFunc();
} }

public saveReward(reward: RewardModel, isNew : boolean ): void {
console.log('saving', reward, isNew, this);
}
} }

+ 0
- 28
src/app/service/loan_summary.service.ts 查看文件

} }
} }


@Injectable()
export class ProductsService extends LoanQueryService {
constructor(http: HttpClient, auth: AuthService) { super(http, auth, 'Products'); }

public queryForCategory({ CategoryID }: { CategoryID: number }, state?: any): void {
this.query(Object.assign({}, state, {
filter: {
filters: [{
field: 'CategoryID', operator: 'eq', value: CategoryID
}],
logic: 'and'
}
}));
}

public queryForProductName(ProductName: string, state?: any): void {
this.query(Object.assign({}, state, {
filter: {
filters: [{
field: 'ProductName', operator: 'contains', value: ProductName
}],
logic: 'and'
}
}));
}

}

@Injectable() @Injectable()
export class LoanSummaryService extends LoanQueryService { export class LoanSummaryService extends LoanQueryService {
constructor(http: HttpClient, auth: AuthService) { super(http, auth, 'full-loan-overview'); } constructor(http: HttpClient, auth: AuthService) { super(http, auth, 'full-loan-overview'); }

正在加载...
取消
保存