fix(deposits): FD Single Rate Calculator sent tenureInMonths=0 for tenures under 30 days
SYMPTOM FD Single account create screen, Rate Calculator: entering a tenure under 30 days (e.g. 27) and clicking "Find Rate" produced a Bad Request - "The parameter `tenureInMonths` must be greater than 0." ROOT CAUSE calculateRate() (fixed-deposit-account-interest-rate-chart-step. component.ts) always converted the Days-unit tenure to months before calling the backend calculator: tenureInMonths = Math.floor(enteredDays / 30) For any tenure under 30 days this floors to 0, which the backend correctly rejects (paired backend commit: "FD Single Rate Calculator crashed for tenures under 30 days"). FIX - fixed-deposits.service.ts: calculateFixedDepositInterest() - tenureInMonths is now optional, added optional tenureInDays. - fixed-deposit-account-interest-rate-chart-step.component.ts - calculateRate(): for a Days-unit tenure >= 30 days, unchanged (tenureInMonths = floor(days/30)); for < 30 days, sends tenureInDays instead and leaves tenureInMonths undefined. Also fixed the API-failure fallback's periodic-compounding math, which divided by tenureInMonths directly and would have produced NaN once tenureInMonths could legitimately be undefined - it now falls back to (enteredDays / 30) when tenureInMonths is absent. SCOPE Only the Rate Calculator preview inside the FD Single/Double/Special account create screen. Does not touch how depositPeriod / depositPeriodFrequencyId get sent on actual account submission. IF THIS BREAKS SOMETHING LATER - The same 400 reappearing for a short FD Single tenure -> confirm the Find Rate network call carries tenureInDays and NOT a zero tenureInMonths; check calculateRate()'s branch choosing between the two. - A wrong maturity preview number specifically when the backend API call fails and the frontend falls back to its own formula -> check the `effectiveMonths = tenureInMonths ?? enteredDays / 30` fallback line in calculateRate(). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+10
-4
@@ -334,14 +334,18 @@ export class FixedDepositAccountInterestRateChartStepComponent implements OnChan
|
||||
const frequencyId = this.resolveFrequencyId(this.tenurePeriodUnit);
|
||||
|
||||
if (this.principalAmount && this.principalAmount > 0) {
|
||||
// Convert tenure to months for backend API
|
||||
let tenureInMonths = 0;
|
||||
// Convert tenure to months for backend API. A Days tenure under 30 days rounds down to 0
|
||||
// months, which the backend rejects -- send it as tenureInDays instead in that case.
|
||||
let tenureInMonths: number | undefined;
|
||||
let tenureInDays: number | undefined;
|
||||
if (this.tenurePeriodUnit === 'Years') {
|
||||
tenureInMonths = this.tenureValue * 12;
|
||||
} else if (this.tenurePeriodUnit === 'Months') {
|
||||
tenureInMonths = this.tenureValue;
|
||||
} else {
|
||||
} else if (enteredDays >= 30) {
|
||||
tenureInMonths = Math.floor(enteredDays / 30);
|
||||
} else {
|
||||
tenureInDays = enteredDays;
|
||||
}
|
||||
|
||||
// Map compounding period type id → months (0=Daily, 1=Daily, 4=Monthly, 5=Quarterly, 6=SemiAnnual, 7=Annual)
|
||||
@@ -395,6 +399,7 @@ export class FixedDepositAccountInterestRateChartStepComponent implements OnChan
|
||||
principalAmount: this.principalAmount,
|
||||
annualInterestRate: rate,
|
||||
tenureInMonths,
|
||||
tenureInDays,
|
||||
interestCompoundingPeriodInMonths: compMonths, // 0 = daily, now supported by backend
|
||||
interestPostingPeriodInMonths: postMonths,
|
||||
submittedOnDate: submittedOnDateStr,
|
||||
@@ -417,7 +422,8 @@ export class FixedDepositAccountInterestRateChartStepComponent implements OnChan
|
||||
Math.round(this.principalAmount * Math.pow(1 + r / daysInYearVal, enteredDays) * 100) / 100;
|
||||
} else {
|
||||
const n = 12 / compMonths;
|
||||
const totalCompoundings = Math.floor(tenureInMonths / compMonths);
|
||||
const effectiveMonths = tenureInMonths ?? enteredDays / 30;
|
||||
const totalCompoundings = Math.floor(effectiveMonths / compMonths);
|
||||
const rPerCompounding = rate / (n * 100);
|
||||
result.maturityAmount =
|
||||
Math.round(this.principalAmount * Math.pow(1 + rPerCompounding, totalCompoundings) * 100) / 100;
|
||||
|
||||
@@ -133,7 +133,8 @@ export class FixedDepositsService {
|
||||
calculateFixedDepositInterest(params: {
|
||||
principalAmount: number;
|
||||
annualInterestRate: number;
|
||||
tenureInMonths: number;
|
||||
tenureInMonths?: number;
|
||||
tenureInDays?: number; // alternative to tenureInMonths, for sub-month FD Single tenures
|
||||
interestCompoundingPeriodInMonths: number;
|
||||
interestPostingPeriodInMonths: number;
|
||||
submittedOnDate?: string; // yyyy-MM-dd — enables exact calendar calculation
|
||||
|
||||
Reference in New Issue
Block a user