Skip to content

Commit

Permalink
Loan product using externalId input field
Browse files Browse the repository at this point in the history
  • Loading branch information
Jose Alberto Hernandez authored and alberto-art3ch committed Nov 28, 2024
1 parent 1aed445 commit 497fc3b
Showing 9 changed files with 68 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -14,6 +14,11 @@ <h3 class="mat-h3" fxFlexFill>{{ 'labels.heading.Details' | translate}}</h3>
<span fxFlex="53%">{{ loanProduct.shortName }}</span>
</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">
<span fxFlex="47%">{{ 'labels.inputs.Fund' | translate}}:</span>
<span fxFlex="53%">{{ loanProduct.fundName }}</span>
@@ -928,14 +933,14 @@ <h4 class="mat-h4" fxFlexFill>{{'labels.heading.Map Charge-off reasons to Expens
<ng-container matColumnDef="chargeOffReasonCodeValueId">
<th mat-header-cell *matHeaderCellDef> {{'labels.inputs.Charge-off reason' | translate}} </th>
<td mat-cell *matCellDef="let chargeOffReasonsToExpenseMapping">
{{ chargeOffReasonsToExpenseMapping.chargeOffReason.name }}
{{ chargeOffReasonsToExpenseMapping.chargeOffReasonsCodeValue.name }}
</td>
</ng-container>

<ng-container matColumnDef="expenseGLAccountId">
<th mat-header-cell *matHeaderCellDef> {{'labels.inputs.Expense Account' | translate}} </th>
<td mat-cell *matCellDef="let chargeOffReasonsToExpenseMapping">
{{ chargeOffReasonsToExpenseMapping.expenseGLAccount.name }}
({{ chargeOffReasonsToExpenseMapping.chargeOffExpenseAccount.glCode }}) {{ chargeOffReasonsToExpenseMapping.chargeOffExpenseAccount.name }}
</td>
</ng-container>

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
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 { LoanProducts } from '../../loan-products';
import { CodeName, OptionData, StringEnumOptionData } from '../../../../shared/models/option-data.model';
@@ -36,7 +36,7 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
paymentChannelToFundSourceMappings: PaymentChannelToFundSourceMapping[] = [];
feeToIncomeAccountMappings: ChargeToIncomeAccountMapping[] = [];
penaltyToIncomeAccountMappings: ChargeToIncomeAccountMapping[] = [];
chargeOffReasonsToExpenseMappings: ChargeOffReasonsToExpenseMapping[] = [];
chargeOffReasonsToExpenseMappings: ChargeOffReasonsToGLAccountMapping[] = [];

constructor(private accounting: Accounting) { }

@@ -65,7 +65,7 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
this.paymentChannelToFundSourceMappings = this.loanProduct.paymentChannelToFundSourceMappings || [];
this.feeToIncomeAccountMappings = this.loanProduct.feeToIncomeAccountMappings || [];
this.penaltyToIncomeAccountMappings = this.loanProduct.penaltyToIncomeAccountMappings || [];
this.chargeOffReasonsToExpenseMappings = this.loanProduct.chargeOffReasonsToExpenseMappings || [];
this.chargeOffReasonsToExpenseMappings = this.loanProduct.chargeOffReasonToGLAccountMappings || [];

} else {
this.accountingMappings = {};
@@ -133,14 +133,9 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
}

this.chargeOffReasonsToExpenseMappings = [];
if (this.loanProduct.chargeOffReasonsToExpenseMappings?.length > 0) {
this.loanProduct.chargeOffReasonsToExpenseMappings.forEach((m: ChargeOffReasonsToExpenseMapping) => {
this.chargeOffReasonsToExpenseMappings.push({
chargeOffReasonCodeValueId: m.chargeOffReasonCodeValueId,
chargeOffReason: this.optionDataLookUp(m.chargeOffReasonCodeValueId, this.loanProductsTemplate.chargeOffReasonOptions),
expenseGLAccountId: m.expenseGLAccountId,
expenseGLAccount: this.glAccountLookUp(m.expenseGLAccountId, expenseAccountData)
});
if (this.loanProduct.chargeOffReasonToGLAccountMappings?.length > 0) {
this.loanProduct.chargeOffReasonToGLAccountMappings.forEach((m: ChargeOffReasonsToGLAccountMapping) => {
this.chargeOffReasonsToExpenseMappings.push(m);
});
}
}
@@ -343,7 +338,7 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
return (this.loanProduct.paymentChannelToFundSourceMappings?.length > 0
|| this.loanProduct.feeToIncomeAccountMappings?.length > 0
|| this.loanProduct.penaltyToIncomeAccountMappings?.length > 0
|| this.loanProduct.chargeOffReasonsToExpenseMappings?.length > 0);
|| this.loanProduct.chargeOffReasonToGLAccountMappings?.length > 0);
}

getAccountingRuleName(value: string): string {
Original file line number Diff line number Diff line change
@@ -342,8 +342,6 @@ <h4 fxFlex="33%" class="mat-h4">{{'labels.heading.Map Charge-off reasons to Expe
{{'labels.buttons.Add' | translate}}
</button>
</div>


<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="chargeOffReasonsToExpenseMappings.value" *ngIf="chargeOffReasonsToExpenseMappings.value.length !== 0">

<ng-container matColumnDef="chargeOffReasonCodeValueId">
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ 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 {ChargeOffReasonsToExpenseMapping} from '../../../../shared/models/general.model';
import { ChargeOffReasonsToGLAccountMapping } from 'app/shared/models/general.model';

@Component({
selector: 'mifosx-loan-product-accounting-step',
@@ -107,8 +107,8 @@ export class LoanProductAccountingStepComponent implements OnInit {
this.formBuilder.array((this.loanProductsTemplate.penaltyToIncomeAccountMappings || []).map((penaltyIncome: any) =>
({ chargeId: penaltyIncome.charge.id, incomeAccountId: penaltyIncome.incomeAccount.id }))));
this.loanProductAccountingForm.setControl('chargeOffReasonsToExpenseMappings',
this.formBuilder.array((this.loanProductsTemplate.chargeOffReasonsToExpenseMappings || []).map((m: ChargeOffReasonsToExpenseMapping) =>
({ chargeOffReasonCodeValueId: m.chargeOffReasonCodeValueId, expenseGLAccountId: m.expenseGLAccountId }))));
this.formBuilder.array((this.loanProductsTemplate.chargeOffReasonsToExpenseMappings || []).map((m: ChargeOffReasonsToGLAccountMapping) =>
({ chargeOffReasonCodeValueId: m.chargeOffReasonsCodeValue.id, expenseGLAccountId: m.chargeOffExpenseAccount.id }))));
}
}

@@ -324,25 +324,27 @@ export class LoanProductAccountingStepComponent implements OnInit {
}

getChargeOffReasonExpenseFormfields(values?: any) {
const formfields: FormfieldBase[] = [
new SelectBase({
controlName: 'chargeOffReasonCodeValueId',
label: 'Charge-off reason',
value: values ? values.chargeOffReasonCodeValueId : this.chargeOffReasonOptions[0].id,
options: { label: 'name', value: 'id', data: this.chargeOffReasonOptions },
required: true,
order: 1
}),
new SelectBase({
controlName: 'expenseGLAccountId',
label: 'Expense Account',
value: values ? values.expenseGLAccountId : this.expenseAccountData[0].id,
options: { label: 'name', value: 'id', data: this.expenseAccountData },
required: true,
order: 2
})
];
return formfields;
if (values != null) {
const formfields: FormfieldBase[] = [
new SelectBase({
controlName: 'chargeOffReasonCodeValueId',
label: 'Charge-off reason',
value: values ? values.chargeOffReasonCodeValueId : this.chargeOffReasonOptions[0].id,
options: { label: 'name', value: 'id', data: this.chargeOffReasonOptions },
required: true,
order: 1
}),
new SelectBase({
controlName: 'expenseGLAccountId',
label: 'Expense Account',
value: values ? values.expenseGLAccountId : this.expenseAccountData[0].id,
options: { label: 'name', value: 'id', data: this.expenseAccountData },
required: true,
order: 2
})
];
return formfields;
}
}

get isAccountingAccrualBased() {
Original file line number Diff line number Diff line change
@@ -2,22 +2,27 @@

<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>
<input matInput formControlName="name" matTooltip="{{ 'tooltips.Product name is a unique identifier' | translate}}" required>
<mat-error>
{{'labels.inputs.Product Name' | translate}} {{'labels.commons.is' | translate}} <strong>{{'labels.commons.required' | translate}}</strong>
</mat-error>
</mat-form-field>

<mat-form-field fxFlex="24%">
<mat-form-field fxFlex="48%">
<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>
<mat-error>
{{'labels.inputs.Short Name' | translate}} {{'labels.commons.is' | translate}} <strong>{{'labels.commons.required' | translate}}</strong>
</mat-error>
</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-label>{{'labels.inputs.Fund' | translate}}</mat-label>
<mat-select matTooltip="{{ 'tooltips.Loan products may be assigned' | translate}}" formControlName="fundId">
Original file line number Diff line number Diff line change
@@ -42,6 +42,7 @@ export class LoanProductDetailsStepComponent implements OnInit {
'name': this.loanProductsTemplate.name,
'shortName': this.loanProductsTemplate.shortName,
'description': this.loanProductsTemplate.description,
'externalId': this.loanProductsTemplate.externalId,
'fundId': this.loanProductsTemplate.fundId,
'startDate': this.loanProductsTemplate.startDate && new Date(this.loanProductsTemplate.startDate),
'closeDate': this.loanProductsTemplate.closeDate && new Date(this.loanProductsTemplate.closeDate),
@@ -54,6 +55,7 @@ export class LoanProductDetailsStepComponent implements OnInit {
'name': ['', Validators.required],
'shortName': ['', Validators.required],
'description': [''],
'externalId': [''],
'fundId': [''],
'startDate': [''],
'closeDate': [''],
4 changes: 2 additions & 2 deletions src/app/products/loan-products/models/loan-product.model.ts
Original file line number Diff line number Diff line change
@@ -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 { CreditAllocation, PaymentAllocation } from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';

@@ -125,7 +125,7 @@ export interface LoanProduct {
paymentChannelToFundSourceMappings?: PaymentChannelToFundSourceMapping[];
feeToIncomeAccountMappings?: ChargeToIncomeAccountMapping[];
penaltyToIncomeAccountMappings?: ChargeToIncomeAccountMapping[];
chargeOffReasonsToExpenseMappings?: ChargeOffReasonsToExpenseMapping[];
chargeOffReasonToGLAccountMappings?: ChargeOffReasonsToGLAccountMapping[];
enableAccrualActivityPosting?: boolean;
supportedInterestRefundTypes?: StringEnumOptionData[];
}
8 changes: 5 additions & 3 deletions src/app/shared/footer/footer.component.ts
Original file line number Diff line number Diff line change
@@ -74,9 +74,11 @@ export class FooterComponent implements OnInit, OnDestroy {
this.getConfigurations();
this.server = this.settingsService.server;
this.versionService.getBackendInfo().subscribe((data: any) => {
const buildVersion: string = data.git.build.version.split('-');
this.versions.fineract.version = buildVersion[0];
this.versions.fineract.hash = buildVersion[1];
if (data.git && data.git.build && data.git.build.version) {
const buildVersion: string = data.git.build.version.split('-');
this.versions.fineract.version = buildVersion[0];
this.versions.fineract.hash = buildVersion[1];
}
});
}
}
19 changes: 14 additions & 5 deletions src/app/shared/models/general.model.ts
Original file line number Diff line number Diff line change
@@ -39,11 +39,20 @@ export interface PaymentChannelToFundSourceMapping {
fundSourceAccount: AccountingMapping;
}

export interface ChargeOffReasonsToExpenseMapping {
chargeOffReasonCodeValueId: number;
expenseGLAccountId: number;
chargeOffReason?: OptionData;
expenseGLAccount?: AccountingMapping;
export interface ChargeOffReasonsToGLAccountMapping {
chargeOffReasonCodeValueId?: number;
chargeOffReason? : OptionData;
chargeOffReasonsCodeValue?: ChargeOffReasonsCodeValue;
chargeOffExpenseAccount?: AccountingMapping;
}

export interface ChargeOffReasonsCodeValue {
active: boolean;
description: string;
id: number;
mandatory: boolean;
name: string;
position?: number;
}

export interface PaymentType {

0 comments on commit 497fc3b

Please sign in to comment.