- @for (d of coins; track d.value) {
-
0">
-
- {{ d.label }}
- ₹{{ subtotalFor(d) | number: '1.2-2' }}
-
+ @for (d of notes; track d.value) {
+
0"
+ [style.display]="!d.active && !showInactive ? 'none' : null"
+ [style.opacity]="d.active ? null : 0.55"
+ [attr.title]="d.active ? null : 'Discontinued — not active for new deposits'"
+ >
+
+ {{ d.label }}
+
+
- }
+
+ ₹{{ subtotalFor(d) | number: '1.2-2' }}
+
+
+ }
+
+
+
+ Coins
+ ₹{{ coinsTotal | number: '1.2-2' }}
+ @for (d of coins; track d.value) {
+
0"
+ [style.display]="!d.active && !showInactive ? 'none' : null"
+ [style.opacity]="d.active ? null : 0.55"
+ [attr.title]="d.active ? null : 'Discontinued — not active for new deposits'"
+ >
+
+ {{ d.label }}
+
+
+
+ ₹{{ subtotalFor(d) | number: '1.2-2' }}
+
+
+ }
diff --git a/src/app/savings/saving-account-actions/savings-account-transactions/savings-account-transactions.component.scss b/src/app/savings/saving-account-actions/savings-account-transactions/savings-account-transactions.component.scss
index dfe99b06d..2bce2c4d2 100644
--- a/src/app/savings/saving-account-actions/savings-account-transactions/savings-account-transactions.component.scss
+++ b/src/app/savings/saving-account-actions/savings-account-transactions/savings-account-transactions.component.scss
@@ -453,22 +453,42 @@ $red: #b91c1c;
}
/* ─── Denomination groups ─────────────────────────────────────────── */
-.sat__denom-group {
- padding: 8px 14px 4px;
- & + & {
- border-top: 1px solid #f1f5f9;
- }
+/* ── Denomination table: Denom · Qty · Amount ── */
+.sat__dt {
+ padding: 4px 0 6px;
}
-.sat__denom-group-head {
+.sat__dt-head {
+ display: grid;
+ grid-template-columns: 1fr 140px 120px;
+ align-items: center;
+ gap: 10px;
+ padding: 2px 16px 8px;
+ font-size: 10px;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+ color: #94a3b8;
+ border-bottom: 1px solid $border;
+}
+
+.sat__dt-h-qty {
+ text-align: center;
+}
+
+.sat__dt-h-amount {
+ text-align: right;
+}
+
+.sat__dt-section {
display: flex;
justify-content: space-between;
align-items: baseline;
- margin-bottom: 5px;
+ padding: 12px 16px 4px;
}
-.sat__denom-group-title {
+.sat__dt-section-title {
font-size: 10px;
font-weight: 800;
text-transform: uppercase;
@@ -476,51 +496,52 @@ $red: #b91c1c;
color: $slate;
}
-.sat__denom-group-total {
+.sat__dt-section-total {
font-size: 12px;
font-weight: 700;
color: $navy;
font-variant-numeric: tabular-nums;
}
-.sat__denom-grid {
+.sat__dt-row {
display: grid;
- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
- gap: 6px;
-}
-
-/* ── Single denomination tile ──
- Two-row layout: top has the denomination chip + running subtotal,
- bottom has a full-width stepper (− / count / +). Easier to read,
- gives the cashier obvious tap targets, and never clips on narrow
- columns. */
-.sat__denom {
- display: flex;
- flex-direction: column;
- gap: 5px;
- padding: 6px 9px;
- border-radius: 8px;
- background: #fff;
- border: 1px solid $border;
- transition:
- border-color 0.15s ease,
- background 0.15s ease,
- box-shadow 0.15s ease;
- min-width: 0;
+ grid-template-columns: 1fr 140px 120px;
+ align-items: center;
+ gap: 10px;
+ padding: 7px 16px;
+ border-bottom: 1px dotted #e2e8f0;
+ transition: background 0.12s ease;
&--active {
- border-color: #86efac;
background: #f0fdf4;
- box-shadow: 0 1px 3px -1px rgb(4 120 87 / 18%);
}
}
-.sat__denom-top {
+.sat__dt-denom {
display: flex;
align-items: center;
- justify-content: space-between;
- gap: 6px;
- min-width: 0;
+}
+
+.sat__dt-qty {
+ display: flex;
+ justify-content: center;
+
+ .sat__denom-stepper {
+ width: 130px;
+ }
+}
+
+.sat__dt-amount {
+ text-align: right;
+ font-size: 13px;
+ font-weight: 700;
+ color: $navy;
+ font-variant-numeric: tabular-nums;
+
+ &--zero {
+ color: #cbd5e1;
+ font-weight: 600;
+ }
}
.sat__denom-chip {
@@ -548,6 +569,14 @@ $red: #b91c1c;
color: #854d0e;
border: 1px solid #fcd34d;
}
+
+ &--circle {
+ min-width: 36px;
+ width: 36px;
+ height: 36px;
+ padding: 0;
+ border-radius: 50%;
+ }
}
.sat__denom-amount {
diff --git a/src/app/savings/saving-account-actions/savings-account-transactions/savings-account-transactions.component.ts b/src/app/savings/saving-account-actions/savings-account-transactions/savings-account-transactions.component.ts
index a15a24803..e9dbeed9c 100644
--- a/src/app/savings/saving-account-actions/savings-account-transactions/savings-account-transactions.component.ts
+++ b/src/app/savings/saving-account-actions/savings-account-transactions/savings-account-transactions.component.ts
@@ -19,6 +19,7 @@ import { Router, ActivatedRoute, RouterLink } from '@angular/router';
/** Custom Services */
import { SavingsService } from '../../savings.service';
+import { DenominationMasterService } from 'app/system/denomination-master/denomination-master.service';
import { ClientsService } from 'app/clients/clients.service';
import { SettingsService } from 'app/settings/settings.service';
import { Dates } from 'app/core/utils/dates';
@@ -37,6 +38,7 @@ interface Denomination {
value: number;
kind: 'note' | 'coin';
label: string;
+ active: boolean;
}
/**
@@ -68,6 +70,7 @@ export class SavingsAccountTransactionsComponent implements OnInit {
private clientsService = inject(ClientsService);
private settingsService = inject(SettingsService);
private dialog = inject(MatDialog);
+ private denominationMasterService = inject(DenominationMasterService);
/** Minimum Due Date allowed. */
minDate = new Date(2000, 0, 1);
@@ -93,24 +96,14 @@ export class SavingsAccountTransactionsComponent implements OnInit {
savingAccountId: string;
currency: Currency | null = null;
- /** Indian banknote denominations (descending). */
- readonly notes: Denomination[] = [
- { value: 500, kind: 'note', label: '₹500' },
- { value: 200, kind: 'note', label: '₹200' },
- { value: 100, kind: 'note', label: '₹100' },
- { value: 50, kind: 'note', label: '₹50' },
- { value: 20, kind: 'note', label: '₹20' },
- { value: 10, kind: 'note', label: '₹10' }
- ];
+ /** Banknote denominations — loaded dynamically from the Denomination Master (active only). */
+ notes: Denomination[] = [];
- /** Indian coin denominations (descending). */
- readonly coins: Denomination[] = [
- { value: 20, kind: 'coin', label: '₹20' },
- { value: 10, kind: 'coin', label: '₹10' },
- { value: 5, kind: 'coin', label: '₹5' },
- { value: 2, kind: 'coin', label: '₹2' },
- { value: 1, kind: 'coin', label: 'Re 1' }
- ];
+ /** Coin denominations — loaded dynamically from the Denomination Master. */
+ coins: Denomination[] = [];
+
+ /** When false, discontinued (inactive) denominations stay hidden in the grid. */
+ showInactive = false;
/** Quantity per denomination — keyed by `${kind}:${value}`. */
denominationCounts: Record
= {};
@@ -152,9 +145,40 @@ export class SavingsAccountTransactionsComponent implements OnInit {
ngOnInit() {
this.maxDate = this.settingsService.businessDate;
this.createSavingAccountTransactionForm();
+ this.loadDenominations();
this.loadContextStrip();
}
+ /** Load active denominations from the Denomination Master so the cash
+ * breakdown grid reflects the bank's current configuration. */
+ private loadDenominations(): void {
+ this.denominationMasterService.getAll().subscribe({
+ next: (list: any[]) => {
+ const rows: Denomination[] = (list || []).map((d) => ({
+ value: d.denomination,
+ kind: d.kind as 'note' | 'coin',
+ label: '₹' + d.denomination,
+ active: !!d.isActive
+ }));
+ const order = (a: Denomination, b: Denomination) => b.value - a.value;
+ this.notes = rows.filter((r) => r.kind === 'note').sort(order);
+ this.coins = rows.filter((r) => r.kind === 'coin').sort(order);
+ },
+ error: () => {
+ this.notes = [];
+ this.coins = [];
+ }
+ });
+ }
+
+ /** True when at least one discontinued denomination exists. */
+ get hasInactive(): boolean {
+ return [
+ ...this.notes,
+ ...this.coins
+ ].some((d) => !d.active);
+ }
+
/**
* Pull the savings account + client to populate the cashier's context
* strip (account number, client name, KYC status, risk level, same-day
diff --git a/src/app/savings/savings-account-view/savings-account-view.component.html b/src/app/savings/savings-account-view/savings-account-view.component.html
index a9db2e800..c29a4f77e 100644
--- a/src/app/savings/savings-account-view/savings-account-view.component.html
+++ b/src/app/savings/savings-account-view/savings-account-view.component.html
@@ -104,155 +104,172 @@
-
-
diff --git a/src/app/savings/savings-account-view/savings-account-view.component.ts b/src/app/savings/savings-account-view/savings-account-view.component.ts
index 5739366fe..8d1603aa0 100644
--- a/src/app/savings/savings-account-view/savings-account-view.component.ts
+++ b/src/app/savings/savings-account-view/savings-account-view.component.ts
@@ -170,6 +170,14 @@ export class SavingsAccountViewComponent implements OnInit {
return this.ACTION_ICON[name] ?? fallback ?? 'circle';
}
+ hasKind(kind: 'transact' | 'block' | 'interest' | 'admin' | 'danger'): boolean {
+ const all = [
+ ...(this.buttonConfig?.singleButtons ?? []),
+ ...(this.buttonConfig?.options ?? [])
+ ];
+ return all.some((item) => this.kindOf(item.name) === kind);
+ }
+
/**
* Fetches savings account data from `resolve`
* @param {ActivatedRoute} route Activated Route
diff --git a/src/app/system/denomination-master/denomination-master.service.ts b/src/app/system/denomination-master/denomination-master.service.ts
index 6b037b0ad..cd9797f5f 100644
--- a/src/app/system/denomination-master/denomination-master.service.ts
+++ b/src/app/system/denomination-master/denomination-master.service.ts
@@ -16,6 +16,10 @@ export class DenominationMasterService {
return this.http.get