Merge pull request #2665 from alberto-art3ch/WEB-316/advance-accounting-rule-can-be-set-for-each-classification-type
WEB-316: Advance Accounting rule can be set for each classification type
This commit is contained in:
+68
-2
@@ -722,7 +722,7 @@
|
||||
<span class="flex-60">{{ loanProduct.multiDisburseLoan | yesNo }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-fill layout-row-wrap responsive-column" *ngIf="loanProduct.multiDisburseLoan">
|
||||
<div class="flex-100 layout-row-wrap responsive-column" *ngIf="loanProduct.multiDisburseLoan">
|
||||
<span class="flex-40">{{ 'labels.inputs.Maximum Tranche count' | translate }}:</span>
|
||||
<span class="flex-60">{{ loanProduct.maxTrancheCount }}</span>
|
||||
<div class="flex-fill layout-row" *ngIf="loanProduct.outstandingLoanBalance">
|
||||
@@ -737,7 +737,7 @@
|
||||
|
||||
<h3 class="mat-h3 flex-fill">{{ 'labels.heading.Event Settings' | translate }}</h3>
|
||||
|
||||
<div class="flex-fill">
|
||||
<div class="flex-100">
|
||||
<span class="flex-40"
|
||||
>{{
|
||||
'labels.inputs.Use the Global Configurations values to the Repayment Event (notifications)' | translate
|
||||
@@ -1252,6 +1252,72 @@
|
||||
<tr mat-row *matRowDef="let row; columns: chargeOffReasonExpenseDisplayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngIf="buydownFeeClassificationToIncomeAccountMappings?.length > 0"
|
||||
class="flex-100 layout-row-wrap responsive-column"
|
||||
>
|
||||
<h4 class="mat-h4 flex-100">
|
||||
{{ 'labels.heading.Buydown Fee classifications to Income accounts' | translate }}
|
||||
</h4>
|
||||
|
||||
<table
|
||||
class="mat-elevation-z1 flex-100"
|
||||
mat-table
|
||||
[dataSource]="buydownFeeClassificationToIncomeAccountMappings"
|
||||
>
|
||||
<ng-container matColumnDef="chargeOffReasonCodeValueId">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Classification' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let classificationToIncomeAccountMapping">
|
||||
{{ classificationToIncomeAccountMapping.classificationCodeValue.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="expenseAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Income Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let classificationToIncomeAccountMapping">
|
||||
({{ classificationToIncomeAccountMapping.incomeAccount.glCode }})
|
||||
{{ classificationToIncomeAccountMapping.incomeAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chargeOffReasonExpenseDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargeOffReasonExpenseDisplayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngIf="capitalizedIncomeClassificationToIncomeAccountMappings?.length > 0"
|
||||
class="flex-100 layout-row-wrap responsive-column"
|
||||
>
|
||||
<h4 class="mat-h4 flex-100">
|
||||
{{ 'labels.heading.Capitalized Income classifications to Income accounts' | translate }}
|
||||
</h4>
|
||||
|
||||
<table
|
||||
class="mat-elevation-z1 flex-100"
|
||||
mat-table
|
||||
[dataSource]="capitalizedIncomeClassificationToIncomeAccountMappings"
|
||||
>
|
||||
<ng-container matColumnDef="chargeOffReasonCodeValueId">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Classification' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let capitalizedIncomeClassificationToIncomeAccountMapping">
|
||||
{{ capitalizedIncomeClassificationToIncomeAccountMapping.classificationCodeValue.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="expenseAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Income Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let capitalizedIncomeClassificationToIncomeAccountMapping">
|
||||
({{ capitalizedIncomeClassificationToIncomeAccountMapping.incomeAccount.glCode }})
|
||||
{{ capitalizedIncomeClassificationToIncomeAccountMapping.incomeAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chargeOffReasonExpenseDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargeOffReasonExpenseDisplayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+48
-5
@@ -1,11 +1,12 @@
|
||||
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
||||
import { DelinquencyBucket, LoanProduct } from '../../models/loan-product.model';
|
||||
import { AccountingMappingDTO, DelinquencyBucket, LoanProduct } from '../../models/loan-product.model';
|
||||
import {
|
||||
AccountingMapping,
|
||||
Charge,
|
||||
ChargeOffReasonCodeValue,
|
||||
CodeValue,
|
||||
ChargeOffReasonToExpenseAccountMapping,
|
||||
ChargeToIncomeAccountMapping,
|
||||
ClassificationToIncomeAccountMapping,
|
||||
GLAccount,
|
||||
PaymentChannelToFundSourceMapping,
|
||||
PaymentType,
|
||||
@@ -114,6 +115,8 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|
||||
feeToIncomeAccountMappings: ChargeToIncomeAccountMapping[] = [];
|
||||
penaltyToIncomeAccountMappings: ChargeToIncomeAccountMapping[] = [];
|
||||
chargeOffReasonToExpenseAccountMappings: ChargeOffReasonToExpenseAccountMapping[] = [];
|
||||
buydownFeeClassificationToIncomeAccountMappings: ClassificationToIncomeAccountMapping[] = [];
|
||||
capitalizedIncomeClassificationToIncomeAccountMappings: ClassificationToIncomeAccountMapping[] = [];
|
||||
|
||||
constructor(private accounting: Accounting) {}
|
||||
|
||||
@@ -145,6 +148,10 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|
||||
this.feeToIncomeAccountMappings = this.loanProduct.feeToIncomeAccountMappings || [];
|
||||
this.penaltyToIncomeAccountMappings = this.loanProduct.penaltyToIncomeAccountMappings || [];
|
||||
this.chargeOffReasonToExpenseAccountMappings = this.loanProduct.chargeOffReasonToExpenseAccountMappings || [];
|
||||
this.buydownFeeClassificationToIncomeAccountMappings =
|
||||
this.loanProduct.buydownFeeClassificationToIncomeAccountMappings || [];
|
||||
this.capitalizedIncomeClassificationToIncomeAccountMappings =
|
||||
this.loanProduct.capitalizedIncomeClassificationToIncomeAccountMappings || [];
|
||||
} else {
|
||||
this.accountingMappings = {};
|
||||
|
||||
@@ -159,6 +166,9 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|
||||
const assetAndLiabilityAccountData =
|
||||
this.loanProductsTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions || [];
|
||||
const chargeOffReasonOptions: any = this.loanProductsTemplate.chargeOffReasonOptions || [];
|
||||
const buydownFeeClassificationOptions: any = this.loanProductsTemplate.buydownFeeClassificationOptions || [];
|
||||
const capitalizedIncomeClassificationOptions: any =
|
||||
this.loanProductsTemplate.capitalizedIncomeClassificationOptions || [];
|
||||
|
||||
this.accountingMappings = {
|
||||
fundSourceAccount: this.glAccountLookUp(this.loanProduct.fundSourceAccountId, assetAndLiabilityAccountData),
|
||||
@@ -262,11 +272,42 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|
||||
chargeOffReasonCodeValue: {
|
||||
id: optionData.id,
|
||||
name: optionData.value
|
||||
} as ChargeOffReasonCodeValue
|
||||
} as CodeValue
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
this.buydownFeeClassificationToIncomeAccountMappings = [];
|
||||
if (this.loanProduct.buydownFeeClassificationToIncomeAccountMappings?.length > 0) {
|
||||
this.loanProduct.buydownFeeClassificationToIncomeAccountMappings.forEach((m: any) => {
|
||||
let optionData = this.optionDataLookUp(m.classificationCodeValueId, buydownFeeClassificationOptions);
|
||||
if (optionData !== null) {
|
||||
this.buydownFeeClassificationToIncomeAccountMappings.push({
|
||||
incomeAccount: this.glAccountLookUp(m.incomeAccountId, incomeAccountData),
|
||||
classificationCodeValue: {
|
||||
id: optionData.id,
|
||||
name: optionData.value
|
||||
} as CodeValue
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
this.capitalizedIncomeClassificationToIncomeAccountMappings = [];
|
||||
if (this.loanProduct.capitalizedIncomeClassificationToIncomeAccountMappings?.length > 0) {
|
||||
this.loanProduct.capitalizedIncomeClassificationToIncomeAccountMappings.forEach((m: any) => {
|
||||
let optionData = this.optionDataLookUp(m.classificationCodeValueId, capitalizedIncomeClassificationOptions);
|
||||
if (optionData !== null) {
|
||||
this.capitalizedIncomeClassificationToIncomeAccountMappings.push({
|
||||
incomeAccount: this.glAccountLookUp(m.incomeAccountId, incomeAccountData),
|
||||
classificationCodeValue: {
|
||||
id: optionData.id,
|
||||
name: optionData.value
|
||||
} as CodeValue
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.loanProduct.isInterestRecalculationEnabled) {
|
||||
@@ -453,7 +494,7 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
optionDataLookUp(itemId: any, optionsData: any[]): OptionData {
|
||||
let optionData: OptionData | null;
|
||||
let optionData: OptionData | null = null;
|
||||
optionsData.some((o: any) => {
|
||||
if (o.id === itemId) {
|
||||
optionData = {
|
||||
@@ -576,7 +617,9 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|
||||
this.loanProduct.paymentChannelToFundSourceMappings?.length > 0 ||
|
||||
this.loanProduct.feeToIncomeAccountMappings?.length > 0 ||
|
||||
this.loanProduct.penaltyToIncomeAccountMappings?.length > 0 ||
|
||||
this.loanProduct.chargeOffReasonToExpenseAccountMappings?.length > 0
|
||||
this.loanProduct.chargeOffReasonToExpenseAccountMappings?.length > 0 ||
|
||||
this.loanProduct.buydownFeeClassificationToIncomeAccountMappings?.length > 0 ||
|
||||
this.loanProduct.capitalizedIncomeClassificationToIncomeAccountMappings?.length > 0
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<div class="flex-100 layout-row-wrap responsive-column">
|
||||
<h4 class="mat-h4 flex-33">
|
||||
{{ textHeading | translateKey: 'heading' }}
|
||||
</h4>
|
||||
|
||||
<div class="flex-63">
|
||||
<button type="button" mat-raised-button color="primary" [disabled]="!allowAddAccountingMapping" (click)="add()">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
{{ 'labels.buttons.Add' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<table class="flex-98 mat-elevation-z1" mat-table [dataSource]="tableData" *ngIf="tableData.length !== 0">
|
||||
<ng-container matColumnDef="codeValueId">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.' + textField | translate }}</th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
{{ item.value.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="glAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.GL Account Name or Code' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let item">({{ item.glAccount.glCode }}) {{ item.glAccount.name }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let chargeOffReasonExpense; let i = index">
|
||||
<button mat-icon-button color="primary" (click)="edit(i)">
|
||||
<fa-icon icon="edit"></fa-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="delete(i)">
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="tableDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: tableDisplayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-elevation-z1 {
|
||||
margin: 1em 0 1.5em;
|
||||
}
|
||||
|
||||
h3,
|
||||
h4 {
|
||||
font-weight: 500;
|
||||
}
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { UntypedFormArray } from '@angular/forms';
|
||||
import { MatIconButton } from '@angular/material/button';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import {
|
||||
MatCell,
|
||||
MatCellDef,
|
||||
MatColumnDef,
|
||||
MatHeaderCell,
|
||||
MatHeaderCellDef,
|
||||
MatHeaderRow,
|
||||
MatHeaderRowDef,
|
||||
MatRow,
|
||||
MatRowDef,
|
||||
MatTable
|
||||
} from '@angular/material/table';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AccountingMappingDTO, AdvancedMappingDTO } from 'app/products/loan-products/models/loan-product.model';
|
||||
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
||||
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-advanced-accounting-mapping-rule',
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
FaIconComponent,
|
||||
MatTable,
|
||||
MatColumnDef,
|
||||
MatHeaderCellDef,
|
||||
MatHeaderCell,
|
||||
MatCellDef,
|
||||
MatCell,
|
||||
MatIconButton,
|
||||
MatHeaderRowDef,
|
||||
MatHeaderRow,
|
||||
MatRowDef,
|
||||
MatRow
|
||||
],
|
||||
templateUrl: './advanced-accounting-mapping-rule.component.html',
|
||||
styleUrl: './advanced-accounting-mapping-rule.component.scss'
|
||||
})
|
||||
export class AdvancedAccountingMappingRuleComponent implements OnInit {
|
||||
@Input() formType: string;
|
||||
@Input() formArray: UntypedFormArray;
|
||||
@Input() textHeading: string;
|
||||
@Input() textField: string;
|
||||
@Input() allowAddAccountingMapping: boolean = true;
|
||||
@Input() accountingMappingOptions: any[] = [];
|
||||
|
||||
currentFormValues: any[] = [];
|
||||
@Input() chargeData: any;
|
||||
@Input() penaltyData: any;
|
||||
@Input() paymentTypeData: any;
|
||||
@Input() assetAccountData: any;
|
||||
@Input() incomeAccountData: any;
|
||||
@Input() expenseAccountData: any;
|
||||
@Input() liabilityAccountData: any;
|
||||
@Input() incomeAndLiabilityAccountData: any;
|
||||
@Input() assetAndLiabilityAccountData: any;
|
||||
|
||||
@Output() formChangeEvent: EventEmitter<AdvancedMappingDTO> = new EventEmitter<AdvancedMappingDTO>();
|
||||
|
||||
tableData: any[] = [];
|
||||
|
||||
tableDisplayedColumns: string[] = [
|
||||
'codeValueId',
|
||||
'glAccountId',
|
||||
'actions'
|
||||
];
|
||||
|
||||
constructor(
|
||||
public dialog: MatDialog,
|
||||
public translateService: TranslateService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.tableData = this.formArray?.value || [];
|
||||
this.sendParentData();
|
||||
}
|
||||
|
||||
add() {
|
||||
this.currentFormValues = [];
|
||||
if (this.formType == 'ChargeOffReasonExpense') {
|
||||
this.allowAddAccountingMapping = true;
|
||||
this.tableData.forEach((item: any) => this.currentFormValues.push(item.chargeOffReasonCodeValueId));
|
||||
if (this.accountingMappingOptions.length == this.currentFormValues.length) {
|
||||
this.allowAddAccountingMapping = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
const data = { ...this.getData(this.formType), pristine: false };
|
||||
const dialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.data) {
|
||||
const addData: AccountingMappingDTO = {
|
||||
value: this.getValueData(response.data.value.valueId),
|
||||
glAccount: this.getGlAccountData(response.data.value.glAccountId)
|
||||
};
|
||||
this.tableData.push(addData);
|
||||
this.sendParentData();
|
||||
|
||||
if (this.formType == 'ChargeOffReasonExpense') {
|
||||
this.allowAddAccountingMapping = this.tableData.length < this.accountingMappingOptions.length;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
delete(index: number) {
|
||||
const dialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||
data: { deleteContext: this.translateService.instant('labels.text.this') }
|
||||
});
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.delete) {
|
||||
this.tableData.splice(index, 1);
|
||||
this.sendParentData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sendParentData() {
|
||||
const advancedMappingDTO: AdvancedMappingDTO = {
|
||||
formType: this.formType,
|
||||
values: this.tableData
|
||||
};
|
||||
this.formChangeEvent.emit(advancedMappingDTO);
|
||||
}
|
||||
|
||||
getData(formType: string, values?: any) {
|
||||
switch (formType) {
|
||||
case 'PaymentFundSource':
|
||||
return {
|
||||
title: 'Configure Fund Sources for Payment Channels',
|
||||
formfields: this.getPaymentFundSourceFormfields(values)
|
||||
};
|
||||
case 'FeesIncome':
|
||||
return { title: 'Map Fees to Income Accounts', formfields: this.getFeesIncomeFormfields(values) };
|
||||
case 'PenaltyIncome':
|
||||
return {
|
||||
title: 'Map Penalties to Specific Income Accounts',
|
||||
formfields: this.getPenaltyIncomeFormfields(values)
|
||||
};
|
||||
case 'ChargeOffReasonExpense':
|
||||
return {
|
||||
title: 'Map Charge-off reasons to Expense accounts',
|
||||
formfields: this.getChargeOffReasonExpenseFormfields(values)
|
||||
};
|
||||
case 'BuydownFeeClassificationToIncome':
|
||||
return {
|
||||
title: 'Buydown Fee classifications to Income accounts',
|
||||
formfields: this.getClassificationIncomeFormfields(values)
|
||||
};
|
||||
case 'CapitalizedIncomeClassificationToIncome':
|
||||
return {
|
||||
title: 'Capitalized Income classifications to Income accounts',
|
||||
formfields: this.getClassificationIncomeFormfields(values)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
getPaymentFundSourceFormfields(values?: any) {
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'paymentTypeId',
|
||||
label: 'Payment Type',
|
||||
value: values ? values.paymentTypeId : this.paymentTypeData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.paymentTypeData },
|
||||
required: true,
|
||||
order: 1
|
||||
}),
|
||||
new SelectBase({
|
||||
controlName: 'fundSourceAccountId',
|
||||
label: 'Fund Source',
|
||||
value: values ? values.fundSourceAccountId : this.assetAccountData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.assetAccountData },
|
||||
required: true,
|
||||
order: 2
|
||||
})
|
||||
|
||||
];
|
||||
return formfields;
|
||||
}
|
||||
|
||||
getFeesIncomeFormfields(values?: any) {
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'chargeId',
|
||||
label: 'Fees',
|
||||
value: values ? values.chargeId : this.chargeData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.chargeData },
|
||||
required: true,
|
||||
order: 1
|
||||
}),
|
||||
new SelectBase({
|
||||
controlName: 'incomeAccountId',
|
||||
label: 'Income Account',
|
||||
value: values ? values.incomeAccountId : this.incomeAndLiabilityAccountData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.incomeAndLiabilityAccountData },
|
||||
required: true,
|
||||
order: 2
|
||||
})
|
||||
|
||||
];
|
||||
return formfields;
|
||||
}
|
||||
|
||||
getPenaltyIncomeFormfields(values?: any) {
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'chargeId',
|
||||
label: 'Penalty',
|
||||
value: values ? values.chargeId : this.penaltyData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.penaltyData },
|
||||
required: true,
|
||||
order: 1
|
||||
}),
|
||||
new SelectBase({
|
||||
controlName: 'incomeAccountId',
|
||||
label: 'Income Account',
|
||||
value: values ? values.incomeAccountId : this.incomeAccountData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.incomeAccountData },
|
||||
required: true,
|
||||
order: 2
|
||||
})
|
||||
|
||||
];
|
||||
return formfields;
|
||||
}
|
||||
|
||||
getChargeOffReasonExpenseFormfields(values?: any) {
|
||||
const reasonOptions = this.accountingMappingOptions.filter(
|
||||
(item: any) => !this.currentFormValues.includes(item.id)
|
||||
);
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'chargeOffReasonCodeValueId',
|
||||
label: 'Charge-off reason',
|
||||
value: values ? values.chargeOffReasonCodeValueId : reasonOptions[0].id,
|
||||
options: { label: 'name', value: 'id', data: reasonOptions },
|
||||
required: true,
|
||||
order: 1
|
||||
}),
|
||||
new SelectBase({
|
||||
controlName: 'expenseAccountId',
|
||||
label: 'Expense Account',
|
||||
value: values ? values.expenseAccountId : this.expenseAccountData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.expenseAccountData },
|
||||
required: true,
|
||||
order: 2
|
||||
})
|
||||
|
||||
];
|
||||
return formfields;
|
||||
}
|
||||
|
||||
getClassificationIncomeFormfields(values?: any) {
|
||||
const classificationOptions = this.accountingMappingOptions.filter(
|
||||
(item: any) => !this.currentFormValues.includes(item.id)
|
||||
);
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'valueId',
|
||||
label: 'Classification',
|
||||
value: values ? values.chargeOffReasonCodeValueId : classificationOptions[0].id,
|
||||
options: { label: 'name', value: 'id', data: classificationOptions },
|
||||
required: true,
|
||||
order: 1
|
||||
}),
|
||||
new SelectBase({
|
||||
controlName: 'glAccountId',
|
||||
label: 'Income Account',
|
||||
value: values ? values.incomeAccountId : this.incomeAccountData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.incomeAccountData },
|
||||
required: true,
|
||||
order: 2
|
||||
})
|
||||
|
||||
];
|
||||
return formfields;
|
||||
}
|
||||
|
||||
getValueData(valueId: number): any {
|
||||
return this.accountingMappingOptions.find((i: any) => {
|
||||
return i.id === valueId;
|
||||
});
|
||||
}
|
||||
|
||||
getGlAccountData(valueId: number): any {
|
||||
return this.incomeAccountData.find((i: any) => {
|
||||
return i.id === valueId;
|
||||
});
|
||||
}
|
||||
}
|
||||
+22
@@ -514,6 +514,28 @@
|
||||
<tr mat-header-row *matHeaderRowDef="chargeOffReasonExpenseDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargeOffReasonExpenseDisplayedColumns"></tr>
|
||||
</table>
|
||||
|
||||
<mifosx-advanced-accounting-mapping-rule
|
||||
class="flex-100 m-t-10"
|
||||
[textField]="'Classification'"
|
||||
[formType]="'BuydownFeeClassificationToIncome'"
|
||||
[formArray]="buydownfeeClassificationToIncomeAccountMappings"
|
||||
[textHeading]="'Buydown Fee classifications to Income accounts'"
|
||||
[incomeAccountData]="incomeAccountData"
|
||||
[accountingMappingOptions]="buydownFeeClassificationOptions"
|
||||
(formChangeEvent)="formChangeEvent($event)"
|
||||
></mifosx-advanced-accounting-mapping-rule>
|
||||
|
||||
<mifosx-advanced-accounting-mapping-rule
|
||||
class="flex-100 m-t-10"
|
||||
[textField]="'Classification'"
|
||||
[formType]="'CapitalizedIncomeClassificationToIncome'"
|
||||
[formArray]="capitalizedIncomeClassificationToIncomeAccountMappings"
|
||||
[textHeading]="'Capitalized Income classifications to Income accounts'"
|
||||
[incomeAccountData]="incomeAccountData"
|
||||
[accountingMappingOptions]="capitalizedIncomeClassificationOptions"
|
||||
(formChangeEvent)="formChangeEvent($event)"
|
||||
></mifosx-advanced-accounting-mapping-rule>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+91
-3
@@ -8,7 +8,10 @@ import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.componen
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
|
||||
import { ChargeOffReasonToExpenseAccountMapping } from 'app/shared/models/general.model';
|
||||
import {
|
||||
ChargeOffReasonToExpenseAccountMapping,
|
||||
ClassificationToIncomeAccountMapping
|
||||
} from 'app/shared/models/general.model';
|
||||
import { DeferredIncomeRecognition } from '../loan-product-payment-strategy-step/payment-allocation-model';
|
||||
import { MatRadioGroup, MatRadioButton } from '@angular/material/radio';
|
||||
import { MatDivider } from '@angular/material/divider';
|
||||
@@ -31,6 +34,8 @@ import {
|
||||
import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper';
|
||||
import { FindPipe } from '../../../../pipes/find.pipe';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
import { AdvancedAccountingMappingRuleComponent } from './advanced-accounting-mapping-rule/advanced-accounting-mapping-rule.component';
|
||||
import { AccountingMappingDTO, AdvancedMappingDTO } from '../../models/loan-product.model';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-loan-product-accounting-step',
|
||||
@@ -57,7 +62,8 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
MatRow,
|
||||
MatStepperPrevious,
|
||||
MatStepperNext,
|
||||
FindPipe
|
||||
FindPipe,
|
||||
AdvancedAccountingMappingRuleComponent
|
||||
]
|
||||
})
|
||||
export class LoanProductAccountingStepComponent implements OnInit, OnChanges {
|
||||
@@ -78,6 +84,8 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges {
|
||||
incomeAndLiabilityAccountData: any;
|
||||
assetAndLiabilityAccountData: any;
|
||||
chargeOffReasonOptions: any;
|
||||
capitalizedIncomeClassificationOptions: any[] = [];
|
||||
buydownFeeClassificationOptions: any[] = [];
|
||||
|
||||
currentFormValues: any[] = [];
|
||||
allowAddChargeOffReasonExpense = true;
|
||||
@@ -123,6 +131,9 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges {
|
||||
this.assetAndLiabilityAccountData =
|
||||
this.loanProductsTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions || [];
|
||||
this.chargeOffReasonOptions = this.loanProductsTemplate.chargeOffReasonOptions || [];
|
||||
this.capitalizedIncomeClassificationOptions =
|
||||
this.loanProductsTemplate.capitalizedIncomeClassificationOptions || [];
|
||||
this.buydownFeeClassificationOptions = this.loanProductsTemplate.buydownFeeClassificationOptions || [];
|
||||
|
||||
this.loanProductAccountingForm.patchValue({
|
||||
accountingRule: this.loanProductsTemplate.accountingRule.id
|
||||
@@ -201,7 +212,9 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges {
|
||||
this.loanProductsTemplate.paymentChannelToFundSourceMappings ||
|
||||
this.loanProductsTemplate.feeToIncomeAccountMappings ||
|
||||
this.loanProductsTemplate.penaltyToIncomeAccountMappings ||
|
||||
this.loanProductsTemplate.chargeOffReasonToExpenseAccountMappings
|
||||
this.loanProductsTemplate.chargeOffReasonToExpenseAccountMappings ||
|
||||
this.loanProductsTemplate.buydownFeeClassificationToIncomeAccountMappings ||
|
||||
this.loanProductsTemplate.capitalizedIncomeClassificationToIncomeAccountMappings
|
||||
? true
|
||||
: false
|
||||
});
|
||||
@@ -244,6 +257,28 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges {
|
||||
)
|
||||
)
|
||||
);
|
||||
this.loanProductAccountingForm.setControl(
|
||||
'buydownfeeClassificationToIncomeAccountMappings',
|
||||
this.formBuilder.array(
|
||||
(this.loanProductsTemplate.buydownFeeClassificationToIncomeAccountMappings || []).map(
|
||||
(m: ClassificationToIncomeAccountMapping) => ({
|
||||
value: m.classificationCodeValue,
|
||||
glAccount: m.incomeAccount
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
this.loanProductAccountingForm.setControl(
|
||||
'capitalizedIncomeClassificationToIncomeAccountMappings',
|
||||
this.formBuilder.array(
|
||||
(this.loanProductsTemplate.capitalizedIncomeClassificationToIncomeAccountMappings || []).map(
|
||||
(m: ClassificationToIncomeAccountMapping) => ({
|
||||
value: m.classificationCodeValue,
|
||||
glAccount: m.incomeAccount
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,6 +376,14 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges {
|
||||
'chargeOffReasonToExpenseAccountMappings',
|
||||
this.formBuilder.array([])
|
||||
);
|
||||
this.loanProductAccountingForm.addControl(
|
||||
'buydownfeeClassificationToIncomeAccountMappings',
|
||||
this.formBuilder.array([])
|
||||
);
|
||||
this.loanProductAccountingForm.addControl(
|
||||
'capitalizedIncomeClassificationToIncomeAccountMappings',
|
||||
this.formBuilder.array([])
|
||||
);
|
||||
} else {
|
||||
this.loanProductAccountingForm.setControl(
|
||||
'paymentChannelToFundSourceMappings',
|
||||
@@ -352,6 +395,14 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges {
|
||||
'chargeOffReasonToExpenseAccountMappings',
|
||||
this.formBuilder.array([])
|
||||
);
|
||||
this.loanProductAccountingForm.setControl(
|
||||
'buydownfeeClassificationToIncomeAccountMappings',
|
||||
this.formBuilder.array([])
|
||||
);
|
||||
this.loanProductAccountingForm.setControl(
|
||||
'capitalizedIncomeClassificationToIncomeAccountMappings',
|
||||
this.formBuilder.array([])
|
||||
);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -415,6 +466,16 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges {
|
||||
return this.loanProductAccountingForm.get('chargeOffReasonToExpenseAccountMappings') as UntypedFormArray;
|
||||
}
|
||||
|
||||
get buydownfeeClassificationToIncomeAccountMappings(): UntypedFormArray {
|
||||
return this.loanProductAccountingForm.get('buydownfeeClassificationToIncomeAccountMappings') as UntypedFormArray;
|
||||
}
|
||||
|
||||
get capitalizedIncomeClassificationToIncomeAccountMappings(): UntypedFormArray {
|
||||
return this.loanProductAccountingForm.get(
|
||||
'capitalizedIncomeClassificationToIncomeAccountMappings'
|
||||
) as UntypedFormArray;
|
||||
}
|
||||
|
||||
setLoanProductAccountingFormDirty() {
|
||||
if (this.loanProductAccountingForm.pristine) {
|
||||
this.loanProductAccountingForm.markAsDirty();
|
||||
@@ -635,4 +696,31 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formChangeEvent(accountingData: AdvancedMappingDTO) {
|
||||
if (accountingData.formType === 'BuydownFeeClassificationToIncome') {
|
||||
this.loanProductAccountingForm.setControl(
|
||||
'buydownfeeClassificationToIncomeAccountMappings',
|
||||
this.formBuilder.array(
|
||||
(accountingData.values || []).map((m: AccountingMappingDTO) => ({
|
||||
classificationCodeValueId: m.value.id,
|
||||
incomeAccountId: m.glAccount.id
|
||||
}))
|
||||
)
|
||||
);
|
||||
console.log(this.loanProductAccountingForm.value.buydownfeeClassificationToIncomeAccountMappings);
|
||||
} else if (accountingData.formType === 'CapitalizedIncomeClassificationToIncome') {
|
||||
this.loanProductAccountingForm.setControl(
|
||||
'capitalizedIncomeClassificationToIncomeAccountMappings',
|
||||
this.formBuilder.array(
|
||||
(accountingData.values || []).map((m: AccountingMappingDTO) => ({
|
||||
classificationCodeValueId: m.value.id,
|
||||
incomeAccountId: m.glAccount.id
|
||||
}))
|
||||
)
|
||||
);
|
||||
console.log(this.loanProductAccountingForm.value.capitalizedIncomeClassificationToIncomeAccountMappings);
|
||||
}
|
||||
this.setLoanProductAccountingFormDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,10 @@ import {
|
||||
AccountingMapping,
|
||||
ChargeOffReasonToExpenseAccountMapping,
|
||||
ChargeToIncomeAccountMapping,
|
||||
ClassificationToIncomeAccountMapping,
|
||||
CodeValue,
|
||||
Currency,
|
||||
GLAccount,
|
||||
PaymentChannelToFundSourceMapping
|
||||
} from 'app/shared/models/general.model';
|
||||
import { OptionData, StringEnumOptionData } from 'app/shared/models/option-data.model';
|
||||
@@ -152,6 +155,8 @@ export interface LoanProduct {
|
||||
enableAccrualActivityPosting?: boolean;
|
||||
supportedInterestRefundTypes?: StringEnumOptionData[];
|
||||
chargeOffBehaviour?: StringEnumOptionData;
|
||||
buydownFeeClassificationToIncomeAccountMappings?: ClassificationToIncomeAccountMapping[];
|
||||
capitalizedIncomeClassificationToIncomeAccountMappings?: ClassificationToIncomeAccountMapping[];
|
||||
}
|
||||
|
||||
export interface AllowAttributeOverrides {
|
||||
@@ -193,3 +198,13 @@ export interface InterestRecalculationData {
|
||||
allowCompoundingOnEod: boolean;
|
||||
disallowInterestCalculationOnPastDue: boolean;
|
||||
}
|
||||
|
||||
export interface AdvancedMappingDTO {
|
||||
formType: string;
|
||||
values: AccountingMappingDTO[];
|
||||
}
|
||||
|
||||
export interface AccountingMappingDTO {
|
||||
value: CodeValue;
|
||||
glAccount: GLAccount;
|
||||
}
|
||||
|
||||
@@ -122,6 +122,7 @@ import { ViewAdvancePaymenyAllocationComponent } from './loan-products/view-loan
|
||||
import { AdvancePaymentAllocationTabComponent } from './loan-products/loan-product-stepper/loan-product-payment-strategy-step/advance-payment-allocation-tab/advance-payment-allocation-tab.component';
|
||||
import { LoanProductSummaryComponent } from './loan-products/common/loan-product-summary/loan-product-summary.component';
|
||||
import { LoanProductDeferredIncomeRecognitionStepComponent } from './loan-products/loan-product-stepper/loan-product-capitalized-income-step/loan-product-deferred-income-recognition-step.component';
|
||||
import { AdvancedAccountingMappingRuleComponent } from './loan-products/loan-product-stepper/loan-product-accounting-step/advanced-accounting-mapping-rule/advanced-accounting-mapping-rule.component';
|
||||
|
||||
/**
|
||||
* Products Module
|
||||
@@ -249,7 +250,8 @@ import { LoanProductDeferredIncomeRecognitionStepComponent } from './loan-produc
|
||||
ViewAdvancePaymenyAllocationComponent,
|
||||
AdvancePaymentAllocationTabComponent,
|
||||
LoanProductSummaryComponent,
|
||||
LoanProductDeferredIncomeRecognitionStepComponent
|
||||
LoanProductDeferredIncomeRecognitionStepComponent,
|
||||
AdvancedAccountingMappingRuleComponent
|
||||
]
|
||||
})
|
||||
export class ProductsModule {}
|
||||
|
||||
@@ -42,11 +42,25 @@ export interface PaymentChannelToFundSourceMapping {
|
||||
export interface ChargeOffReasonToExpenseAccountMapping {
|
||||
chargeOffReasonCodeValueId?: number;
|
||||
expenseAccountId?: number;
|
||||
chargeOffReasonCodeValue?: ChargeOffReasonCodeValue;
|
||||
chargeOffReasonCodeValue?: CodeValue;
|
||||
expenseAccount?: AccountingMapping;
|
||||
}
|
||||
|
||||
export interface ChargeOffReasonCodeValue {
|
||||
export interface AccountMapping {
|
||||
codeValueId?: number;
|
||||
glAccountId?: number;
|
||||
codeValue?: CodeValue;
|
||||
glAccount?: AccountingMapping;
|
||||
}
|
||||
|
||||
export interface ClassificationToIncomeAccountMapping {
|
||||
classificationCodeValueId?: number;
|
||||
incomeAccountId?: number;
|
||||
classificationCodeValue?: CodeValue;
|
||||
incomeAccount?: AccountingMapping;
|
||||
}
|
||||
|
||||
export interface CodeValue {
|
||||
active: boolean;
|
||||
description: string;
|
||||
id: number;
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import {
|
||||
import { CustomParametersTableComponent } from './custom-parameters-table/custom-parameters-table.component';
|
||||
import { SystemService } from 'app/system/system.service';
|
||||
import { CdkScrollable } from '@angular/cdk/scrolling';
|
||||
import { NgFor, NgClass } from '@angular/common';
|
||||
import { NgClass } from '@angular/common';
|
||||
import { MatList, MatListItem } from '@angular/material/list';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
@@ -839,6 +839,8 @@
|
||||
"Bulk Import": "Hromadný import",
|
||||
"Bulk Loan Reassignment": "Hromadné přeřazení půjčky",
|
||||
"Business Rule Parameters": "Parametry obchodních pravidel",
|
||||
"Buydown Fee classifications to Income accounts": "Klasifikace poplatků za odkup na příjmové účty",
|
||||
"Capitalized Income classifications to Income accounts": "Klasifikace kapitalizovaných výnosů do výnosových účtů",
|
||||
"COB Catch-Up is": "COB Catch-Up je",
|
||||
"Calculate Interest": "Vypočítejte úrok",
|
||||
"Campaign Message": "Zpráva kampaně",
|
||||
|
||||
@@ -840,6 +840,8 @@
|
||||
"Bulk Import": "Massenimport",
|
||||
"Bulk Loan Reassignment": "Neuzuweisung von Massenkrediten",
|
||||
"Business Rule Parameters": "Geschäftsregelparameter",
|
||||
"Buydown Fee classifications to Income accounts": "Buydown-Gebührenklassifizierungen für Einkommenskonten",
|
||||
"Capitalized Income classifications to Income accounts": "Klassifizierung kapitalisierter Einkünfte in Einkommenskonten",
|
||||
"COB Catch-Up is": "COB Catch-Up ist",
|
||||
"Calculate Interest": "Zinsen berechnen",
|
||||
"Campaign Message": "Kampagnenbotschaft",
|
||||
|
||||
@@ -845,6 +845,8 @@
|
||||
"Bulk Import": "Bulk Import",
|
||||
"Bulk Loan Reassignment": "Bulk Loan Reassignment",
|
||||
"Business Rule Parameters": "Business Rule Parameters",
|
||||
"Buydown Fee classifications to Income accounts": "Buydown Fee classifications to Income accounts",
|
||||
"Capitalized Income classifications to Income accounts": "Capitalized Income classifications to Income accounts",
|
||||
"COB Catch-Up is": "COB Catch-Up is",
|
||||
"Calculate Interest": "Calculate Interest",
|
||||
"Campaign Message": "Campaign Message",
|
||||
|
||||
@@ -839,6 +839,8 @@
|
||||
"Bulk Import": "Importación masiva",
|
||||
"Bulk Loan Reassignment": "Reasignación de Créditos másiva",
|
||||
"Business Rule Parameters": "Parámetros de reglas de negocio",
|
||||
"Buydown Fee classifications to Income accounts": "Clasificaciones de comisiones por reducción de precio en cuentas de ingresos",
|
||||
"Capitalized Income classifications to Income accounts": "Clasificaciones de ingresos capitalizados a cuentas de ingresos",
|
||||
"COB Catch-Up is": "La puesta al día de COB es",
|
||||
"Calculate Interest": "Calcular interés",
|
||||
"Campaign Message": "Mensaje de campaña",
|
||||
|
||||
@@ -839,6 +839,8 @@
|
||||
"Bulk Import": "Importación masiva",
|
||||
"Bulk Loan Reassignment": "Reasignación de Créditos másiva",
|
||||
"Business Rule Parameters": "Parámetros de reglas de negocio",
|
||||
"Buydown Fee classifications to Income accounts": "Clasificaciones de comisiones por reducción de precio en cuentas de ingresos",
|
||||
"Capitalized Income classifications to Income accounts": "Clasificaciones de ingresos capitalizados a cuentas de ingresos",
|
||||
"COB Catch-Up is": "La puesta al día de COB es",
|
||||
"Calculate Interest": "Calcular interés",
|
||||
"Campaign Message": "Mensaje de campaña",
|
||||
|
||||
@@ -840,6 +840,8 @@
|
||||
"Bulk Import": "Importation en masse",
|
||||
"Bulk Loan Reassignment": "Réaffectation groupée de prêts",
|
||||
"Business Rule Parameters": "Paramètres des règles métier",
|
||||
"Buydown Fee classifications to Income accounts": "Classification des frais de rachat dans les comptes de revenus",
|
||||
"Capitalized Income classifications to Income accounts": "Classifications des revenus capitalisés vers les comptes de revenus",
|
||||
"COB Catch-Up is": "Le rattrapage COB est",
|
||||
"Calculate Interest": "Calculer les intérêts",
|
||||
"Campaign Message": "Message de campagne",
|
||||
|
||||
@@ -840,6 +840,8 @@
|
||||
"Bulk Import": "Importazione in blocco",
|
||||
"Bulk Loan Reassignment": "Riassegnazione del prestito in blocco",
|
||||
"Business Rule Parameters": "Parametri delle regole aziendali",
|
||||
"Buydown Fee classifications to Income accounts": "Classificazioni delle commissioni di riacquisto nei conti di reddito",
|
||||
"Capitalized Income classifications to Income accounts": "Classificazioni del reddito capitalizzato nei conti di reddito",
|
||||
"COB Catch-Up is": "Il recupero del COB lo è",
|
||||
"Calculate Interest": "Calcola gli interessi",
|
||||
"Campaign Message": "Messaggio della campagna",
|
||||
|
||||
@@ -840,6 +840,8 @@
|
||||
"Bulk Import": "대량 가져오기",
|
||||
"Bulk Loan Reassignment": "대량대출 재할당",
|
||||
"Business Rule Parameters": "비즈니스 규칙 매개변수",
|
||||
"Buydown Fee classifications to Income accounts": "소득 계정에 대한 Buydown 수수료 분류",
|
||||
"Capitalized Income classifications to Income accounts": "자본화된 소득 분류를 소득 계정으로",
|
||||
"COB Catch-Up is": "COB 따라잡기는",
|
||||
"Calculate Interest": "이자 계산",
|
||||
"Campaign Message": "캠페인 메시지",
|
||||
|
||||
@@ -840,6 +840,8 @@
|
||||
"Bulk Import": "Masinis importas",
|
||||
"Bulk Loan Reassignment": "Masinės paskolos perskirstymas",
|
||||
"Business Rule Parameters": "Verslo taisyklių parametrai",
|
||||
"Buydown Fee classifications to Income accounts": "Išpirkimo mokesčių klasifikavimas į pajamų sąskaitas",
|
||||
"Capitalized Income classifications to Income accounts": "Kapitalizuotų pajamų klasifikavimas į pajamų sąskaitas",
|
||||
"COB Catch-Up is": "COB Catch-Up yra",
|
||||
"Calculate Interest": "Apskaičiuokite palūkanas",
|
||||
"Campaign Message": "Kampanijos pranešimas",
|
||||
|
||||
@@ -840,6 +840,8 @@
|
||||
"Bulk Import": "Lielapjoma importēšana",
|
||||
"Bulk Loan Reassignment": "Lielapjoma aizdevuma pārcelšana",
|
||||
"Business Rule Parameters": "Biznesa noteikumu parametri",
|
||||
"Buydown Fee classifications to Income accounts": "Izpirkšanas maksu klasifikācija ienākumu kontos",
|
||||
"Capitalized Income classifications to Income accounts": "Kapitalizēto ienākumu klasifikācija ienākumu kontos",
|
||||
"COB Catch-Up is": "COB Catch-Up ir",
|
||||
"Calculate Interest": "Aprēķināt procentus",
|
||||
"Campaign Message": "Kampaņas ziņojums",
|
||||
|
||||
@@ -840,6 +840,8 @@
|
||||
"Bulk Import": "थोक आयात",
|
||||
"Bulk Loan Reassignment": "बल्क ऋण पुन: असाइनमेन्ट",
|
||||
"Business Rule Parameters": "व्यापार नियम प्यारामिटरहरू",
|
||||
"Buydown Fee classifications to Income accounts": "आय खाताहरूमा खरिद शुल्क वर्गीकरण",
|
||||
"Capitalized Income classifications to Income accounts": "आय खाताहरूमा पूंजीकृत आय वर्गीकरण",
|
||||
"COB Catch-Up is": "COB क्याच-अप हो",
|
||||
"Calculate Interest": "ब्याज गणना गर्नुहोस्",
|
||||
"Campaign Message": "अभियान सन्देश",
|
||||
|
||||
@@ -840,6 +840,8 @@
|
||||
"Bulk Import": "Importação em massa",
|
||||
"Bulk Loan Reassignment": "Reatribuição de empréstimo em massa",
|
||||
"Business Rule Parameters": "Parâmetros de regras de negócios",
|
||||
"Buydown Fee classifications to Income accounts": "Classificações de taxas de recompra para contas de renda",
|
||||
"Capitalized Income classifications to Income accounts": "Classificações de renda capitalizada para contas de renda",
|
||||
"COB Catch-Up is": "A recuperação do COB é",
|
||||
"Calculate Interest": "Calcular juros",
|
||||
"Campaign Message": "Mensagem da campanha",
|
||||
|
||||
@@ -840,6 +840,8 @@
|
||||
"Bulk Import": "Ingiza Wingi",
|
||||
"Bulk Loan Reassignment": "Ugawaji upya wa mkopo kwa wingi",
|
||||
"Business Rule Parameters": "Vigezo vya Sheria ya Biashara",
|
||||
"Buydown Fee classifications to Income accounts": "Uainishaji wa Ada ya Kununua kwa akaunti za Mapato",
|
||||
"Capitalized Income classifications to Income accounts": "Uainishaji wa Mapato ya Mtaji kwa akaunti za Mapato",
|
||||
"COB Catch-Up is": "COB Catch-Up ni",
|
||||
"Calculate Interest": "Hesabu Riba",
|
||||
"Campaign Message": "Ujumbe wa Kampeni",
|
||||
|
||||
Reference in New Issue
Block a user