From 9e85872eaca27fb547d7a71d4487ef15fb44b514 Mon Sep 17 00:00:00 2001 From: Nitesh Yadav Date: Fri, 8 May 2026 13:51:19 +0530 Subject: [PATCH] rd account and rd product code update --- .../ckyc-reports/ckyc-reports.component.ts | 2 +- ...-recurring-deposits-account.component.html | 7 +- ...te-recurring-deposits-account.component.ts | 130 ++- ...t-recurring-deposit-account.component.html | 8 +- ...dit-recurring-deposit-account.component.ts | 46 +- ...osits-account-currency-step.component.html | 16 - ...eposits-account-currency-step.component.ts | 6 - ...deposits-account-details-step.component.ts | 4 - ...nt-interest-rate-chart-step.component.html | 386 +++++++- ...nt-interest-rate-chart-step.component.scss | 867 ++++++++++++++++-- ...ount-interest-rate-chart-step.component.ts | 313 ++++++- ...posits-account-preview-step.component.html | 390 ++++---- ...posits-account-preview-step.component.scss | 127 ++- ...deposits-account-preview-step.component.ts | 128 ++- ...deposits-account-terms-step.component.html | 2 +- .../interest-rate-chart-tab.component.ts | 7 +- .../recurring-deposits.service.ts | 7 + src/app/products/products-routing.module.ts | 17 - ...ate-recurring-deposit-product.component.ts | 107 ++- ...dit-recurring-deposit-product.component.ts | 68 +- ...posit-product-currency-step.component.html | 22 - ...deposit-product-currency-step.component.ts | 6 - ...eposit-product-details-step.component.html | 9 - ...-deposit-product-details-step.component.ts | 3 - ...eposit-product-preview-step.component.html | 48 +- ...-deposit-product-terms-step.component.html | 39 + ...ng-deposit-product-terms-step.component.ts | 18 +- .../recurring-deposit-products.component.html | 12 - ...curring-deposit-general-tab.component.html | 14 - ...w-recurring-deposit-product.component.html | 9 - src/app/shared/footer/footer.component.ts | 5 +- .../codes/view-code/view-code.component.ts | 3 +- .../checker-inbox-and-tasks.component.ts | 4 +- .../users/view-user/view-user.component.ts | 4 +- src/environments/.env.ts | 4 +- 35 files changed, 2247 insertions(+), 591 deletions(-) diff --git a/src/app/ckyc/ckyc-reports/ckyc-reports.component.ts b/src/app/ckyc/ckyc-reports/ckyc-reports.component.ts index a4f4f68df..97193a983 100644 --- a/src/app/ckyc/ckyc-reports/ckyc-reports.component.ts +++ b/src/app/ckyc/ckyc-reports/ckyc-reports.component.ts @@ -108,7 +108,7 @@ export class CkycReportsComponent implements OnInit, AfterViewInit { ngOnInit(): void { this.parseAndStore(SAMPLE_CKYC_FILE); - // eslint-disable-next-line no-console + console.log( '[CKYC] Sample loaded —', this.customers.length, diff --git a/src/app/deposits/recurring-deposits/create-recurring-deposits-account/create-recurring-deposits-account.component.html b/src/app/deposits/recurring-deposits/create-recurring-deposits-account/create-recurring-deposits-account.component.html index b2f2a3d15..966827f69 100644 --- a/src/app/deposits/recurring-deposits/create-recurring-deposits-account/create-recurring-deposits-account.component.html +++ b/src/app/deposits/recurring-deposits/create-recurring-deposits-account/create-recurring-deposits-account.component.html @@ -74,7 +74,8 @@ @@ -97,11 +98,13 @@ [recurringDepositsAccountTemplate]="recurringDepositsAccountTemplate" [recurringDepositsAccountProductTemplate]="recurringDepositsAccountProductTemplate" [recurringDepositAccountData]="recurringDepositAccountData" - [rdInterestRates]="rdInterestRates" [rdNominee]="rdNominee" [rdCurrencyFlags]="rdCurrencyFlags" [rdTenureDays]="rdTenureDays" [rdApplicableSlab]="rdApplicableSlab" + [rdMaturityAmount]="rdMaturityAmount" + [rdInterestEarned]="rdInterestEarned" + [rdDaysInYear]="rdDaysInYear" (submitEvent)="submit()" > diff --git a/src/app/deposits/recurring-deposits/create-recurring-deposits-account/create-recurring-deposits-account.component.ts b/src/app/deposits/recurring-deposits/create-recurring-deposits-account/create-recurring-deposits-account.component.ts index 9a73f3c25..bfc5384a9 100644 --- a/src/app/deposits/recurring-deposits/create-recurring-deposits-account/create-recurring-deposits-account.component.ts +++ b/src/app/deposits/recurring-deposits/create-recurring-deposits-account/create-recurring-deposits-account.component.ts @@ -75,8 +75,10 @@ export class CreateRecurringDepositsAccountComponent { recurringDepositsAccountTemplate: any; /** Recurring Deposit Account Product Template */ recurringDepositsAccountProductTemplate: any; - /** Active CBS base interest rate chart */ - rdInterestRates: any[] = []; + /** Selected tenure value and frequency from calculator */ + selectedTenureValue: number | null = null; + selectedTenureFrequencyId: number | null = null; + selectedDepositAmount: number | null = null; constructor() { this.route.data.subscribe((data: { recurringDepositsAccountTemplate: any }) => { @@ -90,14 +92,13 @@ export class CreateRecurringDepositsAccountComponent { */ setTemplate($event: any) { this.recurringDepositsAccountProductTemplate = $event; - this.productsService.getRdBaseInterestRates().subscribe({ - next: (rates: any[]) => { - this.rdInterestRates = rates || []; - }, - error: () => { - this.rdInterestRates = []; - } - }); + } + + /** Captures tenure selection from calculator */ + handleTenureSelected($event: any) { + this.selectedTenureValue = $event.depositPeriod; + this.selectedTenureFrequencyId = $event.depositPeriodFrequencyId; + this.selectedDepositAmount = $event.depositAmount; } /** Get Recurring Deposit Account Details Form Data */ @@ -123,17 +124,31 @@ export class CreateRecurringDepositsAccountComponent { } get rdTenureDays(): number | null { - return this.recurringDepositsAccountChartStep?.tenureDays ?? null; + return this.recurringDepositsAccountChartStep?.matchResult?.tenureDays ?? null; } get rdApplicableSlab(): any | null { - return this.recurringDepositsAccountChartStep?.applicableSlab ?? null; + return this.recurringDepositsAccountChartStep?.matchResult?.slab ?? null; + } + + get rdMaturityAmount(): number | null { + return this.recurringDepositsAccountChartStep?.matchResult?.maturityAmount ?? null; + } + + get rdInterestEarned(): number | null { + return this.recurringDepositsAccountChartStep?.matchResult?.interestEarned ?? null; + } + + get rdDaysInYear(): number | null { + return this.recurringDepositsAccountChartStep?.matchResult?.daysInYear ?? null; + } + + get submittedOnDate(): Date | null { + return this.recurringDepositAccountDetailsForm?.value?.submittedOnDate ?? null; } get rdCurrencyFlags() { return { - balanceSwapOption: this.recurringDepositsAccountCurrencyStep?.balanceSwapOption ?? false, - msme: this.recurringDepositsAccountCurrencyStep?.msme ?? false, autoDebitFacility: this.recurringDepositsAccountCurrencyStep?.autoDebitFacility ?? false }; } @@ -145,34 +160,93 @@ export class CreateRecurringDepositsAccountComponent { const locale = this.settingsService.language.code; const dateFormat = this.settingsService.dateFormat; const monthDayFormat = 'dd MMMM'; + const pt = this.recurringDepositsAccountProductTemplate; const details = this.recurringDepositAccount; const currencyStep = this.recurringDepositsAccountCurrencyStep; + // Terms — pulled from product template + const terms: any = {}; + if (pt?.nominalAnnualInterestRate != null) terms.nominalAnnualInterestRate = pt.nominalAnnualInterestRate; + if (pt?.interestCompoundingPeriodType?.id != null) + terms.interestCompoundingPeriodType = pt.interestCompoundingPeriodType.id; + if (pt?.interestPostingPeriodType?.id != null) terms.interestPostingPeriodType = pt.interestPostingPeriodType.id; + if (pt?.interestCalculationType?.id != null) terms.interestCalculationType = pt.interestCalculationType.id; + if (pt?.interestCalculationDaysInYearType?.id != null) + terms.interestCalculationDaysInYearType = pt.interestCalculationDaysInYearType.id; + + // Settings — pulled from product template + const settings: any = {}; + if (pt?.lockinPeriodFrequency != null) settings.lockinPeriodFrequency = pt.lockinPeriodFrequency; + if (pt?.lockinPeriodFrequencyType?.id != null) settings.lockinPeriodFrequencyType = pt.lockinPeriodFrequencyType.id; + if (pt?.minDepositTerm != null) settings.minDepositTerm = pt.minDepositTerm; + if (pt?.minDepositTermType?.id != null) settings.minDepositTermTypeId = pt.minDepositTermType.id; + if (pt?.inMultiplesOfDepositTerm != null) settings.inMultiplesOfDepositTerm = pt.inMultiplesOfDepositTerm; + if (pt?.inMultiplesOfDepositTermType?.id != null) + settings.inMultiplesOfDepositTermTypeId = pt.inMultiplesOfDepositTermType.id; + if (pt?.maxDepositTerm != null) settings.maxDepositTerm = pt.maxDepositTerm; + if (pt?.maxDepositTermType?.id != null) settings.maxDepositTermTypeId = pt.maxDepositTermType.id; + if (pt?.preClosurePenalApplicable != null) settings.preClosurePenalApplicable = pt.preClosurePenalApplicable; + if (pt?.preClosurePenalInterest != null) settings.preClosurePenalInterest = pt.preClosurePenalInterest; + if (pt?.preClosurePenalInterestOnType?.id != null) + settings.preClosurePenalInterestOnTypeId = pt.preClosurePenalInterestOnType.id; + if (pt?.maturityInstructionId != null) settings.maturityInstructionId = pt.maturityInstructionId; + if (pt?.transferInterestToSavings != null) settings.transferInterestToSavings = pt.transferInterestToSavings; + if (pt?.withHoldTax != null) settings.withHoldTax = pt.withHoldTax; + + // Flags and other product defaults + const productDefaults: any = { + isCalendarInherited: pt?.isCalendarInherited ?? false, + isMandatoryDeposit: pt?.isMandatoryDeposit ?? false, + allowWithdrawal: pt?.allowWithdrawal ?? false, + adjustAdvanceTowardsFuturePayments: pt?.adjustAdvanceTowardsFuturePayments ?? false, + autoDebitFacility: currencyStep?.autoDebitFacility ?? pt?.autoDebitFacility ?? false + }; + + // Charges from product template + const rawCharges: any[] = pt?.charges ?? []; + const recurringDepositAccount: any = { ...details, + ...terms, + ...settings, + ...productDefaults, clientId: this.recurringDepositsAccountTemplate.clientId, - charges: [], - isCalendarInherited: false, - mandatoryRecommendedDepositAmount: 0, - recurringFrequency: 1, - recurringFrequencyType: 2, + mandatoryRecommendedDepositAmount: pt?.minDepositAmount ?? 0, + recurringFrequency: pt?.recurringFrequency ?? 1, + recurringFrequencyType: pt?.recurringFrequencyType ?? 2, // Monthly submittedOnDate: this.dateUtils.formatDate(details.submittedOnDate, dateFormat), expectedFirstDepositOnDate: this.dateUtils.formatDate(details.expectedFirstDepositOnDate, dateFormat), dateFormat, monthDayFormat, locale, - // Currency step overrides - balanceSwapOption: currencyStep?.balanceSwapOption ?? details.balanceSwapOption ?? false, - msme: currencyStep?.msme ?? details.msme ?? false, - autoDebitFacility: currencyStep?.autoDebitFacility ?? details.autoDebitFacility ?? false + charts: [ + { + chartSlabs: + pt?.accountChart?.chartSlabs ?? pt?.activeChart?.chartSlabs ?? pt?.interestRateCharts?.[0]?.chartSlabs ?? [] + } + ], + charges: rawCharges.map((charge: any) => ({ + chargeId: charge.chargeId ?? charge.id, + amount: charge.amount, + dueDate: charge.dueDate && this.dateUtils.formatDate(charge.dueDate, dateFormat), + feeOnMonthDay: charge.feeOnMonthDay, + feeInterval: charge.feeInterval + })) }; - // Tenure from interest rate chart step (depositPeriod in days) - const tenureDays = this.rdTenureDays; - if (tenureDays && tenureDays > 0) { - recurringDepositAccount.depositPeriod = tenureDays; - recurringDepositAccount.depositPeriodFrequencyId = 0; // 0 = Days + // Tenure override from interest rate chart calculator + if (this.selectedTenureValue && this.selectedTenureFrequencyId !== null) { + recurringDepositAccount.depositPeriod = this.selectedTenureValue; + recurringDepositAccount.depositPeriodFrequencyId = this.selectedTenureFrequencyId; + } else if (this.rdTenureDays) { + recurringDepositAccount.depositPeriod = this.rdTenureDays; + recurringDepositAccount.depositPeriodFrequencyId = 0; // Days + } + + // Amount override from calculator if provided + if (this.selectedDepositAmount) { + recurringDepositAccount.mandatoryRecommendedDepositAmount = this.selectedDepositAmount; } // Nominee from currency step diff --git a/src/app/deposits/recurring-deposits/edit-recurring-deposit-account/edit-recurring-deposit-account.component.html b/src/app/deposits/recurring-deposits/edit-recurring-deposit-account/edit-recurring-deposit-account.component.html index 372966041..055268a5f 100644 --- a/src/app/deposits/recurring-deposits/edit-recurring-deposit-account/edit-recurring-deposit-account.component.html +++ b/src/app/deposits/recurring-deposits/edit-recurring-deposit-account/edit-recurring-deposit-account.component.html @@ -71,7 +71,7 @@ @@ -94,7 +94,11 @@ [recurringDepositsAccountTemplate]="recurringDepositsAccountAndTemplate" [recurringDepositsAccountProductTemplate]="recurringDepositsAccountProductTemplate" [recurringDepositAccountData]="recurringDepositAccountData" - [rdInterestRates]="rdInterestRates" + [rdTenureDays]="rdTenureDays" + [rdApplicableSlab]="rdApplicableSlab" + [rdMaturityAmount]="rdMaturityAmount" + [rdInterestEarned]="rdInterestEarned" + [rdDaysInYear]="rdDaysInYear" (submitEvent)="submit()" > diff --git a/src/app/deposits/recurring-deposits/edit-recurring-deposit-account/edit-recurring-deposit-account.component.ts b/src/app/deposits/recurring-deposits/edit-recurring-deposit-account/edit-recurring-deposit-account.component.ts index 278e8e501..8df7a977d 100644 --- a/src/app/deposits/recurring-deposits/edit-recurring-deposit-account/edit-recurring-deposit-account.component.ts +++ b/src/app/deposits/recurring-deposits/edit-recurring-deposit-account/edit-recurring-deposit-account.component.ts @@ -67,12 +67,37 @@ export class EditRecurringDepositAccountComponent { @ViewChild(RecurringDepositsAccountChargesStepComponent, { static: true }) recurringDepositAccountChargesStep: RecurringDepositsAccountChargesStepComponent; + @ViewChild(RecurringDepositsAccountInterestRateChartStepComponent) + recurringDepositsAccountChartStep: RecurringDepositsAccountInterestRateChartStepComponent; + + get rdTenureDays(): number | null { + return this.recurringDepositsAccountChartStep?.matchResult?.tenureDays ?? null; + } + + get rdApplicableSlab(): any | null { + return this.recurringDepositsAccountChartStep?.matchResult?.slab ?? null; + } + + get rdMaturityAmount(): number | null { + return this.recurringDepositsAccountChartStep?.matchResult?.maturityAmount ?? null; + } + + get rdInterestEarned(): number | null { + return this.recurringDepositsAccountChartStep?.matchResult?.interestEarned ?? null; + } + + get rdDaysInYear(): number | null { + return this.recurringDepositsAccountChartStep?.matchResult?.daysInYear ?? null; + } + + get submittedOnDate(): Date | null { + return this.recurringDepositAccountDetailsForm?.value?.submittedOnDate ?? null; + } + /** Recurring Deposits Account And Template */ recurringDepositsAccountAndTemplate: any; /** Recurring Deposit Account Product Template */ recurringDepositsAccountProductTemplate: any; - /** Active CBS base interest rate chart */ - rdInterestRates: any[] = []; constructor() { this.route.data.subscribe((data: { recurringDepositsAccountAndTemplate: any }) => { @@ -86,14 +111,6 @@ export class EditRecurringDepositAccountComponent { */ setTemplate($event: any) { this.recurringDepositsAccountProductTemplate = $event; - this.productsService.getRdBaseInterestRates().subscribe({ - next: (rates: any[]) => { - this.rdInterestRates = rates || []; - }, - error: () => { - this.rdInterestRates = []; - } - }); } /** Get Recurring Deposit Account Details Form Data */ @@ -169,6 +186,15 @@ export class EditRecurringDepositAccountComponent { this.recurringDepositAccount.expectedFirstDepositOnDate, dateFormat ), + charts: [ + { + chartSlabs: + this.recurringDepositsAccountProductTemplate?.accountChart?.chartSlabs ?? + this.recurringDepositsAccountProductTemplate?.activeChart?.chartSlabs ?? + this.recurringDepositsAccountProductTemplate?.interestRateCharts?.[0]?.chartSlabs ?? + [] + } + ], dateFormat, monthDayFormat, locale diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-currency-step/recurring-deposits-account-currency-step.component.html b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-currency-step/recurring-deposits-account-currency-step.component.html index 569e917ee..d5790362f 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-currency-step/recurring-deposits-account-currency-step.component.html +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-currency-step/recurring-deposits-account-currency-step.component.html @@ -27,22 +27,6 @@ -
-
-

Balance Swap Option

-

Enable automated transfer of excess funds to linked deposits or vice-versa to maintain liquidity.

-
- -
- -
-
-

MSME

-

Micro, Small and Medium Enterprises — mark this account under MSME category.

-
- -
-

Auto Debit Facility

diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-currency-step/recurring-deposits-account-currency-step.component.ts b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-currency-step/recurring-deposits-account-currency-step.component.ts index d793ae8fe..e8cfabdaa 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-currency-step/recurring-deposits-account-currency-step.component.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-currency-step/recurring-deposits-account-currency-step.component.ts @@ -31,15 +31,11 @@ export class RecurringDepositsAccountCurrencyStepComponent implements OnChanges nomineeData: any = null; // Editable feature toggles (pre-filled from product, overridable by user) - balanceSwapOption = false; - msme = false; autoDebitFacility = false; ngOnChanges(changes: SimpleChanges): void { if (changes['recurringDepositsAccountProductTemplate']?.currentValue) { const pt = changes['recurringDepositsAccountProductTemplate'].currentValue; - this.balanceSwapOption = !!pt.balanceSwapOption; - this.msme = !!pt.msme; this.autoDebitFacility = !!pt.autoDebitFacility; } } @@ -51,8 +47,6 @@ export class RecurringDepositsAccountCurrencyStepComponent implements OnChanges /** Called by parent to collect currency step values */ get currencyStepData() { return { - balanceSwapOption: this.balanceSwapOption, - msme: this.msme, autoDebitFacility: this.autoDebitFacility, ...(this.nomineeData ? { nominee: this.nomineeData } : {}) }; diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-details-step/recurring-deposits-account-details-step.component.ts b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-details-step/recurring-deposits-account-details-step.component.ts index 62ea2c590..3bd5b04a2 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-details-step/recurring-deposits-account-details-step.component.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-details-step/recurring-deposits-account-details-step.component.ts @@ -338,8 +338,6 @@ export class RecurringDepositsAccountDetailsStepComponent implements OnInit { ], fieldOfficerId: [''], externalId: [''], - balanceSwapOption: [false], - msme: [false], autoDebitFacility: [false] }); } @@ -375,8 +373,6 @@ export class RecurringDepositsAccountDetailsStepComponent implements OnInit { this.loadClientAccounts(); } this.recurringDepositAccountDetailsForm.patchValue({ - balanceSwapOption: !!response.balanceSwapOption, - msme: !!response.msme, autoDebitFacility: !!response.autoDebitFacility }); this.cdr.detectChanges(); diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.html b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.html index aeda181b5..af9c62527 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.html +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.html @@ -6,47 +6,359 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. --> -
- - @if (_activeRdVersion) { -
-
- - Tenure & Interest Calculator -
-
-
- - Enter Tenure (Days) - - Enter the number of days for your RD - +
+ + @if (interestRateChartData.length > 0) { +
+
+
+
- - @if (tenureDays && tenureDays > 0) { - @if (applicableSlab) { -
-
- Tenure - {{ tenureDays }} Days -
-
- Applicable Slab - {{ applicableSlab.description }} -
-
- Annual Interest Rate - {{ applicableSlab.annualInterestRate | number: '1.2-2' }}% -
-
- } @else { -
- - No matching slab found for {{ tenureDays }} days -
+
+
{{ chartName || 'RD Interest Rate Chart' }}
+ @if (chartDescription) { +
{{ chartDescription }}
} +
+
+
+
+ + + From: {{ chartFromDate | dateFormat }} + + @if (chartEndDate) { + + + To: {{ chartEndDate | dateFormat }} + + } +
+ @if (isPrimaryGroupingByAmount) { + Grouped by Amount }
} + + +
+
+
+
+ +
+
+ RD Rate Calculator + Enter your RD tenure to find the applicable interest rate +
+
+
+ +
+
+ +
+ +
+ + +
+ @for (unit of allowedPeriodUnits; track unit) { + + } +
+
+
+ + +
+ +
+ ₹ + +
+
+ +
+ + @if (tenureValue || matchResult) { + + } +
+
+ + + @if (validationWarning) { +
+ + {{ validationWarning }} +
+ } + + + @if (matchResult) { +
+
+ +
+
+ +
+ +
+ Your Selected RD Tenure + {{ tenureValue }} {{ tenurePeriodUnit }} +
+ Will be saved +
+ +
+ {{ matchResult.appliedRate | number: '1.2-2' }}% + Annual Interest Rate +
+
+
+ + Applicable Slab: + + {{ matchResult.slab.fromPeriod }}–{{ matchResult.slab.toPeriod ?? '∞' }} + {{ matchResult.slab.periodType?.value }} + + +
+ @if (matchResult.slab.description) { +
+ + {{ matchResult.slab.description }} +
+ } +
+ + + @if (matchResult.maturityAmount !== null) { +
+
+ + RD Maturity Summary (Estimate) +
+
+
+ Monthly Installment + ₹ {{ principalAmount | number: '1.2-2' }} +
+
+ Tenure + {{ tenureValue }} {{ tenurePeriodUnit }} +
+
+ Interest Rate + {{ matchResult.appliedRate | number: '1.2-2' }}% p.a. +
+
+ Estimated Interest Earned + ₹ {{ matchResult.interestEarned | number: '1.2-2' }} +
+
+ Estimated Maturity Amount + + ₹ {{ matchResult.maturityAmount | number: '1.2-2' }} + +
+
+
+ } + @if (!matchResult.maturityAmount) { +
+ + Enter a monthly installment amount above to see the maturity calculation. +
+ } +
+
+ } +
+
+ + +
+
+
+ + Interest Rate Slabs + @if (interestRateChartData.length) { + {{ interestRateChartData.length }} slab{{ interestRateChartData.length !== 1 ? 's' : '' }} + } +
+ @if (matchResult) { + Matched slab is highlighted + } +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Period + + {{ slab.fromPeriod }} + @if (slab.toPeriod !== null) { + – {{ slab.toPeriod }} + } @else { + + + } + + {{ slab.periodType?.value }} + Amount Range + @if (slab.amountRangeFrom || slab.amountRangeTo) { + {{ slab.amountRangeFrom | number }} – {{ slab.amountRangeTo | number }} + } @else { + — + } + Interest Rate + {{ slab.annualInterestRate | number: '1.2-2' }}% + Description + {{ slab.description || '—' }} + Incentives + @if (slab.incentives?.length) { + + } @else { + None + } + +
+ @if (slab.incentives?.length) { +
+
Incentives for this slab
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Entity Type{{ inc.entityType?.value }}Attribute{{ inc.attributeName?.value }}Condition{{ inc.conditionType?.value | titlecase }}Value{{ inc.attributeValueDesc }}Type{{ inc.incentiveType?.value }}Amount{{ inc.amount }}
+
+ } +
+
+ + @if (!interestRateChartData.length) { +
+ + No interest rate slabs defined for this product. +
+ } +
+
diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.scss b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.scss index 12e438941..423283f4a 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.scss +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.scss @@ -6,125 +6,836 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// ── Tenure Calculator ───────────────────────────────────────────────────────── -.tenure-calc { - border: 1px solid #e2e8f0; - border-radius: 10px; - overflow: hidden; +$border: #e2e8f0; +$gray-50: #f8f9fa; +$gray-100: #f1f5f9; +$gray-200: #e8eaed; +$gray-600: #64748b; +$gray-700: #334155; +$gray-900: #0f172a; +$blue: #2563eb; +$blue-light: #dbeafe; +$green: #16a34a; +$green-light: #dcfce7; +$amber: #d97706; +$amber-light: #fef3c7; +$purple: #7c3aed; +$purple-light: #ede9fe; +$red: #dc2626; +$red-light: #fee2e2; + +.fdrc-wrapper { + display: flex; + flex-direction: column; + gap: 16px; +} + +// ── Chart Header Card ────────────────────────────────────────────────────── + +.fdrc-header-card { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 16px; background: #fff; - box-shadow: 0 1px 4px rgb(0 0 0 / 5%); - margin-bottom: 1.25rem; + border: 1px solid $border; + border-radius: 12px; + padding: 16px 20px; + flex-wrap: wrap; + + &__left { + display: flex; + align-items: center; + gap: 12px; + min-width: 0; + } + + &__icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 10px; + background: $blue-light; + color: $blue; + font-size: 18px; + flex-shrink: 0; + } + + &__title { + font-size: 15px; + font-weight: 700; + color: $gray-900; + } + + &__desc { + font-size: 12px; + color: $gray-600; + margin-top: 2px; + } + + &__meta { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: 8px; + } + + &__dates { + display: flex; + gap: 12px; + flex-wrap: wrap; + justify-content: flex-end; + } +} + +.fdrc-meta-item { + display: flex; + align-items: center; + gap: 5px; + font-size: 12px; + color: $gray-700; + + i { + color: $gray-600; + } + + strong { + color: $gray-900; + } +} + +// ── Pills ────────────────────────────────────────────────────────────────── + +.fdrc-pill { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 3px 10px; + border-radius: 999px; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.03em; + white-space: nowrap; + + &--type { + background: #f1f5f9; + color: $gray-700; + } + + &--single { + background: $amber-light; + color: $amber; + } + + &--double { + background: $purple-light; + color: $purple; + } + + &--special { + background: $green-light; + color: $green; + } + + &--amount { + background: $blue-light; + color: $blue; + } +} + +// ── Calculator Card ──────────────────────────────────────────────────────── + +.fdrc-calc-card { + background: #fff; + border: 1px solid $border; + border-radius: 12px; + overflow: hidden; &__header { display: flex; align-items: center; - gap: 8px; - background: #f0f9ff; - border-bottom: 1px solid #bae6fd; - padding: 0.65rem 1rem; - font-size: 0.85rem; + justify-content: space-between; + padding: 14px 20px; + background: $gray-50; + border-bottom: 1px solid $gray-200; + } + + &__header-left { + display: flex; + align-items: center; + gap: 12px; + } + + &__title { + font-size: 14px; + font-weight: 700; + color: $gray-900; + display: block; + } + + &__sub { + font-size: 12px; + color: $gray-600; + display: block; + margin-top: 1px; + } + + &__body { + padding: 20px; + } +} + +.fdrc-calc-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + border-radius: 8px; + background: $blue-light; + color: $blue; + font-size: 16px; + flex-shrink: 0; +} + +.fdrc-calc-inputs { + display: flex; + flex-wrap: wrap; + gap: 16px; + align-items: flex-end; +} + +.fdrc-calc-field { + display: flex; + flex-direction: column; + gap: 6px; + flex: 1 1 220px; + min-width: 180px; +} + +.fdrc-calc-label { + font-size: 12px; + font-weight: 600; + color: $gray-700; + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.fdrc-calc-optional { + font-weight: 400; + text-transform: none; + letter-spacing: 0; + color: $gray-600; +} + +.fdrc-tenure-row { + display: flex; + align-items: center; + gap: 8px; +} + +.fdrc-tenure-input { + height: 42px; + border: 1.5px solid $border; + border-radius: 8px; + padding: 0 12px; + font-size: 15px; + font-weight: 600; + color: $gray-900; + background: #fff; + width: 130px; + transition: border-color 0.15s; + + &:focus { + outline: none; + border-color: $blue; + } + + &--amount { + width: 180px; + } +} + +.fdrc-period-badge { + display: inline-flex; + align-items: center; + padding: 0 14px; + height: 42px; + background: $gray-100; + border: 1.5px solid $border; + border-radius: 8px; + font-size: 13px; + font-weight: 700; + color: $gray-700; +} + +.fdrc-period-tabs { + display: flex; + border: 1.5px solid $border; + border-radius: 8px; + overflow: hidden; +} + +.fdrc-period-tab { + height: 42px; + padding: 0 14px; + font-size: 13px; + font-weight: 600; + border: none; + background: #fff; + color: $gray-600; + cursor: pointer; + transition: + background 0.15s, + color 0.15s; + + & + & { + border-left: 1px solid $border; + } + + &--active { + background: $blue; + color: #fff; + } +} + +.fdrc-amount-row { + display: flex; + align-items: center; +} + +.fdrc-amount-prefix { + display: inline-flex; + align-items: center; + justify-content: center; + width: 40px; + height: 42px; + background: $gray-100; + border: 1.5px solid $border; + border-right: none; + border-radius: 8px 0 0 8px; + font-size: 15px; + font-weight: 700; + color: $gray-700; +} + +.fdrc-amount-row .fdrc-tenure-input { + border-radius: 0 8px 8px 0; +} + +.fdrc-calc-hint { + font-size: 11px; + color: $amber; + display: flex; + align-items: center; + gap: 4px; +} + +.fdrc-calc-actions { + display: flex; + align-items: center; + gap: 10px; + flex-shrink: 0; + margin-top: 22px; +} + +.fdrc-calc-btn { + display: inline-flex; + align-items: center; + gap: 7px; + height: 42px; + padding: 0 22px; + background: $blue; + color: #fff; + border: none; + border-radius: 8px; + font-size: 14px; + font-weight: 700; + cursor: pointer; + transition: background 0.15s; + + &:hover { + background: #1d4ed8; + } +} + +.fdrc-calc-reset { + display: inline-flex; + align-items: center; + gap: 6px; + height: 42px; + padding: 0 16px; + background: transparent; + color: $gray-600; + border: 1.5px solid $border; + border-radius: 8px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: + border-color 0.15s, + color 0.15s; + + &:hover { + border-color: $red; + color: $red; + } +} + +// ── Alert ───────────────────────────────────────────────────────────────── + +.fdrc-alert { + display: flex; + align-items: flex-start; + gap: 10px; + padding: 12px 16px; + border-radius: 8px; + margin-top: 16px; + font-size: 13px; + + i { + margin-top: 1px; + flex-shrink: 0; + } + + &--warn { + background: $amber-light; + color: #b45309; + border: 1px solid rgba($amber, 0.4); + } +} + +// ── Tenure Banner (inside result card) ─────────────────────────────────── + +.fdrc-tenure-banner { + display: flex; + align-items: center; + gap: 12px; + padding: 10px 14px; + background: #fff; + border: 1.5px solid rgba($green, 0.4); + border-radius: 8px; + margin-bottom: 14px; + + > i { + font-size: 18px; + color: $green; + flex-shrink: 0; + } + + &__content { + display: flex; + flex-direction: column; + gap: 1px; + flex: 1; + } + + &__label { + font-size: 10px; font-weight: 700; - color: #0369a1; text-transform: uppercase; - letter-spacing: 0.05em; + letter-spacing: 0.06em; + color: $gray-600; + } + + &__value { + font-size: 20px; + font-weight: 800; + color: $gray-900; + line-height: 1.2; + } + + &__saved { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 4px 10px; + background: $green-light; + color: $green; + border-radius: 999px; + font-size: 11px; + font-weight: 700; + white-space: nowrap; + flex-shrink: 0; + } +} + +// ── Result Card ─────────────────────────────────────────────────────────────── + +.fdrc-result-card { + display: flex; + align-items: flex-start; + gap: 16px; + margin-top: 16px; + padding: 18px 20px; + background: $green-light; + border: 1.5px solid rgba($green, 0.35); + border-radius: 12px; + + &__check { + font-size: 26px; + color: $green; + flex-shrink: 0; + margin-top: 2px; + } + + &__body { + flex: 1; + min-width: 0; + } +} + +.fdrc-result-rate { + display: flex; + align-items: baseline; + gap: 8px; + margin-bottom: 10px; + + &__value { + font-size: 28px; + font-weight: 800; + color: $green; + line-height: 1; + } + + &__label { + font-size: 13px; + color: #166534; + font-weight: 600; + } +} + +.fdrc-result-meta { + display: flex; + flex-direction: column; + gap: 5px; + + &__item { + display: flex; + align-items: center; + gap: 7px; + font-size: 12px; + color: $gray-700; i { - font-size: 13px; + color: $green; + font-size: 11px; + } + + strong { + color: $gray-900; + } + } +} + +// ── Maturity Card ──────────────────────────────────────────────────────────── + +.fdrc-maturity-card { + margin-top: 16px; + background: #fff; + border: 1.5px solid rgba($green, 0.2); + border-radius: 10px; + overflow: hidden; + + &__header { + background: rgba($green, 0.05); + padding: 8px 14px; + border-bottom: 1px solid rgba($green, 0.1); + display: flex; + align-items: center; + gap: 8px; + font-size: 12px; + font-weight: 700; + color: #166534; + + i { + font-size: 14px; } } &__body { - padding: 1rem 1.25rem; - } - - &__input-row { + padding: 12px 14px; display: flex; - align-items: flex-start; - gap: 1rem; + flex-direction: column; + gap: 8px; + } +} + +.fdrc-maturity-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 20px; + + &__label { + font-size: 12px; + color: $gray-600; } - &__field { - width: 260px; - } - - &__result { - margin-top: 1rem; - border: 1px solid #e0f2fe; - border-radius: 8px; - overflow: hidden; - } - - &__result-row { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0.55rem 1rem; - border-bottom: 1px solid #f0f9ff; - font-size: 0.88rem; - - &:last-child { - border-bottom: none; - } + &__value { + font-size: 13px; + font-weight: 700; + color: $gray-900; &--highlight { - background: #f0f9ff; + color: $green; + } + + &--big { + font-size: 16px; + color: $green; } } - &__result-label { - color: #64748b; - font-weight: 500; + &--interest { + padding-top: 4px; + margin-top: 4px; + border-top: 1px dashed $border; } - &__result-value { - color: #1e293b; - font-weight: 600; + &--total { + padding-top: 8px; + margin-top: 4px; + border-top: 1.5px solid $gray-200; } +} - &__result-rate { - font-size: 1.25rem; - font-weight: 800; - color: #0369a1; +.fdrc-payout-hint { + display: flex; + align-items: center; + gap: 8px; + margin-top: 12px; + font-size: 12px; + color: $gray-600; + font-style: italic; + + i { + color: $amber; } +} - &__no-match { - margin-top: 0.75rem; - padding: 0.6rem 1rem; - border-radius: 8px; - background: #fef2f2; - color: #dc2626; - font-size: 0.85rem; - font-weight: 600; +// ── Rate Chart Table Card ───────────────────────────────────────────────── + +.fdrc-table-card { + background: #fff; + border: 1px solid $border; + border-radius: 12px; + overflow: hidden; + + &__header { display: flex; align-items: center; - gap: 6px; + justify-content: space-between; + padding: 14px 20px; + background: $gray-50; + border-bottom: 1px solid $gray-200; + flex-wrap: wrap; + gap: 8px; + } + + &__title-row { + display: flex; + align-items: center; + gap: 10px; i { - font-size: 13px; + color: $blue; } } + + &__title { + font-size: 14px; + font-weight: 700; + color: $gray-900; + } } -.margin-t { - margin-top: 2em; +.fdrc-slab-count { + display: inline-flex; + align-items: center; + padding: 2px 8px; + background: $blue-light; + color: $blue; + border-radius: 999px; + font-size: 11px; + font-weight: 700; } -table { +.fdrc-highlight-note { + font-size: 12px; + color: $green; + font-weight: 600; + display: flex; + align-items: center; + gap: 5px; +} + +.fdrc-table-wrap { + overflow-x: auto; +} + +.fdrc-table { width: 100%; + min-width: 600px; +} - tr.incentives-row { - height: 0; +.fdrc-th { + font-size: 11px !important; + font-weight: 700 !important; + text-transform: uppercase; + letter-spacing: 0.06em; + color: $gray-700 !important; + background: $gray-50; + padding: 10px 16px !important; +} - > td { - padding: 0; - } +.fdrc-td { + padding: 12px 16px !important; + font-size: 13px; + color: $gray-700; + vertical-align: middle; - .incentives { - overflow: hidden; - } + &--period { + display: flex; + flex-direction: column; + gap: 2px; + } - .mat-card { - border-radius: 0; - } + &--na { + color: #94a3b8; + } +} + +.fdrc-period-range { + font-weight: 700; + color: $gray-900; + font-size: 13px; +} + +.fdrc-period-type { + font-size: 11px; + color: $gray-600; +} + +.fdrc-rate-badge { + display: inline-flex; + align-items: center; + padding: 3px 10px; + background: $blue-light; + color: $blue; + border-radius: 999px; + font-size: 13px; + font-weight: 700; +} + +.fdrc-incentive-btn { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 4px 12px; + height: 32px; + background: transparent; + border: 1.5px solid $border; + border-radius: 6px; + font-size: 12px; + font-weight: 600; + color: $gray-700; + cursor: pointer; + transition: + border-color 0.15s, + color 0.15s; + + &:hover { + border-color: $blue; + color: $blue; + } +} + +.fdrc-header-row { + background: $gray-50; +} + +.fdrc-data-row { + transition: background 0.15s; + + &:hover td { + background: $gray-50; + } + + &--matched td { + background: $green-light !important; + border-left: 3px solid $green; + } +} + +.fdrc-incentives-row { + height: 0; +} + +.fdrc-incentives-cell { + padding: 0 !important; +} + +.fdrc-incentives-wrap { + overflow: hidden; +} + +.fdrc-incentives-inner { + padding: 16px 20px; + background: $gray-50; + border-bottom: 1px solid $border; +} + +.fdrc-incentives-title { + font-size: 12px; + font-weight: 700; + color: $gray-700; + margin-bottom: 12px; + display: flex; + align-items: center; + gap: 8px; + + i { + color: $amber; + } +} + +.fdrc-incentives-table { + width: 100%; + background: #fff; + border: 1px solid $border; + border-radius: 8px; + overflow: hidden; + + th { + font-size: 10px !important; + padding: 8px 12px !important; + background: $gray-100; + } + + td { + font-size: 12px; + padding: 8px 12px !important; + } +} + +.fdrc-empty { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px; + color: $gray-600; + gap: 12px; + + i { + font-size: 32px; + opacity: 0.3; + } + + span { + font-size: 14px; } } diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.ts b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.ts index 07bc5a5e3..38ba5fdbd 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-interest-rate-chart-step/recurring-deposits-account-interest-rate-chart-step.component.ts @@ -6,8 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/** Angular Imports */ -import { Component, OnInit, Input, OnChanges, ViewChild, Output, EventEmitter } from '@angular/core'; +import { Component, OnInit, Input, OnChanges, ViewChild, Output, EventEmitter, inject } from '@angular/core'; +import { RecurringDepositsService } from '../../recurring-deposits.service'; import { MatTable, MatColumnDef, @@ -30,6 +30,18 @@ import { YesnoPipe } from '../../../../pipes/yesno.pipe'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; import { FormsModule } from '@angular/forms'; +export type RdPeriodUnit = 'Days' | 'Months' | 'Years'; + +export interface SlabMatchResult { + slab: any; + slabIndex: number; + appliedRate: number; + maturityAmount?: number; + interestEarned?: number; + tenureDays?: number; + daysInYear?: number; +} + /** * Recurring Deposits Account Interest Rate Chart Step */ @@ -64,45 +76,44 @@ import { FormsModule } from '@angular/forms'; TitleCasePipe, DateFormatPipe, FormatNumberPipe, - YesnoPipe + YesnoPipe, + DecimalPipe ] }) export class RecurringDepositsAccountInterestRateChartStepComponent implements OnInit, OnChanges { @Input() recurringDepositsAccountTemplate: any; @Input() recurringDepositsAccountProductTemplate: any; + @Input() submittedOnDate: Date | null = null; - /** - * CBS base rate chart loaded from the active base-interest-rate service. - * When set, this table is shown instead of the legacy accountChart.chartSlabs. - */ - @Input() set rdInterestRates(rates: any[]) { - this._rdInterestRates = rates || []; - this._activeRdVersion = this._rdInterestRates.find((v: any) => v.isActive) ?? this._rdInterestRates[0] ?? null; + @Output() tenureSelected = new EventEmitter<{ + depositPeriod: number; + depositPeriodFrequencyId: number; + depositAmount?: number; + maturityAmount?: number; + interestEarned?: number; + daysInYear?: number; + }>(); + + get interestRateChartData(): any[] { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + if (!template) return []; + return ( + template.accountChart?.chartSlabs ?? + template.activeChart?.chartSlabs ?? + template.interestRateCharts?.[0]?.chartSlabs ?? + template.interestRateChart?.chartSlabs ?? + template.chartSlabs ?? + [] + ); } - _rdInterestRates: any[] = []; - _activeRdVersion: any = null; - - readonly rdSlabColumns = [ - 'srNo', - 'description', - 'fromPeriod', - 'toPeriod', - 'periodTypeLabel', - 'annualInterestRate' - ]; - - /** Interest Rate Chart Data (legacy – used when no custom rate chart is available) */ - interestRateChartData: any = []; - /** Columns to be displayed in interest rate chart table. */ - chartSlabsDisplayedColumns: any[] = [ + chartSlabsDisplayedColumns: string[] = [ 'period', 'amountRange', 'interest', 'description', 'actions' ]; - /** Columns to be displayed in incentives sub-table. */ incentivesDisplayedColumns: string[] = [ 'entityType', 'attributeName', @@ -111,38 +122,242 @@ export class RecurringDepositsAccountInterestRateChartStepComponent implements O 'incentiveType', 'amount' ]; - /** Additional Column to display incentives table */ chartSlabsIncentivesDisplayedColumns: string[] = ['incentives']; - /** Expand Chart Slab Index used in the view */ - expandChartSlabIndex: number; - /** Tenure entered by user (in days) */ - tenureDays: number | null = null; + expandChartSlabIndex: number | null = null; @ViewChild('chartsTable', { static: true }) chartsTableRef: MatTable; - constructor() {} + // ── Tenure Calculator ─────────────────────────────────────────────────── + tenureValue: number | null = null; + tenurePeriodUnit: RdPeriodUnit = 'Months'; + principalAmount: number | null = null; // Monthly installment for RD - /** Find the matching slab for the entered tenure */ - get applicableSlab(): any | null { - if (!this.tenureDays || !this._activeRdVersion?.slabs?.length) return null; - const days = this.tenureDays; - return ( - this._activeRdVersion.slabs.find((s: any) => { - const from = s.fromPeriod ?? 0; - const to = s.toPeriod ?? Infinity; - return days >= from && days <= to; - }) ?? null - ); - } + matchResult: SlabMatchResult | null = null; + validationWarning: string | null = null; + + /** Period unit options */ + readonly allowedPeriodUnits: RdPeriodUnit[] = [ + 'Months', + 'Years' + ]; + + private recurringDepositsService = inject(RecurringDepositsService); ngOnChanges() { - if (this.recurringDepositsAccountProductTemplate) { - this.interestRateChartData = this.recurringDepositsAccountProductTemplate.accountChart?.chartSlabs ?? []; + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + if (template) { + if (this.chartsTableRef) { + this.chartsTableRef.renderRows(); + } + this.resetCalculator(); + this.tenurePeriodUnit = this.allowedPeriodUnits[1]; // Default to Months } } - ngOnInit() { - this.interestRateChartData = []; + // Convert entered tenure to Days for slab matching + private toDays(value: number, unit: RdPeriodUnit): number { + if (unit === 'Days') return value; + if (unit === 'Months') return value * 30; + return value * 365; + } + + // Convert slab period to days + private slabPeriodToDays(period: number, periodTypeValue: string): number { + const p = (periodTypeValue || '').toLowerCase(); + if (p.includes('month')) return period * 30; + if (p.includes('year')) return period * 365; + return period; // days + } + + calculateRate() { + this.validationWarning = null; + this.matchResult = null; + + if (!this.tenureValue || this.tenureValue <= 0) { + this.validationWarning = 'Please enter a valid tenure value greater than 0.'; + return; + } + + const enteredDays = this.toDays(this.tenureValue, this.tenurePeriodUnit); + const slabs: any[] = this.interestRateChartData || []; + + if (!slabs.length) { + this.validationWarning = 'No interest rate slabs are defined for this product.'; + return; + } + + let matchedSlab: any = null; + let matchedIndex = -1; + + for (let i = 0; i < slabs.length; i++) { + const slab = slabs[i]; + const periodTypeValue = slab.periodType?.value || 'Days'; + const fromDays = this.slabPeriodToDays(slab.fromPeriod ?? 0, periodTypeValue); + const toDays = slab.toPeriod != null ? this.slabPeriodToDays(slab.toPeriod, periodTypeValue) : Infinity; + + if (enteredDays >= fromDays && enteredDays <= toDays) { + matchedSlab = slab; + matchedIndex = i; + break; + } + } + + if (!matchedSlab) { + this.validationWarning = 'No applicable interest rate slab found for the entered tenure.'; + return; + } + + const rate = matchedSlab.annualInterestRate ?? 0; + const result: SlabMatchResult = { + slab: matchedSlab, + slabIndex: matchedIndex, + appliedRate: rate, + tenureDays: enteredDays + }; + + // Maturity Estimation via Backend API + if (this.principalAmount && this.principalAmount > 0) { + const compoundingType = this.recurringDepositsAccountProductTemplate?.interestCompoundingPeriodType?.id; + let compoundingMonths = 1; // Default Monthly + if (compoundingType === 5) compoundingMonths = 3; + else if (compoundingType === 6) compoundingMonths = 6; + else if (compoundingType === 7) compoundingMonths = 12; + else if (compoundingType === 1) compoundingMonths = 0; // Special case for Daily in my API logic + + // Calculate exact months based on unit to avoid rounding errors (e.g. 10 years = 120 months, not 122) + let tenureInMonths = 0; + if (this.tenurePeriodUnit === 'Years') { + tenureInMonths = this.tenureValue * 12; + } else if (this.tenurePeriodUnit === 'Months') { + tenureInMonths = this.tenureValue; + } else { + tenureInMonths = Math.floor(enteredDays / 30); + } + + const calculationData: any = { + depositAmount: this.principalAmount, + annualInterestRate: rate, + tenureInMonths: tenureInMonths, + interestCompoundingPeriodInMonths: compoundingMonths + }; + + if (this.submittedOnDate) { + const date = new Date(this.submittedOnDate); + calculationData.submittedOnDate = date.toISOString().split('T')[0]; + calculationData.dateFormat = 'yyyy-MM-dd'; // Standard ISO for API + calculationData.locale = 'en'; + } + + this.recurringDepositsService.calculateRecurringDepositInterest(calculationData).subscribe((apiResult: any) => { + result.maturityAmount = apiResult.maturityAmount; + result.interestEarned = apiResult.totalInterest; + result.daysInYear = apiResult.daysInYear; + this.matchResult = { ...result }; + this.emitTenureSelection(); + }); + } else { + this.matchResult = result; + this.emitTenureSelection(); + } + } + + private emitTenureSelection() { + const frequencyId = this.resolveFrequencyId(this.tenurePeriodUnit); + if (frequencyId !== null && this.matchResult) { + this.tenureSelected.emit({ + depositPeriod: this.tenureValue || 0, + depositPeriodFrequencyId: frequencyId, + depositAmount: this.principalAmount || undefined, + maturityAmount: this.matchResult.maturityAmount, + interestEarned: this.matchResult.interestEarned, + daysInYear: this.matchResult.daysInYear + }); + } + } + + private resolveFrequencyId(unit: RdPeriodUnit): number | null { + const options: any[] = this.recurringDepositsAccountProductTemplate?.periodFrequencyTypeOptions ?? []; + const unitLower = unit.toLowerCase(); + const match = options.find((o: any) => (o.value || '').toLowerCase().includes(unitLower)); + if (match) return match.id; + const fallback: Record = { Days: 0, Months: 2, Years: 3 }; + return fallback[unit] ?? null; + } + + resetCalculator() { + this.tenureValue = null; + this.principalAmount = null; + this.matchResult = null; + this.validationWarning = null; + this.tenurePeriodUnit = 'Months'; + } + + onPeriodUnitChange() { + this.matchResult = null; + this.validationWarning = null; + } + + isMatchedSlab(index: number): boolean { + return this.matchResult?.slabIndex === index; + } + + // ── Header Getters ────────────────────────────────────────────────────── + + get chartName(): string { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + return ( + template?.accountChart?.name || + template?.activeChart?.name || + template?.interestRateCharts?.[0]?.name || + template?.interestRateChart?.name || + template?.name || + '' + ); + } + + get chartFromDate(): any { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + return ( + template?.accountChart?.fromDate || + template?.activeChart?.fromDate || + template?.interestRateCharts?.[0]?.fromDate || + template?.interestRateChart?.fromDate || + template?.fromDate + ); + } + + get chartEndDate(): any { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + return ( + template?.accountChart?.endDate || + template?.activeChart?.endDate || + template?.interestRateCharts?.[0]?.endDate || + template?.interestRateChart?.endDate || + template?.endDate + ); + } + + get chartDescription(): string { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + return ( + template?.accountChart?.description || + template?.activeChart?.description || + template?.interestRateCharts?.[0]?.description || + template?.interestRateChart?.description || + template?.description || + '' + ); + } + + get isPrimaryGroupingByAmount(): boolean { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + return !!( + template?.accountChart?.isPrimaryGroupingByAmount || + template?.activeChart?.isPrimaryGroupingByAmount || + template?.interestRateCharts?.[0]?.isPrimaryGroupingByAmount || + template?.interestRateChart?.isPrimaryGroupingByAmount || + template?.isPrimaryGroupingByAmount + ); } } diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.html b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.html index 38cf810f9..824777e6b 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.html +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.html @@ -422,18 +422,6 @@ {{ recurringDepositsAccountProductTemplate.taxGroup.name }}
} -
- Balance Swap Option - - {{ rdCurrencyFlags?.balanceSwapOption | yesNo }} - -
-
- MSME - - {{ rdCurrencyFlags?.msme | yesNo }} - -
Auto Debit Facility @@ -497,7 +485,7 @@
Inactive - @if (recurringDepositsAccountProductTemplate?.daysToInactiveFromProduct != null) { + @if (recurringDepositsAccountProductTemplate?.daysToInactiveFromProduct !== null) { After {{ recurringDepositsAccountProductTemplate.daysToInactiveFromProduct }} days of no transaction } @else { Not configured @@ -511,7 +499,7 @@
Dormant - @if (recurringDepositsAccountProductTemplate?.daysToDormancyFromProduct != null) { + @if (recurringDepositsAccountProductTemplate?.daysToDormancyFromProduct !== null) { {{ recurringDepositsAccountProductTemplate.daysToDormancyFromProduct }} days after inactive } @else { Not configured @@ -525,7 +513,7 @@
Escheat - @if (recurringDepositsAccountProductTemplate?.daysToEscheatFromProduct != null) { + @if (recurringDepositsAccountProductTemplate?.daysToEscheatFromProduct !== null) { {{ recurringDepositsAccountProductTemplate.daysToEscheatFromProduct }} days after dormant } @else { Not configured @@ -637,183 +625,225 @@
} - - @if (_activeRdVersion || recurringDepositsAccountProductTemplate?.accountChart) { + + @if (rdMaturityAmount) { +
+
+ + Maturity Summary + Projected +
+
+
+
+ Total Deposit Amount + {{ rdMaturityAmount - rdInterestEarned | formatNumber }} {{ currencyName }} +
+
+ Applicable Interest Rate + {{ rdApplicableSlab?.annualInterestRate | formatNumber }}% +
+
+ Tenure + {{ selectedTenureLabel }} +
+
+ Estimated Interest Earned + + + {{ rdInterestEarned | formatNumber }} {{ currencyName }} + +
+
+ Days in Year + {{ rdDaysInYear ?? 365 }} Days +
+
+ Projected Maturity Amount + + {{ rdMaturityAmount | formatNumber }} {{ currencyName }} + +
+
+
+
+ } + + + @if (interestRateChartData?.length > 0) {
- Interest Rate - @if (_activeRdVersion) { - {{ _activeRdVersion.versionLabel }} + {{ 'labels.heading.Interest Rate Chart' | translate }} + @if (rdTenureDays) { + + Selected Tenure: {{ selectedTenureLabel }} + }
- @if (_activeRdVersion) { - @if (rdTenureDays && rdApplicableSlab) { -
-
- Tenure - {{ rdTenureDays }} Days -
-
- Applicable Slab - {{ rdApplicableSlab.description }} -
-
- Annual Interest Rate - {{ rdApplicableSlab.annualInterestRate | formatNumber }}% + + @if (rdTenureDays && matchedSlabIndex >= 0) { +
+
+ +
+ Your RD Tenure + {{ selectedTenureLabel }}
- } @else { - No tenure entered — interest rate not calculated - } - } @else { -
- @if (recurringDepositsAccountProductTemplate?.accountChart?.name) { -
- {{ 'labels.inputs.name' | translate }} - {{ recurringDepositsAccountProductTemplate.accountChart.name }} -
- } - @if (recurringDepositsAccountProductTemplate?.accountChart?.fromDate) { -
- {{ 'labels.inputs.Valid from Date' | translate }} - {{ - recurringDepositsAccountProductTemplate.accountChart.fromDate | dateFormat - }} -
- } - @if (recurringDepositsAccountProductTemplate?.accountChart?.endDate) { -
- {{ 'labels.inputs.End Date' | translate }} - {{ - recurringDepositsAccountProductTemplate.accountChart.endDate | dateFormat - }} -
- } - @if (recurringDepositsAccountProductTemplate?.accountChart?.description) { -
- {{ 'labels.inputs.Description' | translate }} - {{ - recurringDepositsAccountProductTemplate.accountChart.description - }} -
- } -
- {{ 'labels.inputs.Primary Grouping by Amount' | translate }} - {{ - recurringDepositsAccountProductTemplate?.accountChart?.isPrimaryGroupingByAmount | yesNo - }} +
+
+ Applicable Interest Rate + {{ interestRateChartData[matchedSlabIndex]?.annualInterestRate | formatNumber }}% +
+
+ + Slab: {{ interestRateChartData[matchedSlabIndex]?.fromPeriod }}–{{ + interestRateChartData[matchedSlabIndex]?.toPeriod ?? '∞' + }} + {{ interestRateChartData[matchedSlabIndex]?.periodType?.value }}
+ } - @if (interestRateChartData?.length) { - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + +
{{ 'labels.inputs.Period' | translate }} - {{ chartSlab.fromPeriod }} - {{ chartSlab.toPeriod }} {{ - chartSlab.periodType?.value | translateKey: 'catalogs' - }} - {{ 'labels.inputs.Amount Range' | translate }} - {{ chartSlab.amountRangeFrom | formatNumber }} - {{ chartSlab.amountRangeTo | formatNumber }} - {{ 'labels.inputs.Interest' | translate }}{{ chartSlab.annualInterestRate | formatNumber }} %{{ 'labels.inputs.Description' | translate }}{{ chartSlab.description }}{{ 'labels.inputs.Actions' | translate }} - - + @if (chartName) { +
+ {{ 'labels.inputs.name' | translate }} + {{ chartName }} +
+ } + @if (chartFromDate) { +
+ Valid From + {{ chartFromDate | dateFormat }} +
+ } +
+ Primary Grouping by Amount + + {{ isPrimaryGroupingByAmount | yesNo }} + +
+ + + @if (interestRateChartData?.length) { + + + + + + + + + + + + + + + + + + + + - - - - -
{{ 'labels.inputs.Period' | translate }} + {{ chartSlab.fromPeriod }} - {{ chartSlab.toPeriod }} {{ + chartSlab.periodType?.value | translateKey: 'catalogs' + }} + {{ 'labels.inputs.Amount Range' | translate }} + {{ chartSlab.amountRangeFrom | formatNumber }} - {{ chartSlab.amountRangeTo | formatNumber }} + {{ 'labels.inputs.Interest' | translate }}{{ chartSlab.annualInterestRate | formatNumber }} %{{ 'labels.inputs.Description' | translate }}{{ chartSlab.description }}{{ 'labels.inputs.Actions' | translate }} +
+ + {{ + (expandChartSlabIndex === chartSlabIndex + ? 'labels.buttons.Hide Incentives' + : 'labels.buttons.View Incentives' + ) | translate + }} + +
+
+ +

{{ 'labels.heading.Incentives' | translate }}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'labels.inputs.Entity Type' | translate }}{{ incentive.entityType?.value }}{{ 'labels.inputs.Attribute Name' | translate }}{{ incentive.attributeName?.value }}{{ 'labels.inputs.Condition Type' | translate }}{{ incentive.conditionType?.value | titlecase }}{{ 'labels.inputs.Attribute Value' | translate }}{{ incentive.attributeValueDesc }}{{ 'labels.inputs.Incentive Type' | translate }}{{ incentive.incentiveType?.value }}{{ 'labels.inputs.Interest' | translate }}{{ incentive.amount | formatNumber }}
+
+
+
+ @if (rdTenureDays && matchedSlabIndex >= 0) { +
+ + Highlighted row is the slab applicable for your selected tenure of + {{ selectedTenureLabel }} +
} }
diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.scss b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.scss index d64f7dfdd..8865b082a 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.scss +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.scss @@ -181,32 +181,125 @@ margin-top: 1em; } -// ── Preview Tenure Result Card ───────────────────────────────────────────────── -.preview-tenure-result { - border: 1px solid #e0f2fe; +// ── Section badge variant for tenure ───────────────────────────────────────── +.preview-section__badge--tenure { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 3px 10px; + border-radius: 999px; + font-size: 11px; + font-weight: 700; + background: #dcfce7; + color: #16a34a; + margin-left: auto; +} + +// ── Tenure + Rate banner ────────────────────────────────────────────────────── +.preview-tenure-banner { + display: flex; + align-items: center; + gap: 20px; + padding: 14px 18px; + background: #f0fdf4; + border: 1.5px solid #86efac; border-radius: 10px; - overflow: hidden; + margin-bottom: 16px; + flex-wrap: wrap; - &__row { + &__left { display: flex; - justify-content: space-between; align-items: center; - padding: 0.65rem 1rem; - border-bottom: 1px solid #f0f9ff; + gap: 10px; - &:last-child { - border-bottom: none; - } - - &--highlight { - background: #f0f9ff; + > i { + font-size: 20px; + color: #16a34a; } } - &__rate { - font-size: 1.5rem; + &__label { + display: block; + font-size: 10px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.06em; + color: #4b5563; + } + + &__value { + display: block; + font-size: 22px; font-weight: 800; - color: #0369a1; + color: #0f172a; + line-height: 1.2; + } + + &__divider { + width: 1px; + height: 40px; + background: #86efac; + } + + &__right { + display: flex; + flex-direction: column; + gap: 2px; + } + + &__rate-label { + font-size: 10px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.06em; + color: #4b5563; + } + + &__rate { + font-size: 26px; + font-weight: 800; + color: #16a34a; + line-height: 1.2; + } + + &__slab { + display: flex; + align-items: center; + gap: 6px; + font-size: 12px; + color: #374151; + margin-left: auto; + + i { + color: #16a34a; + font-size: 11px; + } + } +} + +// ── Matched slab row highlight ──────────────────────────────────────────────── +.preview-slab-row--matched td { + background: #dcfce7 !important; + border-left: 3px solid #16a34a; +} + +// ── Legend below table ──────────────────────────────────────────────────────── +.preview-slab-legend { + display: flex; + align-items: center; + gap: 8px; + margin-top: 8px; + font-size: 12px; + color: #4b5563; + + &__dot { + display: inline-block; + width: 12px; + height: 12px; + border-radius: 2px; + background: #dcfce7; + border: 2px solid #16a34a; + flex-shrink: 0; } } diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.ts b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.ts index f67e5f035..32e55ca01 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-preview-step/recurring-deposits-account-preview-step.component.ts @@ -77,10 +77,10 @@ export class RecurringDepositsAccountPreviewStepComponent implements OnChanges { @Input() rdCurrencyFlags: any = null; @Input() rdTenureDays: number | null = null; @Input() rdApplicableSlab: any = null; - @Input() set rdInterestRates(rates: any[]) { - this._rdInterestRates = rates || []; - this._activeRdVersion = this._rdInterestRates.find((v: any) => v.isActive) ?? this._rdInterestRates[0] ?? null; - } + @Input() rdMaturityAmount: number | null = null; + @Input() rdInterestEarned: number | null = null; + @Input() rdDaysInYear: number | null = null; + /** Output the submit action */ @Output() submitEvent = new EventEmitter(); @@ -96,9 +96,6 @@ export class RecurringDepositsAccountPreviewStepComponent implements OnChanges { return this.recurringDepositsAccountProductTemplate?.currency?.inMultiplesOf ?? '—'; } - _rdInterestRates: any[] = []; - _activeRdVersion: any = null; - readonly rdSlabColumns = [ 'srNo', 'description', @@ -117,8 +114,57 @@ export class RecurringDepositsAccountPreviewStepComponent implements OnChanges { 'date', 'repaymentsEvery' ]; - /** Interest Rate Chart Data */ - interestRateChartData: any = []; + get interestRateChartData(): any[] { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + if (!template) return []; + return ( + template.accountChart?.chartSlabs ?? + template.activeChart?.chartSlabs ?? + template.interestRateCharts?.[0]?.chartSlabs ?? + template.interestRateChart?.chartSlabs ?? + template.chartSlabs ?? + [] + ); + } + + /** Matched Slab Index for highlighting */ + get matchedSlabIndex(): number { + if (!this.rdTenureDays || !this.interestRateChartData) return -1; + + // Find index of the applicable slab in the chart data + return this.interestRateChartData.findIndex((slab) => { + const pTypeValue = slab.periodType?.value || 'Days'; + const fromDays = this.slabPeriodToDays(slab.fromPeriod ?? 0, pTypeValue); + const toDays = slab.toPeriod != null ? this.slabPeriodToDays(slab.toPeriod, pTypeValue) : Infinity; + return this.rdTenureDays >= fromDays && this.rdTenureDays <= toDays; + }); + } + + /** Selected Tenure Label for banner */ + get selectedTenureLabel(): string { + if (!this.rdTenureDays) return ''; + if (this.rdTenureDays >= 365) { + const years = Math.floor(this.rdTenureDays / 365); + const rem = this.rdTenureDays % 365; + return years + (years === 1 ? ' Year' : ' Years') + (rem > 0 ? ` ${rem} Days` : ''); + } + if (this.rdTenureDays >= 30) { + const months = Math.floor(this.rdTenureDays / 30); + const rem = this.rdTenureDays % 30; + return months + (months === 1 ? ' Month' : ' Months') + (rem > 0 ? ` ${rem} Days` : ''); + } + return this.rdTenureDays + ' Days'; + } + + private slabPeriodToDays(period: number, periodTypeValue: string): number { + const p = (periodTypeValue || '').toLowerCase(); + if (p.includes('day')) return period; + if (p.includes('week')) return period * 7; + if (p.includes('month')) return period * 30; + if (p.includes('year')) return period * 365; + return period; + } + /** Columns to be displayed in interest rate chart table. */ chartSlabsDisplayedColumns: any[] = [ 'period', @@ -144,8 +190,68 @@ export class RecurringDepositsAccountPreviewStepComponent implements OnChanges { constructor() {} ngOnChanges() { - if (this.recurringDepositsAccountProductTemplate) { - this.interestRateChartData = this.recurringDepositsAccountProductTemplate.accountChart?.chartSlabs ?? []; + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + if (template) { + // Logic for metadata getters is now handled by the dynamic template reference } } + + // ── Header Getters ────────────────────────────────────────────────────── + + get chartName(): string { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + return ( + template?.accountChart?.name || + template?.activeChart?.name || + template?.interestRateCharts?.[0]?.name || + template?.interestRateChart?.name || + template?.name || + '' + ); + } + + get chartFromDate(): any { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + return ( + template?.accountChart?.fromDate || + template?.activeChart?.fromDate || + template?.interestRateCharts?.[0]?.fromDate || + template?.interestRateChart?.fromDate || + template?.fromDate + ); + } + + get chartEndDate(): any { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + return ( + template?.accountChart?.endDate || + template?.activeChart?.endDate || + template?.interestRateCharts?.[0]?.endDate || + template?.interestRateChart?.endDate || + template?.endDate + ); + } + + get chartDescription(): string { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + return ( + template?.accountChart?.description || + template?.activeChart?.description || + template?.interestRateCharts?.[0]?.description || + template?.interestRateChart?.description || + template?.description || + '' + ); + } + + get isPrimaryGroupingByAmount(): boolean { + const template = this.recurringDepositsAccountProductTemplate || this.recurringDepositsAccountTemplate; + return !!( + template?.accountChart?.isPrimaryGroupingByAmount || + template?.activeChart?.isPrimaryGroupingByAmount || + template?.interestRateCharts?.[0]?.isPrimaryGroupingByAmount || + template?.interestRateChart?.isPrimaryGroupingByAmount || + template?.isPrimaryGroupingByAmount + ); + } } diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-terms-step/recurring-deposits-account-terms-step.component.html b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-terms-step/recurring-deposits-account-terms-step.component.html index cde86842a..b221ede68 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-terms-step/recurring-deposits-account-terms-step.component.html +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-stepper/recurring-deposits-account-terms-step/recurring-deposits-account-terms-step.component.html @@ -14,7 +14,7 @@ Interest Rate & Posting Terms
- @if (recurringDepositsAccountProductTemplate?.nominalAnnualInterestRate != null) { + @if (recurringDepositsAccountProductTemplate?.nominalAnnualInterestRate !== null) {
ℹ️ diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/interest-rate-chart-tab/interest-rate-chart-tab.component.ts b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/interest-rate-chart-tab/interest-rate-chart-tab.component.ts index 77d7c9cf2..8192faeb2 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/interest-rate-chart-tab/interest-rate-chart-tab.component.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/interest-rate-chart-tab/interest-rate-chart-tab.component.ts @@ -92,7 +92,12 @@ export class InterestRateChartTabComponent { */ constructor() { this.route.parent.data.subscribe((data: { recurringDepositsAccountData: any }) => { - this.interestRateChartData = data.recurringDepositsAccountData.accountChart.chartSlabs; + const accountData = data.recurringDepositsAccountData; + this.interestRateChartData = + accountData.accountChart?.chartSlabs ?? + accountData.activeChart?.chartSlabs ?? + accountData.interestRateCharts?.[0]?.chartSlabs ?? + []; }); } } diff --git a/src/app/deposits/recurring-deposits/recurring-deposits.service.ts b/src/app/deposits/recurring-deposits/recurring-deposits.service.ts index a4dab5594..db9af6cc8 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits.service.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits.service.ts @@ -173,4 +173,11 @@ export class RecurringDepositsService { params: httpParams }); } + /** + * Calculates the interest for a recurring deposit account + * @param data Calculation data + */ + calculateRecurringDepositInterest(data: any): Observable { + return this.http.post(`/recurringdepositaccounts/calculate-rd-interest`, data); + } } diff --git a/src/app/products/products-routing.module.ts b/src/app/products/products-routing.module.ts index 6838e83bd..c1a923d76 100644 --- a/src/app/products/products-routing.module.ts +++ b/src/app/products/products-routing.module.ts @@ -49,7 +49,6 @@ import { EditTaxComponentComponent } from './manage-tax-components/edit-tax-comp import { ViewTaxGroupComponent } from './manage-tax-groups/view-tax-group/view-tax-group.component'; import { ShareProductsDividendsComponent } from './share-products/dividends-share-product/dividends.components'; import { CreateRecurringDepositProductComponent } from './recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component'; -import { BaseRecurringDepositInterestRateChartComponent } from './recurring-deposit-products/base-recurring-deposit-interest-rate-chart/base-recurring-deposit-interest-rate-chart.component'; import { CreateDividendComponent } from './share-products/create-dividend/create-dividend.component'; import { ViewFixedDepositProductComponent } from './fixed-deposit-products/view-fixed-deposit-product/view-fixed-deposit-product.component'; import { ViewDividendComponent } from './share-products/view-dividend/view-dividend.component'; @@ -655,14 +654,6 @@ const routes: Routes = [ path: 'recurring-deposit-products', data: { title: 'Recurring Deposit Products', breadcrumb: 'Recurring Deposit Products' }, children: [ - { - path: 'base-interest-rates', - component: BaseRecurringDepositInterestRateChartComponent, - data: { title: 'CBS Base Interest Rates', breadcrumb: 'Base Interest Rates' }, - resolve: { - recurringDepositProductsTemplate: RecurringDepositProductsTemplateResolver - } - }, { path: 'create', component: CreateRecurringDepositProductComponent, @@ -717,14 +708,6 @@ const routes: Routes = [ } } ] - }, - { - path: 'interest-rates', - component: RdInterestRatesTabComponent, - data: { title: 'CBS Base Chart', breadcrumb: 'CBS Base Chart', routeParamBreadcrumb: false }, - resolve: { - rdInterestRates: rdInterestRatesResolver - } } ] }, diff --git a/src/app/products/recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component.ts b/src/app/products/recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component.ts index f30868277..e67d1bf8b 100644 --- a/src/app/products/recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component.ts +++ b/src/app/products/recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component.ts @@ -34,6 +34,7 @@ import { import { ProductsService } from 'app/products/products.service'; import { SettingsService } from 'app/settings/settings.service'; import { Accounting } from 'app/core/utils/accounting'; +import { Dates } from 'app/core/utils/dates'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { RecurringDepositProductPreviewStepComponent } from '../recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component'; import { MatTabsModule } from '@angular/material/tabs'; @@ -72,6 +73,7 @@ export class CreateRecurringDepositProductComponent { private router = inject(Router); private settingsService = inject(SettingsService); private accounting = inject(Accounting); + private dateUtils = inject(Dates); @ViewChild(RecurringDepositProductDetailsStepComponent, { static: true }) recurringDepositProductDetailsStep: RecurringDepositProductDetailsStepComponent; @@ -112,7 +114,7 @@ export class CreateRecurringDepositProductComponent { }); this.accountingRuleData = this.accounting.getAccountingRulesForSavings(); // Load the CBS base chart as the reference for the editable table - this.productsService.getRdBaseInterestRates().subscribe({ + this.productsService.getFdBaseInterestRates().subscribe({ next: (rates: any[]) => { this.rdInterestRates = rates || []; }, @@ -151,7 +153,18 @@ export class CreateRecurringDepositProductComponent { } get activeBaseVersion() { - return this.rdInterestRates.find((version: any) => version.isActive) ?? this.rdInterestRates[0] ?? null; + const chart = + this.rdInterestRates.find((version: any) => version.fdType === 'DOUBLE' && version.isActive) ?? + this.rdInterestRates.find((version: any) => version.fdType === 'DOUBLE') ?? + this.rdInterestRates[0]; + if (chart) { + return { + ...chart, + versionLabel: chart.versionLabel?.replace('FD', 'RD'), + remarks: chart.remarks?.replace('FD', 'RD') + }; + } + return null; } get activeBaseSlabs() { @@ -166,17 +179,66 @@ export class CreateRecurringDepositProductComponent { ...this.recurringDepositProductSettingsStep.recurringDepositProductSettings, ...this.recurringDepositProductChargesStep.recurringDepositProductCharges, ...this.recurringDepositProductAccountingStep.recurringDepositProductAccounting, + charts: this.recurringDepositProductCharts, rdSlabs: this.activeBaseSlabs }; } + get recurringDepositProductCharts() { + const activeBaseVersion = this.activeBaseVersion; + if (!activeBaseVersion?.slabs?.length) { + return []; + } + const dateFormat = this.settingsService.dateFormat; + + return [ + { + name: activeBaseVersion.versionLabel || 'CBS Base Chart', + description: activeBaseVersion.remarks || activeBaseVersion.versionLabel || 'CBS base chart', + fromDate: + this.dateUtils.formatDate(activeBaseVersion.effectiveFromDate, dateFormat) || + activeBaseVersion.effectiveFromDate, + ...(activeBaseVersion.effectiveToDate + ? { + endDate: + this.dateUtils.formatDate(activeBaseVersion.effectiveToDate, dateFormat) || + activeBaseVersion.effectiveToDate + } + : {}), + isPrimaryGroupingByAmount: false, + locale: this.settingsService.language.code, + dateFormat, + chartSlabs: activeBaseVersion.slabs.map((slab: any) => { + const chartSlab: any = { + periodType: slab.periodTypeEnum, + fromPeriod: slab.fromPeriod, + toPeriod: slab.toPeriod, + annualInterestRate: slab.annualInterestRate, + description: slab.description || '', + incentives: [] as any[] + }; + + if (slab.amountRangeFrom !== null && slab.amountRangeFrom !== undefined && slab.amountRangeFrom !== '') { + chartSlab.amountRangeFrom = slab.amountRangeFrom; + } + + if (slab.amountRangeTo !== null && slab.amountRangeTo !== undefined && slab.amountRangeTo !== '') { + chartSlab.amountRangeTo = slab.amountRangeTo; + } + + return chartSlab; + }) + } + ] as any[]; + } + submit() { - // TODO: Update once language and date settings are setup - const recurringDepositProduct = { + const recurringDepositProduct: any = this.pruneEmptyValues({ ...this.recurringDepositProduct, - charges: this.recurringDepositProduct.charges.map((charge: any) => ({ id: charge.id })), - locale: this.settingsService.language.code // locale required for depositAmount - }; + charts: this.recurringDepositProductCharts, + charges: (this.recurringDepositProduct.charges ?? []).map((charge: any) => ({ id: charge.id })), + locale: this.settingsService.language.code + }); if (!recurringDepositProduct.description) { recurringDepositProduct.description = ''; } @@ -191,4 +253,35 @@ export class CreateRecurringDepositProductComponent { ); }); } + + private pruneEmptyValues(value: T): T { + if (Array.isArray(value)) { + return value.map((item) => this.pruneEmptyValues(item)).filter((item) => item !== undefined) as T; + } + + if (value && typeof value === 'object') { + return Object.entries(value as Record).reduce( + (acc, [ + key, + currentValue + ]) => { + const cleanedValue = this.pruneEmptyValues(currentValue); + if (cleanedValue === undefined) { + return acc; + } + return { + ...acc, + [key]: cleanedValue + }; + }, + {} as Record + ) as T; + } + + if (value === '' || value === null || value === undefined) { + return undefined as T; + } + + return value; + } } diff --git a/src/app/products/recurring-deposit-products/edit-recurring-deposit-product/edit-recurring-deposit-product.component.ts b/src/app/products/recurring-deposit-products/edit-recurring-deposit-product/edit-recurring-deposit-product.component.ts index 84979a8a5..595b959f3 100644 --- a/src/app/products/recurring-deposit-products/edit-recurring-deposit-product/edit-recurring-deposit-product.component.ts +++ b/src/app/products/recurring-deposit-products/edit-recurring-deposit-product/edit-recurring-deposit-product.component.ts @@ -34,6 +34,7 @@ import { import { ProductsService } from 'app/products/products.service'; import { SettingsService } from 'app/settings/settings.service'; import { Accounting } from 'app/core/utils/accounting'; +import { Dates } from 'app/core/utils/dates'; import { MatTabsModule } from '@angular/material/tabs'; import { RecurringDepositProductPreviewStepComponent } from '../recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; @@ -70,6 +71,7 @@ export class EditRecurringDepositProductComponent { private router = inject(Router); private settingsService = inject(SettingsService); private accounting = inject(Accounting); + private dateUtils = inject(Dates); @ViewChild(RecurringDepositProductDetailsStepComponent, { static: true }) recurringDepositProductDetailsStep: RecurringDepositProductDetailsStepComponent; @@ -107,7 +109,7 @@ export class EditRecurringDepositProductComponent { constructor() { this.route.data.subscribe((data: { recurringDepositProductAndTemplate: any }) => { this.recurringDepositProductsTemplate = data.recurringDepositProductAndTemplate; - this.productsService.getRdBaseInterestRates().subscribe({ + this.productsService.getFdBaseInterestRates().subscribe({ next: (rates: any[]) => { this.rdInterestRates = rates || []; }, @@ -148,7 +150,18 @@ export class EditRecurringDepositProductComponent { } get activeBaseVersion() { - return this.rdInterestRates.find((version: any) => version.isActive) ?? this.rdInterestRates[0] ?? null; + const chart = + this.rdInterestRates.find((version: any) => version.fdType === 'DOUBLE' && version.isActive) ?? + this.rdInterestRates.find((version: any) => version.fdType === 'DOUBLE') ?? + this.rdInterestRates[0]; + if (chart) { + return { + ...chart, + versionLabel: chart.versionLabel?.replace('FD', 'RD'), + remarks: chart.remarks?.replace('FD', 'RD') + }; + } + return null; } get activeBaseSlabs() { @@ -163,6 +176,7 @@ export class EditRecurringDepositProductComponent { ...this.recurringDepositProductSettingsStep.recurringDepositProductSettings, ...this.recurringDepositProductChargesStep.recurringDepositProductCharges, ...this.recurringDepositProductAccountingStep.recurringDepositProductAccounting, + charts: this.recurringDepositProductCharts, rdSlabs: this.activeBaseSlabs }; } @@ -170,13 +184,63 @@ export class EditRecurringDepositProductComponent { get recurringDepositProductPreview() { return { ...this.recurringDepositProduct, + charts: this.recurringDepositProductCharts, rdSlabs: this.activeBaseSlabs }; } + get recurringDepositProductCharts() { + const activeBaseVersion = this.activeBaseVersion; + if (!activeBaseVersion?.slabs?.length) { + return []; + } + const dateFormat = this.settingsService.dateFormat; + + return [ + { + name: activeBaseVersion.versionLabel || 'CBS Base Chart', + description: activeBaseVersion.remarks || activeBaseVersion.versionLabel || 'CBS base chart', + fromDate: + this.dateUtils.formatDate(activeBaseVersion.effectiveFromDate, dateFormat) || + activeBaseVersion.effectiveFromDate, + ...(activeBaseVersion.effectiveToDate + ? { + endDate: + this.dateUtils.formatDate(activeBaseVersion.effectiveToDate, dateFormat) || + activeBaseVersion.effectiveToDate + } + : {}), + isPrimaryGroupingByAmount: false, + locale: this.settingsService.language.code, + dateFormat, + chartSlabs: activeBaseVersion.slabs.map((slab: any) => { + const chartSlab: any = { + periodType: slab.periodTypeEnum, + fromPeriod: slab.fromPeriod, + toPeriod: slab.toPeriod, + annualInterestRate: slab.annualInterestRate, + description: slab.description || '', + incentives: [] as any[] + }; + + if (slab.amountRangeFrom !== null && slab.amountRangeFrom !== undefined && slab.amountRangeFrom !== '') { + chartSlab.amountRangeFrom = slab.amountRangeFrom; + } + + if (slab.amountRangeTo !== null && slab.amountRangeTo !== undefined && slab.amountRangeTo !== '') { + chartSlab.amountRangeTo = slab.amountRangeTo; + } + + return chartSlab; + }) + } + ] as any[]; + } + submit() { const recurringDepositProduct: any = this.pruneEmptyValues({ ...this.recurringDepositProduct, + charts: this.recurringDepositProductCharts, charges: (this.recurringDepositProduct.charges ?? []).map((charge: any) => ({ id: charge.id })), locale: this.settingsService.language.code }); diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-currency-step/recurring-deposit-product-currency-step.component.html b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-currency-step/recurring-deposit-product-currency-step.component.html index d21e17094..0114b7dea 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-currency-step/recurring-deposit-product-currency-step.component.html +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-currency-step/recurring-deposit-product-currency-step.component.html @@ -63,28 +63,6 @@
-
-
-

Balance Swap Option

-

Enable automated transfer of excess funds to linked deposits or vice-versa to maintain liquidity.

-
- - yes - no - -
- -
-
-

MSME

-

Micro, Small and Medium Enterprises

-
- - yes - no - -
-

Nomination Facility

diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-currency-step/recurring-deposit-product-currency-step.component.ts b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-currency-step/recurring-deposit-product-currency-step.component.ts index 25e2a9c41..efc71693a 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-currency-step/recurring-deposit-product-currency-step.component.ts +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-currency-step/recurring-deposit-product-currency-step.component.ts @@ -55,8 +55,6 @@ export class RecurringDepositProductCurrencyStepComponent implements OnInit { daysToInactive: this.recurringDepositProductsTemplate.daysToInactive ?? 30, daysToDormancy: this.recurringDepositProductsTemplate.daysToDormancy ?? 60, daysToEscheat: this.recurringDepositProductsTemplate.daysToEscheat ?? 90, - balanceSwapOption: this.recurringDepositProductsTemplate.balanceSwapOption ?? false, - msme: this.recurringDepositProductsTemplate.msme ?? false, nominationFacility: this.recurringDepositProductsTemplate.nominationFacility ?? false, autoDebitFacility: this.recurringDepositProductsTemplate.autoDebitFacility ?? false }); @@ -80,8 +78,6 @@ export class RecurringDepositProductCurrencyStepComponent implements OnInit { daysToInactive: [30], daysToDormancy: [60], daysToEscheat: [90], - balanceSwapOption: [false], - msme: [false], nominationFacility: [false], autoDebitFacility: [false] }); @@ -93,8 +89,6 @@ export class RecurringDepositProductCurrencyStepComponent implements OnInit { currencyCode: formValue.currencyCode, digitsAfterDecimal: formValue.digitsAfterDecimal, dormancyAlert: formValue.dormancyAlert, - balanceSwapOption: formValue.balanceSwapOption, - msme: formValue.msme, nominationFacility: formValue.nominationFacility, autoDebitFacility: formValue.autoDebitFacility }; diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.html b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.html index 5ec95ac4e..c85e13da2 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.html +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.html @@ -78,15 +78,6 @@ Account Type is required - - Customer Segment - - @for (customerSegment of customerSegmentData; track customerSegment) { - {{ customerSegment }} - } - - - GL Account (Liability) diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts index 749ac8a3b..c0b089668 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-details-step/recurring-deposit-product-details-step.component.ts @@ -72,7 +72,6 @@ export class RecurringDepositProductDetailsStepComponent implements OnInit, OnCh null, Validators.required ], - customerSegment: [null], glAccountId: [null], effectiveTo: [''], endDate: [''], @@ -107,7 +106,6 @@ export class RecurringDepositProductDetailsStepComponent implements OnInit, OnCh private applyTemplate(template: any) { this.accountTypeData = this.getOptionNames(template.accountTypeOptions); - this.customerSegmentData = this.getOptionNames(template.customerSegmentOptions); this.liabilityAccountOptions = template.accountingMappingOptions?.liabilityAccountOptions ?? []; this.cdr.detectChanges(); @@ -117,7 +115,6 @@ export class RecurringDepositProductDetailsStepComponent implements OnInit, OnCh shortName: isEditing ? template.shortName : template.shortName || '', description: template.description || '', accountType: template.accountType ?? this.accountTypeData[0] ?? null, - customerSegment: template.customerSegment ?? this.customerSegmentData[0] ?? null, glAccountId: template.glAccountId ?? null, effectiveTo: this.parseDate(template.effectiveTo), endDate: this.parseDate(template.endDate), diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.html b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.html index a946f557e..a5a5d73a7 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.html +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.html @@ -1,4 +1,4 @@ -

{{ 'labels.inputs.Terms' | translate }}

@@ -324,8 +325,9 @@
} - + @if (recurringDepositProduct.rdSlabs?.length) { +

{{ 'labels.heading.Interest Rate Charts' | translate }}

diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.html b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.html index df3d7e0f7..5ff5154a4 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.html +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.html @@ -7,6 +7,25 @@ -->
+
+
+ + Deposit Amount +
+
+
+ + Minimum + + + + + Maximum + + +
+
+
@@ -78,6 +97,26 @@ + + Interest Compounding Period + + @for (opt of interestCompoundingPeriodTypeData; track opt.id) { + {{ opt.value | translateKey: 'catalogs' }} + } + + Interest Compounding Period is required + + + + Days in Year + + @for (opt of interestCalculationDaysInYearTypeData; track opt.id) { + {{ opt.value | translateKey: 'catalogs' }} + } + + Days in Year is required + + @if (recurringDepositProductTermsForm.value.interestCalculationType === 2) { Average Period diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.ts b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.ts index 838f3e42e..66e7ae25f 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.ts +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-terms-step/recurring-deposit-product-terms-step.component.ts @@ -85,7 +85,9 @@ export class RecurringDepositProductTermsStepComponent implements OnInit { frequencyFixDay: isEditing ? (this.recurringDepositProductsTemplate.frequencyFixDay ?? 30) : 30, lastInterestDate: this.recurringDepositProductsTemplate.lastInterestDate ? this.parseDate(this.recurringDepositProductsTemplate.lastInterestDate) - : '' + : '', + minDepositAmount: this.recurringDepositProductsTemplate.minDepositAmount ?? '', + maxDepositAmount: this.recurringDepositProductsTemplate.maxDepositAmount ?? '' }); } @@ -145,7 +147,9 @@ export class RecurringDepositProductTermsStepComponent implements OnInit { 30, [Validators.min(0)] ], - lastInterestDate: [''] + lastInterestDate: [''], + minDepositAmount: [''], + maxDepositAmount: [''] }); } @@ -156,14 +160,8 @@ export class RecurringDepositProductTermsStepComponent implements OnInit { if (formValue.effectiveDate instanceof Date) { formValue.effectiveDate = this.dateUtils.formatDate(formValue.effectiveDate, dateFormat) || ''; } - if (formValue.lastInterestDate instanceof Date) { - formValue.lastInterestDate = this.dateUtils.formatDate(formValue.lastInterestDate, dateFormat) || ''; - } - for (const key in formValue) { - if (formValue[key] === '') { - delete formValue[key]; - } - } + formValue.minDepositAmount = formValue.minDepositAmount; + formValue.maxDepositAmount = formValue.maxDepositAmount; return formValue; } } diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-products.component.html b/src/app/products/recurring-deposit-products/recurring-deposit-products.component.html index a2e463e62..5523e15cc 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-products.component.html +++ b/src/app/products/recurring-deposit-products/recurring-deposit-products.component.html @@ -20,18 +20,6 @@ {{ 'labels.buttons.Create Recurring Deposit Product' | translate }}
-
- -
diff --git a/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.html b/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.html index 1105b7f68..b2ecd741d 100644 --- a/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.html +++ b/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.html @@ -48,12 +48,6 @@ {{ recurringDepositProduct.accountType }}
} - @if (recurringDepositProduct.customerSegment) { -
- Customer Segment: - {{ recurringDepositProduct.customerSegment }} -
- } @if (recurringDepositProduct.glAccountId) {
GL Account (Liability): @@ -99,14 +93,6 @@ Dormancy Alert: {{ recurringDepositProduct.dormancyAlert | yesNo }}
-
- Balance Swap Option: - {{ recurringDepositProduct.balanceSwapOption | yesNo }} -
-
- MSME: - {{ recurringDepositProduct.msme | yesNo }} -
Nomination Facility: {{ recurringDepositProduct.nominationFacility | yesNo }} diff --git a/src/app/products/recurring-deposit-products/view-recurring-deposit-product/view-recurring-deposit-product.component.html b/src/app/products/recurring-deposit-products/view-recurring-deposit-product/view-recurring-deposit-product.component.html index 4bde6da1a..041cff962 100644 --- a/src/app/products/recurring-deposit-products/view-recurring-deposit-product/view-recurring-deposit-product.component.html +++ b/src/app/products/recurring-deposit-products/view-recurring-deposit-product/view-recurring-deposit-product.component.html @@ -18,15 +18,6 @@ > {{ 'labels.heading.General' | translate }} - - CBS Base Chart - @for (recurringDepositDatatable of recurringDepositDatatables; track recurringDepositDatatable) {