Loan product with Advanced Credit Allocation

This commit is contained in:
Jose Alberto Hernandez
2024-02-07 13:41:14 +01:00
committed by Adam Saghy
parent e8f6e5e34a
commit 5d0e063be6
28 changed files with 389 additions and 70 deletions
@@ -356,6 +356,18 @@
</span>
</div>
<div fxFlexFill *ngIf="isAdvancedPaymentAllocation">
<span fxFlex="47%">Advanced Credit Allocation Transactions:</span>
<span fxFlex="53%">
<mat-accordion>
<mifosx-view-advance-paymeny-allocation *ngFor="let creditAllocation of creditAllocations"
[creditAllocation]="creditAllocation"
[advancePaymentAllocationData]="advancePaymentAllocationData">
</mifosx-view-advance-paymeny-allocation>
</mat-accordion>
</span>
</div>
<h3 class="mat-h3" fxFlexFill>Down Payments</h3>
<mat-divider [inset]="true"></mat-divider>
@@ -1,7 +1,7 @@
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { DelinquencyBucket, LoanProduct } from '../../models/loan-product.model';
import { AccountingMapping, Charge, ChargeToIncomeAccountMapping, GLAccount, PaymentChannelToFundSourceMapping, PaymentType, PaymentTypeOption } from '../../../../shared/models/general.model';
import { AdvancePaymentAllocationData, PaymentAllocation } from '../../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
import { AdvancePaymentAllocationData, CreditAllocation, PaymentAllocation } from '../../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
import { LoanProducts } from '../../loan-products';
import { CodeName, OptionData } from '../../../../shared/models/option-data.model';
@@ -17,6 +17,7 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
@Input() loanProductsTemplate: any | null;
@Input() useDueForRepaymentsConfigurations: boolean;
@Input() paymentAllocations: PaymentAllocation | null;
@Input() creditAllocations: CreditAllocation | null;
variationsDisplayedColumns: string[] = ['valueConditionType', 'borrowerCycleNumber', 'minValue', 'defaultValue', 'maxValue'];
chargesDisplayedColumns: string[] = ['name', 'chargeCalculationType', 'amount', 'chargeTimeType'];
@@ -185,15 +186,23 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
}
if (this.loanProduct.advancedPaymentAllocationTransactionTypes) {
const advancedAllocationTransactionTypes: OptionData[] = this.loanProduct.advancedPaymentAllocationTransactionTypes
.concat(this.loanProduct.creditAllocationTransactionTypes);
const advancedPaymentAllocationTypes: OptionData[] = this.loanProduct.advancedPaymentAllocationTypes
.concat(this.loanProduct.creditAllocationAllocationTypes);
this.advancePaymentAllocationData = {
transactionTypes: this.loanProduct.advancedPaymentAllocationTransactionTypes,
allocationTypes: this.loanProduct.advancedPaymentAllocationTypes,
transactionTypes: advancedAllocationTransactionTypes,
allocationTypes: advancedPaymentAllocationTypes,
futureInstallmentAllocationRules: this.loanProduct.advancedPaymentAllocationFutureInstallmentAllocationRules
};
} else {
const advancedAllocationTransactionTypes: OptionData[] = this.loanProductsTemplate.advancedPaymentAllocationTransactionTypes
.concat(this.loanProductsTemplate.creditAllocationTransactionTypes);
const advancedPaymentAllocationTypes: OptionData[] = this.loanProductsTemplate.advancedPaymentAllocationTypes
.concat(this.loanProductsTemplate.creditAllocationAllocationTypes);
this.advancePaymentAllocationData = {
transactionTypes: this.loanProductsTemplate.advancedPaymentAllocationTransactionTypes,
allocationTypes: this.loanProductsTemplate.advancedPaymentAllocationTypes,
transactionTypes: advancedAllocationTransactionTypes,
allocationTypes: advancedPaymentAllocationTypes,
futureInstallmentAllocationRules: this.loanProductsTemplate.advancedPaymentAllocationFutureInstallmentAllocationRules
};
}
@@ -65,9 +65,13 @@
<mifosx-loan-product-payment-strategy-step
[advancedPaymentAllocations]="advancedPaymentAllocations"
[advancedCreditAllocations]="advancedCreditAllocations"
[advancedPaymentAllocationTransactionTypes]="loanProductsTemplate.advancedPaymentAllocationTransactionTypes"
[paymentAllocationOrderDefault]="loanProductsTemplate.advancedPaymentAllocationTypes"
[advancedCreditAllocationTransactionTypes]="loanProductsTemplate.creditAllocationTransactionTypes"
[creditAllocationOrderDefault]="loanProductsTemplate.creditAllocationAllocationTypes"
(setPaymentAllocation)="setPaymentAllocation($event)"
(setCreditAllocation)="setCreditAllocation($event)"
>
</mifosx-loan-product-payment-strategy-step>
@@ -35,7 +35,9 @@ export class CreateLoanProductComponent implements OnInit {
isAdvancedPaymentStrategy = false;
paymentAllocation: PaymentAllocation[] = [];
creditAllocation: PaymentAllocation[] = [];
advancedPaymentAllocations: AdvancedPaymentAllocation[] = [];
advancedCreditAllocations: AdvancedPaymentAllocation[] = [];
/**
* @param {ActivatedRoute} route Activated Route.
@@ -90,6 +92,10 @@ export class CreateLoanProductComponent implements OnInit {
this.paymentAllocation = paymentAllocation;
}
setCreditAllocation(paymentAllocation: PaymentAllocation[]): void {
this.creditAllocation = paymentAllocation;
}
get loanProductSettingsForm() {
return this.loanProductSettingsStep.loanProductSettingsForm;
}
@@ -119,6 +125,7 @@ export class CreateLoanProductComponent implements OnInit {
};
if (this.isAdvancedPaymentStrategy) {
loanProduct['paymentAllocation'] = this.paymentAllocation;
loanProduct['creditAllocation'] = this.creditAllocation;
}
return loanProduct;
}
@@ -65,9 +65,13 @@
<mifosx-loan-product-payment-strategy-step
[advancedPaymentAllocations]="advancedPaymentAllocations"
[advancedCreditAllocations]="advancedCreditAllocations"
[advancedPaymentAllocationTransactionTypes]="loanProductAndTemplate.advancedPaymentAllocationTransactionTypes"
[paymentAllocationOrderDefault]="loanProductAndTemplate.advancedPaymentAllocationTypes"
[advancedCreditAllocationTransactionTypes]="loanProductAndTemplate.creditAllocationTransactionTypes"
[creditAllocationOrderDefault]="loanProductAndTemplate.creditAllocationAllocationTypes"
(setPaymentAllocation)="setPaymentAllocation($event)"
(setCreditAllocation)="setCreditAllocation($event)"
>
</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 { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model';
import { LoanProducts } from '../loan-products';
import { AdvancedPaymentAllocation, AdvancedPaymentStrategy, PaymentAllocation, PaymentAllocationOrder, PaymentAllocationTransactionTypes } from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
import { AdvancedPaymentAllocation, AdvancedPaymentStrategy, CreditAllocation, PaymentAllocation, PaymentAllocationOrder, PaymentAllocationTransactionTypes } from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
@Component({
selector: 'mifosx-edit-loan-product',
@@ -37,7 +37,9 @@ export class EditLoanProductComponent implements OnInit {
isAdvancedPaymentStrategy = false;
wasPaymentAllocationChanged = false;
paymentAllocation: PaymentAllocation[] = [];
creditAllocation: CreditAllocation[] = [];
advancedPaymentAllocations: AdvancedPaymentAllocation[] = [];
advancedCreditAllocations: AdvancedPaymentAllocation[] = [];
/**
* @param {ActivatedRoute} route Activated Route.
@@ -68,6 +70,7 @@ export class EditLoanProductComponent implements OnInit {
this.advancePaymentStrategy(this.loanProductAndTemplate.transactionProcessingStrategyCode);
if (this.isAdvancedPaymentStrategy) {
this.paymentAllocation = this.loanProductAndTemplate.paymentAllocation;
this.creditAllocation = this.loanProductAndTemplate.creditAllocation;
}
}
@@ -93,6 +96,8 @@ export class EditLoanProductComponent implements OnInit {
buildAdvancedPaymentAllocation(): void {
this.advancedPaymentAllocations = this.advancedPaymentStrategy.buildAdvancedPaymentAllocationList(this.loanProductAndTemplate);
this.advancedCreditAllocations = this.advancedPaymentStrategy.buildAdvancedCreditAllocationList(this.loanProductAndTemplate);
console.log(this.advancedCreditAllocations);
}
setPaymentAllocation(paymentAllocation: PaymentAllocation[]): void {
@@ -100,6 +105,11 @@ export class EditLoanProductComponent implements OnInit {
this.wasPaymentAllocationChanged = true;
}
setCreditAllocation(creditAllocation: CreditAllocation[]): void {
this.creditAllocation = creditAllocation;
this.wasPaymentAllocationChanged = true;
}
paymentAllocationChanged(value: boolean): void {
this.wasPaymentAllocationChanged = value;
}
@@ -138,8 +148,10 @@ export class EditLoanProductComponent implements OnInit {
};
// Default empty array
loanProduct['paymentAllocation'] = [];
loanProduct['creditAllocation'] = [];
if (this.isAdvancedPaymentStrategy) {
loanProduct['paymentAllocation'] = this.paymentAllocation;
loanProduct['creditAllocation'] = this.creditAllocation;
}
return loanProduct;
}
@@ -8,9 +8,9 @@
</button>
</div>
<div class="mat-elevation-z8 container m-t-15">
<div class="mat-elevation-z8 container m-t-15" *ngIf="paymentAllocationsData">
<table mat-table [dataSource]="paymentAllocationsData" #table cdkDropList
[cdkDropListData]="paymentAllocationsData" (cdkDropListDropped)="dropTable($event)">
[cdkDropListData]="paymentAllocationsData" (cdkDropListDropped)="dropTable($event, false)">
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> </th>
@@ -20,12 +20,12 @@
</ng-container>
<ng-container matColumnDef="order">
<th mat-header-cell *matHeaderCellDef> Order </th>
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Order' | translate }}</th>
<td mat-cell *matCellDef="let paymentAllocation; let rowIndex = index"> {{ (rowIndex + 1) }} </td>
</ng-container>
<ng-container matColumnDef="paymentAllocation">
<th mat-header-cell *matHeaderCellDef> Payment Allocation </th>
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Payment Allocation' | translate }}</th>
<td mat-cell *matCellDef="let paymentAllocation"> {{ paymentAllocation.value }} </td>
</ng-container>
@@ -34,12 +34,38 @@
</table>
</div>
<mat-form-field fxFlex="33%" class="m-t-20">
<mat-label>Future Installment Allocation Rule</mat-label>
<div class="mat-elevation-z8 container m-t-15" *ngIf="creditAllocationsData">
<table mat-table [dataSource]="creditAllocationsData" #table cdkDropList
[cdkDropListData]="creditAllocationsData" (cdkDropListDropped)="dropTable($event, true)">
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> </th>
<td mat-cell *matCellDef="let creditAllocation">
<fa-icon icon="bars"></fa-icon>
</td>
</ng-container>
<ng-container matColumnDef="order">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Order' | translate }}</th>
<td mat-cell *matCellDef="let creditAllocation; let rowIndex = index"> {{ (rowIndex + 1) }} </td>
</ng-container>
<ng-container matColumnDef="paymentAllocation">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Payment Allocation' | translate }}</th>
<td mat-cell *matCellDef="let creditAllocation"> {{ creditAllocation.value }} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row cdkDrag [cdkDragData]="row" *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
<mat-form-field fxFlex="33%" class="m-t-20" *ngIf="advancedPaymentAllocation && advancedPaymentAllocation.futureInstallmentAllocationRules">
<mat-label>{{ 'labels.inputs.Future Installment Allocation Rule' | translate }}</mat-label>
<mat-select [formControl]="futureInstallmentAllocationRule">
<mat-option *ngFor="let futureInstallmentAllocationRule of advancedPaymentAllocation.futureInstallmentAllocationRules"
[value]="futureInstallmentAllocationRule.code">
{{ futureInstallmentAllocationRule.value | translate}}
{{ futureInstallmentAllocationRule.value | translate }}
</mat-option>
</mat-select>
</mat-form-field>
@@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { AdvancedPaymentAllocation, AdvancedPaymentStrategy, FutureInstallmentAllocationRule, PaymentAllocationOrder, PaymentAllocationTransactionType } from '../payment-allocation-model';
import { AdvancedPaymentAllocation, AdvancedPaymentStrategy, CreditAllocationOrder, FutureInstallmentAllocationRule, PaymentAllocationOrder, PaymentAllocationTransactionType } from '../payment-allocation-model';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { MatTable } from '@angular/material/table';
import { MatDialog } from '@angular/material/dialog';
@@ -18,7 +18,8 @@ export class AdvancePaymentAllocationTabComponent implements OnInit {
@Output() paymentAllocationChange = new EventEmitter<boolean>();
@Output() transactionTypeRemoved = new EventEmitter<PaymentAllocationTransactionType>();
paymentAllocationsData: PaymentAllocationOrder[] = [];
paymentAllocationsData: PaymentAllocationOrder[] | null = null;
creditAllocationsData: CreditAllocationOrder[] | null = null;
/** Columns to be displayed in the table. */
displayedColumns: string[] = ['actions', 'order', 'paymentAllocation'];
@@ -31,29 +32,51 @@ export class AdvancePaymentAllocationTabComponent implements OnInit {
private advancedPaymentStrategy: AdvancedPaymentStrategy) { }
ngOnInit(): void {
this.paymentAllocationsData = this.advancedPaymentAllocation.paymentAllocationOrder;
this.futureInstallmentAllocationRule.patchValue(this.advancedPaymentAllocation.futureInstallmentAllocationRule.code);
this.futureInstallmentAllocationRule.valueChanges.subscribe((value: any) => {
this.advancedPaymentAllocation.futureInstallmentAllocationRules.forEach((item: FutureInstallmentAllocationRule) => {
if (value === item.code) {
this.advancedPaymentAllocation.futureInstallmentAllocationRule = item;
this.paymentAllocationChange.emit(true);
}
console.log(this.advancedPaymentAllocation);
if (this.advancedPaymentAllocation) {
if (this.advancedPaymentAllocation.creditAllocationOrder) {
this.creditAllocationsData = this.advancedPaymentAllocation.creditAllocationOrder;
}
if (this.advancedPaymentAllocation.paymentAllocationOrder) {
this.paymentAllocationsData = this.advancedPaymentAllocation.paymentAllocationOrder;
}
if (this.advancedPaymentAllocation.futureInstallmentAllocationRule) {
this.futureInstallmentAllocationRule.patchValue(this.advancedPaymentAllocation.futureInstallmentAllocationRule.code);
}
this.futureInstallmentAllocationRule.valueChanges.subscribe((value: any) => {
this.advancedPaymentAllocation.futureInstallmentAllocationRules.forEach((item: FutureInstallmentAllocationRule) => {
if (value === item.code) {
this.advancedPaymentAllocation.futureInstallmentAllocationRule = item;
this.paymentAllocationChange.emit(true);
}
});
});
});
}
}
dropTable(event: CdkDragDrop<any[]>) {
const prevIndex = this.paymentAllocationsData.findIndex((d: any) => d === event.item.data);
moveItemInArray(this.paymentAllocationsData, prevIndex, event.currentIndex);
this.paymentAllocationsData = [...this.paymentAllocationsData];
this.advancedPaymentAllocation.paymentAllocationOrder = this.paymentAllocationsData;
this.table.renderRows();
this.paymentAllocationChange.emit(true);
dropTable(event: CdkDragDrop<any[]>, credit: boolean) {
if (!credit) {
const prevIndex = this.paymentAllocationsData.findIndex((d: any) => d === event.item.data);
moveItemInArray(this.paymentAllocationsData, prevIndex, event.currentIndex);
this.paymentAllocationsData = [...this.paymentAllocationsData];
this.advancedPaymentAllocation.paymentAllocationOrder = this.paymentAllocationsData;
this.table.renderRows();
this.paymentAllocationChange.emit(true);
} else {
const prevIndex = this.creditAllocationsData.findIndex((d: any) => d === event.item.data);
moveItemInArray(this.creditAllocationsData, prevIndex, event.currentIndex);
this.creditAllocationsData = [...this.creditAllocationsData];
this.advancedPaymentAllocation.creditAllocationOrder = this.creditAllocationsData;
this.table.renderRows();
this.paymentAllocationChange.emit(true);
}
}
isDefault(): boolean {
return this.advancedPaymentStrategy.isDefault(this.advancedPaymentAllocation.transaction);
if (this.advancedPaymentAllocation && this.advancedPaymentAllocation.transaction) {
return this.advancedPaymentStrategy.isDefault(this.advancedPaymentAllocation.transaction);
}
return false;
}
removeTransaction(): void {
@@ -1,7 +1,7 @@
<mat-tab-group animationDuration="0ms" fxLayout="row wrap" fxLayoutGap="2%"
fxLayout.lt-md="column">
<mat-tab *ngFor="let advancedPaymentAllocation of advancedPaymentAllocations">
<mat-tab *ngFor="let advancedPaymentAllocation of advancedAllocations">
<ng-template mat-tab-label>
{{advancedPaymentAllocation.transaction.code}}
</ng-template>
@@ -1,10 +1,11 @@
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { AdvancedPaymentAllocation, AdvancedPaymentStrategy, PaymentAllocation, PaymentAllocationOrder, PaymentAllocationTransactionType } from './payment-allocation-model';
import { AdvancedPaymentAllocation, AdvancedPaymentStrategy, CreditAllocation, PaymentAllocation, PaymentAllocationOrder, PaymentAllocationTransactionType } from './payment-allocation-model';
import { MatDialog } from '@angular/material/dialog';
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
import { MatTabGroup } from '@angular/material/tabs';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'mifosx-loan-product-payment-strategy-step',
@@ -13,30 +14,39 @@ import { MatTabGroup } from '@angular/material/tabs';
})
export class LoanProductPaymentStrategyStepComponent implements OnInit {
advancedAllocations: AdvancedPaymentAllocation[] = [];
@Input() advancedPaymentAllocations: AdvancedPaymentAllocation[] = [];
@Input() advancedCreditAllocations: AdvancedPaymentAllocation[] = [];
@Input() advancedPaymentAllocationTransactionTypes: PaymentAllocationTransactionType[] = [];
@Input() paymentAllocationOrderDefault: PaymentAllocationOrder[];
@Input() advancedCreditAllocationTransactionTypes: PaymentAllocationTransactionType[] = [];
@Input() creditAllocationOrderDefault: PaymentAllocationOrder[];
@Output() paymentAllocationChange = new EventEmitter<boolean>();
@Output() setPaymentAllocation = new EventEmitter<PaymentAllocation[]>();
@Output() setCreditAllocation = new EventEmitter<CreditAllocation[]>();
@ViewChild(MatTabGroup) tabGroup: MatTabGroup;
constructor(private dialog: MatDialog,
private advancedPaymentStrategy: AdvancedPaymentStrategy) { }
private advancedPaymentStrategy: AdvancedPaymentStrategy,
private translateService: TranslateService) { }
ngOnInit(): void {
this.sendPaymentAllocation();
this.advancedAllocations = this.advancedPaymentAllocations.concat(this.advancedCreditAllocations);
this.sendAllocations();
}
sendPaymentAllocation(): void {
const data = this.advancedPaymentStrategy.buildPaymentAllocations(this.advancedPaymentAllocations);
this.setPaymentAllocation.emit(data);
sendAllocations(): void {
this.setPaymentAllocation.emit(this.advancedPaymentStrategy.buildPaymentAllocations(this.advancedPaymentAllocations));
if (this.advancedCreditAllocations?.length > 0) {
this.setCreditAllocation.emit(this.advancedPaymentStrategy.buildCreditAllocations(this.advancedCreditAllocations));
}
}
paymentAllocationChanged(changed: boolean): void {
this.paymentAllocationChange.emit(changed);
this.sendPaymentAllocation();
this.sendAllocations();
}
addTransaction(): void {
@@ -44,10 +54,20 @@ export class LoanProductPaymentStrategyStepComponent implements OnInit {
this.advancedPaymentAllocations.forEach((item: AdvancedPaymentAllocation) => {
transactionTypesCurrent.push(item.transaction.code);
});
this.advancedCreditAllocations.forEach((item: AdvancedPaymentAllocation) => {
transactionTypesCurrent.push(item.transaction.code);
});
const transactionTypesOptions: PaymentAllocationTransactionType[] = [];
this.advancedPaymentAllocationTransactionTypes.forEach((option: PaymentAllocationTransactionType) => {
if (!this.advancedPaymentStrategy.isDefault(option) && transactionTypesCurrent.indexOf(option.code) < 0) {
option.credit = false;
transactionTypesOptions.push(option);
}
});
this.advancedCreditAllocationTransactionTypes.forEach((option: PaymentAllocationTransactionType) => {
if (transactionTypesCurrent.indexOf(option.code) < 0) {
option.credit = true;
transactionTypesOptions.push(option);
}
});
@@ -55,14 +75,17 @@ export class LoanProductPaymentStrategyStepComponent implements OnInit {
const formfields: FormfieldBase[] = [
new SelectBase({
controlName: 'code',
label: 'Transaction Type',
label: this.translateService.instant('labels.inputs.Transaction Type'),
options: { label: 'code', value: 'code', data: transactionTypesOptions },
order: 1
})
];
const data = {
title: 'Advanced Payment Allocation Transaction Type',
layout: { addButtonText: 'Add' },
title: this.translateService.instant('labels.inputs.Advanced Payment Allocation Transaction Type'),
layout: {
addButtonText: this.translateService.instant('labels.buttons.Add'),
cancelButtonText: this.translateService.instant('labels.buttons.Cancel')
},
formfields: formfields
};
const transactionTypeDialogRef = this.dialog.open(FormDialogComponent, { data });
@@ -71,14 +94,20 @@ export class LoanProductPaymentStrategyStepComponent implements OnInit {
const defaultPaymentAllocation: AdvancedPaymentAllocation = this.advancedPaymentAllocations[0];
transactionTypesOptions.forEach((transactionType: PaymentAllocationTransactionType) => {
if (transactionType.code === response.data.value.code) {
this.advancedPaymentAllocations.push(
this.advancedPaymentStrategy.buildAdvancedPaymentAllocation(true, transactionType,
this.paymentAllocationOrderDefault,
defaultPaymentAllocation.futureInstallmentAllocationRules)
);
if (!transactionType.credit) {
this.advancedPaymentAllocations.push(
this.advancedPaymentStrategy.buildAdvancedPaymentAllocation(true, transactionType, this.paymentAllocationOrderDefault,
defaultPaymentAllocation.futureInstallmentAllocationRules)
);
} else {
this.advancedCreditAllocations.push(
this.advancedPaymentStrategy.buildAdvancedCreditAllocation(transactionType, this.creditAllocationOrderDefault)
);
}
this.paymentAllocationChange.emit(true);
this.tabGroup.selectedIndex = (this.advancedPaymentAllocations.length - 1);
this.sendPaymentAllocation();
this.advancedAllocations = this.advancedPaymentAllocations.concat(this.advancedCreditAllocations);
this.tabGroup.selectedIndex = (this.advancedAllocations.length - 1);
this.sendAllocations();
}
});
}
@@ -86,14 +115,25 @@ export class LoanProductPaymentStrategyStepComponent implements OnInit {
}
transactionTypeRemoved(transaction: PaymentAllocationTransactionType): void {
this.advancedPaymentAllocations.forEach((item: AdvancedPaymentAllocation, index: number) => {
if (item.transaction.code === transaction.code) {
this.advancedPaymentAllocations.splice(index, 1);
this.paymentAllocationChange.emit(true);
this.tabGroup.selectedIndex = (index - 1);
this.sendPaymentAllocation();
}
});
if (!transaction.credit) {
this.advancedPaymentAllocations.forEach((item: AdvancedPaymentAllocation, index: number) => {
if (item.transaction.code === transaction.code) {
this.advancedPaymentAllocations.splice(index, 1);
this.paymentAllocationChange.emit(true);
this.tabGroup.selectedIndex = (index - 1);
this.sendAllocations();
}
});
} else {
this.advancedCreditAllocations.forEach((item: AdvancedPaymentAllocation, index: number) => {
if (item.transaction.code === transaction.code) {
this.advancedCreditAllocations.splice(index, 1);
this.paymentAllocationChange.emit(true);
this.tabGroup.selectedIndex = (index - 1);
this.sendAllocations();
}
});
}
}
}
@@ -4,6 +4,7 @@ export interface PaymentAllocationTransactionType {
id: number;
value: string;
code: string;
credit?: boolean;
}
export interface PaymentAllocationType {
@@ -30,15 +31,27 @@ export interface PaymentAllocation {
futureInstallmentAllocationRule: string;
}
export interface CreditAllocationOrder {
id?: number;
creditAllocationRule: string;
order: number;
}
export interface CreditAllocation {
transactionType: string;
creditAllocationOrder: CreditAllocationOrder[];
}
export class PaymentAllocationTransactionTypes {
public static DEFAULT_TRANSACTION: PaymentAllocationTransactionType = { id: 1, value: 'Default', code: 'DEFAULT' };
}
export class AdvancedPaymentAllocation {
transaction: PaymentAllocationTransactionType;
paymentAllocationOrder: PaymentAllocationOrder[];
futureInstallmentAllocationRule: FutureInstallmentAllocationRule;
futureInstallmentAllocationRules: FutureInstallmentAllocationRule[];
paymentAllocationOrder?: PaymentAllocationOrder[];
futureInstallmentAllocationRule?: FutureInstallmentAllocationRule;
futureInstallmentAllocationRules?: FutureInstallmentAllocationRule[];
creditAllocationOrder?: CreditAllocationOrder[];
}
export class AdvancePaymentAllocationData {
@@ -52,6 +65,23 @@ export class AdvancePaymentAllocationData {
})
export class AdvancedPaymentStrategy {
public buildAdvancedCreditAllocationList(loanProduct: any): AdvancedPaymentAllocation[] {
const advancedPaymentAllocation: AdvancedPaymentAllocation[] = [];
const advancedCreditAllocationTransactionTypes: PaymentAllocationTransactionType[] =
loanProduct.creditAllocationTransactionTypes;
const advancedPaymentAllocationTypes: CreditAllocationOrder[] = loanProduct.creditAllocationAllocationTypes;
if (loanProduct.creditAllocation) {
loanProduct.creditAllocation.forEach((item: CreditAllocation) => {
advancedPaymentAllocation.push({
transaction: this.getItemByCode(item.transactionType, advancedCreditAllocationTransactionTypes),
creditAllocationOrder: this.buildCurrentCreditAllocationOrder(item.creditAllocationOrder,
advancedPaymentAllocationTypes),
});
});
}
return advancedPaymentAllocation;
}
public buildAdvancedPaymentAllocationList(loanProduct: any): AdvancedPaymentAllocation[] {
const advancedPaymentAllocation: AdvancedPaymentAllocation[] = [];
const advancedPaymentAllocationTransactionTypes: PaymentAllocationTransactionType[] =
@@ -94,6 +124,14 @@ export class AdvancedPaymentStrategy {
};
}
public buildAdvancedCreditAllocation(transaction: PaymentAllocationTransactionType,
currentItems: PaymentAllocationOrder[]): AdvancedPaymentAllocation {
return {
transaction: transaction,
paymentAllocationOrder: this.buildPaymentAllocationTransactionOrder(true, currentItems, currentItems)
};
}
public buildPaymentAllocationTransactionOrder(forDefault: boolean, currentItems: PaymentAllocationOrder[], defaultItems: PaymentAllocationOrder[]): PaymentAllocationOrder[] {
const paymentAllocationOrder: PaymentAllocationOrder[] = [];
if (forDefault) {
@@ -123,6 +161,18 @@ export class AdvancedPaymentStrategy {
return paymentAllocations;
}
public buildCreditAllocations(advancedCreditAllocations: AdvancedPaymentAllocation[]): CreditAllocation[] {
const creditAllocations: CreditAllocation[] = [];
advancedCreditAllocations.forEach((creditAllocation: AdvancedPaymentAllocation) => {
creditAllocations.push({
transactionType: creditAllocation.transaction.code,
creditAllocationOrder: this.buildCreditAllocationOrder(creditAllocation.creditAllocationOrder)
});
});
return creditAllocations;
}
public buildPaymentAllocationOrder(paymentAllocationOrder: PaymentAllocationOrder[]): PaymentAllocationOrder[] {
const paymentAllocations: any[] = [];
paymentAllocationOrder.forEach((item: any, index: number) => {
@@ -135,6 +185,18 @@ export class AdvancedPaymentStrategy {
return paymentAllocations;
}
public buildCreditAllocationOrder(creditAllocationOrder: CreditAllocationOrder[]): CreditAllocationOrder[] {
const creditAllocations: CreditAllocationOrder[] = [];
creditAllocationOrder.forEach((item: any, index: number) => {
creditAllocations.push({
order: (index + 1),
creditAllocationRule: item.code
});
});
return creditAllocations;
}
public buildCurrentPaymentAllocationOrder(currentItems: any[], defaultItems: PaymentAllocationOrder[]):
PaymentAllocationOrder[] {
const paymentAllocationOrder: PaymentAllocationOrder[] = [];
@@ -144,6 +206,15 @@ export class AdvancedPaymentStrategy {
return paymentAllocationOrder;
}
public buildCurrentCreditAllocationOrder(currentItems: any[], defaultItems: CreditAllocationOrder[]):
CreditAllocationOrder[] {
const creditAllocationOrder: CreditAllocationOrder[] = [];
currentItems.forEach((item: any) => {
creditAllocationOrder.push(this.getItemByCode(item.creditAllocationRule, defaultItems));
});
return creditAllocationOrder;
}
public getItemByCode(code: string,
options: any[]): any {
let transaction: any;
@@ -5,6 +5,7 @@
[loanProductsTemplate]="loanProductsTemplate"
[useDueForRepaymentsConfigurations]="loanProduct.useDueForRepaymentsConfigurations"
[paymentAllocations]="loanProduct.paymentAllocation"
[creditAllocations]="loanProduct.creditAllocation"
>
</mifosx-loan-product-summary>
@@ -1,6 +1,6 @@
import { AccountingMapping, ChargeToIncomeAccountMapping, Currency, PaymentChannelToFundSourceMapping } from 'app/shared/models/general.model';
import { OptionData } from 'app/shared/models/option-data.model';
import { PaymentAllocation } from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
import { CreditAllocation, PaymentAllocation } from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
export interface LoanProduct {
id: number;
@@ -41,6 +41,7 @@ export interface LoanProduct {
transactionProcessingStrategyCode: string;
transactionProcessingStrategyName: string;
paymentAllocation?: PaymentAllocation[];
creditAllocation?: CreditAllocation[];
daysInMonthType: OptionData;
daysInYearType: OptionData;
isInterestRecalculationEnabled: boolean;
@@ -69,6 +70,8 @@ export interface LoanProduct {
advancedPaymentAllocationTransactionTypes: OptionData[];
advancedPaymentAllocationFutureInstallmentAllocationRules: OptionData[];
advancedPaymentAllocationTypes: OptionData[];
creditAllocationTransactionTypes: OptionData[];
creditAllocationAllocationTypes: OptionData[];
multiDisburseLoan: boolean;
maxTrancheCount: number;
disallowExpectedDisbursements: boolean;
@@ -9,5 +9,6 @@
[loanProduct]="loanProduct"
[useDueForRepaymentsConfigurations]="useDueForRepaymentsConfigurations"
[paymentAllocations]="loanProduct.paymentAllocation"
[creditAllocations]="loanProduct.creditAllocation"
>
</mifosx-loan-product-summary>
@@ -1,8 +1,8 @@
<mat-expansion-panel>
<mat-expansion-panel *ngIf="paymentAllocation">
<mat-expansion-panel-header>
<mat-panel-title>
<div fxFlexFill>
<span fxFlex="40%">Transaction Type:</span>
<span fxFlex="40%">{{ 'labels.inputs.Transaction Type' | translate }}:</span>
<span fxFlex="60%">{{ transactionTypeValue(paymentAllocation.transactionType) }}</span>
</div>
</mat-panel-title>
@@ -11,18 +11,18 @@
<div fxFlexFill>
<div fxFlexFill>
<span fxFlex="40%">Future Installment Allocation:</span>
<span fxFlex="40%">{{ 'labels.inputs.Future Installment Allocation Rule' | translate }}:</span>
<span fxFlex="60%">{{ futureInstallmentRuleValue(paymentAllocation.futureInstallmentAllocationRule) }}</span>
</div>
<div fxFlexFill>
<span fxFlex="40%">Payment Allocation Order</span>
<span fxFlex="40%">{{ 'labels.inputs.Payment Allocation Order' | translate }}</span>
<span fxFlex="60%">
<table>
<thead>
<tr>
<th>Order</th>
<th>Payment Allocation Rule</th>
<th>{{ 'labels.inputs.Order' | translate }}</th>
<th>{{ 'labels.inputs.Payment Allocation Rule' | translate }}</th>
</tr>
</thead>
<tbody>
@@ -36,3 +36,36 @@
</div>
</div>
</mat-expansion-panel>
<mat-expansion-panel *ngIf="creditAllocation">
<mat-expansion-panel-header>
<mat-panel-title>
<div fxFlexFill>
<span fxFlex="40%">{{ 'labels.inputs.Transaction Type' | translate }}:</span>
<span fxFlex="60%">{{ transactionTypeValue(creditAllocation.transactionType) }}</span>
</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div fxFlexFill>
<div fxFlexFill>
<span fxFlex="40%">{{ 'labels.inputs.Credit Allocation Order' | translate }}</span>
<span fxFlex="60%">
<table>
<thead>
<tr>
<th>{{ 'labels.inputs.Order' | translate }}</th>
<th>{{ 'labels.inputs.Credit Allocation Rule' | translate }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let creditAllocation of creditAllocation.creditAllocationOrder; let idx = index;">
<td>{{ (idx + 1) }}</td>
<td>{{ allocationRuleValue(creditAllocation.creditAllocationRule) }}</td>
</tr>
</tbody>
</table>
</span>
</div>
</div>
</mat-expansion-panel>
@@ -1,5 +1,5 @@
import { Component, Input, OnInit } from '@angular/core';
import { AdvancePaymentAllocationData, PaymentAllocation } from 'app/products/loan-products/loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
import { AdvancePaymentAllocationData, CreditAllocation, PaymentAllocation } from 'app/products/loan-products/loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
@Component({
selector: 'mifosx-view-advance-paymeny-allocation',
@@ -8,7 +8,8 @@ import { AdvancePaymentAllocationData, PaymentAllocation } from 'app/products/lo
})
export class ViewAdvancePaymenyAllocationComponent implements OnInit {
@Input() paymentAllocation: PaymentAllocation;
@Input() paymentAllocation: PaymentAllocation | null;
@Input() creditAllocation: CreditAllocation | null;
@Input() advancePaymentAllocationData: AdvancePaymentAllocationData;
constructor() { }