Loan Product views enhancements

This commit is contained in:
Jose Alberto Hernandez
2023-11-30 10:45:15 +01:00
committed by Adam Saghy
parent 79595f6a1c
commit 4271ca92dc
8 changed files with 116 additions and 42 deletions
@@ -46,7 +46,7 @@
</div> </div>
<div *ngIf="loanDetailsData.summary" class="loans-overview mat-typography" fxFlex="40%"> <div *ngIf="loanDetailsData.summary" class="loans-overview mat-typography" fxFlex="40%">
<h3> {{"labels.heading.Account OverView" | translate}} </h3> <h3> {{"labels.heading.Account Overview" | translate}} </h3>
<table class="account-overview"> <table class="account-overview">
<tbody> <tbody>
<tr> <tr>
@@ -43,27 +43,27 @@
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
<div fxFlexFill *ngIf="loanProduct.currencyCode"> <div fxFlexFill>
<span fxFlex="47%">Currency:</span> <span fxFlex="47%">Currency:</span>
<span fxFlex="53%">{{ loanProduct.currencyCode | find:loanProductsTemplate.currencyOptions:'code':'name' }}</span> <span fxFlex="53%">{{ loanProduct.currency.code }}</span>
</div> </div>
<div fxFlexFill *ngIf="!loanProduct.currencyCode"> <div fxFlexFill>
<span fxFlex="47%">Currency:</span> <span fxFlex="47%">Currency:</span>
<span fxFlex="53%">{{ loanProduct.currency.name }}</span> <span fxFlex="53%">{{ loanProduct.currency.displayLabel }}</span>
</div> </div>
<div fxFlexFill *ngIf="!loanProduct.currencyCode"> <div fxFlexFill>
<span fxFlex="47%">Decimal Places:</span> <span fxFlex="47%">Decimal Places:</span>
<span fxFlex="53%">{{ loanProduct.currency.decimalPlaces }}</span> <span fxFlex="53%">{{ loanProduct.currency.decimalPlaces }}</span>
</div> </div>
<div fxFlexFill *ngIf="!loanProduct.currencyCode"> <div fxFlexFill>
<span fxFlex="47%">Currency in multiples of:</span> <span fxFlex="47%">Currency in multiples of:</span>
<span fxFlex="53%">{{ loanProduct.currency.inMultiplesOf }}</span> <span fxFlex="53%">{{ loanProduct.currency.inMultiplesOf }}</span>
</div> </div>
<div fxFlexFill *ngIf="!loanProduct.currencyCode"> <div fxFlexFill>
<span fxFlex="47%">Installment in multiples of:</span> <span fxFlex="47%">Installment in multiples of:</span>
<span fxFlex="53%">{{ loanProduct.installmentAmountInMultiplesOf }}</span> <span fxFlex="53%">{{ loanProduct.installmentAmountInMultiplesOf }}</span>
</div> </div>
@@ -87,17 +87,17 @@
<div fxFlexFill *ngIf="loanProduct.allowApprovedDisbursedAmountsOverApplied"> <div fxFlexFill *ngIf="loanProduct.allowApprovedDisbursedAmountsOverApplied">
<span fxFlex="47%">Over Applied Amount:</span> <span fxFlex="47%">Over Applied Amount:</span>
<span fxFlex="53%" *ngIf="loanProduct.overAppliedCalculationType === 'percentage'">{{ loanProduct.overAppliedNumber <span fxFlex="53%" *ngIf="loanProduct.overAppliedCalculationType === 'percentage'">{{ loanProduct.overAppliedNumber
| formatNumber | formatNumber
}} %</span> }} %</span>
<span fxFlex="53%" *ngIf="loanProduct.overAppliedCalculationType === 'flat'">{{ loanProduct.overAppliedNumber | <span fxFlex="53%" *ngIf="loanProduct.overAppliedCalculationType === 'flat'">{{ loanProduct.overAppliedNumber |
formatNumber }} {{ formatNumber }} {{
loanProduct.currencyCode }}</span> loanProduct.currencyCode }}</span>
</div> </div>
<div fxFlexFill> <div fxFlexFill>
<span fxFlex="47%">Installment day calculation from:</span> <span fxFlex="47%">Installment day calculation from:</span>
<span fxFlex="53%">{{ loanProduct.repaymentStartDateType.value }}</span> <span fxFlex="53%">{{ loanProduct.repaymentStartDateType?.value }}</span>
</div> </div>
<div fxFlexFill> <div fxFlexFill>
@@ -118,7 +118,7 @@
<span fxFlex="53%">{{ loanProduct.interestRatePerPeriod + ' (Min: ' + (loanProduct.minInterestRatePerPeriod ? <span fxFlex="53%">{{ loanProduct.interestRatePerPeriod + ' (Min: ' + (loanProduct.minInterestRatePerPeriod ?
loanProduct.minInterestRatePerPeriod : loanProduct.interestRatePerPeriod) + ', Max: ' + loanProduct.minInterestRatePerPeriod : loanProduct.interestRatePerPeriod) + ', Max: ' +
(loanProduct.maxInterestRatePerPeriod ? loanProduct.maxInterestRatePerPeriod : loanProduct.interestRatePerPeriod) (loanProduct.maxInterestRatePerPeriod ? loanProduct.maxInterestRatePerPeriod : loanProduct.interestRatePerPeriod)
+ ')' + ' ' + loanProduct.interestRateFrequencyType.value }}</span> + ')' + ' ' + loanProduct.interestRateFrequencyType?.value }}</span>
</div> </div>
<div fxFlexFill *ngIf="loanProduct.isLinkedToFloatingInterestRates" fxLayout="row wrap" fxLayout.lt-md="column"> <div fxFlexFill *ngIf="loanProduct.isLinkedToFloatingInterestRates" fxLayout="row wrap" fxLayout.lt-md="column">
@@ -300,7 +300,7 @@
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
<div fxFlexFill> <div fxFlexFill *ngIf="loanProduct.amortizationType?.value">
<span fxFlex="47%">Amortization:</span> <span fxFlex="47%">Amortization:</span>
<span fxFlex="53%">{{ loanProduct.amortizationType.value }}</span> <span fxFlex="53%">{{ loanProduct.amortizationType.value }}</span>
</div> </div>
@@ -312,15 +312,15 @@
<div fxFlexFill> <div fxFlexFill>
<span fxFlex="47%">Interest Method:</span> <span fxFlex="47%">Interest Method:</span>
<span fxFlex="53%">{{ loanProduct.interestType.value }}</span> <span fxFlex="53%">{{ loanProduct.interestType?.value }}</span>
</div> </div>
<div fxFlexFill> <div fxFlexFill>
<span fxFlex="47%">Interest Calculation Period:</span> <span fxFlex="47%">Interest Calculation Period:</span>
<span fxFlex="53%">{{ loanProduct.interestCalculationPeriodType.value }}</span> <span fxFlex="53%">{{ loanProduct.interestCalculationPeriodType?.value }}</span>
</div> </div>
<div fxFlexFill> <div fxFlexFill *ngIf="loanProduct.allowPartialPeriodInterestCalculation">
<span fxFlex="47%">Allow Partial Interest Calculation with same as repayment:</span> <span fxFlex="47%">Allow Partial Interest Calculation with same as repayment:</span>
<span fxFlex="53%">{{ loanProduct.allowPartialPeriodInterestCalculation | yesNo }}</span> <span fxFlex="53%">{{ loanProduct.allowPartialPeriodInterestCalculation | yesNo }}</span>
</div> </div>
@@ -339,7 +339,12 @@
<span fxFlex="53%" class="repayment-strategy">{{ loanProduct.transactionProcessingStrategyName }}</span> <span fxFlex="53%" class="repayment-strategy">{{ loanProduct.transactionProcessingStrategyName }}</span>
</div> </div>
<div fxFlexFill *ngIf="isAdvancedPaymentAllocationStrategy()"> <div fxFlexFill *ngIf="isAdvancedPaymentAllocation">
<span fxFlex="47%">Loan Schedule Processing Type:</span>
<span fxFlex="53%">{{ loanProduct.loanScheduleProcessingType.value }}</span>
</div>
<div fxFlexFill *ngIf="isAdvancedPaymentAllocation">
<span fxFlex="47%">Advanced Payment Allocation Transactions:</span> <span fxFlex="47%">Advanced Payment Allocation Transactions:</span>
<span fxFlex="53%"> <span fxFlex="53%">
<mat-accordion> <mat-accordion>
@@ -351,11 +356,6 @@
</span> </span>
</div> </div>
<div fxFlexFill *ngIf="isAdvancedPaymentAllocationStrategy()">
<span fxFlex="47%">Loan Schedule Processing Type:</span>
<span fxFlex="53%">{{ loanProduct.loanScheduleProcessingType.value }}</span>
</div>
<h3 class="mat-h3" fxFlexFill>Down Payments</h3> <h3 class="mat-h3" fxFlexFill>Down Payments</h3>
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
@@ -414,12 +414,12 @@
<div fxFlexFill> <div fxFlexFill>
<span fxFlex="47%">Days in year:</span> <span fxFlex="47%">Days in year:</span>
<span fxFlex="53%">{{ loanProduct.daysInYearType.value }}</span> <span fxFlex="53%">{{ loanProduct.daysInYearType?.value }}</span>
</div> </div>
<div fxFlexFill> <div fxFlexFill>
<span fxFlex="47%">Days in month:</span> <span fxFlex="47%">Days in month:</span>
<span fxFlex="53%">{{ loanProduct.daysInMonthType.value }}</span> <span fxFlex="53%">{{ loanProduct.daysInMonthType?.value }}</span>
</div> </div>
<div fxFlexFill> <div fxFlexFill>
@@ -3,7 +3,7 @@ import { LoanProduct } from '../../models/loan-product.model';
import { AccountingMapping, Charge, ChargeToIncomeAccountMapping, GLAccount, PaymentChannelToFundSourceMapping, PaymentType, PaymentTypeOption } from '../../../../shared/models/general.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, PaymentAllocation } from '../../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
import { LoanProducts } from '../../loan-products'; import { LoanProducts } from '../../loan-products';
import { OptionData } from '../../../../shared/models/option-data.model'; import { CodeName, OptionData } from '../../../../shared/models/option-data.model';
@Component({ @Component({
selector: 'mifosx-loan-product-summary', selector: 'mifosx-loan-product-summary',
@@ -12,6 +12,7 @@ import { OptionData } from '../../../../shared/models/option-data.model';
}) })
export class LoanProductSummaryComponent implements OnInit, OnChanges { export class LoanProductSummaryComponent implements OnInit, OnChanges {
@Input() action: string;
@Input() loanProduct: LoanProduct; @Input() loanProduct: LoanProduct;
@Input() loanProductsTemplate: any | null; @Input() loanProductsTemplate: any | null;
@Input() useDueForRepaymentsConfigurations: boolean; @Input() useDueForRepaymentsConfigurations: boolean;
@@ -43,9 +44,19 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
} }
setCurrentValues(): void { setCurrentValues(): void {
if (this.loanProduct.accountingMappings) { this.isAdvancedPaymentAllocation = LoanProducts.isAdvancedPaymentAllocationStrategy(this.loanProduct.transactionProcessingStrategyCode);
if (!this.loanProduct.currency) {
this.loanProductsTemplate.currencyOptions.some((o: any) => {
if (o.code === this.loanProduct.currencyCode) {
this.loanProduct.currency = o;
}
});
}
if (this.action === 'view') {
this.accountingMappings = this.loanProduct.accountingMappings; this.accountingMappings = this.loanProduct.accountingMappings;
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 || [];
@@ -125,15 +136,49 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
this.loanProductsTemplate.interestRecalculationFrequencyTypeOptions), this.loanProductsTemplate.interestRecalculationFrequencyTypeOptions),
preClosureInterestCalculationStrategy: this.optionDataLookUp(this.loanProduct.preClosureInterestCalculationStrategy, preClosureInterestCalculationStrategy: this.optionDataLookUp(this.loanProduct.preClosureInterestCalculationStrategy,
this.loanProductsTemplate.preClosureInterestCalculationStrategyOptions), this.loanProductsTemplate.preClosureInterestCalculationStrategyOptions),
allowCompoundingOnEod: this.loanProduct.allowCompoundingOnEod, allowCompoundingOnEod: this.loanProduct.allowCompoundingOnEod,
isArrearsBasedOnOriginalSchedule: this.loanProduct.isArrearsBasedOnOriginalSchedule, isArrearsBasedOnOriginalSchedule: this.loanProduct.isArrearsBasedOnOriginalSchedule,
isCompoundingToBePostedAsTransaction: this.loanProduct.isCompoundingToBePostedAsTransaction, isCompoundingToBePostedAsTransaction: this.loanProduct.isCompoundingToBePostedAsTransaction,
recalculationRestFrequencyInterval: this.loanProduct.recalculationRestFrequencyInterval recalculationRestFrequencyInterval: this.loanProduct.recalculationRestFrequencyInterval
}; };
} }
}
this.isAdvancedPaymentAllocation = LoanProducts.isAdvancedPaymentAllocationStrategy(this.loanProduct.transactionProcessingStrategyCode); let optionValue: OptionData = this.optionDataLookUp(this.loanProduct.amortizationType, this.loanProductsTemplate.amortizationTypeOptions);
this.loanProduct.amortizationType = optionValue;
optionValue = this.optionDataLookUp(this.loanProduct.interestType, this.loanProductsTemplate.interestTypeOptions);
this.loanProduct.interestType = optionValue;
optionValue = this.optionDataLookUp(this.loanProduct.interestCalculationPeriodType, this.loanProductsTemplate.interestCalculationPeriodTypeOptions);
this.loanProduct.interestCalculationPeriodType = optionValue;
optionValue = this.optionDataLookUp(this.loanProduct.daysInMonthType, this.loanProductsTemplate.daysInMonthTypeOptions);
this.loanProduct.daysInMonthType = optionValue;
optionValue = this.optionDataLookUp(this.loanProduct.daysInYearType, this.loanProductsTemplate.daysInYearTypeOptions);
this.loanProduct.daysInYearType = optionValue;
optionValue = this.optionDataLookUp(this.loanProduct.interestRateFrequencyType, this.loanProductsTemplate.interestRateFrequencyTypeOptions);
this.loanProduct.interestRateFrequencyType = optionValue;
optionValue = this.optionDataLookUp(this.loanProduct.repaymentStartDateType, this.loanProductsTemplate.repaymentStartDateTypeOptions);
this.loanProduct.repaymentStartDateType = optionValue;
const codeValue: CodeName = this.codeNameLookUpByCode(this.loanProduct.transactionProcessingStrategyCode,
this.loanProductsTemplate.transactionProcessingStrategyOptions);
this.loanProduct.transactionProcessingStrategyName = codeValue.name;
if (this.isAdvancedPaymentAllocation) {
if (!this.loanProduct.loanScheduleProcessingType || !this.loanProduct.loanScheduleProcessingType.value) {
this.loanProduct.loanScheduleProcessingType = this.optionDataLookUpByCode(this.loanProduct.loanScheduleProcessingType,
this.loanProductsTemplate.loanScheduleProcessingTypeOptions);
}
if (!this.loanProduct.loanScheduleType || !this.loanProduct.loanScheduleType.value) {
this.loanProduct.loanScheduleType = this.optionDataLookUpByCode(this.loanProduct.loanScheduleType,
this.loanProductsTemplate.loanScheduleTypeOptions);
}
}
}
if (this.loanProduct.advancedPaymentAllocationTransactionTypes) { if (this.loanProduct.advancedPaymentAllocationTransactionTypes) {
this.advancePaymentAllocationData = { this.advancePaymentAllocationData = {
@@ -148,10 +193,9 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
futureInstallmentAllocationRules: this.loanProductsTemplate.advancedPaymentAllocationFutureInstallmentAllocationRules futureInstallmentAllocationRules: this.loanProductsTemplate.advancedPaymentAllocationFutureInstallmentAllocationRules
}; };
} }
} }
optionDataLookUp(itemId: number, optionsData: any[]): OptionData { optionDataLookUp(itemId: any, optionsData: any[]): OptionData {
let optionData: OptionData | null; let optionData: OptionData | null;
optionsData.some((o: any) => { optionsData.some((o: any) => {
if (o.id === itemId) { if (o.id === itemId) {
@@ -165,12 +209,39 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
return optionData; return optionData;
} }
optionDataLookUpByCode(currentValue: any, optionsData: any[]): OptionData {
let optionData: OptionData | null;
optionsData.some((o: any) => {
if (o.code === currentValue) {
optionData = {
id: o.id || 0,
code: o.code,
value: o.value || o.name
};
}
});
return optionData;
}
codeNameLookUpByCode(currentValue: any, optionsData: any[]): CodeName {
let optionData: CodeName | null;
optionsData.some((o: any) => {
if (o.code === currentValue) {
optionData = {
code: o.code,
name: o.name
};
}
});
return optionData;
}
glAccountLookUp(glAccountId: number, glAccounts: GLAccount[]): AccountingMapping { glAccountLookUp(glAccountId: number, glAccounts: GLAccount[]): AccountingMapping {
let accountMapping: AccountingMapping | null = null; let accountMapping: AccountingMapping | null = null;
if (glAccountId) { if (glAccountId) {
glAccounts.some((glAccount: GLAccount) => { glAccounts.some((glAccount: GLAccount) => {
if (glAccount.id === glAccountId) { if (glAccount.id === glAccountId) {
accountMapping = {id: glAccount.id, name: glAccount.name, glCode: glAccount.glCode}; accountMapping = { id: glAccount.id, name: glAccount.name, glCode: glAccount.glCode };
} }
}); });
} }
@@ -182,7 +253,7 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
if (chargeId) { if (chargeId) {
charges.some((charge: Charge) => { charges.some((charge: Charge) => {
if (charge.id === chargeId) { if (charge.id === chargeId) {
chargeData = {id: charge.id, name: charge.name, penalty: charge.penalty}; chargeData = { id: charge.id, name: charge.name, penalty: charge.penalty };
} }
}); });
} }
@@ -220,8 +291,4 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
|| this.loanProduct.penaltyToIncomeAccountMappings?.length > 0); || this.loanProduct.penaltyToIncomeAccountMappings?.length > 0);
} }
isAdvancedPaymentAllocationStrategy(): boolean {
return LoanProducts.isAdvancedPaymentAllocationStrategy(this.loanProduct.transactionProcessingStrategyCode);
}
} }
@@ -25,7 +25,9 @@ export class LoanProductPaymentStrategyStepComponent implements OnInit {
constructor(private dialog: MatDialog, constructor(private dialog: MatDialog,
private advancedPaymentStrategy: AdvancedPaymentStrategy) { } private advancedPaymentStrategy: AdvancedPaymentStrategy) { }
ngOnInit(): void { } ngOnInit(): void {
this.sendPaymentAllocation();
}
sendPaymentAllocation(): void { sendPaymentAllocation(): void {
const data = this.advancedPaymentStrategy.buildPaymentAllocations(this.advancedPaymentAllocations); const data = this.advancedPaymentStrategy.buildPaymentAllocations(this.advancedPaymentAllocations);
@@ -1,5 +1,6 @@
<mifosx-loan-product-summary <mifosx-loan-product-summary
[action]="'preview'"
[loanProduct]="loanProduct" [loanProduct]="loanProduct"
[loanProductsTemplate]="loanProductsTemplate" [loanProductsTemplate]="loanProductsTemplate"
[useDueForRepaymentsConfigurations]="loanProduct.useDueForRepaymentsConfigurations" [useDueForRepaymentsConfigurations]="loanProduct.useDueForRepaymentsConfigurations"
@@ -468,6 +468,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
}); });
} }
this.advancedTransactionProcessingStrategyDisabled = false; this.advancedTransactionProcessingStrategyDisabled = false;
this.isAdvancedTransactionProcessingStrategy = false;
} else { } else {
// Only Advanced Payment Allocation Strategy // Only Advanced Payment Allocation Strategy
this.transactionProcessingStrategyDataBase.some( this.transactionProcessingStrategyDataBase.some(
@@ -480,6 +481,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
this.loanProductSettingsForm.patchValue({ this.loanProductSettingsForm.patchValue({
'transactionProcessingStrategyCode': this.transactionProcessingStrategyData[0].code 'transactionProcessingStrategyCode': this.transactionProcessingStrategyData[0].code
}); });
this.isAdvancedTransactionProcessingStrategy = true;
} }
}); });
} }
@@ -10,6 +10,7 @@ export interface LoanProduct {
useBorrowerCycle: boolean; useBorrowerCycle: boolean;
status: string; status: string;
currency: Currency; currency: Currency;
currencyCode?: string;
fundId?: number; fundId?: number;
fundName?: string; fundName?: string;
startDate?: string; startDate?: string;
@@ -5,6 +5,7 @@
</div> </div>
<mifosx-loan-product-summary <mifosx-loan-product-summary
[action]="'view'"
[loanProduct]="loanProduct" [loanProduct]="loanProduct"
[useDueForRepaymentsConfigurations]="useDueForRepaymentsConfigurations" [useDueForRepaymentsConfigurations]="useDueForRepaymentsConfigurations"
[paymentAllocations]="loanProduct.paymentAllocation" [paymentAllocations]="loanProduct.paymentAllocation"