Fix Loan product Payment Allocation (#1855)
Co-authored-by: Jose Alberto Hernandez <alberto@blue-daemon.local>
This commit is contained in:
co-authored by
Jose Alberto Hernandez
parent
80936a3ea9
commit
32a9db1f6d
@@ -108,7 +108,7 @@
|
|||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
<mat-menu #accountApplications="matMenu">
|
<mat-menu #accountApplications="matMenu">
|
||||||
<button mat-menu-item *mifosxHasPermission="'CREATE_LOANACCOUNT'"
|
<button mat-menu-item *mifosxHasPermission="'CREATE_LOAN'"
|
||||||
[routerLink]="['loans-accounts', 'create']">New Loan Account</button>
|
[routerLink]="['loans-accounts', 'create']">New Loan Account</button>
|
||||||
<button mat-menu-item *mifosxHasPermission="'CREATE_SAVINGSACCOUNT'"
|
<button mat-menu-item *mifosxHasPermission="'CREATE_SAVINGSACCOUNT'"
|
||||||
[routerLink]="['savings-accounts', 'create']">New Savings Account</button>
|
[routerLink]="['savings-accounts', 'create']">New Savings Account</button>
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
<button mat-menu-item routerLink="/clients">{{ 'labels.menus.Clients' | translate }}</button>
|
<button mat-menu-item routerLink="/clients">{{ 'labels.menus.Clients' | translate }}</button>
|
||||||
<button mat-menu-item routerLink="/groups">{{ 'labels.menus.Groups' | translate }}</button>
|
<button mat-menu-item routerLink="/groups">{{ 'labels.menus.Groups' | translate }}</button>
|
||||||
<button mat-menu-item routerLink="/centers">{{ 'labels.menus.Centers' | translate }}</button>
|
<button mat-menu-item routerLink="/centers">{{ 'labels.menus.Centers' | translate }}</button>
|
||||||
<span fxHide.lg>
|
<span fxHide.lt-lg="true">
|
||||||
<button mat-menu-item [routerLink]="['/accounting']">{{ 'labels.menus.Accounting' | translate }}</button>
|
<button mat-menu-item [routerLink]="['/accounting']">{{ 'labels.menus.Accounting' | translate }}</button>
|
||||||
<button mat-menu-item [matMenuTriggerFor]="reportsMenu">{{ 'labels.menus.Reports' | translate }}</button>
|
<button mat-menu-item [matMenuTriggerFor]="reportsMenu">{{ 'labels.menus.Reports' | translate }}</button>
|
||||||
<button mat-menu-item [matMenuTriggerFor]="adminMenu">{{ 'labels.menus.Admin' | translate }}</button>
|
<button mat-menu-item [matMenuTriggerFor]="adminMenu">{{ 'labels.menus.Admin' | translate }}</button>
|
||||||
@@ -89,11 +89,11 @@
|
|||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
<mat-menu #adminMenu="matMenu" [overlapTrigger]="false">
|
<mat-menu #adminMenu="matMenu" [overlapTrigger]="false">
|
||||||
<button mat-menu-item [routerLink]="['/users']">{{ 'labels.menus.Users' | translate }}</button>
|
<button mat-menu-item (click)="navigateMenu('/appusers')">{{ 'labels.menus.Users' | translate }}</button>
|
||||||
<button mat-menu-item [routerLink]="['/organization']">{{ 'labels.menus.Organization' | translate }}</button>
|
<button mat-menu-item [routerLink]="['/organization']">{{ 'labels.menus.Organization' | translate }}</button>
|
||||||
<button mat-menu-item [routerLink]="['/system']">{{ 'labels.menus.System' | translate }}</button>
|
<button mat-menu-item [routerLink]="['/system']">{{ 'labels.menus.System' | translate }}</button>
|
||||||
<button mat-menu-item [routerLink]="['/products']">{{ 'labels.menus.Products' | translate }}</button>
|
<button mat-menu-item [routerLink]="['/products']">{{ 'labels.menus.Products' | translate }}</button>
|
||||||
<button mat-menu-item [routerLink]="['/templates']">{{ 'labels.menus.Templates' | translate }}</button>
|
<button mat-menu-item routerLink="/templates">{{ 'labels.menus.Templates' | translate }}</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
<mat-menu #selfServiceMenu="matMenu" [overlapTrigger]="false">
|
<mat-menu #selfServiceMenu="matMenu" [overlapTrigger]="false">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/** Angular Imports */
|
/** Angular Imports */
|
||||||
import { Component, OnInit, Input, EventEmitter, Output, ViewChild, AfterViewInit, ElementRef, TemplateRef } from '@angular/core';
|
import { Component, OnInit, Input, EventEmitter, Output, ViewChild, AfterViewInit, ElementRef, TemplateRef, AfterContentChecked, ChangeDetectorRef } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { MatSidenav } from '@angular/material/sidenav';
|
import { MatSidenav } from '@angular/material/sidenav';
|
||||||
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
||||||
@@ -25,7 +25,7 @@ import { ConfigurationWizardComponent } from '../../../configuration-wizard/conf
|
|||||||
templateUrl: './toolbar.component.html',
|
templateUrl: './toolbar.component.html',
|
||||||
styleUrls: ['./toolbar.component.scss']
|
styleUrls: ['./toolbar.component.scss']
|
||||||
})
|
})
|
||||||
export class ToolbarComponent implements OnInit, AfterViewInit {
|
export class ToolbarComponent implements OnInit, AfterViewInit, AfterContentChecked {
|
||||||
|
|
||||||
/* Reference of institution */
|
/* Reference of institution */
|
||||||
@ViewChild('institution') institution: ElementRef<any>;
|
@ViewChild('institution') institution: ElementRef<any>;
|
||||||
@@ -64,7 +64,8 @@ export class ToolbarComponent implements OnInit, AfterViewInit {
|
|||||||
private authenticationService: AuthenticationService,
|
private authenticationService: AuthenticationService,
|
||||||
private popoverService: PopoverService,
|
private popoverService: PopoverService,
|
||||||
private configurationWizardService: ConfigurationWizardService,
|
private configurationWizardService: ConfigurationWizardService,
|
||||||
private dialog: MatDialog) { }
|
private dialog: MatDialog,
|
||||||
|
private changeDetector: ChangeDetectorRef) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribes to breakpoint for handset.
|
* Subscribes to breakpoint for handset.
|
||||||
@@ -77,6 +78,10 @@ export class ToolbarComponent implements OnInit, AfterViewInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterContentChecked(): void {
|
||||||
|
this.changeDetector.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the current state of sidenav.
|
* Toggles the current state of sidenav.
|
||||||
*/
|
*/
|
||||||
@@ -187,4 +192,10 @@ export class ToolbarComponent implements OnInit, AfterViewInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
navigateMenu(routePath: string): void {
|
||||||
|
console.log(routePath);
|
||||||
|
this.router.navigate([routePath]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -63,9 +63,10 @@
|
|||||||
|
|
||||||
<ng-template matStepLabel>PAYMENT ALLOCATION</ng-template>
|
<ng-template matStepLabel>PAYMENT ALLOCATION</ng-template>
|
||||||
|
|
||||||
<mifosx-loan-product-payment-strategy-step
|
<mifosx-loan-product-payment-strategy-step *ngFor="let transactionType of transactionTypes"
|
||||||
[loanProductsTemplate]="loanProductsTemplate"
|
[loanProductsTemplate]="loanProductsTemplate"
|
||||||
(paymentAllocation)="setPaymentAllocation($event)"
|
(paymentAllocation)="setPaymentAllocation($event)"
|
||||||
|
(transactionType)="transactionType"
|
||||||
>
|
>
|
||||||
</mifosx-loan-product-payment-strategy-step>
|
</mifosx-loan-product-payment-strategy-step>
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { LoanProductAccountingStepComponent } from '../loan-product-stepper/loan
|
|||||||
/** Custom Services */
|
/** Custom Services */
|
||||||
import { ProductsService } from 'app/products/products.service';
|
import { ProductsService } from 'app/products/products.service';
|
||||||
import { LoanProducts } from '../loan-products';
|
import { LoanProducts } from '../loan-products';
|
||||||
import { PaymentAllocation } from '../loan-product-stepper/loan-product-payment-strategy-step/loan-product-payment-strategy-step.component';
|
import { PaymentAllocation, PaymentAllocationTransactionType, PaymentAllocationTransactionTypes, PaymentAllocationTypes } from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'mifosx-create-loan-product',
|
selector: 'mifosx-create-loan-product',
|
||||||
@@ -35,6 +35,9 @@ export class CreateLoanProductComponent implements OnInit {
|
|||||||
|
|
||||||
isAdvancedPaymentStrategy = false;
|
isAdvancedPaymentStrategy = false;
|
||||||
paymentAllocation: PaymentAllocation[] = [];
|
paymentAllocation: PaymentAllocation[] = [];
|
||||||
|
transactionTypes: PaymentAllocationTransactionType[] = [
|
||||||
|
PaymentAllocationTransactionTypes.DEFAULT_TRANSACTION
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ActivatedRoute} route Activated Route.
|
* @param {ActivatedRoute} route Activated Route.
|
||||||
|
|||||||
@@ -63,10 +63,11 @@
|
|||||||
|
|
||||||
<ng-template matStepLabel>PAYMENT ALLOCATION</ng-template>
|
<ng-template matStepLabel>PAYMENT ALLOCATION</ng-template>
|
||||||
|
|
||||||
<mifosx-loan-product-payment-strategy-step
|
<mifosx-loan-product-payment-strategy-step *ngFor="let transactionType of transactionTypes"
|
||||||
[loanProductsTemplate]="loanProductsTemplate"
|
[loanProductsTemplate]="loanProductsTemplate"
|
||||||
(paymentAllocation)="setPaymentAllocation($event)"
|
(paymentAllocation)="setPaymentAllocation($event)"
|
||||||
(paymentAllocationChange)="paymentAllocationChanged($event)"
|
(paymentAllocationChange)="paymentAllocationChanged($event)"
|
||||||
|
(transactionType)="transactionType"
|
||||||
>
|
>
|
||||||
</mifosx-loan-product-payment-strategy-step>
|
</mifosx-loan-product-payment-strategy-step>
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { LoanProductAccountingStepComponent } from '../loan-product-stepper/loan
|
|||||||
import { ProductsService } from 'app/products/products.service';
|
import { ProductsService } from 'app/products/products.service';
|
||||||
import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model';
|
import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model';
|
||||||
import { LoanProducts } from '../loan-products';
|
import { LoanProducts } from '../loan-products';
|
||||||
import { PaymentAllocation } from '../loan-product-stepper/loan-product-payment-strategy-step/loan-product-payment-strategy-step.component';
|
import { PaymentAllocation, PaymentAllocationTransactionType, PaymentAllocationTransactionTypes } from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'mifosx-edit-loan-product',
|
selector: 'mifosx-edit-loan-product',
|
||||||
@@ -37,6 +37,9 @@ export class EditLoanProductComponent implements OnInit {
|
|||||||
isAdvancedPaymentStrategy = false;
|
isAdvancedPaymentStrategy = false;
|
||||||
wasPaymentAllocationChanged = false;
|
wasPaymentAllocationChanged = false;
|
||||||
paymentAllocation: PaymentAllocation[] = [];
|
paymentAllocation: PaymentAllocation[] = [];
|
||||||
|
transactionTypes: PaymentAllocationTransactionType[] = [
|
||||||
|
PaymentAllocationTransactionTypes.DEFAULT_TRANSACTION
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ActivatedRoute} route Activated Route.
|
* @param {ActivatedRoute} route Activated Route.
|
||||||
|
|||||||
+45
-22
@@ -1,32 +1,55 @@
|
|||||||
<div class="container space-top" fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
<div class="container space-top" fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
<div fxFlexFill fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||||
|
|
||||||
<mat-form-field fxFlex="33%">
|
<mat-form-field fxFlex="33%">
|
||||||
<mat-label>Future Installment Allocation Rule</mat-label>
|
<mat-label>Transaction Type</mat-label>
|
||||||
<mat-select [formControl]="futureInstallmentAllocationRule">
|
<mat-select [formControl]="transactionTypeCtrl" disabled>
|
||||||
<mat-option *ngFor="let installmentAllocation of installmentAllocationOptions" [value]="installmentAllocation.code">
|
<mat-option *ngFor="let transactionTypeOption of transactionTypeOptions" [value]="transactionTypeOption.code">
|
||||||
{{ installmentAllocation.name | translate }}
|
{{ transactionTypeOption.name | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<div class="mat-elevation-z8 container">
|
<div class="mat-elevation-z8 container m-t-20">
|
||||||
|
|
||||||
<table mat-table [dataSource]="transactionTypesData" #table cdkDropList [cdkDropListData]="transactionTypesData"
|
<table mat-table [dataSource]="paymentAllocationsData" #table cdkDropList
|
||||||
(cdkDropListDropped)="dropTable($event)">
|
[cdkDropListData]="paymentAllocationsData" (cdkDropListDropped)="dropTable($event)"
|
||||||
|
matTooltip="You can drag and drop the rows to set a Payment Allocations order">
|
||||||
|
|
||||||
<ng-container matColumnDef="order">
|
<ng-container matColumnDef="order">
|
||||||
<th mat-header-cell *matHeaderCellDef> Order </th>
|
<th mat-header-cell *matHeaderCellDef> Order </th>
|
||||||
<td mat-cell *matCellDef="let transactionType; let rowIndex = index"> {{ (rowIndex + 1) }} </td>
|
<td mat-cell *matCellDef="let paymentAllocation; let rowIndex = index"> {{ (rowIndex + 1) }} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="transactionName">
|
<ng-container matColumnDef="paymentAllocation">
|
||||||
<th mat-header-cell *matHeaderCellDef> Transaction Type </th>
|
<th mat-header-cell *matHeaderCellDef> Payment Allocation </th>
|
||||||
<td mat-cell *matCellDef="let transactionType"> {{ transactionType.name }} </td>
|
<td mat-cell *matCellDef="let paymentAllocation"> {{ paymentAllocation.name }} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
<tr mat-row cdkDrag [cdkDragData]="row" *matRowDef="let row; columns: displayedColumns;"></tr>
|
<tr mat-row cdkDrag [cdkDragData]="row" *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="33%" class="m-t-20">
|
||||||
|
<mat-label>Future Installment Allocation Rule</mat-label>
|
||||||
|
<mat-select [formControl]="futureInstallmentAllocationRule">
|
||||||
|
<mat-option *ngFor="let installmentAllocation of installmentAllocationOptions"
|
||||||
|
[value]="installmentAllocation.code">
|
||||||
|
{{ installmentAllocation.name | translate }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left" class="m-r-10"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+25
-89
@@ -3,23 +3,7 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angu
|
|||||||
import { UntypedFormControl, Validators } from '@angular/forms';
|
import { UntypedFormControl, Validators } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { MatTable } from '@angular/material/table';
|
import { MatTable } from '@angular/material/table';
|
||||||
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
import { FutureInstallmentAllocationRules, PaymentAllocation, PaymentAllocationOrder, PaymentAllocationTransactionType, PaymentAllocationTransactionTypes, PaymentAllocationTypes, PaymentCode } from './payment-allocation-model';
|
||||||
|
|
||||||
interface PaymentCode {
|
|
||||||
name: string;
|
|
||||||
code: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PaymentAllocationOrder {
|
|
||||||
paymentAllocationRule: string;
|
|
||||||
order: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PaymentAllocation {
|
|
||||||
transactionType: string;
|
|
||||||
paymentAllocationOrder: PaymentAllocationOrder[];
|
|
||||||
futureInstallmentAllocationRule: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'mifosx-loan-product-payment-strategy-step',
|
selector: 'mifosx-loan-product-payment-strategy-step',
|
||||||
@@ -29,112 +13,64 @@ export interface PaymentAllocation {
|
|||||||
export class LoanProductPaymentStrategyStepComponent implements OnInit {
|
export class LoanProductPaymentStrategyStepComponent implements OnInit {
|
||||||
|
|
||||||
@Input() loanProductsTemplate: any;
|
@Input() loanProductsTemplate: any;
|
||||||
|
@Input() transactionType: PaymentAllocationTransactionType;
|
||||||
@Output() paymentAllocation = new EventEmitter<PaymentAllocation[]>();
|
@Output() paymentAllocation = new EventEmitter<PaymentAllocation[]>();
|
||||||
@Output() paymentAllocationChange = new EventEmitter<boolean>();
|
@Output() paymentAllocationChange = new EventEmitter<boolean>();
|
||||||
|
|
||||||
transactionTypesData: PaymentCode[] = [];
|
paymentAllocationsData: PaymentCode[] = [];
|
||||||
transactionTypeOptions: PaymentCode[] = [];
|
|
||||||
installmentAllocationOptions: PaymentCode[] = [];
|
installmentAllocationOptions: PaymentCode[] = [];
|
||||||
|
transactionTypeOptions: PaymentCode[] = [];
|
||||||
|
|
||||||
transactionType = new UntypedFormControl('');
|
transactionTypeCtrl = new UntypedFormControl('');
|
||||||
futureInstallmentAllocationRule = new UntypedFormControl('', Validators.required);
|
futureInstallmentAllocationRule = new UntypedFormControl('', Validators.required);
|
||||||
|
|
||||||
@ViewChild('table') table: MatTable<any>;
|
@ViewChild('table') table: MatTable<any>;
|
||||||
|
|
||||||
/** Columns to be displayed in the table. */
|
/** Columns to be displayed in the table. */
|
||||||
displayedColumns: string[] = ['order', 'transactionName'];
|
displayedColumns: string[] = ['order', 'paymentAllocation'];
|
||||||
|
|
||||||
constructor(private dialog: MatDialog) { }
|
constructor() { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.transactionTypesData = [];
|
this.paymentAllocationsData = [];
|
||||||
this.setOptions();
|
this.setOptions();
|
||||||
this.sendPaymentAllocation();
|
this.sendPaymentAllocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
setOptions(): void {
|
setOptions(): void {
|
||||||
this.transactionTypeOptions = [
|
this.paymentAllocationsData = PaymentAllocationTypes.options;
|
||||||
{ name: 'Past due penalty', code: 'PAST_DUE_PENALTY' },
|
this.transactionTypeOptions = PaymentAllocationTransactionTypes.options;
|
||||||
{ name: 'Past due fee', code: 'PAST_DUE_FEE' },
|
this.transactionTypeCtrl.patchValue(this.transactionTypeOptions[0].code);
|
||||||
{ name: 'Past due principal', code: 'PAST_DUE_PRINCIPAL' },
|
if (this.transactionType) {
|
||||||
{ name: 'Past due interest', code: 'PAST_DUE_INTEREST' },
|
this.transactionTypeCtrl.patchValue(this.transactionType.code);
|
||||||
{ name: 'Due penalty', code: 'DUE_PENALTY' },
|
}
|
||||||
{ name: 'Due fee', code: 'DUE_FEE' },
|
this.installmentAllocationOptions = FutureInstallmentAllocationRules.options;
|
||||||
{ name: 'Due principal', code: 'DUE_PRINCIPAL' },
|
this.futureInstallmentAllocationRule.patchValue(this.installmentAllocationOptions[0].code);
|
||||||
{ name: 'Due interest', code: 'DUE_INTEREST' },
|
|
||||||
{ name: 'In advance penalty', code: 'IN_ADVANCE_PENALTY' },
|
|
||||||
{ name: 'In advance fee', code: 'IN_ADVANCE_FEE' },
|
|
||||||
{ name: 'In advance principal', code: 'IN_ADVANCE_PRINCIPAL' },
|
|
||||||
{ name: 'In advance interest', code: 'IN_ADVANCE_INTEREST' }
|
|
||||||
];
|
|
||||||
this.transactionTypesData = this.transactionTypeOptions;
|
|
||||||
|
|
||||||
this.installmentAllocationOptions = [
|
|
||||||
{ name: 'Next Installment', code: 'NEXT_INSTALLMENT' },
|
|
||||||
{ name: 'Last Installment', code: 'LAST_INSTALLMENT' },
|
|
||||||
{ name: 'Reamortization', code: 'REAMORTIZATION' }
|
|
||||||
];
|
|
||||||
|
|
||||||
this.futureInstallmentAllocationRule.patchValue('NEXT_INSTALLMENT');
|
|
||||||
}
|
|
||||||
|
|
||||||
addTransactionType(): void {
|
|
||||||
this.transactionTypeOptions.forEach((txType: PaymentCode) => {
|
|
||||||
if (txType.code === this.transactionType.value) {
|
|
||||||
this.transactionTypesData = [
|
|
||||||
...this.transactionTypesData,
|
|
||||||
txType
|
|
||||||
];
|
|
||||||
this.sendPaymentAllocation();
|
|
||||||
this.removePaymentCode(txType);
|
|
||||||
this.resetTransactionType();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
removePaymentCode(txType: PaymentCode): void {
|
|
||||||
this.transactionTypeOptions = this.transactionTypeOptions.filter(({ code }) => code !== txType.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
resetTransactionType(): void {
|
|
||||||
this.transactionType.patchValue('');
|
|
||||||
this.transactionType.markAsUntouched();
|
|
||||||
}
|
|
||||||
|
|
||||||
removeTransactionType(index: number) {
|
|
||||||
const transactionTypeName = this.transactionTypesData[index].name;
|
|
||||||
const dialogRef = this.dialog.open(DeleteDialogComponent, {
|
|
||||||
data: { deleteContext: transactionTypeName }
|
|
||||||
});
|
|
||||||
dialogRef.afterClosed().subscribe((response: any) => {
|
|
||||||
if (response.delete) {
|
|
||||||
this.transactionTypesData.splice(index, 1);
|
|
||||||
this.transactionTypesData = this.transactionTypesData.concat([]);
|
|
||||||
this.transactionTypesData = [...this.transactionTypesData];
|
|
||||||
this.sendPaymentAllocation();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dropTable(event: CdkDragDrop<any[]>) {
|
dropTable(event: CdkDragDrop<any[]>) {
|
||||||
const prevIndex = this.transactionTypesData.findIndex((d: any) => d === event.item.data);
|
const prevIndex = this.paymentAllocationsData.findIndex((d: any) => d === event.item.data);
|
||||||
moveItemInArray(this.transactionTypesData, prevIndex, event.currentIndex);
|
moveItemInArray(this.paymentAllocationsData, prevIndex, event.currentIndex);
|
||||||
this.transactionTypesData = [...this.transactionTypesData];
|
this.paymentAllocationsData = [...this.paymentAllocationsData];
|
||||||
this.table.renderRows();
|
this.table.renderRows();
|
||||||
this.sendPaymentAllocation();
|
this.sendPaymentAllocation();
|
||||||
this.paymentAllocationChange.emit(true);
|
this.paymentAllocationChange.emit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendPaymentAllocation(): void {
|
sendPaymentAllocation(): void {
|
||||||
|
let transactionTypeVal = PaymentAllocationTransactionTypes.DEFAULT_TRANSACTION.code;
|
||||||
|
if (this.transactionType) {
|
||||||
|
transactionTypeVal = this.transactionType.code;
|
||||||
|
}
|
||||||
const paymentAllocationOrder: PaymentAllocationOrder[] = [];
|
const paymentAllocationOrder: PaymentAllocationOrder[] = [];
|
||||||
this.transactionTypesData.forEach((txType: PaymentCode, index: number) => {
|
this.paymentAllocationsData.forEach((txType: PaymentCode, index: number) => {
|
||||||
paymentAllocationOrder.push({ 'paymentAllocationRule': txType.code, order: (index + 1) });
|
paymentAllocationOrder.push({ 'paymentAllocationRule': txType.code, order: (index + 1) });
|
||||||
});
|
});
|
||||||
|
|
||||||
const paymentAllocation: PaymentAllocation[] = [];
|
const paymentAllocation: PaymentAllocation[] = [];
|
||||||
paymentAllocation.push({
|
paymentAllocation.push({
|
||||||
'futureInstallmentAllocationRule': this.futureInstallmentAllocationRule.value,
|
'futureInstallmentAllocationRule': this.futureInstallmentAllocationRule.value,
|
||||||
'transactionType': 'DEFAULT',
|
'transactionType': transactionTypeVal,
|
||||||
'paymentAllocationOrder': paymentAllocationOrder
|
'paymentAllocationOrder': paymentAllocationOrder
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
export interface PaymentCode {
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PaymentAllocationOrder {
|
||||||
|
paymentAllocationRule: string;
|
||||||
|
order: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PaymentAllocation {
|
||||||
|
transactionType: string;
|
||||||
|
paymentAllocationOrder: PaymentAllocationOrder[];
|
||||||
|
futureInstallmentAllocationRule: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PaymentAllocationTransactionType {
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PaymentAllocationTransactionTypes {
|
||||||
|
public static DEFAULT_TRANSACTION: PaymentAllocationTransactionType = { name: 'Default', code: 'DEFAULT' };
|
||||||
|
|
||||||
|
public static options: PaymentCode[] = [
|
||||||
|
this.DEFAULT_TRANSACTION
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PaymentAllocationTypes {
|
||||||
|
public static options: PaymentCode[] = [
|
||||||
|
{ name: 'Past due penalty', code: 'PAST_DUE_PENALTY' },
|
||||||
|
{ name: 'Past due fee', code: 'PAST_DUE_FEE' },
|
||||||
|
{ name: 'Past due principal', code: 'PAST_DUE_PRINCIPAL' },
|
||||||
|
{ name: 'Past due interest', code: 'PAST_DUE_INTEREST' },
|
||||||
|
{ name: 'Due penalty', code: 'DUE_PENALTY' },
|
||||||
|
{ name: 'Due fee', code: 'DUE_FEE' },
|
||||||
|
{ name: 'Due principal', code: 'DUE_PRINCIPAL' },
|
||||||
|
{ name: 'Due interest', code: 'DUE_INTEREST' },
|
||||||
|
{ name: 'In advance penalty', code: 'IN_ADVANCE_PENALTY' },
|
||||||
|
{ name: 'In advance fee', code: 'IN_ADVANCE_FEE' },
|
||||||
|
{ name: 'In advance principal', code: 'IN_ADVANCE_PRINCIPAL' },
|
||||||
|
{ name: 'In advance interest', code: 'IN_ADVANCE_INTEREST' }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FutureInstallmentAllocationRules {
|
||||||
|
public static options: PaymentCode[] = [
|
||||||
|
{ name: 'Next Installment', code: 'NEXT_INSTALLMENT' },
|
||||||
|
{ name: 'Last Installment', code: 'LAST_INSTALLMENT' },
|
||||||
|
{ name: 'Reamortization', code: 'REAMORTIZATION' }
|
||||||
|
];
|
||||||
|
}
|
||||||
+1
-1
@@ -37,7 +37,7 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="i > 0">
|
<ng-container *ngIf="i > 0">
|
||||||
<th mat-header-cell class="right" *matHeaderCellDef> {{datatableColumn}} </th>
|
<th mat-header-cell class="right" *matHeaderCellDef> {{ getInputName(datatableColumn) }} </th>
|
||||||
<td mat-cell class="right" *matCellDef="let data" [ngClass]="isToDelete(data)">
|
<td mat-cell class="right" *matCellDef="let data" [ngClass]="isToDelete(data)">
|
||||||
{{ formatValue(data, datatableColumn) }}
|
{{ formatValue(data, datatableColumn) }}
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
+4
@@ -256,4 +256,8 @@ export class DatatableMultiRowComponent implements OnInit, OnDestroy, OnChanges
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getInputName(attr: string): string {
|
||||||
|
return this.datatables.getName(attr);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { UserResolver } from './user.resolver';
|
|||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
Route.withShell([
|
Route.withShell([
|
||||||
{
|
{
|
||||||
path: 'users',
|
path: 'appusers',
|
||||||
data: { title: extract('Users'), breadcrumb: 'Users' },
|
data: { title: extract('Users'), breadcrumb: 'Users' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export class UsersService {
|
|||||||
* @returns {Observable<any>} Users data
|
* @returns {Observable<any>} Users data
|
||||||
*/
|
*/
|
||||||
getUsers(): Observable<any> {
|
getUsers(): Observable<any> {
|
||||||
return this.http.get('/users');
|
return this.http.get(`/users`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -88,3 +88,7 @@ $error-log: #ffa726;
|
|||||||
color: $status-inactive;
|
color: $status-inactive;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cdk-drag-placeholder {
|
||||||
|
background: $peter-river;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user