Four independent, self-contained changes bundled from this session's work:
1. Auto-derive Senior Citizen / Minor / Customer Segment instead of manual entry
Senior Citizen was a manual, staff-editable checkbox on FD/RD account
creation with no validation against the client's actual age -- this let
non-senior clients get the senior-citizen interest rate by mistake (found
twice on live test accounts, where m_savings_account.is_senior_citizen
was true despite the client being confirmed non-senior at the client
record level). Likewise "minor" client classification was hardcoded to
the age-18 threshold with no single source of truth, and FD/RD account
creation's "Customer Segment" (Individual / Non-Individual) had no
connection to the Individual/Non-Individual Legal Form already captured
at client creation.
- New src/app/clients/shared/client-age.util.ts centralises age/DOB
derivation: MINOR_AGE_THRESHOLD (now 10, was 18), SENIOR_CITIZEN_AGE_
THRESHOLD (60), AGE_OF_MAJORITY (18, kept separate from the minor
threshold -- majority date math is unrelated to the minor/adult
classification threshold), calculateAge/isMinorAge/isSeniorCitizenAge/
isIndividualClient/deriveSeniorCitizenStatus.
- FD/RD interest-rate-chart steps: Senior Citizen checkbox is now derived
from the client's DOB (age >= 60, individual clients only) and
disabled for manual editing; a hint explains why it is checked/
unchecked.
- Client general step and all four account-details-steps (savings,
current, FD, RD): replaced hardcoded 18/60 literals with the shared
helpers; "Must be below 18" hints now read the actual threshold.
- FD/RD account-details-steps: Customer Segment auto-selects to match
the client's Legal Form (exact match, not substring -- a substring
match would misclassify "Individual" as matching "Non-Individual").
- RD preview step: fixed a pre-existing display bug that always showed
the product's default Customer Segment instead of what was actually
selected on the account.
2. Fix wrong Account Name / Account Type on Disbursement Review screens
Clerk disbursement review and "My Disbursement Requests" showed the
account NUMBER instead of the holder's name, and always labelled the
account type "SAVINGS" regardless of the real account type (FD/RD/
Share/Loan), because transaction-entry.component.ts's account-type
mapping only checked for CA/CB and its account-name fallback chain
never tried clientName. Added creditEntryAccountType() covering
GL/CA/CB/FD/RD/SHR/LA, and accountTypeLabel() display helpers on both
review screens.
3. Stop reversed transactions from distorting displayed running balances
Passbook and Transactions tabs were including reversed transactions in
their client-side running-balance recalculation, so a reversed posting
(visible struck-through) still shifted the balance shown for every
transaction after it. Both now filter out txn.reversed before computing
running balances; Transactions tab also defaults "Hide Reversed" to on.
4. New Interest Schedule dialog on the FD account view
Added custom-dialogs/interest-schedule-dialog, opened from the FD
General tab, showing the account's period-by-period interest schedule.
Excludes src/environments/.env.ts (auto-generated build version/hash
stamp, regenerated on every build -- not meaningful to hand-commit).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
WHAT THIS CHANGES
==================
Frontend counterpart to the backend FD in-place renewal, senior-citizen
rate, and Payment action work.
1. RENEWAL HISTORY TAB (new) -- fixed-deposit-account-view/renewal-history-tab/.
A vertical timeline, one card per term of the FD, oldest first. Backend
data arrives as a list of lowercase-keyed maps (Postgres unquoted SQL
aliases), which the component normalises. Includes term-rate-chart-dialog,
a popup showing one term's full rate-by-tenure chart, including the
senior-citizen column, with an "Applied" badge on the rate that was
actually used. Route added in fixed-deposits-routing.module.ts, tab
link added in fixed-deposit-account-view.component.html (shown only
when the account has renewal history).
2. PAYMENT DIALOG (new) -- fixed-deposit-account-view/custom-dialogs/payment-dialog/.
Card-based picker for the four supported closure types (Transfer to
Savings, Re-Invest Principal and Interest, Re-Invest Principal Only,
Partial Re-Invest), with Withdraw Deposit filtered out client-side.
Fetches its own template via a new fixedDepositsService method
(getFixedDepositsAccountPaymentTemplate, command=payment) rather than
reusing the Close template, since the Payment template is the only one
the backend includes PARTIAL_REINVEST in.
The Partial Re-Invest amount cap is date-dependent: the backend bounds
it against the account balance AFTER posting interest to the chosen
closed-on date, which lands on the maturity amount on or after
maturity and on the current balance before it. The dialog mirrors this
(reinvestCap / processingOnOrAfterMaturity) so the shown split actually
adds up and the client-side validator agrees with the server. This was
wrong in an earlier pass of this work (compared against a fixed figure
regardless of date) and was caught and fixed via a real reconciliation
check (77000 + 23000 did not equal the displayed total) before this
commit.
Added: a loading-failure state (previously the spinner ran forever on
a failed template fetch), an inline submit-error message (previously a
failed POST left the dialog open with no feedback), an empty-savings-
accounts hint, and accessibility attributes on the option cards
(role="radio", aria-checked, a visible check icon, focus-visible
outline) since selection was previously colour-only.
3. TRANSACTIONS TAB -- merges synthetic "FD Renewed" marker rows into the
real transaction list, since an in-place renewal posts no actual
ledger transaction and would otherwise look like the balance changed
for no reason.
4. INTEREST RATE CHART TAB -- added the senior-citizen rate column.
5. DEPOSIT CERTIFICATE DIALOG -- lists the full renewal history on FD
certificates. renewalCount is renewalHistory.length - 1 (the first
row is the original term, not a renewal); an earlier version of this
used the raw row count and overstated the renewal count by one on a
customer-facing document, caught and fixed before this commit.
6. CLIENTS GENERAL TAB -- fixedDepositAccountsForDisplay folds a renewed
FD's superseded terms out of the account list (each renewal used to
show as two unrelated accounts, one Closed and one Active). Memoised
on the source array's identity so it does not rebuild, and rebind the
table, on every change-detection tick. Only rewrites FD rows; Savings,
RD, Current, and Share account rows pass through this getter
untouched, and the RD/Savings sections of the template were left
bound directly to the original savingAccounts array.
KNOWN CAVEATS
=============
- This depends on the paired backend commit (same date, "feat(deposits):
FD in-place renewal, senior-citizen rate persistence, and Payment
action"). Deploying this frontend without that backend change means
the Payment dialog and Renewal History tab will call endpoints that
do not exist yet.
- Renewal-history rows rely on the backend returning lowercase column
keys (a Postgres-specific behaviour of unquoted SQL aliases via
JdbcTemplate). Confirmed correct against this project's Postgres
dev database; if this project ever runs on a different database
engine, that assumption would need re-checking.
- src/environments/.env.ts is intentionally excluded from this commit;
it is a local build-version stamp file that should never be
committed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The pending-product-edit comparison listed every field the edit form posted -- around fifty,
nearly all unchanged -- as an inline panel under the table, which buried the handful a checker
actually needs to look at. It is now a dialog listing only fields whose value differs.
Values are resolved to what the maker saw rather than what the payload carries: enum and
GL-account ids become their labels, dates in either API shape read the same, and empty
values no longer register as changes. Without that, option fields compared an expanded
{id, value} object against a bare id and reported every one of them as changed.
Fixed Deposit accounts created by a reinvestment now show the account they came from, and the
matured account shows the one it went into, each linking to the other.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fixed and Recurring Deposit wizards now bidirectionally sync the Product tab's
linked-account selection with the new Terms tab's Transfer-to-Savings account,
disable the Withdraw Deposit maturity instruction end-to-end, and card-style
the Transfer to Savings picker to match the existing linked-account UI. Adds
a printable FD/RD deposit certificate from the account view page, following
the existing letter-mgmt certificate pattern.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Matches the backend change that stopped auto-depositing money at
activation: removes the opening-balance field from every Activate
screen (Savings, Current, FD, RD) since funding now happens as a
separate deposit afterward, and removes the Digital-Facility step from
every Create wizard since every facility starts disabled by default
and gets turned on later through Edit Nominee & Features.
Also merges Approve+Activate into a single action for Savings,
Current, FD and RD accounts -- one click takes the account straight to
Active instead of two separate screens.
- Add 'Modify Application' button in kebab menu for rejected accounts (all 4 types)
- Rewrite edit components with tab-based UI matching create form
- Pre-populate all create-time values in edit form: product, account status,
customer segment, account type, joint holders, nominees, introducer,
deposit account link, senior citizen rate, tenure, flags (msme/balanceSwap/autoDebit)
- Fix edit mode detection using accountNo presence
- Add preselectedIntroducer @Input to IntroducerSearchComponent for pre-fill
- Support both camelCase and lowercase keys for joint holders (MySQL queryForList)
- Fix account number display: actual accountNo before previewAccountNo
- Fix cbsAccountType restore: cbsAccountType only, avoid Fineract enum object
- Add nominees fetch via /clients/{id}/nominees API in all 4 edit components
- Fix RD/FD Interest Rate Chart: SimpleChanges to prevent reset race condition
- Pre-check Senior Citizen checkbox in edit form from isSeniorCitizen DB field
- Auto-calculate rate when tenure pre-filled in edit mode
- FD calculator: use backend calculate-fd-interest API for all compounding types
- Support interestCompoundingPeriodInMonths=0 (daily) in FD calculator API
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- validateCashierHasMorningTransfer() blocks deposits & withdrawals when no today's cash transfer received
- validatePreviousDayClosed() blocks all transactions when previous day unsettled
- morningTransferReceived field added to cashier-day-status API response
- Warning banners shown in Savings, Current, FD, RD transaction forms
- Submit button disabled when either condition is active
- getCashierTotalCash SQL fixed: dm.denomination_value -> dm.denomination
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Savings/Current/FD/RD withdrawal forms: card-style overdraft warning when
requested denomination count exceeds cashier stock; submit blocked on overdraft
- Cash History detail view: show both RECEIVED and GIVEN denomination breakdowns
for Cash Exchange (previously only RECEIVED side was displayed)
- Closing Cash Report: add Cash Exchanges section (denomination-wise received/given/net)
- Excess Transaction Report: include cash exchanges >= threshold with Type badge
(Exchange/Txn) and ID Proof column for RBI/AML compliance
- cashier-shared.scss: etr-badge and closing-exchange-head styles
- Cash Exchange entry: overdraft warning redesigned to cx-overdraft-card BEM layout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- All 4 deposit forms (Current/Savings/FD/RD) now send denominationId +
denominationValue in denominationBreakdown so the backend can persist rows.
- Submit is disabled when a denomination breakdown is entered but its total
does not match the transaction amount.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Deposit forms (Current/Savings/FD/RD) now load cash denominations from
the Denomination Master instead of a hardcoded list:
- active + discontinued denominations fetched via /denominationmaster
- discontinued rows hidden by default behind a "Show discontinued" toggle,
rendered faded and disabled (cannot be counted) when revealed
- rows sorted by value descending; redesigned as a Denom/Qty/Amount table
with circular coin chips and per-row amount (faded at zero)
Also: savings account-actions menu now scrolls (max-height + grouped
sections mirror the current-account menu) and renders all action items.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Wire up Edit/View/Delete buttons with click handlers in all 4 HTML templates
(Current Account, Savings, Fixed Deposit, Recurring Deposit)
- Remove broken [routerLink] from Recurring Deposit HTML
- Add viewInstruction() and editInstruction() methods to all 4 tab components
- Use navigateByUrl with absolute path built from this.router.url to avoid
Angular multi-level .. navigation bug (was producing literal .. in URL)
CA/Savings/RD: basePath + /transfer-funds/:id/view|edit
FD: basePath + /transactions/account-transfers/:id/view|edit
- Fix deleteStandingInstruction() to refresh table after delete in all tabs
- Fix AccountTransfersService.deleteStandingInstrucions to use
PUT ?command=delete instead of HTTP DELETE (backend soft-delete only)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rebuilt current account deposit/withdrawal with sat two-column layout
- Applied same sat design to FD cash transaction and RD deposit/withdrawal
- Added Deposit action to FD: button config, actions dict, doAction routing
- Both FD Deposit and Withdrawal now render FixedDepositsCashTransaction
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Block 0% nominee share in all steppers (Savings, FD, RD, Current) —
Add button disabled via isValid, addNominee() guards < 1, nominee-form
error condition fixed for value=0
- Joint ownership: default primary share 50%, enforce min 1% on blur,
max 100% on input with DOM clamp via $event, auto-redistribute
co-holders proportionally when primary share changes,
isJointOwnershipValid guards each holder >= 1
- Pending/Rejected account tabs: normalize date format to 22 May 2026
for both array and string date values from API
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaced checked in package-lock.json by regenerated one.
Ran ng update @angular/core@20 @angular/cli@20
Ran npm install @angular-builders/jest@^20.0.0 @fortawesome/angular-fontawesome@^3.0.0 @swimlane/ngx-graph@^11
Ran npm install ngx-mat-select-search@^8.0.2.
Ran ng update @angular/material@20.
Updated all eslint and typescript to the latest versions.
Removed @angular-devkit/schematics.
Updated fontawesome.
Updated rxjs and tslib.
Moved required node version from 16 to 20.
Updated jest-preset-angular.
Set preserveWhitespaces to false.
Corrected two type declarations in two typescript files to make ng serve run without errors.
Removed unused angular-devkit/schematics from view-user.component.ts .
Updated list of supported browsers.
Upgraded prettier.
Ran prettier . --write the first time.
Ran prettier . --write the second time.
Ran ng generate @angular/core:inject with defaults, excepted a handful of files.
Fixed remaining eslint problems.
Added dist directory to ignores in eslint.config.js.
Let prettier fix formatting, almost everything is just line breaks.
Made htmlhint ignore @if and @for Angular constructs.
Updated node version in Github workflow to 22.12.0 (build.yml).
Updated .env.ts.
Updated Angular datetime format strings from YYYY-MM-DD to yyyy-MM-dd.
Merged changes from dev into angular20 branch.