mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merged PR 1831: Kundendaten // B2B - nach "Bearbeiten" speichern nicht möglich
fix(customer): Updated Validations for B2B Customer Conditional Validator - If Organisation Name is set First and Lastname is not required, If no first and last name organisation name is required Ref: #4996
This commit is contained in:
committed by
Nino Righi
parent
a93251f082
commit
cdcd41a884
@@ -12,22 +12,45 @@
|
||||
|
||||
<form [formGroup]="formGroup" (ngSubmit)="save()">
|
||||
<ng-container *ngIf="isBusinessKonto$ | async">
|
||||
<shared-form-control label="Firma" class="col-span-2">
|
||||
<input class="input-control" placeholder="Firma" type="text" formControlName="organisation" tabindex="1" />
|
||||
<shared-form-control
|
||||
[label]="formGroup.controls.organisation.errors?.required ? 'Firma *' : 'Firma'"
|
||||
class="col-span-2"
|
||||
>
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Firma"
|
||||
type="text"
|
||||
formControlName="organisation"
|
||||
tabindex="1"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Abteilung">
|
||||
<input class="input-control" placeholder="Abteilung" type="text" formControlName="department" tabindex="2" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Abteilung"
|
||||
type="text"
|
||||
formControlName="department"
|
||||
tabindex="2"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="USt-ID">
|
||||
<input class="input-control" placeholder="Abteilung" type="text" formControlName="vatId" tabindex="3" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Abteilung"
|
||||
type="text"
|
||||
formControlName="vatId"
|
||||
tabindex="3"
|
||||
/>
|
||||
</shared-form-control>
|
||||
</ng-container>
|
||||
|
||||
<shared-form-control label="Anrede">
|
||||
<shared-select formControlName="gender" placeholder="Anrede" tabindex="4" [autofocus]="true">
|
||||
<shared-select-option *ngFor="let gender of genderSettings.genders" [value]="gender.value">{{ gender.label }}</shared-select-option>
|
||||
<shared-select-option *ngFor="let gender of genderSettings.genders" [value]="gender.value">{{
|
||||
gender.label
|
||||
}}</shared-select-option>
|
||||
</shared-select>
|
||||
</shared-form-control>
|
||||
|
||||
@@ -42,50 +65,107 @@
|
||||
</shared-select>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Nachname">
|
||||
<input class="input-control" placeholder="Nachname" type="text" formControlName="lastName" tabindex="6" />
|
||||
<shared-form-control
|
||||
[label]="formGroup.controls.organisation.errors?.required ? 'Nachname *' : 'Nachname'"
|
||||
>
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Nachname"
|
||||
type="text"
|
||||
formControlName="lastName"
|
||||
tabindex="6"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Vorname">
|
||||
<input class="input-control" placeholder="Vorname" type="text" formControlName="firstName" tabindex="7" />
|
||||
<shared-form-control
|
||||
[label]="formGroup.controls.organisation.errors?.required ? 'Vorname *' : 'Vorname'"
|
||||
>
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Vorname"
|
||||
type="text"
|
||||
formControlName="firstName"
|
||||
tabindex="7"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<ng-container *ngIf="!(isBusinessKonto$ | async)">
|
||||
<shared-form-control label="Firma" class="col-span-2">
|
||||
<input class="input-control" placeholder="Firma" type="text" formControlName="organisation" tabindex="8" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Firma"
|
||||
type="text"
|
||||
formControlName="organisation"
|
||||
tabindex="8"
|
||||
/>
|
||||
</shared-form-control>
|
||||
</ng-container>
|
||||
|
||||
<shared-form-control label="Straße">
|
||||
<input class="input-control" placeholder="Straße" type="text" formControlName="street" tabindex="9" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Straße"
|
||||
type="text"
|
||||
formControlName="street"
|
||||
tabindex="9"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Hausnummer">
|
||||
<input class="input-control" placeholder="Hausnummer" type="text" formControlName="streetNumber" tabindex="10" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Hausnummer"
|
||||
type="text"
|
||||
formControlName="streetNumber"
|
||||
tabindex="10"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="PLZ">
|
||||
<input class="input-control" placeholder="PLZ" type="text" formControlName="zipCode" tabindex="11" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="PLZ"
|
||||
type="text"
|
||||
formControlName="zipCode"
|
||||
tabindex="11"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Ort">
|
||||
<input class="input-control" placeholder="Ort" type="text" formControlName="city" tabindex="12" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Ort"
|
||||
type="text"
|
||||
formControlName="city"
|
||||
tabindex="12"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Adresszusatz" class="col-span-2">
|
||||
<input class="input-control" placeholder="Adresszusatz" type="text" formControlName="info" tabindex="13" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Adresszusatz"
|
||||
type="text"
|
||||
formControlName="info"
|
||||
tabindex="13"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control class="col-span-2" label="Land">
|
||||
<shared-select placeholder="Land" formControlName="country" tabindex="14">
|
||||
<shared-select-option *ngFor="let country of countries$ | async" [value]="country.isO3166_A_3">
|
||||
<shared-select-option
|
||||
*ngFor="let country of countries$ | async"
|
||||
[value]="country.isO3166_A_3"
|
||||
>
|
||||
{{ country.name }}
|
||||
</shared-select-option>
|
||||
</shared-select>
|
||||
</shared-form-control>
|
||||
|
||||
<div class="text-center col-span-2">
|
||||
<shared-checkbox formControlName="isDefault">Diese Lieferadresse als Standard Adresse festlegen</shared-checkbox>
|
||||
<shared-checkbox formControlName="isDefault"
|
||||
>Diese Lieferadresse als Standard Adresse festlegen</shared-checkbox
|
||||
>
|
||||
</div>
|
||||
<div class="mt-6 text-center col-span-2">
|
||||
<button
|
||||
@@ -98,3 +178,4 @@
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import { RouterLink } from '@angular/router';
|
||||
import { IconComponent } from '@shared/components/icon';
|
||||
import { zipCodeValidator } from '../../validators/zip-code-validator';
|
||||
import { GenderSettingsService } from '@shared/services/gender';
|
||||
import { validateCompanyOrPersonalInfoRequired } from '../../validators/gender-b2b-validator';
|
||||
|
||||
@Component({
|
||||
selector: 'page-add-shipping-address-main-view',
|
||||
@@ -70,10 +71,30 @@ export class AddShippingAddressMainViewComponent implements OnInit, OnDestroy {
|
||||
|
||||
ngOnInit() {
|
||||
this._store.customer$.pipe(takeUntil(this._onDestroy)).subscribe(() => {
|
||||
// Dynamic validation rules based on account type
|
||||
// For business accounts (isBusinessKonto), we apply different validation rules
|
||||
// than for personal accounts
|
||||
if (this._store.isBusinessKonto) {
|
||||
this.formGroup.controls.organisation.setValidators([Validators.required]);
|
||||
// For business accounts:
|
||||
// - Clear individual validators from personal info fields
|
||||
// - Add a form-level validator that requires either company OR personal info
|
||||
// - Make address fields optional to support different business address formats
|
||||
this.formGroup.controls.organisation.setValidators([]);
|
||||
this.formGroup.controls.gender.setValidators([]);
|
||||
this.formGroup.controls.firstName.setValidators([]);
|
||||
this.formGroup.controls.lastName.setValidators([]);
|
||||
this.formGroup.setValidators([validateCompanyOrPersonalInfoRequired]);
|
||||
this.formGroup.controls.street.setValidators([]);
|
||||
this.formGroup.controls.streetNumber.setValidators([]);
|
||||
} else {
|
||||
// For personal accounts:
|
||||
// - Organization info is optional
|
||||
// - First and last name are required
|
||||
// - No special form-level validators needed
|
||||
this.formGroup.controls.organisation.clearValidators();
|
||||
this.formGroup.controls.firstName.setValidators([Validators.required]);
|
||||
this.formGroup.controls.lastName.setValidators([Validators.required]);
|
||||
this.formGroup.setValidators([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -133,7 +154,10 @@ export class AddShippingAddressMainViewComponent implements OnInit, OnDestroy {
|
||||
formData.isDefault,
|
||||
);
|
||||
|
||||
this._navigation.navigateToDetails({ processId: this._store.processId, customerId: this._store.customerId });
|
||||
this._navigation.navigateToDetails({
|
||||
processId: this._store.processId,
|
||||
customerId: this._store.customerId,
|
||||
});
|
||||
} catch (error) {
|
||||
this.formGroup.enable();
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ import { UiCommonModule } from '@ui/common';
|
||||
import { UiFormControlModule } from '@ui/form-control';
|
||||
import { UiSelectModule } from '@ui/select';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { UiDateInputDirective } from '@ui/input';
|
||||
import { validateCompanyOrPersonalInfoRequired } from '../../validators/gender-b2b-validator';
|
||||
|
||||
@Component({
|
||||
selector: 'page-customer-data-edit-b2b',
|
||||
@@ -26,8 +27,9 @@ import { UiDateInputDirective } from '@ui/input';
|
||||
],
|
||||
})
|
||||
export class CustomerDataEditB2BComponent extends CustomerDataEditComponent {
|
||||
afterInitForm = (control) => {
|
||||
afterInitForm = (control: FormGroup) => {
|
||||
control.get('lastName').setValidators([]);
|
||||
control.get('firstName').setValidators([]);
|
||||
control.setValidators([validateCompanyOrPersonalInfoRequired]);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,22 +12,49 @@
|
||||
|
||||
<form [formGroup]="formGroup" (ngSubmit)="save()">
|
||||
<ng-container *ngIf="isBusinessKonto$ | async">
|
||||
<shared-form-control label="Firma" class="col-span-2">
|
||||
<input class="input-control" placeholder="Firma" type="text" formControlName="organisation" tabindex="1" />
|
||||
<shared-form-control
|
||||
[label]="formGroup.controls.organisation.errors?.required ? 'Firma *' : 'Firma'"
|
||||
class="col-span-2"
|
||||
[hasRequiredMark]="
|
||||
formGroup.controls.organisation.errors?.required ||
|
||||
formGroup.errors?.eitherCompanyOrPersonalRequired
|
||||
"
|
||||
>
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Firma"
|
||||
type="text"
|
||||
formControlName="organisation"
|
||||
tabindex="1"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Abteilung">
|
||||
<input class="input-control" placeholder="Abteilung" type="text" formControlName="department" tabindex="2" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Abteilung"
|
||||
type="text"
|
||||
formControlName="department"
|
||||
tabindex="2"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="USt-ID">
|
||||
<input class="input-control" placeholder="Abteilung" type="text" formControlName="vatId" tabindex="3" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Abteilung"
|
||||
type="text"
|
||||
formControlName="vatId"
|
||||
tabindex="3"
|
||||
/>
|
||||
</shared-form-control>
|
||||
</ng-container>
|
||||
|
||||
<shared-form-control label="Anrede">
|
||||
<shared-select formControlName="gender" placeholder="Anrede" tabindex="4" [autofocus]="true">
|
||||
<shared-select-option *ngFor="let gender of genderSettings.genders" [value]="gender.value">{{ gender.label }}</shared-select-option>
|
||||
<shared-select-option *ngFor="let gender of genderSettings.genders" [value]="gender.value">{{
|
||||
gender.label
|
||||
}}</shared-select-option>
|
||||
</shared-select>
|
||||
</shared-form-control>
|
||||
|
||||
@@ -42,50 +69,115 @@
|
||||
</shared-select>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Nachname">
|
||||
<input class="input-control" placeholder="Nachname" type="text" formControlName="lastName" tabindex="6" />
|
||||
<shared-form-control
|
||||
[label]="formGroup.controls.organisation.errors?.required ? 'Nachname *' : 'Nachname'"
|
||||
[hasRequiredMark]="
|
||||
formGroup.controls.lastName.errors?.required ||
|
||||
formGroup.errors?.eitherCompanyOrPersonalRequired
|
||||
"
|
||||
>
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Nachname"
|
||||
type="text"
|
||||
formControlName="lastName"
|
||||
tabindex="6"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Vorname">
|
||||
<input class="input-control" placeholder="Vorname" type="text" formControlName="firstName" tabindex="7" />
|
||||
<shared-form-control
|
||||
[label]="formGroup.controls.organisation.errors?.required ? 'Vorname *' : 'Vorname'"
|
||||
[hasRequiredMark]="
|
||||
formGroup.controls.firstName.errors?.required ||
|
||||
formGroup.errors?.eitherCompanyOrPersonalRequired
|
||||
"
|
||||
>
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Vorname"
|
||||
type="text"
|
||||
formControlName="firstName"
|
||||
tabindex="7"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<ng-container *ngIf="!(isBusinessKonto$ | async)">
|
||||
<shared-form-control label="Firma" class="col-span-2">
|
||||
<input class="input-control" placeholder="Firma" type="text" formControlName="organisation" tabindex="8" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Firma"
|
||||
type="text"
|
||||
formControlName="organisation"
|
||||
tabindex="8"
|
||||
/>
|
||||
</shared-form-control>
|
||||
</ng-container>
|
||||
|
||||
<shared-form-control label="Straße">
|
||||
<input class="input-control" placeholder="Straße" type="text" formControlName="street" tabindex="9" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Straße"
|
||||
type="text"
|
||||
formControlName="street"
|
||||
tabindex="9"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Hausnummer">
|
||||
<input class="input-control" placeholder="Hausnummer" type="text" formControlName="streetNumber" tabindex="10" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Hausnummer"
|
||||
type="text"
|
||||
formControlName="streetNumber"
|
||||
tabindex="10"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="PLZ">
|
||||
<input class="input-control" placeholder="PLZ" type="text" formControlName="zipCode" tabindex="11" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="PLZ"
|
||||
type="text"
|
||||
formControlName="zipCode"
|
||||
tabindex="11"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Ort">
|
||||
<input class="input-control" placeholder="Ort" type="text" formControlName="city" tabindex="12" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Ort"
|
||||
type="text"
|
||||
formControlName="city"
|
||||
tabindex="12"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control label="Adresszusatz" class="col-span-2">
|
||||
<input class="input-control" placeholder="Adresszusatz" type="text" formControlName="info" tabindex="13" />
|
||||
<input
|
||||
class="input-control"
|
||||
placeholder="Adresszusatz"
|
||||
type="text"
|
||||
formControlName="info"
|
||||
tabindex="13"
|
||||
/>
|
||||
</shared-form-control>
|
||||
|
||||
<shared-form-control class="col-span-2" label="Land">
|
||||
<shared-select placeholder="Land" formControlName="country" tabindex="14">
|
||||
<shared-select-option *ngFor="let country of countries$ | async" [value]="country.isO3166_A_3">
|
||||
<shared-select-option
|
||||
*ngFor="let country of countries$ | async"
|
||||
[value]="country.isO3166_A_3"
|
||||
>
|
||||
{{ country.name }}
|
||||
</shared-select-option>
|
||||
</shared-select>
|
||||
</shared-form-control>
|
||||
|
||||
<div class="text-center col-span-2">
|
||||
<shared-checkbox formControlName="isDefault">Diese Lieferadresse als Standard Adresse festlegen</shared-checkbox>
|
||||
<shared-checkbox formControlName="isDefault"
|
||||
>Diese Lieferadresse als Standard Adresse festlegen</shared-checkbox
|
||||
>
|
||||
</div>
|
||||
<div class="mt-6 text-center col-span-2">
|
||||
<button
|
||||
@@ -98,3 +190,4 @@
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, inject, ChangeDetectorRef } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
ChangeDetectionStrategy,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
inject,
|
||||
ChangeDetectorRef,
|
||||
} from '@angular/core';
|
||||
import { CheckboxComponent } from '@shared/components/checkbox';
|
||||
import { FormControl, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||
import { SelectModule } from '@shared/components/select';
|
||||
@@ -16,6 +23,7 @@ import { ActivatedRoute, RouterLink } from '@angular/router';
|
||||
import { ComponentStore } from '@ngrx/component-store';
|
||||
import { zipCodeValidator } from '../../validators/zip-code-validator';
|
||||
import { GenderSettingsService } from '@shared/services/gender';
|
||||
import { validateCompanyOrPersonalInfoRequired } from '../../validators/gender-b2b-validator';
|
||||
|
||||
export interface EditShippingAddressMainViewState {
|
||||
shippingAddress?: ShippingAddressDTO;
|
||||
@@ -102,9 +110,15 @@ export class EditShippingAddressMainViewComponent
|
||||
|
||||
this._store.customer$.pipe(takeUntil(this._onDestroy)).subscribe(() => {
|
||||
if (this._store.isBusinessKonto) {
|
||||
this.formGroup.controls.organisation.setValidators([Validators.required]);
|
||||
this.formGroup.controls.organisation.setValidators([]);
|
||||
this.formGroup.controls.firstName.setValidators([]);
|
||||
this.formGroup.controls.lastName.setValidators([]);
|
||||
this.formGroup.setValidators([validateCompanyOrPersonalInfoRequired]);
|
||||
} else {
|
||||
this.formGroup.controls.organisation.clearValidators();
|
||||
this.formGroup.controls.firstName.setValidators([Validators.required]);
|
||||
this.formGroup.controls.lastName.setValidators([Validators.required]);
|
||||
this.formGroup.setValidators([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -185,7 +199,10 @@ export class EditShippingAddressMainViewComponent
|
||||
formData.isDefault,
|
||||
);
|
||||
|
||||
this._navigation.navigateToDetails({ processId: this._store.processId, customerId: this._store.customerId });
|
||||
this._navigation.navigateToDetails({
|
||||
processId: this._store.processId,
|
||||
customerId: this._store.customerId,
|
||||
});
|
||||
} catch (error) {
|
||||
this.formGroup.enable();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ export function requireGenderWhenNameIsSet(control: UntypedFormGroup): Validatio
|
||||
const genderControl = control.get('gender');
|
||||
const nameControl = control.get('lastName');
|
||||
|
||||
genderControl?.setErrors(null);
|
||||
|
||||
if (nameControl && !Validators.required(nameControl)) {
|
||||
const errors = Validators.min(1)(genderControl) ? { required: true } : null;
|
||||
|
||||
@@ -36,3 +38,62 @@ export function requireGenderWhenNameIsSet(control: UntypedFormGroup): Validatio
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Angular form validator that implements mutual exclusivity between organisation name and personal details.
|
||||
* Either:
|
||||
* 1. Organisation name must be provided (company case), OR
|
||||
* 2. Both first name and last name must be provided (individual case)
|
||||
*
|
||||
* @param control - The form group containing 'firstName', 'lastName', and nested 'organisation.name' controls
|
||||
* @returns Validation errors if the mutual exclusivity rule is violated, null otherwise
|
||||
*/
|
||||
export function validateCompanyOrPersonalInfoRequired(
|
||||
control: UntypedFormGroup,
|
||||
): ValidationErrors | null {
|
||||
const firstNameControl = control.get('firstName');
|
||||
const lastNameControl = control.get('lastName');
|
||||
const organisationControl = control.get('organisation');
|
||||
|
||||
// Safely access the nested company name, with null checks
|
||||
const companyNameControl = organisationControl?.get('name') ?? organisationControl;
|
||||
|
||||
if (!firstNameControl || !lastNameControl || !companyNameControl) {
|
||||
// If any control is missing, we can't validate
|
||||
return null;
|
||||
}
|
||||
|
||||
const hasCompanyName = !!companyNameControl.value;
|
||||
const hasFirstName = !!firstNameControl.value;
|
||||
const hasLastName = !!lastNameControl.value;
|
||||
const hasPersonalInfo = hasFirstName || hasLastName;
|
||||
|
||||
// Clear previous validation errors
|
||||
firstNameControl.setErrors(null);
|
||||
lastNameControl.setErrors(null);
|
||||
companyNameControl.setErrors(null);
|
||||
|
||||
// Case 1: Neither company name nor personal info provided - require one of them
|
||||
if (!hasCompanyName && !hasPersonalInfo) {
|
||||
const errors = { required: true };
|
||||
companyNameControl.setErrors(errors);
|
||||
firstNameControl.setErrors(errors);
|
||||
lastNameControl.setErrors(errors);
|
||||
return { eitherCompanyOrPersonalRequired: true };
|
||||
}
|
||||
|
||||
// Case 2: First name provided but last name missing
|
||||
if (hasFirstName && !hasLastName) {
|
||||
lastNameControl.setErrors({ required: true });
|
||||
return { lastNameRequired: true };
|
||||
}
|
||||
|
||||
// Case 3: Last name provided but first name missing
|
||||
if (!hasFirstName && hasLastName) {
|
||||
firstNameControl.setErrors({ required: true });
|
||||
return { firstNameRequired: true };
|
||||
}
|
||||
|
||||
// Valid: Either company name or complete personal info is provided
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user