From 45a337915e0260cd5597236bc3748207aaa579c8 Mon Sep 17 00:00:00 2001 From: Nitesh Yadav Date: Mon, 14 Sep 2026 11:49:36 +0530 Subject: [PATCH] fix(clients): block Alternate Mobile No from matching Mobile No Same number in both fields defeats the point of having a second contact route, and re-running DIP on an identical number is pointless. Added a cross-field validator on alternateMobileNo, re-checked whenever mobileNo changes, with a matching error message and the Verify-with-DIP button disabled while the clash exists. Co-Authored-By: Claude Sonnet 5 --- .../client-general-step.component.html | 11 +++++++++- .../client-general-step.component.ts | 22 +++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/app/clients/client-stepper/client-general-step/client-general-step.component.html b/src/app/clients/client-stepper/client-general-step/client-general-step.component.html index dc8109323..dbe9d8b20 100644 --- a/src/app/clients/client-stepper/client-general-step/client-general-step.component.html +++ b/src/app/clients/client-stepper/client-general-step/client-general-step.component.html @@ -969,6 +969,11 @@ createClientForm.get('alternateMobileNo')?.touched ) { Enter valid 10-digit number (starts with 6-9) + } @else if ( + createClientForm.get('alternateMobileNo')?.hasError('sameAsMobile') && + createClientForm.get('alternateMobileNo')?.touched + ) { + Alternate number can't be the same as Mobile No } @@ -979,7 +984,11 @@ color="primary" type="button" class="verify-btn" - [disabled]="readOnly || createClientForm.get('alternateMobileNo')?.value?.length !== 10" + [disabled]=" + readOnly || + createClientForm.get('alternateMobileNo')?.value?.length !== 10 || + createClientForm.get('alternateMobileNo')?.hasError('sameAsMobile') + " (click)="verifyAlternateDIP()" > diff --git a/src/app/clients/client-stepper/client-general-step/client-general-step.component.ts b/src/app/clients/client-stepper/client-general-step/client-general-step.component.ts index 5fafd6717..ed53470c4 100644 --- a/src/app/clients/client-stepper/client-general-step/client-general-step.component.ts +++ b/src/app/clients/client-stepper/client-general-step/client-general-step.component.ts @@ -25,7 +25,10 @@ import { UntypedFormGroup, Validators, UntypedFormControl, - ReactiveFormsModule + ReactiveFormsModule, + ValidatorFn, + AbstractControl, + ValidationErrors } from '@angular/forms'; import { Subject, Subscription, merge } from 'rxjs'; import { filter, switchMap, takeUntil } from 'rxjs/operators'; @@ -922,6 +925,16 @@ export class ClientGeneralStepComponent implements OnInit, OnDestroy, OnChanges } } + /** Alternate Mobile No must differ from Mobile No — the same number saved in both fields is + * meaningless (there's no second contact route) and the DIP checks would just repeat. */ + private notSameAsMobileNoValidator(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + const value = control.value; + const mobileNo = control.parent?.get('mobileNo')?.value; + return value && mobileNo && value === mobileNo ? { sameAsMobile: true } : null; + }; + } + /** * Creates the client form. */ @@ -961,7 +974,8 @@ export class ClientGeneralStepComponent implements OnInit, OnDestroy, OnChanges '', [ Validators.pattern(/^[6-9]\d{9}$/), - Validators.maxLength(10) + Validators.maxLength(10), + this.notSameAsMobileNoValidator() ] ], emailAddress: [ @@ -1334,6 +1348,10 @@ export class ClientGeneralStepComponent implements OnInit, OnDestroy, OnChanges // invalid) and its own reset never had a chance to run. this.mobileOtpVerified = false; this.mobileNewOtpId = null; + // Alternate Mobile No's "not same as Mobile No" validator reads mobileNo's current + // value, so re-run it here too — otherwise fixing mobileNo away from a clash leaves + // the alternate field's error stuck until the user also edits that field. + this.createClientForm.get('alternateMobileNo')?.updateValueAndValidity({ emitEvent: false }); }); this.createClientForm