diff --git a/src/app/products/loan-products/create-loan-product/create-loan-product.component.html b/src/app/products/loan-products/create-loan-product/create-loan-product.component.html index 260e066d8..b4eb5fe69 100644 --- a/src/app/products/loan-products/create-loan-product/create-loan-product.component.html +++ b/src/app/products/loan-products/create-loan-product/create-loan-product.component.html @@ -26,6 +26,7 @@
@@ -51,6 +52,7 @@ diff --git a/src/app/products/loan-products/create-loan-product/create-loan-product.component.ts b/src/app/products/loan-products/create-loan-product/create-loan-product.component.ts index 70bf6bf1f..85b3eb1b0 100644 --- a/src/app/products/loan-products/create-loan-product/create-loan-product.component.ts +++ b/src/app/products/loan-products/create-loan-product/create-loan-product.component.ts @@ -88,6 +88,7 @@ export class CreateLoanProductComponent implements OnInit { selectedTabIndex = 0; isAdvancedPaymentStrategy = false; + selectedProductSubGroup = ''; paymentAllocation: PaymentAllocation[] = []; creditAllocation: PaymentAllocation[] = []; supportedInterestRefundTypes: StringEnumOptionData[] = []; @@ -144,6 +145,10 @@ export class CreateLoanProductComponent implements OnInit { return this.loanProductTermsStep.loanProductTermsForm; } + setProductSubGroup(value: string) { + this.selectedProductSubGroup = value; + } + advancePaymentStrategy(value: string) { this.isAdvancedPaymentStrategy = LoanProducts.isAdvancedPaymentAllocationStrategy(value); if (this.isAdvancedPaymentStrategy) { diff --git a/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.html b/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.html index 8e2da682b..5bc35069e 100644 --- a/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.html +++ b/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.html @@ -39,6 +39,7 @@ @@ -56,6 +57,7 @@ diff --git a/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts b/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts index b5fb93f9b..b4569cf8e 100644 --- a/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts +++ b/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts @@ -95,6 +95,7 @@ export class EditLoanProductComponent implements OnInit { itemsByDefault: GlobalConfiguration[] = []; isAdvancedPaymentStrategy = false; + selectedProductSubGroup = ''; wasPaymentAllocationChanged = false; paymentAllocation: PaymentAllocation[] = []; creditAllocation: CreditAllocation[] = []; @@ -218,6 +219,10 @@ export class EditLoanProductComponent implements OnInit { this.isAdvancedPaymentStrategy = LoanProducts.isAdvancedPaymentAllocationStrategy(value); } + setProductSubGroup(value: string): void { + this.selectedProductSubGroup = value; + } + buildAdvancedPaymentAllocation(): void { this.advancedPaymentAllocations = this.advancedPaymentStrategy.buildAdvancedPaymentAllocationList( this.loanProductAndTemplate diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/loan-product-accounting-step.component.ts b/src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/loan-product-accounting-step.component.ts index 4b3880fd6..95fb2c7e6 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/loan-product-accounting-step.component.ts +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-accounting-step/loan-product-accounting-step.component.ts @@ -210,7 +210,14 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges { intOverdueReserveAccountId: accountingMappings.intOverdueReserveAccount?.id || '', undebitedInterestAccountId: accountingMappings.undebitedInterestAccount?.id || '', penalIntCrGlAccountId: accountingMappings.penalIntCrGlAccount?.id || '', - rdMaturedGlAccountId: accountingMappings.rdMaturedGlAccount?.id || '' + rdMaturedGlAccountId: accountingMappings.rdMaturedGlAccount?.id || '', + glAccountId: accountingMappings.glAccount?.id || '', + icChargeGlAccountId: accountingMappings.icChargeGlAccount?.id || '', + inoperativeGlAccountId: accountingMappings.inoperativeGlAccount?.id || '', + creditBalanceLiabilityGlAccountId: accountingMappings.creditBalanceLiabilityGlAccount?.id || '', + creditBalanceAssetGlAccountId: accountingMappings.creditBalanceAssetGlAccount?.id || '', + overdueAccountsGlAccountId: accountingMappings.overdueAccountsGlAccount?.id || '', + rebateGlAccountId: accountingMappings.rebateGlAccount?.id || '' }); if (this.loanProductsTemplate.paymentChannelToFundSourceMappings) { @@ -281,11 +288,8 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges { 'receivablePenaltyAccountId', 'intReceivablesGlAccountId', 'intPayableGlAccountId', - 'deafIntPayableGlAccountId', - 'intOverdueReserveAccountId', - 'undebitedInterestAccountId', - 'penalIntCrGlAccountId', - 'rdMaturedGlAccountId' + 'glAccountId', + 'inoperativeGlAccountId' ]; commonFields.forEach((field) => { if (!this.loanProductAccountingForm.contains(field)) { @@ -293,6 +297,26 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges { } }); + // Optional custom GL account fields (legacy screenshot fields not marked mandatory) — + // no Validators.required, so mat-form-field does not render a required asterisk for these. + const optionalCommonFields = [ + 'deafIntPayableGlAccountId', + 'intOverdueReserveAccountId', + 'undebitedInterestAccountId', + 'penalIntCrGlAccountId', + 'rdMaturedGlAccountId', + 'icChargeGlAccountId', + 'creditBalanceLiabilityGlAccountId', + 'creditBalanceAssetGlAccountId', + 'overdueAccountsGlAccountId', + 'rebateGlAccountId' + ]; + optionalCommonFields.forEach((field) => { + if (!this.loanProductAccountingForm.contains(field)) { + this.loanProductAccountingForm.addControl(field, new UntypedFormControl('')); + } + }); + if (!this.loanProductAccountingForm.contains('advancedAccountingRules')) { this.loanProductAccountingForm.addControl('advancedAccountingRules', new UntypedFormControl(false)); } @@ -708,15 +732,15 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges { { key: 'intReceivablesGlAccountId', label: 'Int. Receivables GL A/c', - inputLabel: 'Int. Receivables GL A/c', + inputLabel: 'Int Receivables GL A/c', controlName: 'intReceivablesGlAccountId', options: this.assetAccountData, - required: false + required: true }, { key: 'deafIntPayableGlAccountId', label: 'Deaf Int. Payble GL A/c', - inputLabel: 'Deaf Int. Payble GL A/c', + inputLabel: 'Deaf Int Payble GL A/c', controlName: 'deafIntPayableGlAccountId', options: this.assetAccountData, required: false @@ -724,7 +748,7 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges { { key: 'intOverdueReserveAccountId', label: 'Int. Overdue Reserve A/c (AS)', - inputLabel: 'Int. Overdue Reserve A/c', + inputLabel: 'Int Overdue Reserve A/c', controlName: 'intOverdueReserveAccountId', options: this.assetAccountData, required: false @@ -736,6 +760,38 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges { controlName: 'rdMaturedGlAccountId', options: this.assetAccountData, required: false + }, + { + key: 'glAccountId', + label: 'GL A/c No.', + inputLabel: 'GL A/c No', + controlName: 'glAccountId', + options: this.assetAccountData, + required: true + }, + { + key: 'inoperativeGlAccountId', + label: 'InOperative GL A/c', + inputLabel: 'InOperative GL A/c', + controlName: 'inoperativeGlAccountId', + options: this.assetAccountData, + required: true + }, + { + key: 'creditBalanceAssetGlAccountId', + label: 'Cr.Balance Asset GL A/c', + inputLabel: 'Cr Balance Asset GL A/c', + controlName: 'creditBalanceAssetGlAccountId', + options: this.assetAccountData, + required: false + }, + { + key: 'overdueAccountsGlAccountId', + label: 'Overdue Accounts GL A/c No.', + inputLabel: 'Overdue Accounts GL A/c No', + controlName: 'overdueAccountsGlAccountId', + options: this.assetAccountData, + required: false } ], otherMappingsControlName: 'assetsOtherGlMappings', @@ -848,10 +904,18 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges { { key: 'penalIntCrGlAccountId', label: 'Penal Int. Cr. GL A/c', - inputLabel: 'Penal Int. Cr. GL A/c', + inputLabel: 'Penal Int Cr GL A/c', controlName: 'penalIntCrGlAccountId', options: this.incomeAccountData, required: false + }, + { + key: 'icChargeGlAccountId', + label: 'I.C. Charge GL A/c No.', + inputLabel: 'IC Charge GL A/c No', + controlName: 'icChargeGlAccountId', + options: this.incomeAccountData, + required: false } ], otherMappingsControlName: 'incomeOtherGlMappings', @@ -903,6 +967,14 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges { options: this.expenseAccountData, required: true, deferredBuyDownMerchantOnly: true + }, + { + key: 'rebateGlAccountId', + label: 'Rebate GL A/c No.', + inputLabel: 'Rebate GL A/c No', + controlName: 'rebateGlAccountId', + options: this.expenseAccountData, + required: false } ], otherMappingsControlName: 'expensesOtherGlMappings', @@ -934,10 +1006,10 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges { { key: 'intPayableGlAccountId', label: 'Int. Payable GL A/c', - inputLabel: 'Int. Payable GL A/c', + inputLabel: 'Int Payable GL A/c', controlName: 'intPayableGlAccountId', options: this.liabilityAccountData, - required: false + required: true }, { key: 'undebitedInterestAccountId', @@ -946,6 +1018,14 @@ export class LoanProductAccountingStepComponent implements OnInit, OnChanges { controlName: 'undebitedInterestAccountId', options: this.liabilityAccountData, required: false + }, + { + key: 'creditBalanceLiabilityGlAccountId', + label: 'Cr.Balance Liability GL A/c', + inputLabel: 'Cr Balance Liability GL A/c', + controlName: 'creditBalanceLiabilityGlAccountId', + options: this.liabilityAccountData, + required: false } ], otherMappingsControlName: 'liabilitiesOtherGlMappings', diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.html b/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.html index ec1e817bf..0b193fefc 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.html +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.html @@ -6,7 +6,11 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - +
@@ -171,3 +174,174 @@ }
+--> + + +
+
+
+ +

Cheque & Standing Instruction Charges

+
+
+ + Chq. Book Charge + + YES + NO + + + + + Chq. Return Charge + + YES + NO + + + + + I.C. Charge Debit + + YES + NO + + + + + Cash Bundle Charge + + YES + NO + + + + + Cash Bundle Charge With PAN Limit + + + + + Per Cheque Entry Charge + + + + + Per Cheque Entry Service Charge + + + + + Per Inward Cheque Entry Charge + + + + + Per Outward Cheque Entry Charge + + + + + Creditor Standing Instr. Fail Charge + + + + + Debtor Standing Instr. Fail Charge + + + + + Calculate Daily Against Clearing Charge + + YES + NO + + +
+
+ +
+
+ +

Minimum Balance Charges

+
+
+ + Minimum Balance Checking + + Strict + Average + Lenient + + + + + Auto Minimum Balance Charge + + YES + NO + + + + + Calculate Daily Min. Balance Charges + + YES + NO + + + + + Minimum Balance Charge + + YES + NO + + + + + Min. Balance Charge (Rs.) + + + + + Min. Balance Charge For Cheque Issue (Rs.) + + + + + Min. Balance Charge Method + + Flat + Slab + + + + + Months After Min. Balance Charge Calculate + + + + + For Cheque Issue + + + + + For Cheque Issue (Avg.) + + + + + For Withdrawal Slip + + + + + For Withdrawal Slip (Avg.) + + +
+
+
diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.scss b/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.scss index d40566222..b80a406a8 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.scss +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.scss @@ -88,3 +88,27 @@ $gray-900: #202124; .lpch-table { width: 100%; } + +.lpch-section__body { + display: grid; + grid-template-columns: repeat(2, 1fr); + align-items: start; + gap: 18px 16px; + padding: 20px 24px; + + @media (width <= 600px) { + grid-template-columns: 1fr; + } +} + +.lpch-section__body.lpch-grid-4 { + grid-template-columns: repeat(4, 1fr); + + @media (width <= 1100px) { + grid-template-columns: repeat(2, 1fr); + } + + @media (width <= 600px) { + grid-template-columns: 1fr; + } +} diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.ts b/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.ts index f914bb42c..09e230b43 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.ts +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-charges-step/loan-product-charges-step.component.ts @@ -7,7 +7,7 @@ */ import { Component, Input, OnInit, inject } from '@angular/core'; -import { UntypedFormControl } from '@angular/forms'; +import { UntypedFormControl, UntypedFormBuilder, UntypedFormGroup, ReactiveFormsModule } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; @@ -51,12 +51,16 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; MatRow, ChargesFilterPipe, ChargesPenaltyFilterPipe, - FormatNumberPipe + FormatNumberPipe, + ReactiveFormsModule ] }) export class LoanProductChargesStepComponent implements OnInit { dialog = inject(MatDialog); private translateService = inject(TranslateService); + private formBuilder = inject(UntypedFormBuilder); + + legacyChargesForm: UntypedFormGroup; @Input() loanProductsTemplate: any; @Input() currencyCode: UntypedFormControl; @@ -76,6 +80,48 @@ export class LoanProductChargesStepComponent implements OnInit { pristine = true; + constructor() { + this.createLegacyChargesForm(); + } + + createLegacyChargesForm() { + this.legacyChargesForm = this.formBuilder.group({ + // Cheque-related charges (legacy "A/c Mas Scr2 Para") + chequeBookChargeEnabled: ['NO'], + chequeReturnChargeEnabled: ['NO'], + icChargeDebitEnabled: ['NO'], + cashBundleChargeEnabled: ['NO'], + cashBundleChargeWithPanLimit: [''], + + // Cheque transaction charges (legacy Page 4) + perChequeEntryCharge: [''], + perChequeEntryServiceCharge: [''], + perInwardChequeEntryCharge: [''], + perOutwardChequeEntryCharge: [''], + + // Standing Instruction fail charges (legacy Page 4) + creditorStandingInstructionFailCharge: [''], + debtorStandingInstructionFailCharge: [''], + + // Minimum Balance Information (legacy Page 2 + Page 4) + minimumBalanceCheckingType: [''], + autoMinimumBalanceCharge: [''], + calculateDailyMinimumBalanceCharges: ['NO'], + minimumBalanceChargeEnabled: ['NO'], + minimumBalanceChargeAmount: [''], + minimumBalanceChargeForChequeIssue: [''], + minimumBalanceChargeMethod: [''], + monthsAfterMinBalanceChargeCalculate: [''], + forChequeIssue: [''], + forChequeIssueAvg: [''], + forWithdrawalSlip: [''], + forWithdrawalSlipAvg: [''], + + // Against Clearing charge (legacy Page 4) + calculateDailyAgainstClearingCharge: ['NO'] + }); + } + ngOnInit() { this.chargeData = this.loanProductsTemplate.chargeOptions; this.overdueChargeData = this.loanProductsTemplate.penaltyOptions @@ -112,7 +158,8 @@ export class LoanProductChargesStepComponent implements OnInit { get loanProductCharges() { return { - charges: this.chargesDataSource + charges: this.chargesDataSource, + ...this.legacyChargesForm.value }; } } diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.html b/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.html index 49df9f6d2..30a298473 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.html +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.html @@ -7,40 +7,144 @@ -->
+
-

{{ 'labels.inputs.Product Name' | translate }} & {{ 'labels.inputs.Description' | translate }}

+

General Information

-
- - {{ 'labels.inputs.Product Name' | translate }} - - - {{ 'labels.inputs.Product Name' | translate }} {{ 'labels.commons.is' | translate }} - {{ 'labels.commons.required' | translate }} - - +
+
+ + Account Type Group + + @for (group of productTypeGroups; track group.id) { + {{ group.label }} + } + + - - {{ 'labels.inputs.Short Name' | translate }} - - - {{ 'labels.inputs.Short Name' | translate }} {{ 'labels.commons.is' | translate }} - {{ 'labels.commons.required' | translate }} - - + @if (availableSubGroups.length) { + + Product Type Sub Group + + @for (subGroup of availableSubGroups; track subGroup.id) { + {{ subGroup.label }} + } + + + } + + + A/c. Type Description + + + {{ 'labels.inputs.Product Name' | translate }} {{ 'labels.commons.is' | translate }} + {{ 'labels.commons.required' | translate }} + + + + + {{ 'labels.inputs.Short Name' | translate }} + + + {{ 'labels.inputs.Short Name' | translate }} {{ 'labels.commons.is' | translate }} + {{ 'labels.commons.required' | translate }} + + + + + A/c Type Code + + + + + MICR Trn. Code + + + + + Reserved Code Srno For ECS + + + + + Reverse ECS No. + + +
+ +
+ + Lock Cheque Info + + YES + NO + + + + + Lock Page 2 Info + + YES + NO + + + + + Computerization Date + + + + + + + PFMS Account Type + + + + + Chq. Print Description + + + + + POS A/c Type Description + + + + + Renewal Dt. Add Months + + + + + Renewal Grace Days + + + + + Doc. Renewal Dt. Add Months + + +
@@ -97,86 +201,94 @@

Interest Information

-
- - Debit Int. Calculation - - @for (opt of yesNoOptions; track opt.value) { - {{ opt.label }} - } - - - - - Separate Penal Int. - - @for (opt of yesNoOptions; track opt.value) { - {{ opt.label }} - } - - - - - Credit Int. Calculation - - @for (opt of yesNoOptions; track opt.value) { - {{ opt.label }} - } - - - - - Sub A/c Type Balance - - @for (opt of yesNoOptions; track opt.value) { - {{ opt.label }} - } - - - - - Final Int. Rounding - - @for (opt of yesNoOptions; track opt.value) { - {{ opt.label }} - } - - - - @if (loanProductDetailsForm.get('finalIntRounding')?.value) { +
+
- Rounding UpTo - + Debit Int. Calculation + + @for (opt of yesNoOptions; track opt.value) { + {{ opt.label }} + } + - } + + + Separate Penal Int. + + @for (opt of yesNoOptions; track opt.value) { + {{ opt.label }} + } + + + + + Final Int. Rounding + + @for (opt of yesNoOptions; track opt.value) { + {{ opt.label }} + } + + + + @if (loanProductDetailsForm.get('finalIntRounding')?.value) { + + Rounding UpTo + + + } +
+ +
+ + Credit Int. Calculation + + @for (opt of yesNoOptions; track opt.value) { + {{ opt.label }} + } + + + + + Sub A/c Type Balance + + @for (opt of yesNoOptions; track opt.value) { + {{ opt.label }} + } + + +
+
+
+ + GL Account mappings for these fields (Int. Receivables, Penal Int. Cr., RD Matured, Int. Payable, Deaf Int. + Payable, Int. Overdue Reserve, UnDebited Interest) are available in the Accounting tab.
- +
- -

Product Classification

+ +

PPS Limit & Write Off Details

- Product Type Group - - @for (group of productTypeGroups; track group.id) { - {{ group.label }} - } + PPS Limit + + + + + Is this Actyp Write Off? + + YES + NO - @if (loanProductDetailsForm.get('productTypeGroup')?.value) { + @if (loanProductDetailsForm.get('isWriteOffAccountType')?.value === 'YES') { - GL Account ({{ glClassificationLabel }}) - - @for (acc of availableGlAccounts; track acc.id) { - ({{ acc.glCode }}) {{ acc.name }} - } - - GL Account is required + Write Off Actyp + }
diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.scss b/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.scss index f6a3f62d5..f6032818a 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.scss +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.scss @@ -46,9 +46,10 @@ $gray-900: #202124; .lpd-grid { display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 4px 16px; - padding: 16px 24px; + grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + align-items: start; + gap: 18px 16px; + padding: 20px 24px; @media (width <= 600px) { grid-template-columns: 1fr; @@ -57,6 +58,7 @@ $gray-900: #202124; .lpd-field { width: 100%; + min-width: 0; &--full { grid-column: 1 / -1; @@ -69,6 +71,43 @@ $gray-900: #202124; padding: 4px 0; } +// Two independent vertical columns of fields, side by side +.lpd-two-col { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4px 40px; + padding: 20px 24px; + align-items: start; + + @media (width <= 700px) { + grid-template-columns: 1fr; + } + + &__column { + display: flex; + flex-direction: column; + } +} + +.lpd-info-note { + display: flex; + align-items: flex-start; + gap: 8px; + margin: 0 24px 16px; + padding: 10px 14px; + background: #eff6ff; + border: 1px solid #bfdbfe; + border-radius: 8px; + font-size: 12.5px; + color: #1e3a8a; + line-height: 1.5; + + i { + color: #2563eb; + margin-top: 2px; + } +} + // GL Section .lpd-gl-section { border-top: 2px solid #e0f2fe; diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.ts b/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.ts index ded56834c..be0a33192 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.ts +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-details-step/loan-product-details-step.component.ts @@ -7,7 +7,7 @@ */ /** Angular Imports */ -import { Component, OnInit, Input, inject } from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, inject } from '@angular/core'; import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { Dates } from 'app/core/utils/dates'; @@ -33,6 +33,7 @@ export class LoanProductDetailsStepComponent implements OnInit { private settingsService = inject(SettingsService); @Input() loanProductsTemplate: any; + @Output() productSubGroupChange = new EventEmitter(); loanProductDetailsForm: UntypedFormGroup; @@ -49,6 +50,10 @@ export class LoanProductDetailsStepComponent implements OnInit { this.createLoanProductDetailsForm(); } + assetAccountOptions: any[] = []; + incomeAccountOptions: any[] = []; + liabilityAccountOptions: any[] = []; + ngOnInit() { this.loanProductDetailsForm.patchValue({ name: this.loanProductsTemplate.name, @@ -58,10 +63,6 @@ export class LoanProductDetailsStepComponent implements OnInit { closeDate: this.loanProductsTemplate.closeDate && new Date(this.loanProductsTemplate.closeDate) }); - const mappingOptions = this.loanProductsTemplate?.accountingMappingOptions ?? {}; - this.assetAccountOptions = mappingOptions.assetAccountOptions ?? []; - this.liabilityAccountOptions = mappingOptions.liabilityAccountOptions ?? []; - this.loanProductDetailsForm.patchValue({ debitIntCalculation: this.loanProductsTemplate.debitIntCalculation ?? false, separatePenalInterest: this.loanProductsTemplate.separatePenalInterest ?? false, @@ -70,66 +71,59 @@ export class LoanProductDetailsStepComponent implements OnInit { finalIntRounding: this.loanProductsTemplate.finalIntRounding ?? false, roundingUpTo: this.loanProductsTemplate.roundingUpTo ?? null }); + + const mappingOptions = this.loanProductsTemplate?.accountingMappingOptions ?? {}; + this.assetAccountOptions = mappingOptions.assetAccountOptions ?? []; + this.incomeAccountOptions = mappingOptions.incomeAccountOptions ?? []; + this.liabilityAccountOptions = mappingOptions.liabilityAccountOptions ?? []; + + const accountingMappings = this.loanProductsTemplate?.accountingMappings; + if (accountingMappings) { + this.loanProductDetailsForm.patchValue({ + intReceivablesGlAccountId: accountingMappings.intReceivablesGlAccount?.id || '', + penalIntCrGlAccountId: accountingMappings.penalIntCrGlAccount?.id || '', + rdMaturedGlAccountId: accountingMappings.rdMaturedGlAccount?.id || '', + intPayableGlAccountId: accountingMappings.intPayableGlAccount?.id || '', + deafIntPayableGlAccountId: accountingMappings.deafIntPayableGlAccount?.id || '', + intOverdueReserveAccountId: accountingMappings.intOverdueReserveAccount?.id || '', + undebitedInterestAccountId: accountingMappings.undebitedInterestAccount?.id || '' + }); + } } /** Product Classification data */ readonly productTypeGroups = [ - { id: 'loans', label: 'Loan' }, - { id: 'advanced', label: 'Advanced' } + { id: 'advances', label: 'Advances A/C' }, + { id: 'loans', label: 'Loans A/C' } ]; readonly productTypeSubGroups: Record = { - loans: [ - { id: 'emi', label: 'EMI' }, - { id: 'cc', label: 'CC (Cash Credit)' }, - { id: 'overdraft', label: 'Overdraft' }, - { id: 'warehouse', label: 'Warehouse' }, - { id: 'gold', label: 'Gold' } + // Renewable, Drawing-Power/limit-based revolving credit facilities + advances: [ + { id: 'cc', label: 'Cash Credit (CC)' }, + { id: 'overdraft', label: 'Overdraft (OD)' }, + { id: 'gold', label: 'Gold Loan' }, + { id: 'warehouse', label: 'Warehouse Receipt / Pledge Loan' }, + { id: 'kcc', label: 'Kisan Credit Card (KCC)' }, + { id: 'bills', label: 'Bills Purchased / Discounted' } ], - advanced: [ - { id: 'fd', label: 'FD (Fixed Deposit)' }, - { id: 'rd', label: 'RD (Recurring Deposit)' } + // Fixed disbursement, fixed tenure, EMI-based term credit facilities + loans: [ + { id: 'term', label: 'Term Loan / Long Term Loan' }, + { id: 'personal', label: 'Personal Loan' }, + { id: 'housing', label: 'Housing Loan' }, + { id: 'vehicle', label: 'Vehicle Loan' }, + { id: 'education', label: 'Education Loan' }, + { id: 'business', label: 'Business / MSME Term Loan' }, + { id: 'gold_emi', label: 'Gold EMI Loan' } ] }; - /** Default GL per product type group */ - private readonly glDefaultMap: Record = { - loans: 'asset', - advanced: 'asset' - }; - get availableSubGroups() { const group = this.loanProductDetailsForm.get('productTypeGroup')?.value; return group ? (this.productTypeSubGroups[group] ?? []) : []; } - get glOptions(): string[] { - return [ - 'asset', - 'liability' - ]; - } - - assetAccountOptions: any[] = []; - liabilityAccountOptions: any[] = []; - - get availableGlAccounts(): any[] { - const type = this.loanProductDetailsForm.get('glClassification')?.value; - if (type === 'asset') return this.assetAccountOptions; - if (type === 'liability') return this.liabilityAccountOptions; - return []; - } - - get glClassificationLabel(): string { - const type = this.loanProductDetailsForm.get('glClassification')?.value; - return type === 'liability' ? 'Liability' : 'Asset'; - } - - get selectedGroupLabel(): string { - const group = this.loanProductDetailsForm.get('productTypeGroup')?.value; - return this.productTypeGroups.find((g) => g.id === group)?.label ?? ''; - } - readonly yesNoOptions = [ { value: true, label: 'YES' }, { value: false, label: 'NO' } @@ -150,21 +144,36 @@ export class LoanProductDetailsStepComponent implements OnInit { closeDate: [''], productTypeGroup: [''], productTypeSubGroup: [''], - glClassification: ['asset'], - glAccount: [''], debitIntCalculation: [false], separatePenalInterest: [false], creditIntCalculation: [false], subAccountTypeBalance: [false], finalIntRounding: [false], - roundingUpTo: [null] + roundingUpTo: [null], + + // General Information (legacy Page 1 header fields) + accountTypeCode: [''], + micrTransactionCode: [''], + reservedEcsSerialNumber: [''], + reverseEcsNumber: [''], + lockChequeInfoEnabled: ['NO'], + lockPageTwoInfoEnabled: ['NO'], + computerizationDate: [''], + chequePrintDescription: [''], + posAccountTypeDescription: [''], + pfmsAccountType: [''], + renewalDateAddMonths: [''], + renewalGraceDays: [''], + documentRenewalDateAddMonths: [''], + + // PPS Limit & Write Off Details + ppsLimit: [''], + isWriteOffAccountType: ['NO'], + writeOffAccountTypeCode: [''] }); - // Auto-set GL based on product type group - this.loanProductDetailsForm.get('productTypeGroup')?.valueChanges.subscribe((group: string) => { - const defaultVal = this.glDefaultMap[group] ?? 'asset'; - this.loanProductDetailsForm.get('glClassification')?.setValue(defaultVal); - this.loanProductDetailsForm.get('glAccount')?.setValue(''); + this.loanProductDetailsForm.get('productTypeSubGroup')?.valueChanges.subscribe((subGroup: string) => { + this.productSubGroupChange.emit(subGroup); }); } diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.html b/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.html index 5853a8895..74a9d2b63 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.html +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.html @@ -235,209 +235,361 @@
- -
-
- -

Cheque Book Settings

-
-
- - Cheque Book Issue Enabled - - YES - NO - - + + @if (showChequeBookSettings) { + + + + + Cheque Book Settings + + +
+ + Cheque Book Issue Enabled + + YES + NO + + - - Cheque Validation Required - - YES - NO - - + + Cheque Validation Required + + YES + NO + + - - Is First Cheque Book Free - - YES - NO - - + + Is First Cheque Book Free + + YES + NO + + - - Cheque Printing Account Type - - Savings Bank - Current Account - Cash Credit - Overdraft - - + + Cheque Printing Account Type + + Savings Bank + Current Account + Cash Credit + Overdraft + + - - Allow Withdrawal Slip Usage - - YES - NO - - + + Allow Withdrawal Slip Usage + + YES + NO + + - - Maintain Cheque Book Stock Registry - - YES - NO - - + + Maintain Cheque Book Stock Registry + + YES + NO + + - - Free Cheque Books Per Year - - + + Free Cheque Books Per Year + + - - Allow Credit By Cheque Number - - YES - NO - - + + Allow Credit By Cheque Number + + YES + NO + + - - Credit Cheque Validation Required - - YES - NO - - + + Credit Cheque Validation Required + + YES + NO + + - - Grace Days For Stock Statement - - -
-
+ + Grace Days For Stock Statement + + +
+ + } - -
-
- -

Additional Product Settings

-
-
- - Account Type Active For Transactions - - YES - NO - - + + + + + Additional Product Settings + + +
+ + Account Type Active For Transactions + + YES + NO + + - - Sub Type Activity Enabled - - YES - NO - - + + Sub Type Activity Enabled + + YES + NO + + - - Account Opening Charges - - + + Account Opening Charges + + - - Maximum Gold Loan Limit - - + + Maximum Gold Loan Limit + + - - Last Account Number Opened - - + + Gold Loan [Packet No.] With Year? + + YES + NO + + - - Customer Termination Allowed - - YES - NO - - + + Last Account Number Opened + + - - Charges For Cash Credit Above Limit - - + + Customer Termination Allowed + + YES + NO + + - - Death Interest GL Account - - + + Charges For Cash Credit Above Limit + + - - Starting Ledger Number - - + + Death Interest GL Account + + - - Ending Ledger Number - - + + Starting Ledger Number + + - - Current Ledger Number - - + + Ending Ledger Number + + - - Remittance Account Number - - + + Current Ledger Number + + - - Is Non Resident Indian Account - - YES - NO - - + + Remittance Account Number + + - - Debit Clearing GL Account - - + + Is Non Resident Indian Account + + YES + NO + + - - Missed Call Alert Service Active - - YES - NO - - + + Debit Clearing GL Account + + - - Standing Instruction Charge GL Account - - + + Missed Call Alert Service Active + + YES + NO + + - - Standing Instruction Debit Charge Skip Option - - Skip Always - Skip on First Failure - Never Skip - Retry after 24 Hours - - + + Standing Instruction Charge GL Account + + - - Opening Balance Multiplier For Remittance Charges - - -
-
+ + Standing Instruction Debit Charge Skip Option + + Skip Always + Skip on First Failure + Never Skip + Retry after 24 Hours + + + + + Opening Balance Multiplier For Remittance Charges + + + + + A/c Move To InOperative A/c + + YES + NO + + + + + Generate GL Diff Entry + + YES + NO + + + + + Sub Type Wise GL Balance Gen + + YES + NO + + + + + Want To Validation While Deleting Debit Entry + + YES + NO + + + + + Want To RC File Concept + + YES + NO + + + + + A/c Close With Zero Bal. In Open Day Process + + YES + NO + + + + + A/c Close When Bal. Zero At Subled Tran Entry + + YES + NO + + + + + Lmt.Enh/Ag.Clg Screen Display + + YES + NO + + + + + Advance Int. Param In Ledger + + YES + NO + + + + + Vehicle Detail In Master + + YES + NO + + + + + Deleted Chq. Issue + + YES + NO + + + + + DP Reduce In Doc. Renewal Date + + YES + NO + + + + + DP Reduce In Renewal Date + + YES + NO + + + + + Auto Close Day-End + + YES + NO + + + + + Loan Rate From Master + + YES + NO + + + + + Cheque Short Name + + + + + Statement Print + + YES + NO + + + + + NESL Code + + +
+ +
@@ -754,6 +906,85 @@ Add Penal Interest Rate + + + Atyp14 Simple Int. + + YES + NO + + + + + FDOD Margin Type + + + + + Check Master Detail Edited (Passing Pend.) + + YES + NO + + + + + Credit/Debit Int. Calc. Separate + + YES + NO + + + + + On Time Interest Provision + + YES + NO + + + + + Check Against Clearing + + YES + NO + + + + + GST On Penalty + + YES + NO + + + + + Penalty Int. Grace Days + + + + + Over Drawn Int. Rate + + + + + Calculate Daily Limit Enhancement (TOD) + + YES + NO + + + + + FDOD Multiple Int. Rate + + YES + NO + +
@@ -801,6 +1032,306 @@ + + @if (showChannelLimits) { + + + + + Channel & Transaction Limits + + +
+ + Is Mobile App? + + YES + NO + + + + + Is ATM? + + YES + NO + + + + @if (loanProductSettingsForm.value.isAtmEnabled === 'YES') { + + ATM Yearly Charge? + + YES + NO + + + + + ATM Min. Balance + + + } + + + Email Active? + + YES + NO + + + + + Is IMPS? + + YES + NO + + + + + Is UPI? + + YES + NO + + + + + Is POS? + + YES + NO + + + + + Is BBPS? + + YES + NO + + + + + Inter Bank Limit (Per Day) + + + + + Inter Bank Limit (Per Transaction) + + + + + NEFT/RTGS Limit (Per Day) + + + + + NEFT/RTGS Limit (Per Transaction) + + + + + NEFT Cutoff Limit + + + + + RTGS Cutoff Limit + + + + + NEFT/RTGS Min. Balance + + + + + Is Charge Req. NEFT/RTGS (CBS)? + + YES + NO + + + + + Is Charge Req. NEFT/RTGS (Mobile)? + + YES + NO + + + + @if (loanProductSettingsForm.value.isImpsEnabled === 'YES') { + + IMPS Limit (Per Day) + + + + + IMPS Limit (Per Transaction) + + + + + IMPS Limit (Per Month) + + + + + IMPS Min. Limit + + + + + IMPS Monthly Transaction Count + + + } +
+
+ } + + @if ( + showChannelLimits && + (loanProductSettingsForm.value.isPosEnabled === 'YES' || loanProductSettingsForm.value.isAtmEnabled === 'YES') + ) { + + + + + POS Facility & ATM CSV Settings + + +
+ + Max Per Transaction Limit (ATM) + + + + + Max Day Transaction Limit (ATM) + + + + + Max Per Transaction Limit (POS) + + + + + Max Day Transaction Limit (POS) + + + + + Max Per Transaction Limit (ECOM) + + + + + Max Day Transaction Limit (ECOM) + + + + + Max Per Transaction Limit (UPI) + + + + + Max Day Transaction Limit (UPI) + + + + + ATM CSV Product Code + + + + + ATM CSV Type Code + + +
+
+ } + + + + + + Auto Interest Post Parameters + + +
+ + Auto Int. Post Type + + Monthly + Quarterly + Half Yearly + Yearly + + + + + Auto Int. Post When + + Month End + Fix Day + + + + @if (loanProductSettingsForm.value.autoInterestPostWhen === 'FIX_DAY') { + + Fix Day + + + } + + + Auto Last Int. Date + + +
+
+ + @if (showForeclosureSettings) { + + + + + Foreclosure / Early Account Closure + + +
+ + Calculate Early A/c Close Charge? + + YES + NO + + + + @if (loanProductSettingsForm.value.calculateEarlyAccountCloseCharge === 'YES') { + + Early A/c Close Charge + + + + + Early A/c Close Period (In Months) + + + } +
+
+ } +
+
@@ -883,6 +1414,11 @@ + + Grace Days After Overdue For Moratorium A/c + + + {{ 'labels.inputs.Delinquency Bucket' | translate }} diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.scss b/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.scss index 50934aecc..6390274af 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.scss +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.scss @@ -50,8 +50,9 @@ &__body { display: grid; grid-template-columns: repeat(2, 1fr); - gap: 4px 16px; - padding: 16px 24px; + align-items: start; + gap: 18px 16px; + padding: 20px 24px; @media (width <= 600px) { grid-template-columns: 1fr; @@ -83,6 +84,26 @@ grid-column: span 3; } +.lps-narrow { + max-width: 160px; +} + +.lps-accordion { + margin-top: 16px; + + .lps-section__body { + padding: 16px 24px 20px; + } + + mat-panel-title { + display: flex; + align-items: center; + gap: 10px; + font-size: 14px; + font-weight: 600; + } +} + .lps-checkbox-row { display: flex; align-items: center; diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.ts b/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.ts index d230afc79..da9fee4c7 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.ts +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.ts @@ -21,6 +21,12 @@ import { ProcessingStrategyService } from '../../services/processing-strategy.se import { MatTooltip } from '@angular/material/tooltip'; import { MatCheckbox } from '@angular/material/checkbox'; import { MatIconButton } from '@angular/material/button'; +import { + MatAccordion, + MatExpansionPanel, + MatExpansionPanelHeader, + MatExpansionPanelTitle +} from '@angular/material/expansion'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; @@ -34,6 +40,10 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; MatTooltip, MatCheckbox, MatIconButton, + MatAccordion, + MatExpansionPanel, + MatExpansionPanelHeader, + MatExpansionPanelTitle, FaIconComponent, ReactiveFormsModule ] @@ -45,8 +55,41 @@ export class LoanProductSettingsStepComponent implements OnInit { @Input() toEdit: boolean; @Input() loanProductsTemplate: any; @Input() isLinkedToFloatingInterestRates: UntypedFormControl; + @Input() productSubGroup: string; @Output() advancePaymentStrategy = new EventEmitter(); + /** Sub-groups (from Details step) that are current-account-linked, channel-heavy products */ + readonly channelEnabledSubGroups = [ + 'cc', + 'overdraft' + ]; + + /** Sub-groups that are fixed-tenure, EMI-based term loans (foreclosure applies to these) */ + readonly termLoanSubGroups = [ + 'term', + 'personal', + 'housing', + 'vehicle', + 'education', + 'business', + 'gold_emi' + ]; + + get showChannelLimits(): boolean { + return !this.productSubGroup || this.channelEnabledSubGroups.includes(this.productSubGroup); + } + + get showChequeBookSettings(): boolean { + return !this.productSubGroup || ![ + 'gold', + 'gold_emi' + ].includes(this.productSubGroup); + } + + get showForeclosureSettings(): boolean { + return !this.productSubGroup || this.termLoanSubGroups.includes(this.productSubGroup); + } + loanProductSettingsForm: UntypedFormGroup; amortizationTypeData: any; @@ -366,6 +409,24 @@ export class LoanProductSettingsStepComponent implements OnInit { standingInstructionChargeGLAccount: [''], standingInstructionDebitChargeSkipOption: [''], openingBalanceMultiplierForRemittanceCharges: [''], + accountMoveToInoperativeEnabled: ['NO'], + generateGlDiffEntryEnabled: ['NO'], + subTypeWiseGlBalanceGenerationEnabled: ['NO'], + validateBeforeDeletingDebitEntryEnabled: ['NO'], + rcFileConceptEnabled: ['NO'], + accountCloseZeroBalanceInOpenDayProcess: ['NO'], + accountCloseZeroBalanceAtSubledgerTranEntry: ['NO'], + limitEnhancementAgainstClearingScreenDisplayEnabled: ['NO'], + advanceInterestParameterInLedgerEnabled: ['NO'], + vehicleDetailInMasterEnabled: ['NO'], + deletedChequeIssueEnabled: ['NO'], + dpReduceInDocumentRenewalDateEnabled: ['NO'], + dpReduceInRenewalDateEnabled: ['NO'], + autoCloseAtDayEndEnabled: ['NO'], + loanRateFromMasterEnabled: ['NO'], + chequeShortName: [''], + statementPrintEnabled: ['YES'], + neslCode: [''], // Interest Related Parameters drawingPowerAndLimitGenerationProcedure: ['NORMAL D.P. ENTRY IS CONSIDER'], @@ -385,7 +446,7 @@ export class LoanProductSettingsStepComponent implements OnInit { penaltyInterestDateDifferentThanRegularInterest: ['YES'], fixedDepositOverdraftCertificateSortOrder: ['ORDER ON INTEREST RATE'], useDocumentSubmissionDateForInterest: ['NO'], - loanManagementSystemRenewalPenaltyActive: [''], + loanManagementSystemRenewalPenaltyActive: ['NO'], minimumNormalInterestAmount: [''], minimumInterestCalculationMethod: [''], minimumAgainstClearingInterestAmount: [''], @@ -409,6 +470,18 @@ export class LoanProductSettingsStepComponent implements OnInit { nonPerformingAssetPenalInterestRate: [''], fixedDepositOverdraftPenalInterestRateUpdateInBranchProcess: ['YES'], addPenalInterestRate: [''], + atyp14SimpleInterestEnabled: ['NO'], + fixedDepositOverdraftMarginType: [''], + checkMasterDetailEditedPassingPendingEnabled: ['NO'], + creditDebitInterestCalculationSeparateEnabled: ['NO'], + onTimeInterestProvisionEnabled: ['NO'], + checkAgainstClearingEnabled: ['NO'], + gstOnPenaltyEnabled: ['NO'], + penaltyInterestGraceDays: [''], + overdrawnInterestRate: [''], + calculateDailyLimitEnhancementTodEnabled: ['NO'], + fixedDepositOverdraftMultipleInterestRateEnabled: ['NO'], + graceDaysAfterOverdueForMoratorium: [''], // Credit Bureau Settings (CIBIL) cibilAccountType: [''], @@ -426,7 +499,60 @@ export class LoanProductSettingsStepComponent implements OnInit { isFloatingRate: [false], foreclosureChargesApplicable: ['NO'], keyFactStatementEnabled: [true], - annualPercentageRateCalculationEnabled: [true] + annualPercentageRateCalculationEnabled: [true], + + // Channel & Transaction Limits + isMobileAppEnabled: ['NO'], + isAtmEnabled: ['NO'], + atmYearlyChargeEnabled: ['NO'], + atmMinimumBalance: [''], + emailActiveEnabled: ['NO'], + isImpsEnabled: ['NO'], + isUpiEnabled: ['NO'], + isPosEnabled: ['NO'], + isBbpsEnabled: ['NO'], + interBankLimitPerDay: [''], + interBankLimitPerTransaction: [''], + neftRtgsLimitPerDay: [''], + neftRtgsLimitPerTransaction: [''], + neftCutoffLimit: [''], + rtgsCutoffLimit: [''], + neftRtgsMinimumBalance: [''], + isChargeRequiredNeftRtgsCbs: [''], + isChargeRequiredNeftRtgsMobile: [''], + impsLimitPerDay: [''], + impsLimitPerTransaction: [''], + impsLimitPerMonth: [''], + impsMinLimit: [''], + impsMonthlyTransactionCount: [''], + + // POS Facility + maxPerTransactionLimitAtm: [''], + maxDayTransactionLimitAtm: [''], + maxPerTransactionLimitPos: [''], + maxDayTransactionLimitPos: [''], + maxPerTransactionLimitEcom: [''], + maxDayTransactionLimitEcom: [''], + maxPerTransactionLimitUpi: [''], + maxDayTransactionLimitUpi: [''], + + // ATM CSV File Related Other Details + atmCsvProductCode: [''], + atmCsvTypeCode: [''], + + // Auto Interest Post Parameters + autoInterestPostType: [''], + autoInterestPostWhen: [''], + autoInterestPostFixDay: [''], + autoLastInterestDate: [''], + + // Foreclosure / Early Account Closure + calculateEarlyAccountCloseCharge: ['NO'], + earlyAccountCloseCharge: [''], + earlyAccountClosePeriodInMonths: [''], + + // Gold Loan Specific + goldLoanPacketNumberWithYearEnabled: ['NO'] }); } diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.html b/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.html index 6e765fbe3..7b1940a68 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.html +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.html @@ -264,90 +264,56 @@ }
- +
-

Interest Rate Slabs

+

Interest Rate Detail

-
- -
- - -
- - -
- @for (genGroup of slabGroups; track $index) { -
- {{ interestSlabDefinitions[$index].label }} -
- -
- Gen -
- - % -
-
- -
- Spl -
- - % -
-
-
-
- } -
- - -
- - @if (fixedRateGroup.get('hasFixed').value) { -
- - % -
- } -
+
+ + + + + + + + + + + + + + + + + + @for (row of interestRateDetailGroups; track $index) { + + + + + + + + + + } + +
Interest TypeCalculationNormal CategorySpecial CategoryPeriod
Mini. RateMaxi. RateMini. RateMaxi. Rate
{{ interestRateDetailTypes[$index] }} + + + +
diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.scss b/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.scss index bda5c6392..d4f7af28d 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.scss +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.scss @@ -199,175 +199,42 @@ $shadow-hover: 0 4px 12px rgb(37 99 235 / 10%); padding: 8px 4px; } -// ─── Interest Rate Slabs — Option C (2-column grid) ────────────────────────── -.lpt-slab-c { +// ─── Interest Rate Detail table (legacy Page 1 grid) ───────────────────────── +.lpt-ird-table-wrap { padding: 16px 24px 20px; - display: flex; - flex-direction: column; - gap: 0; + overflow-x: auto; } -// Particular row -.lpt-slab-c-particular { - display: flex; - align-items: center; - gap: 14px; - padding-bottom: 14px; - border-bottom: 1px solid $border; - margin-bottom: 12px; - flex-wrap: wrap; -} - -.lpt-slab-c-particular-label { - font-size: 12px; - font-weight: 700; - color: $text-secondary; - text-transform: uppercase; - letter-spacing: 0.05em; - white-space: nowrap; -} - -.lpt-slab-c-name-input { - flex: 1; - max-width: 320px; - padding: 7px 12px; - border: 1px solid $border; - border-radius: 8px; - font-size: 13.5px; - font-weight: 600; - color: $text-primary; - background: $surface; - outline: none; - transition: - border-color 0.15s, - box-shadow 0.15s; - - &::placeholder { - color: #b0b8c4; - font-weight: 400; - } - - &:focus { - border-color: $primary; - box-shadow: 0 0 0 3px rgb(37 99 235 / 10%); - } -} - -// General / Special tab toggle -.lpt-slab-tabs { - display: flex; - gap: 6px; - margin-left: auto; -} - -.lpt-slab-tab { - display: inline-flex; - align-items: center; - gap: 6px; - padding: 6px 16px; - border: 1.5px solid $border; - border-radius: 20px; - background: $surface; +.lpt-ird-table { + width: 100%; + border-collapse: collapse; font-size: 12.5px; - font-weight: 600; - color: $text-secondary; - cursor: pointer; - transition: all 0.15s; - i { + th, + td { + border: 1px solid $border; + padding: 6px 8px; + text-align: center; + } + + thead th { + background: $surface-alt; + font-weight: 700; + color: $text-secondary; + text-transform: uppercase; + letter-spacing: 0.03em; font-size: 11px; } - - &:hover { - border-color: $primary; - color: $primary; - } - - &--active { - background: $primary; - border-color: $primary; - color: $surface; - box-shadow: 0 2px 8px rgb(37 99 235 / 25%); - } } -// 2-column slab grid -.lpt-slab-c-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 8px 16px; - - @media (width <= 540px) { - grid-template-columns: 1fr; - } -} - -.lpt-slab-c-item { - display: flex; - align-items: center; - justify-content: space-between; - gap: 10px; - padding: 8px 12px; - border: 1px solid $border; - border-radius: 8px; - background: $surface; - transition: - border-color 0.15s, - box-shadow 0.15s; - - &:focus-within { - border-color: $primary; - box-shadow: 0 0 0 3px rgb(37 99 235 / 8%); - } -} - -// General + Special pair inside each card -.lpt-slab-c-rate-pair { - display: flex; - gap: 8px; - align-items: center; -} - -.lpt-slab-c-rate-field { - display: flex; - align-items: center; - gap: 4px; -} - -.lpt-slab-c-rate-label { - font-size: 10px; - font-weight: 700; - color: $primary; - background: #eff6ff; - padding: 2px 5px; - border-radius: 4px; +.lpt-ird-type { + text-align: left !important; + font-weight: 600; + color: $text-primary; white-space: nowrap; - - &--special { - color: #92400e; - background: #fef9c3; - } } -.lpt-slab-c-range { - font-size: 12.5px; - font-weight: 500; - color: $text-label; - flex: 1; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -// Input + suffix wrapper -.lpt-slab-c-input-wrap { - display: flex; - align-items: center; - gap: 4px; - flex-shrink: 0; -} - -.lpt-slab-c-input { +.lpt-ird-input { width: 70px; padding: 4px 6px; border: 1px solid $border; @@ -379,79 +246,26 @@ $shadow-hover: 0 4px 12px rgb(37 99 235 / 10%); background: $surface-alt; outline: none; transition: border-color 0.15s; - appearance: textfield; - - &::-webkit-outer-spin-button, - &::-webkit-inner-spin-button { - appearance: none; - } &:focus { border-color: $primary; background: $primary-light; } - - &--fixed { - width: 90px; - } } -.lpt-slab-c-suffix { - font-size: 12px; - font-weight: 700; - color: $text-secondary; - user-select: none; - - &--special { - color: #92400e; - } -} - -.lpt-slab-c-input--special { - &:focus { - border-color: #f59e0b; - background: #fef9c3; - } -} - -.lpt-slab-c-error { - font-size: 10px; - color: #ef4444; -} - -// Fixed Interest Rate row (below grid) -.lpt-slab-c-fixed { - display: flex; - align-items: center; - gap: 20px; - margin: 12px -24px -20px; - padding: 12px 16px; - border-top: 2px dashed $primary-border; - background: $primary-light; - border-radius: 0 0 $radius-card $radius-card; - padding-left: 24px; - padding-right: 24px; -} - -.lpt-slab-c-fixed-toggle { - display: flex; - align-items: center; - gap: 8px; - cursor: pointer; +.lpt-ird-select { + width: 100%; + min-width: 90px; + padding: 4px 6px; + border: 1px solid $border; + border-radius: 6px; font-size: 13px; font-weight: 600; - color: $primary; - user-select: none; + color: $text-primary; + background: $surface; + outline: none; - i { - font-size: 12px; - opacity: 0.7; + &:focus { + border-color: $primary; } } - -.lpt-slab-c-checkbox { - accent-color: $primary; - width: 15px; - height: 15px; - cursor: pointer; -} diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.ts b/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.ts index 9e457b6d8..baf888790 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.ts +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-terms-step/loan-product-terms-step.component.ts @@ -57,24 +57,23 @@ export class LoanProductTermsStepComponent implements OnInit, OnChanges { repaymentFrequencyTypeData: any; repaymentStartDateTypeOptions: any; - readonly interestSlabDefinitions = [ - { label: 'Upto 10,000', maxAmount: 10000 }, - { label: 'Upto 25,000', maxAmount: 25000 }, - { label: 'Upto 1,00,000', maxAmount: 100000 }, - { label: 'Upto 2,00,000', maxAmount: 200000 }, - { label: 'Upto 5,00,000', maxAmount: 500000 }, - { label: 'Upto 10,00,000', maxAmount: 1000000 }, - { label: 'Upto 15,00,000', maxAmount: 1500000 }, - { label: 'Upto 20,00,000', maxAmount: 2000000 }, - { label: 'Upto 25,00,000', maxAmount: 2500000 }, - { label: 'More than 25,00,000', maxAmount: null } + // Legacy "Interest Rate Detail" table — 4 interest types x Normal/Special category x Min/Max Rate x Period + readonly interestRateDetailTypes = [ + 'Normal Debit', + 'Normal Credit', + 'Against Clearing', + 'Penalty' ]; - interestRateSlabsArray: FormArray; - specialSlabsArray: FormArray; - fixedRateGroup: FormGroup; - particularLabel = new FormControl(''); - activeSlabTab: 'general' | 'special' = 'general'; + readonly interestRateDetailPeriods = [ + 'DAILY', + 'MONTHLY', + 'QUARTERLY', + 'HALF YEARLY', + 'YEARLY' + ]; + + interestRateDetailArray: FormArray; constructor() { this.createLoanProductTermsForm(); @@ -134,35 +133,32 @@ export class LoanProductTermsStepComponent implements OnInit, OnChanges { } createLoanProductTermsForm() { - this.interestRateSlabsArray = new FormArray( - this.interestSlabDefinitions.map( + this.interestRateDetailArray = new FormArray( + this.interestRateDetailTypes.map( () => new FormGroup({ - interestRate: new FormControl(null, [ + calculation: new FormControl(false), + normalMinRate: new FormControl(null, [ Validators.min(0), Validators.max(100) - ]) + ]), + normalMaxRate: new FormControl(null, [ + Validators.min(0), + Validators.max(100) + ]), + specialMinRate: new FormControl(null, [ + Validators.min(0), + Validators.max(100) + ]), + specialMaxRate: new FormControl(null, [ + Validators.min(0), + Validators.max(100) + ]), + period: new FormControl('') }) ) ); - this.specialSlabsArray = new FormArray( - this.interestSlabDefinitions.map( - () => - new FormGroup({ - interestRate: new FormControl(null, [ - Validators.min(0), - Validators.max(100) - ]) - }) - ) - ); - - this.fixedRateGroup = new FormGroup({ - hasFixed: new FormControl(false), - fixedAmount: new FormControl({ value: null, disabled: true }, [Validators.min(0)]) - }); - this.loanProductTermsForm = this.formBuilder.group({ isLinkedToFloatingInterestRates: [false], allowApprovedDisbursedAmountsOverApplied: [false], @@ -287,15 +283,6 @@ export class LoanProductTermsStepComponent implements OnInit, OnChanges { } }); - this.fixedRateGroup.get('hasFixed').valueChanges.subscribe((hasFixed: boolean) => { - if (hasFixed) { - this.fixedRateGroup.get('fixedAmount').enable(); - } else { - this.fixedRateGroup.get('fixedAmount').disable(); - this.fixedRateGroup.get('fixedAmount').setValue(null); - } - }); - this.zeroInterest.valueChanges.subscribe((zeroInterest) => { if (zeroInterest) { this.loanProductTermsForm.get('minInterestRatePerPeriod').patchValue(0); @@ -322,16 +309,8 @@ export class LoanProductTermsStepComponent implements OnInit, OnChanges { }); } - get slabGroups(): FormGroup[] { - return this.interestRateSlabsArray.controls as FormGroup[]; - } - - get activeSlabGroups(): FormGroup[] { - return this.interestRateSlabsArray.controls as FormGroup[]; - } - - get specialSlabGroups(): FormGroup[] { - return this.specialSlabsArray.controls as FormGroup[]; + get interestRateDetailGroups(): FormGroup[] { + return this.interestRateDetailArray.controls as FormGroup[]; } get loanProductTerms() { @@ -349,15 +328,10 @@ export class LoanProductTermsStepComponent implements OnInit, OnChanges { minInterestRatePerPeriod: normalizeDecimal(formValue.minInterestRatePerPeriod), interestRatePerPeriod: normalizeDecimal(formValue.interestRatePerPeriod), maxInterestRatePerPeriod: normalizeDecimal(formValue.maxInterestRatePerPeriod), - interestRateSlabs: this.interestRateSlabsArray.getRawValue().map((slab, i) => ({ - maxAmount: this.interestSlabDefinitions[i].maxAmount, - label: this.interestSlabDefinitions[i].label, - interestRate: slab.interestRate - })), - fixedRate: (() => { - const fr = this.fixedRateGroup.getRawValue(); - return fr.hasFixed ? fr.fixedAmount : null; - })() + interestRateDetail: this.interestRateDetailArray.getRawValue().map((row, i) => ({ + interestType: this.interestRateDetailTypes[i], + ...row + })) }; } diff --git a/src/app/products/loan-products/loan-products.ts b/src/app/products/loan-products/loan-products.ts index 884b0a087..2d31b2b24 100644 --- a/src/app/products/loan-products/loan-products.ts +++ b/src/app/products/loan-products/loan-products.ts @@ -9,6 +9,246 @@ import { Injectable, inject } from '@angular/core'; import { SettingsService } from 'app/settings/settings.service'; +// Custom, UI-only fields grafted onto the loan product form to mirror the legacy +// "Account Type Creation" screen. Fineract's LoanProductDataValidator rejects any +// unrecognised parameter, so these are stripped from the payload until a backend +// mechanism (e.g. a linked Data Table) exists to persist them. +const CUSTOM_UI_ONLY_FIELDS: string[] = [ + // Details step — classification & legacy header fields + 'productTypeGroup', + 'productTypeSubGroup', + 'debitIntCalculation', + 'separatePenalInterest', + 'creditIntCalculation', + 'subAccountTypeBalance', + 'finalIntRounding', + 'roundingUpTo', + 'accountTypeCode', + 'micrTransactionCode', + 'reservedEcsSerialNumber', + 'reverseEcsNumber', + 'lockChequeInfoEnabled', + 'lockPageTwoInfoEnabled', + 'computerizationDate', + 'chequePrintDescription', + 'posAccountTypeDescription', + 'pfmsAccountType', + 'renewalDateAddMonths', + 'documentRenewalDateAddMonths', + 'ppsLimit', + 'isWriteOffAccountType', + 'writeOffAccountTypeCode', + 'renewalGraceDays', + // Settings step — Cheque Book Settings + 'chequeBookIssueEnabled', + 'chequeValidationRequired', + 'isFirstChequeBookFree', + 'chequePrintingAccountType', + 'allowWithdrawalSlipUsage', + 'maintainChequeBookStockRegistry', + 'freeChequeBooksPerYear', + 'allowCreditByChequeNumber', + 'creditChequeValidationRequired', + 'graceDaysForStockStatement', + // Settings step — Additional Product Settings + 'accountTypeActiveForTransactions', + 'subTypeActivityEnabled', + 'accountOpeningCharges', + 'maximumGoldLoanLimit', + 'lastAccountNumberOpened', + 'customerTerminationAllowed', + 'chargesForCashCreditAboveLimit', + 'deathInterestGLAccount', + 'startingLedgerNumber', + 'endingLedgerNumber', + 'currentLedgerNumber', + 'remittanceAccountNumber', + 'isNonResidentIndianAccount', + 'debitClearingGLAccount', + 'missedCallAlertServiceActive', + 'standingInstructionChargeGLAccount', + 'standingInstructionDebitChargeSkipOption', + 'openingBalanceMultiplierForRemittanceCharges', + 'goldLoanPacketNumberWithYearEnabled', + 'accountMoveToInoperativeEnabled', + 'generateGlDiffEntryEnabled', + 'subTypeWiseGlBalanceGenerationEnabled', + 'validateBeforeDeletingDebitEntryEnabled', + 'rcFileConceptEnabled', + 'accountCloseZeroBalanceInOpenDayProcess', + 'accountCloseZeroBalanceAtSubledgerTranEntry', + 'limitEnhancementAgainstClearingScreenDisplayEnabled', + 'advanceInterestParameterInLedgerEnabled', + 'vehicleDetailInMasterEnabled', + 'deletedChequeIssueEnabled', + 'dpReduceInDocumentRenewalDateEnabled', + 'dpReduceInRenewalDateEnabled', + 'autoCloseAtDayEndEnabled', + 'loanRateFromMasterEnabled', + 'chequeShortName', + 'statementPrintEnabled', + 'neslCode', + // Settings step — Interest Related Parameters + 'drawingPowerAndLimitGenerationProcedure', + 'advancesInterestCalculationMethod', + 'againstInterestCalculationEnabled', + 'dayWiseAgainstClearingInterestRounding', + 'interestCalculationOneFourthMethod', + 'againstClearingInterestProcedureType', + 'considerDebitClosingAmountForAgainstClearing', + 'interestRoundingMethod', + 'penaltyInterestCalculationEnabled', + 'penaltyInterestCalculationMethod', + 'penaltyInterestProcedureNumber', + 'overdrawnInterestCalculationMethod', + 'calculateOverdrawnInterestAfterRenewal', + 'interestOnCreditBalance', + 'penaltyInterestDateDifferentThanRegularInterest', + 'fixedDepositOverdraftCertificateSortOrder', + 'useDocumentSubmissionDateForInterest', + 'loanManagementSystemRenewalPenaltyActive', + 'minimumNormalInterestAmount', + 'minimumInterestCalculationMethod', + 'minimumAgainstClearingInterestAmount', + 'limitIncreaseUptoInterestAmountInInterestCalculation', + 'minimumPenaltyInterestAmount', + 'daysForLimitIncreaseUptoInterestAmount', + 'additionalInterestRateForFixedDepositOverdraft', + 'considerDdPayorderInAgainstClearingInterestCalculation', + 'graceDaysAfterRenewDate', + 'applyUndebitedInterestConceptEnabled', + 'interestRegisterPrintFormatType', + 'normalGraceDaysAfterOverdue', + 'allowAgainstClearingEntry', + 'allowNoBalanceEntry', + 'fixedDepositOverdraftPenaltyInterestCombinedWithNormalInterest', + 'allowNoBalanceEntryWithPassword', + 'undebitedSimpleInterestAccountWise', + 'dailyInterestCalculationEnabled', + 'dailyInterestCalculationStartDate', + 'nonPerformingAssetPenalInterestRateUpdate', + 'nonPerformingAssetPenalInterestRate', + 'fixedDepositOverdraftPenalInterestRateUpdateInBranchProcess', + 'addPenalInterestRate', + 'atyp14SimpleInterestEnabled', + 'fixedDepositOverdraftMarginType', + 'checkMasterDetailEditedPassingPendingEnabled', + 'creditDebitInterestCalculationSeparateEnabled', + 'onTimeInterestProvisionEnabled', + 'checkAgainstClearingEnabled', + 'gstOnPenaltyEnabled', + 'penaltyInterestGraceDays', + 'overdrawnInterestRate', + 'calculateDailyLimitEnhancementTodEnabled', + 'fixedDepositOverdraftMultipleInterestRateEnabled', + 'graceDaysAfterOverdueForMoratorium', + // Settings step — Credit Bureau Settings (CIBIL) + 'cibilAccountType', + 'cibilCommercialAccountType', + 'highmarkAccountType', + 'highmarkCommercialAccountType', + 'experianAccountType', + 'experianCommercialAccountType', + 'equifaxAccountType', + 'equifaxCommercialAccountType', + // Settings step — RBI Compliance & Product Category + 'loanProductCategory', + 'penalChargeMethod', + 'isFloatingRate', + 'foreclosureChargesApplicable', + 'keyFactStatementEnabled', + 'annualPercentageRateCalculationEnabled', + // Settings step — Channel & Transaction Limits + 'isMobileAppEnabled', + 'isAtmEnabled', + 'atmYearlyChargeEnabled', + 'atmMinimumBalance', + 'emailActiveEnabled', + 'isImpsEnabled', + 'isUpiEnabled', + 'isPosEnabled', + 'isBbpsEnabled', + 'interBankLimitPerDay', + 'interBankLimitPerTransaction', + 'neftRtgsLimitPerDay', + 'neftRtgsLimitPerTransaction', + 'neftCutoffLimit', + 'rtgsCutoffLimit', + 'neftRtgsMinimumBalance', + 'isChargeRequiredNeftRtgsCbs', + 'isChargeRequiredNeftRtgsMobile', + 'impsLimitPerDay', + 'impsLimitPerTransaction', + 'impsLimitPerMonth', + 'impsMinLimit', + 'impsMonthlyTransactionCount', + // Settings step — POS Facility & ATM CSV Settings + 'maxPerTransactionLimitAtm', + 'maxDayTransactionLimitAtm', + 'maxPerTransactionLimitPos', + 'maxDayTransactionLimitPos', + 'maxPerTransactionLimitEcom', + 'maxDayTransactionLimitEcom', + 'maxPerTransactionLimitUpi', + 'maxDayTransactionLimitUpi', + 'atmCsvProductCode', + 'atmCsvTypeCode', + // Settings step — Auto Interest Post Parameters + 'autoInterestPostType', + 'autoInterestPostWhen', + 'autoInterestPostFixDay', + 'autoLastInterestDate', + // Settings step — Foreclosure / Early Account Closure + 'calculateEarlyAccountCloseCharge', + 'earlyAccountCloseCharge', + 'earlyAccountClosePeriodInMonths', + // Terms step + 'debitBalanceAllow', + 'allowDebitTransAfterDueDate', + 'branchLevelAccountType', + 'interestRateDetail', + // Charges step — legacy cheque / standing instruction / minimum balance charges + 'chequeBookChargeEnabled', + 'chequeReturnChargeEnabled', + 'icChargeDebitEnabled', + 'cashBundleChargeEnabled', + 'cashBundleChargeWithPanLimit', + 'perChequeEntryCharge', + 'perChequeEntryServiceCharge', + 'perInwardChequeEntryCharge', + 'perOutwardChequeEntryCharge', + 'creditorStandingInstructionFailCharge', + 'debtorStandingInstructionFailCharge', + 'minimumBalanceCheckingType', + 'autoMinimumBalanceCharge', + 'calculateDailyMinimumBalanceCharges', + 'minimumBalanceChargeEnabled', + 'minimumBalanceChargeAmount', + 'minimumBalanceChargeForChequeIssue', + 'minimumBalanceChargeMethod', + 'monthsAfterMinBalanceChargeCalculate', + 'forChequeIssue', + 'forChequeIssueAvg', + 'forWithdrawalSlip', + 'forWithdrawalSlipAvg', + 'calculateDailyAgainstClearingCharge', + // Accounting step — custom GL account mappings + 'intReceivablesGlAccountId', + 'intPayableGlAccountId', + 'deafIntPayableGlAccountId', + 'intOverdueReserveAccountId', + 'undebitedInterestAccountId', + 'penalIntCrGlAccountId', + 'rdMaturedGlAccountId', + 'glAccountId', + 'icChargeGlAccountId', + 'inoperativeGlAccountId', + 'creditBalanceLiabilityGlAccountId', + 'creditBalanceAssetGlAccountId', + 'overdueAccountsGlAccountId', + 'rebateGlAccountId' +]; + @Injectable({ providedIn: 'root' }) @@ -49,6 +289,9 @@ export class LoanProducts { delete loanProduct.allowAttributeConfiguration; delete loanProduct.advancedAccountingRules; + // Remove custom, UI-only fields not yet recognised by the Fineract backend + CUSTOM_UI_ONLY_FIELDS.forEach((field) => delete loanProduct[field]); + // In Fineract, the POST and PUT endpoints for /v1/loanproducts have a typo in the field // allowPartialPeriodInterestCalculation. Until that is fixed, we need to replace the field name in the payload. loanProduct.allowPartialPeriodInterestCalculation = loanProduct.allowPartialPeriodInterestCalculation;