service-provider-app/src/app/holder/basic-details/basic-details.component.ts
2025-08-10 20:34:41 -03:00

230 lines
7.7 KiB
TypeScript

import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { State } from '../../core/models/state';
import { Region } from '../../core/models/region';
import { NotificationService } from '../../core/services/common/notification.service';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { ZipCodeValidator } from '../../shared/validators/zipcode-validator';
import { CommonService } from '../../core/services/common/common.service';
import { finalize, Subject, takeUntil } from 'rxjs';
import { Country } from '../../core/models/country';
import { BasicDetailService } from '../../core/services/holder/basic-detail.service';
import { BasicDetail } from '../../core/models/holder/basic-detail';
import { StorageService } from '../../core/services/common/storage.service';
import { NavigationService } from '../../core/services/common/navigation.service';
import { environment } from '../../../environments/environment';
@Component({
selector: 'app-basic-detail',
imports: [AngularMaterialModule, ReactiveFormsModule, CommonModule],
templateUrl: './basic-details.component.html',
styleUrl: './basic-details.component.scss'
})
export class BasicDetailComponent implements OnInit, OnDestroy {
@Input() isEditMode = false;
@Input() holderid: number = 0;
@Output() holderIdCreated = new EventEmitter<number>();
basicDetailsForm: FormGroup;
countries: Country[] = [];
regions: Region[] = [];
states: State[] = [];
currentApplicationDetails: { headerid: number, applicationName: string } | null = null;
isLoading = false;
changeInProgress = false;
countriesHasStates = ['US', 'CA', 'MX'];
returnTo: string = environment.appType === 'client' ? 'edit-carnet' : 'process-carnet';
private destroy$ = new Subject<void>();
private fb = inject(FormBuilder);
private basicDetailService = inject(BasicDetailService);
private notificationService = inject(NotificationService);
private commonService = inject(CommonService);
private errorHandler = inject(ApiErrorHandlerService);
private storageService = inject(StorageService);
private navigationService = inject(NavigationService);
constructor() {
this.basicDetailsForm = this.createForm();
this.currentApplicationDetails = this.storageService.get<{ headerid: number, applicationName: string }>('currentapplication')
}
createForm(): FormGroup {
return this.fb.group({
holderName: ['', [Validators.required, Validators.maxLength(100)]],
dbaName: ['', [Validators.maxLength(20)]],
holderNumber: ['', [Validators.required, Validators.maxLength(20)]],
holderType: ['', [Validators.required, Validators.maxLength(20)]],
uscibMember: [false, [Validators.required]],
// govAgency: [false, [Validators.required]],
address1: ['', [Validators.required, Validators.maxLength(100)]],
address2: ['', Validators.maxLength(100)],
city: ['', [Validators.required, Validators.maxLength(50)]],
state: ['', Validators.required],
country: ['US', Validators.required],
zip: ['', [Validators.required, ZipCodeValidator('country')]]
});
}
ngOnInit(): void {
this.loadLookupData();
if (this.holderid > 0) {
this.isLoading = true;
this.basicDetailService.getBasicDetailByHolderId(this.holderid).pipe(finalize(() => {
this.isLoading = false;
})).subscribe({
next: (basicDetail: BasicDetail) => {
this.patchFormData(basicDetail);
// this.holderName.emit(basicDetail.holderName);
},
error: (error: any) => {
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load basic details');
this.notificationService.showError(errorMessage);
console.error('Error loading basic details:', error);
}
});
} else {
this.loadStates('US'); // Load states for default country
}
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
onCountryChange(country: string): void {
this.basicDetailsForm.get('state')?.reset();
if (country) {
this.loadStates(country);
}
this.basicDetailsForm.get('zip')?.updateValueAndValidity();
}
saveBasicDetails() {
if (this.basicDetailsForm.invalid) {
this.basicDetailsForm.markAllAsTouched();
return;
}
const basicDetailData: BasicDetail = this.basicDetailsForm.value;
const saveObservable = this.isEditMode && this.holderid > 0
? this.basicDetailService.updateBasicDetails(this.holderid, basicDetailData)
: this.basicDetailService.createBasicDetail(basicDetailData);
this.changeInProgress = true;
saveObservable.pipe(finalize(() => {
this.changeInProgress = false;
})).subscribe({
next: (basicData: any) => {
this.notificationService.showSuccess(`Basic details ${this.isEditMode ? 'updated' : 'added'} successfully`);
if (!this.isEditMode) {
this.holderIdCreated.emit(basicData.HOLDERID);
// change to edit mode after creation
this.isEditMode = true;
this.holderid = basicData.HOLDERID;
}
// if (this.isEditMode) {
// this.holderName.emit(basicDetailData.holderName);
// }
},
error: (error: any) => {
let errorMessage = this.errorHandler.handleApiError(error, `Failed to ${this.isEditMode ? 'update' : 'add'} basic details`);
this.notificationService.showError(errorMessage);
console.error('Error saving basic details:', error);
}
});
}
updateStateControl(controlName: string, country: string): void {
const stateControl = this.basicDetailsForm.get(controlName);
if (this.countriesHasStates.includes(country)) {
stateControl?.enable();
} else {
stateControl?.disable();
stateControl?.setValue('FN');
}
}
patchFormData(data: BasicDetail): void {
this.basicDetailsForm.patchValue({
holderName: data.holderName,
dbaName: data.dbaName,
holderNumber: data.holderNumber,
holderType: data.holderType,
uscibMember: data.uscibMember,
// govAgency: data.govAgency,
address1: data.address1,
address2: data.address2,
city: data.city,
state: data.state,
country: data.country,
zip: data.zip
})
if (data.country) {
this.loadStates(data.country);
}
}
get f() {
return this.basicDetailsForm.controls;
}
loadLookupData(): void {
this.commonService.getCountries()
.pipe(takeUntil(this.destroy$))
.subscribe({
next: (countries) => {
this.countries = countries;
},
error: (error) => {
console.error('Failed to load countries', error);
}
});
}
loadStates(country: string): void {
country = this.countriesHasStates.includes(country) ? country : 'FN';
this.commonService.getStates(country)
.pipe(takeUntil(this.destroy$))
.subscribe({
next: (states) => {
this.states = states;
this.updateStateControl('state', country);
},
error: (error) => {
console.error('Failed to load states', error);
}
});
}
goBackToCarnetApplication(): void {
this.storageService.removeItem('currentapplication')
this.navigationService.navigate([this.returnTo, this.currentApplicationDetails?.headerid],
{
state: { isEditMode: true },
queryParams: {
applicationname: this.currentApplicationDetails?.applicationName,
return: 'holder'
}
})
}
}