fix(clients): address-proof date fields use calendar picker, Pension Payment Order gets one too

Both the address-proof upload dialog and the permanent-address step used a
native `type="date"` input for the issue/statement date, so no calendar
popup was available. Switched both to Angular Material's datepicker, kept
the client-india-address-step round-trip (payload -> saved description ->
re-parsed on edit) working with the Dates util now that the control holds
a Date object instead of a raw string.

Pension Payment Orders was also the only "Financial & Other" address-proof
type missing requiresDate, so selecting it never showed a date field at
all — added the flag and moved Monthly/Yearly Turnover under the "Other
Income" heading alongside Agriculture/Non-Agriculture Income.
This commit is contained in:
2026-07-30 10:30:00 +05:30
parent 56f13ade67
commit 5dc284bd1c
6 changed files with 72 additions and 68 deletions
@@ -1232,38 +1232,6 @@
}
</mat-form-field>
<mat-form-field appearance="outline" class="form-field">
<mat-label>Monthly Turnover</mat-label>
<span matPrefix class="rupee-prefix">&#8377;</span>
<input matInput type="number" formControlName="monthlyTurnover" min="0" />
@if (
createClientForm.get('monthlyTurnover')?.hasError('pattern') &&
createClientForm.get('monthlyTurnover')?.touched
) {
<mat-error>Enter a valid amount</mat-error>
} @else if (
createClientForm.get('monthlyTurnover')?.hasError('min') && createClientForm.get('monthlyTurnover')?.touched
) {
<mat-error>Amount cannot be negative</mat-error>
}
</mat-form-field>
<mat-form-field appearance="outline" class="form-field">
<mat-label>Yearly Turnover</mat-label>
<span matPrefix class="rupee-prefix">&#8377;</span>
<input matInput type="number" formControlName="annualTurnover" min="0" />
@if (
createClientForm.get('annualTurnover')?.hasError('pattern') &&
createClientForm.get('annualTurnover')?.touched
) {
<mat-error>Enter a valid amount</mat-error>
} @else if (
createClientForm.get('annualTurnover')?.hasError('min') && createClientForm.get('annualTurnover')?.touched
) {
<mat-error>Amount cannot be negative</mat-error>
}
</mat-form-field>
<div class="full-width subsection-title">
<fa-icon icon="coins" class="subsection-icon"></fa-icon>
Other Income
@@ -1303,6 +1271,38 @@
}
</mat-form-field>
<mat-form-field appearance="outline" class="form-field">
<mat-label>Monthly Turnover</mat-label>
<span matPrefix class="rupee-prefix">&#8377;</span>
<input matInput type="number" formControlName="monthlyTurnover" min="0" />
@if (
createClientForm.get('monthlyTurnover')?.hasError('pattern') &&
createClientForm.get('monthlyTurnover')?.touched
) {
<mat-error>Enter a valid amount</mat-error>
} @else if (
createClientForm.get('monthlyTurnover')?.hasError('min') && createClientForm.get('monthlyTurnover')?.touched
) {
<mat-error>Amount cannot be negative</mat-error>
}
</mat-form-field>
<mat-form-field appearance="outline" class="form-field">
<mat-label>Yearly Turnover</mat-label>
<span matPrefix class="rupee-prefix">&#8377;</span>
<input matInput type="number" formControlName="annualTurnover" min="0" />
@if (
createClientForm.get('annualTurnover')?.hasError('pattern') &&
createClientForm.get('annualTurnover')?.touched
) {
<mat-error>Enter a valid amount</mat-error>
} @else if (
createClientForm.get('annualTurnover')?.hasError('min') && createClientForm.get('annualTurnover')?.touched
) {
<mat-error>Amount cannot be negative</mat-error>
}
</mat-form-field>
<div class="full-width subsection-title">
<fa-icon icon="user-shield" class="subsection-icon"></fa-icon>
Senior Citizen / Person with Disability
@@ -173,8 +173,9 @@
@if (selectedAddrProof.requiresDate) {
<mat-form-field appearance="outline" class="addr-ff">
<mat-label>Issue / bill date</mat-label>
<span matPrefix class="addr-prefix"><mat-icon>event</mat-icon></span>
<input matInput type="date" formControlName="issueDate" />
<input matInput [matDatepicker]="addrIssueDatePicker" formControlName="issueDate" />
<mat-datepicker-toggle matSuffix [for]="addrIssueDatePicker"></mat-datepicker-toggle>
<mat-datepicker #addrIssueDatePicker></mat-datepicker>
</mat-form-field>
}
</div>
@@ -20,6 +20,7 @@ import { ClientsService } from '../../clients.service';
import { ProofType, normalizeProofType, groupProofsByCategory } from '../../shared/kyc-proof-types';
import { KycUploadHelperService } from '../../shared/kyc-upload-helper.service';
import { DocumentPreviewDialogComponent } from '../../shared/document-preview-dialog/document-preview-dialog.component';
import { Dates } from 'app/core/utils/dates';
@Component({
selector: 'mifosx-client-india-address-step',
@@ -41,6 +42,7 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
private clientsService = inject(ClientsService);
private kycUpload = inject(KycUploadHelperService);
private dialog = inject(MatDialog);
private dates = inject(Dates);
/** Client ID — when set, loads existing addresses for edit mode */
@Input() clientId: string = '';
@@ -413,11 +415,12 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
files.push({ slot: 'Back', file: this.addrFiles.back });
}
}
const rawIssueDate = this.permanentForm.get('issueDate')?.value;
return {
proof: this.selectedAddrProof,
proofId: this.permanentForm.get('proofId')?.value || '',
documentKey: this.permanentForm.get('documentKey')?.value || '',
issueDate: this.permanentForm.get('issueDate')?.value || '',
issueDate: rawIssueDate ? this.dates.getDate(rawIssueDate) : '',
files
};
}
@@ -560,13 +563,13 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
proofId: matchedProof.id,
documentKey: identifier.documentKey || ''
});
// The description carries `Issue date: dd/mm/yyyy` when set on create (see
// The description carries `Issue date: yyyy-MM-dd` when set on create (see
// create-client.saveAddressProof) — pull it out so the form's issueDate field
// shows what was previously entered.
const desc: string = identifier.description || '';
const issueMatch = desc.match(/Issue date:\s*(.+)$/i);
if (issueMatch) {
this.permanentForm.patchValue({ issueDate: issueMatch[1].trim() });
this.permanentForm.patchValue({ issueDate: this.dates.parseDate(issueMatch[1].trim()) });
}
}