Files
cbsnexora-backend/fineract-core
niteshandClaude Sonnet 5 bc38216ca3 fix(deposits): FD Single Rate Calculator crashed for tenures under 30 days
SYMPTOM
Opening the FD account create screen for a "SINGLE" (Days < 1 Year)
product, entering a Deposit Tenure under 30 days (e.g. 27), and
clicking "Find Rate" returned a 400:
  "The parameter `tenureInMonths` must be greater than 0."

ROOT CAUSE
The Rate Calculator preview always converted the entered tenure to
months before calling GET /fixeddepositaccounts/calculate-fd-interest
(fixed-deposits.service.ts -> fixed-deposit-account-interest-rate-
chart-step.component.ts, calculateRate()):
  tenureInMonths = Math.floor(enteredDays / 30)
For any tenure under 30 days this floors to 0, and
DepositAccountDataValidator.validateForInterestCalc() requires
tenureInMonths > 0 unconditionally, so the request was rejected
before it ever reached the calculation service.

FIX
Added `tenureInDays` as an alternative to `tenureInMonths` for this
one calculator endpoint only (DepositsApiConstants.
FIXED_DEPOSIT_ACCOUNT_INTEREST_CALCULATION_PARAMETERS) - not a
general-purpose FD field, not touched anywhere else:
  - DepositAccountDataValidator: tenureInMonths is required unless
    tenureInDays is a positive value (either satisfies the check).
  - FixedDepositAccountsApiResource#calculateFixedDepositInterest:
    accepts the optional tenureInDays query param.
  - FixedDepositAccountInterestCalculationServiceImpl#calculateInterest:
    when tenureInDays > 0, the exact-calendar maturityDate is computed
    via submittedOnDate.plusDays(tenureInDays) instead of
    plusMonths(tenureInMonths) (which would silently compute a 0-day
    maturity window for a sub-month tenure).
  - Frontend (separate commit) now sends tenureInDays instead of a
    truncated-to-zero tenureInMonths whenever the entered tenure is
    under 30 days.

SCOPE / WHAT THIS DOES NOT TOUCH
Only the interest-preview calculator endpoint above. Real FD/RD
account submission still uses depositPeriod + depositPeriodFrequencyId
(Days=0) exactly as before; this commit does not change how an actual
account's maturity date/amount gets computed at activation.

IF THIS BREAKS SOMETHING LATER
- "tenureInMonths must be greater than 0" reappearing for a SHORT FD
  tenure -> check the frontend is actually sending tenureInDays (network
  tab on the Find Rate call); the validator's OR-logic is in
  DepositAccountDataValidator.validateForInterestCalc().
- A wrong preview maturity amount for a sub-month FD Single -> check
  FixedDepositAccountInterestCalculationServiceImpl#calculateInterest's
  branch choosing plusDays vs plusMonths for maturityDate.
- This bug and fix were previously implemented once, then fully
  reverted mid-session at the user's request (unrelated Deposit Account
  Link regression got tangled up with it), then reapplied cleanly here
  as a standalone, narrowly-scoped fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 14:20:38 +05:30
..