Loan product using externalId input field
This commit is contained in:
committed by
Jose Alberto Hernandez
parent
1aed445156
commit
497fc3b9d9
+7
-2
@@ -14,6 +14,11 @@
|
|||||||
<span fxFlex="53%">{{ loanProduct.shortName }}</span>
|
<span fxFlex="53%">{{ loanProduct.shortName }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div fxFlexFill *ngIf="loanProduct.externalId">
|
||||||
|
<span fxFlex="47%">{{ 'labels.inputs.External Id' | translate}}:</span>
|
||||||
|
<span fxFlex="53%">{{ loanProduct.externalId }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div fxFlexFill *ngIf="loanProduct.fundId">
|
<div fxFlexFill *ngIf="loanProduct.fundId">
|
||||||
<span fxFlex="47%">{{ 'labels.inputs.Fund' | translate}}:</span>
|
<span fxFlex="47%">{{ 'labels.inputs.Fund' | translate}}:</span>
|
||||||
<span fxFlex="53%">{{ loanProduct.fundName }}</span>
|
<span fxFlex="53%">{{ loanProduct.fundName }}</span>
|
||||||
@@ -928,14 +933,14 @@
|
|||||||
<ng-container matColumnDef="chargeOffReasonCodeValueId">
|
<ng-container matColumnDef="chargeOffReasonCodeValueId">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{'labels.inputs.Charge-off reason' | translate}} </th>
|
<th mat-header-cell *matHeaderCellDef> {{'labels.inputs.Charge-off reason' | translate}} </th>
|
||||||
<td mat-cell *matCellDef="let chargeOffReasonsToExpenseMapping">
|
<td mat-cell *matCellDef="let chargeOffReasonsToExpenseMapping">
|
||||||
{{ chargeOffReasonsToExpenseMapping.chargeOffReason.name }}
|
{{ chargeOffReasonsToExpenseMapping.chargeOffReasonsCodeValue.name }}
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="expenseGLAccountId">
|
<ng-container matColumnDef="expenseGLAccountId">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{'labels.inputs.Expense Account' | translate}} </th>
|
<th mat-header-cell *matHeaderCellDef> {{'labels.inputs.Expense Account' | translate}} </th>
|
||||||
<td mat-cell *matCellDef="let chargeOffReasonsToExpenseMapping">
|
<td mat-cell *matCellDef="let chargeOffReasonsToExpenseMapping">
|
||||||
{{ chargeOffReasonsToExpenseMapping.expenseGLAccount.name }}
|
({{ chargeOffReasonsToExpenseMapping.chargeOffExpenseAccount.glCode }}) {{ chargeOffReasonsToExpenseMapping.chargeOffExpenseAccount.name }}
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
|||||||
+7
-12
@@ -1,6 +1,6 @@
|
|||||||
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
||||||
import { DelinquencyBucket, LoanProduct } from '../../models/loan-product.model';
|
import { DelinquencyBucket, LoanProduct } from '../../models/loan-product.model';
|
||||||
import {AccountingMapping, Charge, ChargeOffReasonsToExpenseMapping, ChargeToIncomeAccountMapping, GLAccount, PaymentChannelToFundSourceMapping, PaymentType, PaymentTypeOption} from '../../../../shared/models/general.model';
|
import {AccountingMapping, Charge, ChargeOffReasonsToGLAccountMapping, ChargeToIncomeAccountMapping, GLAccount, PaymentChannelToFundSourceMapping, PaymentType, PaymentTypeOption} from '../../../../shared/models/general.model';
|
||||||
import { AdvancePaymentAllocationData, CreditAllocation, 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 { LoanProducts } from '../../loan-products';
|
||||||
import { CodeName, OptionData, StringEnumOptionData } from '../../../../shared/models/option-data.model';
|
import { CodeName, OptionData, StringEnumOptionData } from '../../../../shared/models/option-data.model';
|
||||||
@@ -36,7 +36,7 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|
|||||||
paymentChannelToFundSourceMappings: PaymentChannelToFundSourceMapping[] = [];
|
paymentChannelToFundSourceMappings: PaymentChannelToFundSourceMapping[] = [];
|
||||||
feeToIncomeAccountMappings: ChargeToIncomeAccountMapping[] = [];
|
feeToIncomeAccountMappings: ChargeToIncomeAccountMapping[] = [];
|
||||||
penaltyToIncomeAccountMappings: ChargeToIncomeAccountMapping[] = [];
|
penaltyToIncomeAccountMappings: ChargeToIncomeAccountMapping[] = [];
|
||||||
chargeOffReasonsToExpenseMappings: ChargeOffReasonsToExpenseMapping[] = [];
|
chargeOffReasonsToExpenseMappings: ChargeOffReasonsToGLAccountMapping[] = [];
|
||||||
|
|
||||||
constructor(private accounting: Accounting) { }
|
constructor(private accounting: Accounting) { }
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|
|||||||
this.paymentChannelToFundSourceMappings = this.loanProduct.paymentChannelToFundSourceMappings || [];
|
this.paymentChannelToFundSourceMappings = this.loanProduct.paymentChannelToFundSourceMappings || [];
|
||||||
this.feeToIncomeAccountMappings = this.loanProduct.feeToIncomeAccountMappings || [];
|
this.feeToIncomeAccountMappings = this.loanProduct.feeToIncomeAccountMappings || [];
|
||||||
this.penaltyToIncomeAccountMappings = this.loanProduct.penaltyToIncomeAccountMappings || [];
|
this.penaltyToIncomeAccountMappings = this.loanProduct.penaltyToIncomeAccountMappings || [];
|
||||||
this.chargeOffReasonsToExpenseMappings = this.loanProduct.chargeOffReasonsToExpenseMappings || [];
|
this.chargeOffReasonsToExpenseMappings = this.loanProduct.chargeOffReasonToGLAccountMappings || [];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.accountingMappings = {};
|
this.accountingMappings = {};
|
||||||
@@ -133,14 +133,9 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.chargeOffReasonsToExpenseMappings = [];
|
this.chargeOffReasonsToExpenseMappings = [];
|
||||||
if (this.loanProduct.chargeOffReasonsToExpenseMappings?.length > 0) {
|
if (this.loanProduct.chargeOffReasonToGLAccountMappings?.length > 0) {
|
||||||
this.loanProduct.chargeOffReasonsToExpenseMappings.forEach((m: ChargeOffReasonsToExpenseMapping) => {
|
this.loanProduct.chargeOffReasonToGLAccountMappings.forEach((m: ChargeOffReasonsToGLAccountMapping) => {
|
||||||
this.chargeOffReasonsToExpenseMappings.push({
|
this.chargeOffReasonsToExpenseMappings.push(m);
|
||||||
chargeOffReasonCodeValueId: m.chargeOffReasonCodeValueId,
|
|
||||||
chargeOffReason: this.optionDataLookUp(m.chargeOffReasonCodeValueId, this.loanProductsTemplate.chargeOffReasonOptions),
|
|
||||||
expenseGLAccountId: m.expenseGLAccountId,
|
|
||||||
expenseGLAccount: this.glAccountLookUp(m.expenseGLAccountId, expenseAccountData)
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,7 +338,7 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|
|||||||
return (this.loanProduct.paymentChannelToFundSourceMappings?.length > 0
|
return (this.loanProduct.paymentChannelToFundSourceMappings?.length > 0
|
||||||
|| this.loanProduct.feeToIncomeAccountMappings?.length > 0
|
|| this.loanProduct.feeToIncomeAccountMappings?.length > 0
|
||||||
|| this.loanProduct.penaltyToIncomeAccountMappings?.length > 0
|
|| this.loanProduct.penaltyToIncomeAccountMappings?.length > 0
|
||||||
|| this.loanProduct.chargeOffReasonsToExpenseMappings?.length > 0);
|
|| this.loanProduct.chargeOffReasonToGLAccountMappings?.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccountingRuleName(value: string): string {
|
getAccountingRuleName(value: string): string {
|
||||||
|
|||||||
-2
@@ -342,8 +342,6 @@
|
|||||||
{{'labels.buttons.Add' | translate}}
|
{{'labels.buttons.Add' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="chargeOffReasonsToExpenseMappings.value" *ngIf="chargeOffReasonsToExpenseMappings.value.length !== 0">
|
<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="chargeOffReasonsToExpenseMappings.value" *ngIf="chargeOffReasonsToExpenseMappings.value.length !== 0">
|
||||||
|
|
||||||
<ng-container matColumnDef="chargeOffReasonCodeValueId">
|
<ng-container matColumnDef="chargeOffReasonCodeValueId">
|
||||||
|
|||||||
+24
-22
@@ -8,7 +8,7 @@ import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.componen
|
|||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||||
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
|
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
|
||||||
import {ChargeOffReasonsToExpenseMapping} from '../../../../shared/models/general.model';
|
import { ChargeOffReasonsToGLAccountMapping } from 'app/shared/models/general.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'mifosx-loan-product-accounting-step',
|
selector: 'mifosx-loan-product-accounting-step',
|
||||||
@@ -107,8 +107,8 @@ export class LoanProductAccountingStepComponent implements OnInit {
|
|||||||
this.formBuilder.array((this.loanProductsTemplate.penaltyToIncomeAccountMappings || []).map((penaltyIncome: any) =>
|
this.formBuilder.array((this.loanProductsTemplate.penaltyToIncomeAccountMappings || []).map((penaltyIncome: any) =>
|
||||||
({ chargeId: penaltyIncome.charge.id, incomeAccountId: penaltyIncome.incomeAccount.id }))));
|
({ chargeId: penaltyIncome.charge.id, incomeAccountId: penaltyIncome.incomeAccount.id }))));
|
||||||
this.loanProductAccountingForm.setControl('chargeOffReasonsToExpenseMappings',
|
this.loanProductAccountingForm.setControl('chargeOffReasonsToExpenseMappings',
|
||||||
this.formBuilder.array((this.loanProductsTemplate.chargeOffReasonsToExpenseMappings || []).map((m: ChargeOffReasonsToExpenseMapping) =>
|
this.formBuilder.array((this.loanProductsTemplate.chargeOffReasonsToExpenseMappings || []).map((m: ChargeOffReasonsToGLAccountMapping) =>
|
||||||
({ chargeOffReasonCodeValueId: m.chargeOffReasonCodeValueId, expenseGLAccountId: m.expenseGLAccountId }))));
|
({ chargeOffReasonCodeValueId: m.chargeOffReasonsCodeValue.id, expenseGLAccountId: m.chargeOffExpenseAccount.id }))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,25 +324,27 @@ export class LoanProductAccountingStepComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getChargeOffReasonExpenseFormfields(values?: any) {
|
getChargeOffReasonExpenseFormfields(values?: any) {
|
||||||
const formfields: FormfieldBase[] = [
|
if (values != null) {
|
||||||
new SelectBase({
|
const formfields: FormfieldBase[] = [
|
||||||
controlName: 'chargeOffReasonCodeValueId',
|
new SelectBase({
|
||||||
label: 'Charge-off reason',
|
controlName: 'chargeOffReasonCodeValueId',
|
||||||
value: values ? values.chargeOffReasonCodeValueId : this.chargeOffReasonOptions[0].id,
|
label: 'Charge-off reason',
|
||||||
options: { label: 'name', value: 'id', data: this.chargeOffReasonOptions },
|
value: values ? values.chargeOffReasonCodeValueId : this.chargeOffReasonOptions[0].id,
|
||||||
required: true,
|
options: { label: 'name', value: 'id', data: this.chargeOffReasonOptions },
|
||||||
order: 1
|
required: true,
|
||||||
}),
|
order: 1
|
||||||
new SelectBase({
|
}),
|
||||||
controlName: 'expenseGLAccountId',
|
new SelectBase({
|
||||||
label: 'Expense Account',
|
controlName: 'expenseGLAccountId',
|
||||||
value: values ? values.expenseGLAccountId : this.expenseAccountData[0].id,
|
label: 'Expense Account',
|
||||||
options: { label: 'name', value: 'id', data: this.expenseAccountData },
|
value: values ? values.expenseGLAccountId : this.expenseAccountData[0].id,
|
||||||
required: true,
|
options: { label: 'name', value: 'id', data: this.expenseAccountData },
|
||||||
order: 2
|
required: true,
|
||||||
})
|
order: 2
|
||||||
];
|
})
|
||||||
return formfields;
|
];
|
||||||
|
return formfields;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get isAccountingAccrualBased() {
|
get isAccountingAccrualBased() {
|
||||||
|
|||||||
+7
-2
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column" fxLayoutAlign.gt-sm="start center">
|
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column" fxLayoutAlign.gt-sm="start center">
|
||||||
|
|
||||||
<mat-form-field fxFlex="72%">
|
<mat-form-field fxFlex="98%">
|
||||||
<mat-label>{{'labels.inputs.Product Name' | translate}}</mat-label>
|
<mat-label>{{'labels.inputs.Product Name' | translate}}</mat-label>
|
||||||
<input matInput formControlName="name" matTooltip="{{ 'tooltips.Product name is a unique identifier' | translate}}" required>
|
<input matInput formControlName="name" matTooltip="{{ 'tooltips.Product name is a unique identifier' | translate}}" required>
|
||||||
<mat-error>
|
<mat-error>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field fxFlex="24%">
|
<mat-form-field fxFlex="48%">
|
||||||
<mat-label>{{'labels.inputs.Short Name' | translate}}</mat-label>
|
<mat-label>{{'labels.inputs.Short Name' | translate}}</mat-label>
|
||||||
<input matInput formControlName="shortName" maxlength="4" matTooltip="{{ 'tooltips.Short name is a unique identifier' | translate}}" required>
|
<input matInput formControlName="shortName" maxlength="4" matTooltip="{{ 'tooltips.Short name is a unique identifier' | translate}}" required>
|
||||||
<mat-error>
|
<mat-error>
|
||||||
@@ -18,6 +18,11 @@
|
|||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field fxFlex="48%">
|
||||||
|
<mat-label>{{'labels.inputs.External Id' | translate}}</mat-label>
|
||||||
|
<input matInput formControlName="externalId" matTooltip="{{ 'tooltips.External Id is a unique identifier' | translate}}">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field fxFlex="48%">
|
<mat-form-field fxFlex="48%">
|
||||||
<mat-label>{{'labels.inputs.Fund' | translate}}</mat-label>
|
<mat-label>{{'labels.inputs.Fund' | translate}}</mat-label>
|
||||||
<mat-select matTooltip="{{ 'tooltips.Loan products may be assigned' | translate}}" formControlName="fundId">
|
<mat-select matTooltip="{{ 'tooltips.Loan products may be assigned' | translate}}" formControlName="fundId">
|
||||||
|
|||||||
+2
@@ -42,6 +42,7 @@ export class LoanProductDetailsStepComponent implements OnInit {
|
|||||||
'name': this.loanProductsTemplate.name,
|
'name': this.loanProductsTemplate.name,
|
||||||
'shortName': this.loanProductsTemplate.shortName,
|
'shortName': this.loanProductsTemplate.shortName,
|
||||||
'description': this.loanProductsTemplate.description,
|
'description': this.loanProductsTemplate.description,
|
||||||
|
'externalId': this.loanProductsTemplate.externalId,
|
||||||
'fundId': this.loanProductsTemplate.fundId,
|
'fundId': this.loanProductsTemplate.fundId,
|
||||||
'startDate': this.loanProductsTemplate.startDate && new Date(this.loanProductsTemplate.startDate),
|
'startDate': this.loanProductsTemplate.startDate && new Date(this.loanProductsTemplate.startDate),
|
||||||
'closeDate': this.loanProductsTemplate.closeDate && new Date(this.loanProductsTemplate.closeDate),
|
'closeDate': this.loanProductsTemplate.closeDate && new Date(this.loanProductsTemplate.closeDate),
|
||||||
@@ -54,6 +55,7 @@ export class LoanProductDetailsStepComponent implements OnInit {
|
|||||||
'name': ['', Validators.required],
|
'name': ['', Validators.required],
|
||||||
'shortName': ['', Validators.required],
|
'shortName': ['', Validators.required],
|
||||||
'description': [''],
|
'description': [''],
|
||||||
|
'externalId': [''],
|
||||||
'fundId': [''],
|
'fundId': [''],
|
||||||
'startDate': [''],
|
'startDate': [''],
|
||||||
'closeDate': [''],
|
'closeDate': [''],
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {AccountingMapping, ChargeOffReasonsToExpenseMapping, ChargeToIncomeAccountMapping, Currency, PaymentChannelToFundSourceMapping} from 'app/shared/models/general.model';
|
import {AccountingMapping, ChargeOffReasonsToGLAccountMapping, ChargeToIncomeAccountMapping, Currency, PaymentChannelToFundSourceMapping} from 'app/shared/models/general.model';
|
||||||
import { OptionData, StringEnumOptionData } from 'app/shared/models/option-data.model';
|
import { OptionData, StringEnumOptionData } from 'app/shared/models/option-data.model';
|
||||||
import { CreditAllocation, 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';
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ export interface LoanProduct {
|
|||||||
paymentChannelToFundSourceMappings?: PaymentChannelToFundSourceMapping[];
|
paymentChannelToFundSourceMappings?: PaymentChannelToFundSourceMapping[];
|
||||||
feeToIncomeAccountMappings?: ChargeToIncomeAccountMapping[];
|
feeToIncomeAccountMappings?: ChargeToIncomeAccountMapping[];
|
||||||
penaltyToIncomeAccountMappings?: ChargeToIncomeAccountMapping[];
|
penaltyToIncomeAccountMappings?: ChargeToIncomeAccountMapping[];
|
||||||
chargeOffReasonsToExpenseMappings?: ChargeOffReasonsToExpenseMapping[];
|
chargeOffReasonToGLAccountMappings?: ChargeOffReasonsToGLAccountMapping[];
|
||||||
enableAccrualActivityPosting?: boolean;
|
enableAccrualActivityPosting?: boolean;
|
||||||
supportedInterestRefundTypes?: StringEnumOptionData[];
|
supportedInterestRefundTypes?: StringEnumOptionData[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,9 +74,11 @@ export class FooterComponent implements OnInit, OnDestroy {
|
|||||||
this.getConfigurations();
|
this.getConfigurations();
|
||||||
this.server = this.settingsService.server;
|
this.server = this.settingsService.server;
|
||||||
this.versionService.getBackendInfo().subscribe((data: any) => {
|
this.versionService.getBackendInfo().subscribe((data: any) => {
|
||||||
const buildVersion: string = data.git.build.version.split('-');
|
if (data.git && data.git.build && data.git.build.version) {
|
||||||
this.versions.fineract.version = buildVersion[0];
|
const buildVersion: string = data.git.build.version.split('-');
|
||||||
this.versions.fineract.hash = buildVersion[1];
|
this.versions.fineract.version = buildVersion[0];
|
||||||
|
this.versions.fineract.hash = buildVersion[1];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,11 +39,20 @@ export interface PaymentChannelToFundSourceMapping {
|
|||||||
fundSourceAccount: AccountingMapping;
|
fundSourceAccount: AccountingMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChargeOffReasonsToExpenseMapping {
|
export interface ChargeOffReasonsToGLAccountMapping {
|
||||||
chargeOffReasonCodeValueId: number;
|
chargeOffReasonCodeValueId?: number;
|
||||||
expenseGLAccountId: number;
|
chargeOffReason? : OptionData;
|
||||||
chargeOffReason?: OptionData;
|
chargeOffReasonsCodeValue?: ChargeOffReasonsCodeValue;
|
||||||
expenseGLAccount?: AccountingMapping;
|
chargeOffExpenseAccount?: AccountingMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChargeOffReasonsCodeValue {
|
||||||
|
active: boolean;
|
||||||
|
description: string;
|
||||||
|
id: number;
|
||||||
|
mandatory: boolean;
|
||||||
|
name: string;
|
||||||
|
position?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PaymentType {
|
export interface PaymentType {
|
||||||
|
|||||||
Reference in New Issue
Block a user