feat: senior citizen rate fix, joint ownership cap, FD/RD UI improvements
- Senior citizen interest rate correctly sent in FD/RD create payload (isSeniorCitizen, seniorCitizenInterestRate, nominalAnnualInterestRate override) - Joint account ownership capped at 100%: Add Holder/Partner button disabled when 100% reached; dialog enforces remaining share as max across all account types - FD/RD interest rate chart step: rate calculator with tenure, senior citizen toggle, maturity preview - FD/RD preview step improvements - Base FD interest rate chart component added under fixed-deposit-products - Base recurring deposit interest rate chart component removed (replaced) - Savings account details step: joint holder improvements - Products routing and module updated for base FD rate chart Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
846b2484d7
commit
61b0244fa0
+22
-4
@@ -106,20 +106,38 @@
|
||||
<div class="arc-step-label arc-step-label--mt">
|
||||
<span class="arc-step-badge">2</span>
|
||||
<span>Ownership Share</span>
|
||||
@if (maxShare < 100) {
|
||||
<span class="arc-remaining-badge">Max available: {{ maxShare }}%</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="arc-share-row">
|
||||
<mat-form-field appearance="outline" class="arc-share-field">
|
||||
<mat-label>Share Percentage</mat-label>
|
||||
<input matInput type="number" formControlName="sharePercentage" min="1" max="100" />
|
||||
<input matInput type="number" formControlName="sharePercentage" min="1" [max]="maxShare" />
|
||||
<span matSuffix class="arc-percent-suffix">%</span>
|
||||
<mat-error>Enter a value between 1 and 100</mat-error>
|
||||
@if (form.get('sharePercentage').hasError('max')) {
|
||||
<mat-error>Maximum available is {{ maxShare }}%</mat-error>
|
||||
} @else {
|
||||
<mat-error>Enter a value between 1 and {{ maxShare }}</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<div class="arc-share-hints">
|
||||
@for (hint of [25, 33, 50, 100]; track hint) {
|
||||
<button type="button" class="arc-hint-chip" (click)="form.get('sharePercentage').setValue(hint)">
|
||||
{{ hint }}%
|
||||
@if (hint <= maxShare) {
|
||||
<button type="button" class="arc-hint-chip" (click)="form.get('sharePercentage').setValue(hint)">
|
||||
{{ hint }}%
|
||||
</button>
|
||||
}
|
||||
}
|
||||
@if (maxShare > 0 && ![25, 33, 50, 100].includes(maxShare)) {
|
||||
<button
|
||||
type="button"
|
||||
class="arc-hint-chip arc-hint-chip--remaining"
|
||||
(click)="form.get('sharePercentage').setValue(maxShare)"
|
||||
>
|
||||
{{ maxShare }}%
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
+25
@@ -102,6 +102,19 @@ mifosx-add-related-client-dialog {
|
||||
}
|
||||
}
|
||||
|
||||
.arc-remaining-badge {
|
||||
margin-left: auto;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
padding: 2px 10px;
|
||||
border-radius: 999px;
|
||||
background: #fef3c7;
|
||||
color: #92400e;
|
||||
border: 1px solid #fcd34d;
|
||||
text-transform: none;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.arc-step-badge {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
@@ -350,6 +363,18 @@ mifosx-add-related-client-dialog {
|
||||
background: $primary-light;
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
&--remaining {
|
||||
border-color: #f59e0b;
|
||||
background: #fffbeb;
|
||||
color: #92400e;
|
||||
|
||||
&:hover {
|
||||
border-color: #d97706;
|
||||
background: #fef3c7;
|
||||
color: #78350f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Actions ───────────────────────────────────────────────────────────────────
|
||||
|
||||
+8
-3
@@ -32,16 +32,21 @@ export class AddRelatedClientDialogComponent implements OnDestroy {
|
||||
private fb = inject(UntypedFormBuilder);
|
||||
private clientsService = inject(ClientsService);
|
||||
dialogRef = inject(MatDialogRef<AddRelatedClientDialogComponent>);
|
||||
data: { excludedClientIds?: number[] } = inject(MAT_DIALOG_DATA, { optional: true }) ?? {};
|
||||
data: { excludedClientIds?: number[]; maxSharePercentage?: number } =
|
||||
inject(MAT_DIALOG_DATA, { optional: true }) ?? {};
|
||||
|
||||
get maxShare(): number {
|
||||
return this.data?.maxSharePercentage ?? 100;
|
||||
}
|
||||
|
||||
form: UntypedFormGroup = this.fb.group({
|
||||
searchText: [''],
|
||||
sharePercentage: [
|
||||
null,
|
||||
this.data?.maxSharePercentage ?? null,
|
||||
[
|
||||
Validators.required,
|
||||
Validators.min(1),
|
||||
Validators.max(100)
|
||||
Validators.max(this.data?.maxSharePercentage ?? 100)
|
||||
]
|
||||
],
|
||||
signingAuthority: [null],
|
||||
|
||||
+2
@@ -259,6 +259,7 @@
|
||||
color="primary"
|
||||
type="button"
|
||||
class="soa-add-btn"
|
||||
[disabled]="totalJointSharePercentage >= 100"
|
||||
(click)="openAddJointHolderDialog()"
|
||||
>
|
||||
<mat-icon>person_add</mat-icon> Add Holder
|
||||
@@ -761,6 +762,7 @@
|
||||
color="primary"
|
||||
type="button"
|
||||
class="ni-add-btn"
|
||||
[disabled]="totalSharePercentage >= 100"
|
||||
(click)="openAddRelatedClientDialog()"
|
||||
>
|
||||
<mat-icon>person_add</mat-icon> Add Partner
|
||||
|
||||
+4
-2
@@ -364,11 +364,12 @@ export class CurrentAccountDetailsStepComponent implements OnInit {
|
||||
...(this.primaryClientId ? [this.primaryClientId] : []),
|
||||
...this.jointHolders.map((h: any) => h.clientId).filter(Boolean)
|
||||
];
|
||||
const maxSharePercentage = Math.max(0, 100 - this.totalJointSharePercentage);
|
||||
const ref = this.dialog.open(AddRelatedClientDialogComponent, {
|
||||
width: '500px',
|
||||
panelClass: 'arc-dialog-panel',
|
||||
disableClose: true,
|
||||
data: { excludedClientIds }
|
||||
data: { excludedClientIds, maxSharePercentage }
|
||||
});
|
||||
ref.afterClosed().subscribe((result) => {
|
||||
if (result) {
|
||||
@@ -443,11 +444,12 @@ export class CurrentAccountDetailsStepComponent implements OnInit {
|
||||
...(this.primaryClientId ? [this.primaryClientId] : []),
|
||||
...this.relatedClients.map((c: any) => c.clientId).filter(Boolean)
|
||||
];
|
||||
const maxSharePercentage = Math.max(0, 100 - this.totalSharePercentage);
|
||||
const ref = this.dialog.open(AddRelatedClientDialogComponent, {
|
||||
width: '500px',
|
||||
panelClass: 'arc-dialog-panel',
|
||||
disableClose: true,
|
||||
data: { excludedClientIds }
|
||||
data: { excludedClientIds, maxSharePercentage }
|
||||
});
|
||||
ref.afterClosed().subscribe((result) => {
|
||||
if (result) {
|
||||
|
||||
Reference in New Issue
Block a user