715 lines
25 KiB
TypeScript
715 lines
25 KiB
TypeScript
import { CommonModule } from '@angular/common';
|
|
import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
|
|
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
|
import { NotificationService } from '../../core/services/common/notification.service';
|
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
|
import { ShippingService } from '../../core/services/carnet/shipping.service';
|
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
|
import { CommonService } from '../../core/services/common/common.service';
|
|
import { Shipping } from '../../core/models/carnet/shipping';
|
|
import { Country } from '../../core/models/country';
|
|
import { State } from '../../core/models/state';
|
|
import { ZipCodeValidator } from '../../shared/validators/zipcode-validator';
|
|
import { finalize, forkJoin, map, of, Subject, switchMap, takeUntil, throwError } from 'rxjs';
|
|
import { DeliveryType } from '../../core/models/delivery-type';
|
|
import { DeliveryMethod } from '../../core/models/delivery-method';
|
|
import { PaymentType } from '../../core/models/payment-type';
|
|
import { format, isAfter, isWeekend, addBusinessDays } from 'date-fns';
|
|
import { MatDialog } from '@angular/material/dialog';
|
|
import { ShippingContact } from '../../core/models/carnet/shipping-contact';
|
|
import { ShippingAddress } from '../../core/models/carnet/shipping-address';
|
|
import { ContactDialogComponent } from './contact-dialog.component';
|
|
import { HolderService } from '../../core/services/carnet/holder.service';
|
|
import { Holder } from '../../core/models/carnet/holder';
|
|
import { NavigationService } from '../../core/services/common/navigation.service';
|
|
import { StorageService } from '../../core/services/common/storage.service';
|
|
import { FormOfSecurity } from '../../core/models/formofsecurity';
|
|
import { CarnetService } from '../../core/services/carnet/carnet.service';
|
|
import { environment } from '../../../environments/environment';
|
|
|
|
@Component({
|
|
selector: 'app-shipping',
|
|
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule],
|
|
templateUrl: './shipping.component.html',
|
|
styleUrl: './shipping.component.scss'
|
|
})
|
|
export class ShippingComponent {
|
|
@Input() headerid: number = 0;
|
|
@Input() isEditMode = false;
|
|
@Input() isViewMode = false;
|
|
@Input() enableSubmitButton = false;
|
|
@Input() applicationName: string = '';
|
|
|
|
@Output() completed = new EventEmitter<boolean>();
|
|
|
|
private fb = inject(FormBuilder);
|
|
private dialog = inject(MatDialog);
|
|
|
|
private shippingService = inject(ShippingService);
|
|
private notificationService = inject(NotificationService);
|
|
private errorHandler = inject(ApiErrorHandlerService);
|
|
private commonService = inject(CommonService);
|
|
private holderService = inject(HolderService);
|
|
private navigationService = inject(NavigationService);
|
|
private storageService = inject(StorageService);
|
|
private carnetService = inject(CarnetService);
|
|
|
|
shippingForm: FormGroup;
|
|
isLoading = false;
|
|
changeInProgress = false;
|
|
showAddressForm = false;
|
|
showContactForm = false;
|
|
deliveryEstimate: string = '';
|
|
holderid: number = 0;
|
|
holder: Holder | undefined | null = null;
|
|
showSubmitButton: boolean = environment.appType === 'client';
|
|
showProcessButton: boolean = environment.appType === 'service-provider';
|
|
|
|
countriesHasStates = ['US', 'CA', 'MX'];
|
|
countries: Country[] = [];
|
|
states: State[] = [];
|
|
deliveryTypes: DeliveryType[] = [];
|
|
deliveryMethods: DeliveryMethod[] = [];
|
|
paymentTypes: PaymentType[] = [];
|
|
formOfSecurities: FormOfSecurity[] = [];
|
|
govFormOfSecurities: FormOfSecurity[] = [];
|
|
nonGovFormOfSecurities: FormOfSecurity[] = [];
|
|
shippingFromDB: Shipping | null = null;
|
|
|
|
private destroy$ = new Subject<void>();
|
|
|
|
preparerAddress: ShippingAddress | null | undefined = null;
|
|
holderAddress: ShippingAddress | null | undefined = null;
|
|
preparerContact: ShippingContact | null | undefined = null;
|
|
preparerContacts: ShippingContact[] = [];
|
|
holderContact: ShippingContact | null | undefined = null;
|
|
holderContacts: ShippingContact[] = [];
|
|
|
|
constructor() {
|
|
this.shippingForm = this.fb.group({
|
|
// needsBond: [false],
|
|
needsInsurance: [false],
|
|
needsLostDocProtection: [false],
|
|
formOfSecurity: ['', Validators.required],
|
|
shipTo: ['PREPARER', Validators.required],
|
|
address: this.fb.group({
|
|
companyName: [''],
|
|
address1: [''],
|
|
address2: [''],
|
|
city: [''],
|
|
state: [''],
|
|
country: ['US'],
|
|
zip: [''],
|
|
}),
|
|
contact: this.fb.group({
|
|
firstName: [''],
|
|
lastName: [''],
|
|
middleInitial: [''],
|
|
title: [''],
|
|
phone: [''],
|
|
mobile: [''],
|
|
fax: [''],
|
|
email: [''],
|
|
refNumber: [''],
|
|
notes: ['']
|
|
}),
|
|
deliveryType: ['', Validators.required],
|
|
deliveryMethod: ['', Validators.required],
|
|
courierAccount: [''],
|
|
paymentMethod: ['', Validators.required],
|
|
paymentNotes: ['']
|
|
});
|
|
|
|
this.shippingForm.get('deliveryType')?.valueChanges.subscribe(() => {
|
|
this.calculateDeliveryEstimate();
|
|
});
|
|
|
|
}
|
|
|
|
ngOnInit(): void {
|
|
this.loadCountries();
|
|
this.loadDeliveryTypes();
|
|
this.loadDeliveryMethods();
|
|
this.loadPaymentTypes();
|
|
this.loadFormOfSecurities();
|
|
|
|
if (this.headerid && this.headerid > 0) {
|
|
this.loadShippingData();
|
|
}
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.destroy$.next();
|
|
this.destroy$.complete();
|
|
}
|
|
|
|
onSubmit(submitApp: boolean): void {
|
|
if (this.shippingForm.invalid) {
|
|
this.shippingForm.markAllAsTouched();
|
|
return;
|
|
}
|
|
|
|
this.changeInProgress = true;
|
|
const shippingData: Shipping = this.shippingForm.value;
|
|
|
|
if (shippingData.shipTo !== '3RDPARTY') {
|
|
shippingData.address = shippingData.shipTo === 'PREPARER' ? this.preparerAddress ?? undefined : this.holderAddress ?? undefined;
|
|
shippingData.contact = shippingData.shipTo === 'PREPARER' ? this.preparerContact ?? undefined : this.holderContact ?? undefined;
|
|
}
|
|
|
|
if (this.holder?.holderType.trim() === 'GOV') {
|
|
shippingData.formOfSecurity = this.govFormOfSecurities?.[0].value;
|
|
}
|
|
|
|
this.shippingService.saveShippingDetails(this.headerid, shippingData).pipe(finalize(() => {
|
|
this.changeInProgress = false;
|
|
})).subscribe({
|
|
next: () => {
|
|
this.notificationService.showSuccess('Shipping & payments information saved successfully');
|
|
this.completed.emit(true);
|
|
|
|
if (this.enableSubmitButton && this.headerid && submitApp) {
|
|
let currentApplicationDetails = { headerid: this.headerid, applicationName: this.applicationName }
|
|
this.storageService.set("currentapplication", currentApplicationDetails);
|
|
|
|
this.navigationService.navigate(["terms"])
|
|
}
|
|
},
|
|
error: (error) => {
|
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save shipping and payment information');
|
|
this.notificationService.showError(errorMessage);
|
|
}
|
|
});
|
|
}
|
|
|
|
onDeliveryTypeChange(): void {
|
|
this.calculateDeliveryEstimate();
|
|
}
|
|
|
|
onDeliveryMethodChange(deliveryMethod: string): void {
|
|
const courierControl = this.shippingForm.get('courierAccount');
|
|
if (deliveryMethod === 'CLC') {
|
|
courierControl?.setValidators([Validators.required]);
|
|
} else {
|
|
courierControl?.clearValidators();
|
|
}
|
|
courierControl?.updateValueAndValidity();
|
|
}
|
|
|
|
onCountryChange(country: string): void {
|
|
this.shippingForm.get('address.state')?.reset();
|
|
|
|
if (country) {
|
|
this.loadStates(country);
|
|
}
|
|
|
|
this.shippingForm.get('address.zip')?.updateValueAndValidity();
|
|
}
|
|
|
|
public refreshShippingData(): void {
|
|
if (this.headerid > 0) {
|
|
this.loadAddressContactData();
|
|
}
|
|
}
|
|
|
|
editAddressForm(): void {
|
|
this.showAddressForm = true;
|
|
let shipTo = this.shippingForm.get('shipTo')?.value;
|
|
|
|
if (shipTo === 'PREPARER' && this.preparerAddress) {
|
|
this.shippingForm.get('address')?.patchValue(this.preparerAddress);
|
|
this.loadStates(this.preparerAddress.country);
|
|
} else if (shipTo === 'HOLDER' && this.holderAddress) {
|
|
this.shippingForm.get('address')?.patchValue(this.holderAddress);
|
|
this.loadStates(this.holderAddress.country);
|
|
}
|
|
}
|
|
|
|
cancelEditAddressForm(): void {
|
|
this.showAddressForm = false;
|
|
this.shippingForm.get('address')?.reset({ country: 'US' });
|
|
this.loadStates('US');
|
|
}
|
|
|
|
onShipToChange(event: any): void {
|
|
const shipTo = event.value;
|
|
this.showAddressForm = false;
|
|
this.showContactForm = false;
|
|
|
|
this.updateAddressContactValidation(shipTo);
|
|
|
|
if (shipTo === '3RDPARTY') {
|
|
this.shippingForm.get('contact')?.reset();
|
|
this.shippingForm.get('address')?.reset({ country: 'US' });
|
|
this.loadStates('US');
|
|
this.showAddressForm = true;
|
|
this.showContactForm = true;
|
|
}
|
|
}
|
|
|
|
loadCountries(): void {
|
|
this.commonService.getCountries()
|
|
.pipe(takeUntil(this.destroy$))
|
|
.subscribe({
|
|
next: (countries) => {
|
|
this.countries = countries;
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to load countries', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
loadDeliveryTypes(): void {
|
|
this.commonService.getDeliveryTypes()
|
|
.pipe(takeUntil(this.destroy$))
|
|
.subscribe({
|
|
next: (deliveryTypes) => {
|
|
this.deliveryTypes = deliveryTypes;
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to load delivery types', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
loadDeliveryMethods(): void {
|
|
this.commonService.getDeliveryMethods()
|
|
.pipe(takeUntil(this.destroy$))
|
|
.subscribe({
|
|
next: (deliveryMethods) => {
|
|
this.deliveryMethods = deliveryMethods;
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to load delivery methods', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
loadPaymentTypes(): void {
|
|
this.commonService.getPaymentTypes()
|
|
.pipe(takeUntil(this.destroy$))
|
|
.subscribe({
|
|
next: (paymentTypes) => {
|
|
this.paymentTypes = paymentTypes;
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to load payment types', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
loadStates(country: string): void {
|
|
this.isLoading = true;
|
|
country = this.countriesHasStates.includes(country) ? country : 'FN';
|
|
this.commonService.getStates(country)
|
|
.pipe(takeUntil(this.destroy$),
|
|
finalize(() => {
|
|
this.isLoading = false;
|
|
})).subscribe({
|
|
next: (states) => {
|
|
this.states = states;
|
|
const stateControl = this.shippingForm.get('contact.state');
|
|
if (this.countriesHasStates.includes(country)) {
|
|
stateControl?.enable();
|
|
} else {
|
|
stateControl?.disable();
|
|
stateControl?.setValue('FN');
|
|
}
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to load states', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
loadFormOfSecurities(): void {
|
|
this.commonService.getFormOfSecurities()
|
|
.pipe(takeUntil(this.destroy$))
|
|
.subscribe({
|
|
next: (fos) => {
|
|
this.govFormOfSecurities = fos.filter(f => f.isGov);
|
|
this.nonGovFormOfSecurities = fos.filter(f => !f.isGov);
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to load form of securities', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
loadShippingData(): void {
|
|
this.isLoading = true;
|
|
this.shippingService.getShippingData(this.headerid).pipe(
|
|
finalize(() => {
|
|
this.isLoading = false;
|
|
})
|
|
).subscribe({
|
|
next: (results: Shipping) => {
|
|
|
|
if (!results) { // do nothing if empty
|
|
return;
|
|
}
|
|
this.shippingFromDB = results;
|
|
this.patchShippingData();
|
|
this.loadAddressContactData();
|
|
},
|
|
error: (error: any) => {
|
|
console.error('Error loading shipping data', error);
|
|
const errorMessage = this.errorHandler.handleApiError(error, 'Failed to load shipping data');
|
|
this.notificationService.showError(errorMessage);
|
|
}
|
|
});
|
|
}
|
|
|
|
loadAddressContactData(): void {
|
|
this.isLoading = true;
|
|
|
|
this.holderService.getHolder(this.headerid).pipe(
|
|
switchMap((holder: Holder) => {
|
|
if (!holder?.holderid) {
|
|
return of(undefined);
|
|
}
|
|
|
|
this.holder = holder;
|
|
this.formOfSecurities = holder.holderType?.trim() === 'GOV' ? this.govFormOfSecurities : this.nonGovFormOfSecurities;
|
|
|
|
return forkJoin({
|
|
holderContacts: this.shippingService.getHolderContactsById(holder.holderid),
|
|
holderAddress: this.shippingService.getHolderAddress(holder),
|
|
preparerAddress: this.shippingService.getPreparerAddress(),
|
|
preparerContacts: this.shippingService.getPreparerContacts()
|
|
}).pipe(
|
|
// Combine the forkJoin results with the original holder object
|
|
map((apiResults: any) => ({ ...apiResults, holder }))
|
|
);
|
|
}),
|
|
finalize(() => this.isLoading = false)
|
|
).subscribe({
|
|
next: (results) => {
|
|
|
|
if (!results && !this.shippingFromDB) { // do nothing if empty
|
|
return;
|
|
}
|
|
|
|
this.holderid = results.holder.holderid;
|
|
this.holderContacts = results.holderContacts;
|
|
this.holderAddress = results.holderAddress;
|
|
this.preparerContacts = results.preparerContacts;
|
|
this.preparerAddress = results.preparerAddress;
|
|
|
|
// Set holder contact
|
|
if (this.shippingFromDB?.shipTo === 'HOLDER' && this.shippingFromDB?.contact?.contactid) {
|
|
this.holderContact = this.holderContacts.find(hc => hc.contactid === this.shippingFromDB?.contact?.contactid);
|
|
} else {
|
|
this.holderContact = this.holderContacts?.[0];
|
|
}
|
|
|
|
// Set preparer contact
|
|
if (this.shippingFromDB?.shipTo === 'PREPARER' && this.shippingFromDB?.contact?.contactid) {
|
|
this.preparerContact = this.preparerContacts.find(pc => pc.contactid === this.shippingFromDB?.contact?.contactid);
|
|
} else {
|
|
this.preparerContact = this.preparerContacts.find(pc => pc.defaultContact);
|
|
}
|
|
this.patchAddressContactData();
|
|
},
|
|
error: (error: any) => {
|
|
console.error('Error loading shipping data', error);
|
|
const errorMessage = this.errorHandler.handleApiError(error, 'Failed to load shipping data');
|
|
this.notificationService.showError(errorMessage);
|
|
}
|
|
});
|
|
}
|
|
|
|
patchShippingData(): void {
|
|
if (!this.shippingFromDB) {
|
|
return;
|
|
}
|
|
|
|
this.shippingForm.patchValue({
|
|
// needsBond: shipping.needsBond,
|
|
needsInsurance: this.shippingFromDB.needsInsurance,
|
|
needsLostDocProtection: this.shippingFromDB.needsLostDocProtection,
|
|
formOfSecurity: this.shippingFromDB.formOfSecurity,
|
|
shipTo: this.shippingFromDB.shipTo,
|
|
deliveryType: this.shippingFromDB.deliveryType,
|
|
deliveryMethod: this.shippingFromDB.deliveryMethod,
|
|
courierAccount: this.shippingFromDB.courierAccount,
|
|
paymentMethod: this.shippingFromDB.paymentMethod
|
|
});
|
|
|
|
if (this.shippingFromDB.deliveryMethod === 'CLC') {
|
|
this.onDeliveryMethodChange(this.shippingFromDB.deliveryMethod);
|
|
}
|
|
|
|
this.calculateDeliveryEstimate();
|
|
this.shippingForm.markAsUntouched();
|
|
this.completed.emit(this.shippingForm.valid);
|
|
}
|
|
|
|
patchAddressContactData(): void {
|
|
|
|
if (!this.shippingFromDB) {
|
|
return
|
|
}
|
|
|
|
if (this.shippingFromDB.address?.country) {
|
|
this.loadStates(this.shippingFromDB.address?.country);
|
|
}
|
|
|
|
let formOfSecurityControl = this.shippingForm.get('formOfSecurity');
|
|
if (this.holder?.holderType.trim() === 'GOV') {
|
|
formOfSecurityControl?.setValue(this.govFormOfSecurities?.[0].value);
|
|
formOfSecurityControl?.disable();
|
|
} else {
|
|
formOfSecurityControl?.enable();
|
|
}
|
|
|
|
this.calculateDeliveryEstimate();
|
|
this.updateAddressContactValidation(this.shippingFromDB.shipTo);
|
|
|
|
if (this.shippingFromDB.shipTo === '3RDPARTY') {
|
|
this.showAddressForm = true;
|
|
this.showContactForm = true;
|
|
|
|
const addressGroup = this.shippingForm.get('address') as FormGroup;
|
|
const contactGroup = this.shippingForm.get('contact') as FormGroup;
|
|
|
|
addressGroup.patchValue({
|
|
addressid: this.shippingFromDB.address?.addressid,
|
|
companyName: this.shippingFromDB.address?.companyName,
|
|
address1: this.shippingFromDB.address?.address1,
|
|
address2: this.shippingFromDB.address?.address2,
|
|
city: this.shippingFromDB.address?.city,
|
|
state: this.shippingFromDB.address?.state,
|
|
zip: this.shippingFromDB.address?.zip,
|
|
country: this.shippingFromDB.address?.country
|
|
})
|
|
|
|
contactGroup.patchValue({
|
|
contactid: this.shippingFromDB.contact?.contactid,
|
|
firstName: this.shippingFromDB.contact?.firstName,
|
|
lastName: this.shippingFromDB.contact?.lastName,
|
|
middleInitial: this.shippingFromDB.contact?.middleInitial,
|
|
title: this.shippingFromDB.contact?.title,
|
|
phone: this.shippingFromDB.contact?.phone,
|
|
mobile: this.shippingFromDB.contact?.mobile,
|
|
fax: this.shippingFromDB.contact?.fax,
|
|
email: this.shippingFromDB.contact?.email,
|
|
refNumber: this.shippingFromDB.contact?.refNumber,
|
|
notes: this.shippingFromDB.contact?.notes,
|
|
})
|
|
}
|
|
this.shippingForm.markAsUntouched();
|
|
this.completed.emit(this.shippingForm.valid);
|
|
}
|
|
|
|
updateAddressContactValidation(shipTo: string): void {
|
|
const addressGroup = this.shippingForm.get('address') as FormGroup;
|
|
const contactGroup = this.shippingForm.get('contact') as FormGroup;
|
|
|
|
if (shipTo === '3RDPARTY') {
|
|
Object.keys(addressGroup.controls).forEach(key => {
|
|
if (key === 'companyName') {
|
|
addressGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(100)]);
|
|
} else if (key === 'address1') {
|
|
addressGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(100)]);
|
|
} else if (key === 'address2') {
|
|
addressGroup.get(key)?.setValidators([Validators.maxLength(100)]);
|
|
} else if (key === 'city') {
|
|
addressGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(50)]);
|
|
} else if (key === 'state') {
|
|
addressGroup.get(key)?.setValidators(Validators.required);
|
|
} else if (key === 'country') {
|
|
addressGroup.get(key)?.setValidators(Validators.required);
|
|
} else if (key === 'zip') {
|
|
addressGroup.get(key)?.setValidators([Validators.required, ZipCodeValidator('country')]);
|
|
}
|
|
addressGroup.get(key)?.updateValueAndValidity();
|
|
});
|
|
Object.keys(contactGroup.controls).forEach(key => {
|
|
if (key === 'firstName') {
|
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(50)]);
|
|
} else if (key === 'lastName') {
|
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(50)]);
|
|
} else if (key === 'middleInitial') {
|
|
contactGroup.get(key)?.setValidators([Validators.maxLength(1)]);
|
|
} else if (key === 'title') {
|
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(100)]);
|
|
} else if (key === 'phone') {
|
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]);
|
|
} else if (key === 'mobile') {
|
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]);
|
|
} else if (key === 'fax') {
|
|
contactGroup.get(key)?.setValidators([Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]);
|
|
} else if (key === 'email') {
|
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.email, Validators.maxLength(100)]);
|
|
}
|
|
contactGroup.get(key)?.updateValueAndValidity();
|
|
});
|
|
} else {
|
|
Object.keys(addressGroup.controls).forEach(key => {
|
|
addressGroup.get(key)?.clearValidators();
|
|
addressGroup.get(key)?.updateValueAndValidity();
|
|
});
|
|
Object.keys(contactGroup.controls).forEach(key => {
|
|
contactGroup.get(key)?.clearValidators();
|
|
contactGroup.get(key)?.updateValueAndValidity();
|
|
});
|
|
}
|
|
}
|
|
|
|
getAddressLabel(): string {
|
|
let shipTo = this.shippingForm.get('shipTo')?.value;
|
|
|
|
if (shipTo === 'PREPARER' && this.preparerAddress) {
|
|
return `${this.preparerAddress.companyName}, ${this.preparerAddress.address1},
|
|
${this.preparerAddress.city}, ${this.preparerAddress.state}, ${this.preparerAddress.zip},
|
|
${this.preparerAddress.country}`;
|
|
}
|
|
|
|
if (shipTo === 'HOLDER' && this.holderAddress) {
|
|
return `${this.holderAddress.companyName}, ${this.holderAddress.address1},
|
|
${this.holderAddress.city}, ${this.holderAddress.state}, ${this.holderAddress.zip},
|
|
${this.holderAddress.country}`;
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
getContactLabel(): string {
|
|
const shipTo = this.shippingForm.get('shipTo')?.value;
|
|
const contact = shipTo === 'PREPARER' ? this.preparerContact :
|
|
shipTo === 'HOLDER' ? this.holderContact : null;
|
|
|
|
if (!contact) {
|
|
return 'No contact information available';
|
|
}
|
|
|
|
// Build name parts, filtering out null/undefined/empty strings
|
|
const nameParts = [
|
|
contact.firstName,
|
|
contact.middleInitial,
|
|
contact.lastName
|
|
].filter(part => part != null && part.trim() !== '');
|
|
|
|
// Build contact info parts
|
|
const contactInfoParts = [
|
|
contact.email,
|
|
contact.phone
|
|
].filter(part => part != null && part.trim() !== '');
|
|
|
|
// Combine all non-empty parts
|
|
const allParts = [
|
|
nameParts.join(' '), // Join name parts with single spaces
|
|
...contactInfoParts // Add email and phone if they exist
|
|
].filter(part => part.trim() !== '');
|
|
|
|
return allParts.join(', ') || '';
|
|
}
|
|
|
|
calculateDeliveryEstimate(): void {
|
|
const deliveryType = this.shippingForm.get('deliveryType')?.value;
|
|
const deliveryTypeObj = this.deliveryTypes.find(dt => dt.value === deliveryType);
|
|
const daysToDelivery: number = Number(deliveryTypeObj?.daysToDelivery) !== 0 ? Number(deliveryTypeObj?.daysToDelivery) : 3;
|
|
const cutOffTime: number = Number(deliveryTypeObj?.cutOffTime) !== 0 ? Number(deliveryTypeObj?.cutOffTime) : 16;
|
|
|
|
const now = new Date();
|
|
const cutoffTime = new Date();
|
|
cutoffTime.setHours(cutOffTime, 0, 0, 0);
|
|
|
|
let deliveryDate: Date;
|
|
let message = 'Estimated delivery: ';
|
|
const isAfterCutoff = isAfter(now, cutoffTime);
|
|
const isWeekendDay = isWeekend(now);
|
|
|
|
switch (deliveryType) {
|
|
case 'SAME':
|
|
if (isAfterCutoff || isWeekendDay) {
|
|
deliveryDate = addBusinessDays(now, 1);
|
|
message += format(deliveryDate, 'EEEE, MMMM do, yyyy');
|
|
} else {
|
|
message += format(now, 'EEEE, MMMM do, yyyy');
|
|
}
|
|
break;
|
|
|
|
case 'STD':
|
|
// Standard is 3 business days
|
|
if (isAfterCutoff || isWeekendDay) {
|
|
// If after cutoff or weekend, add 4 business days
|
|
deliveryDate = addBusinessDays(now, daysToDelivery);
|
|
} else {
|
|
// Before cutoff on weekday, add 3 business days
|
|
deliveryDate = addBusinessDays(now, daysToDelivery - 1);
|
|
}
|
|
|
|
message += format(deliveryDate, 'EEEE, MMMM do, yyyy');
|
|
break;
|
|
|
|
case 'NBD':
|
|
// Next business day for pickup
|
|
if (isAfterCutoff || isWeekendDay) {
|
|
// If after cutoff or weekend, add 2 business days
|
|
deliveryDate = addBusinessDays(now, daysToDelivery);
|
|
} else {
|
|
// Before cutoff on weekday, add 1 business day
|
|
deliveryDate = addBusinessDays(now, daysToDelivery);
|
|
}
|
|
|
|
message += format(deliveryDate, 'EEEE, MMMM do, yyyy');
|
|
break;
|
|
|
|
default:
|
|
message = '';
|
|
}
|
|
|
|
this.deliveryEstimate = message;
|
|
}
|
|
|
|
selectContact(): void {
|
|
let shipTo = this.shippingForm.get('shipTo')?.value;
|
|
|
|
const contacts = shipTo === 'PREPARER' ? this.preparerContacts : this.holderContacts;
|
|
const currentContact = shipTo === 'PREPARER' ? this.preparerContact : this.holderContact;
|
|
|
|
const dialogRef = this.dialog.open(ContactDialogComponent, {
|
|
width: '500px',
|
|
data: { contacts: contacts, currentContact: currentContact }
|
|
});
|
|
|
|
dialogRef.afterClosed().subscribe(selectedItem => {
|
|
if (selectedItem) {
|
|
const selectedContact = contacts.find(c => c.contactid === selectedItem.contactid);
|
|
if (shipTo === 'PREPARER') {
|
|
this.preparerContact = selectedContact;
|
|
} else {
|
|
this.holderContact = selectedContact;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
submitApplication(): void {
|
|
this.onSubmit(true);
|
|
}
|
|
|
|
returnToHome(): void {
|
|
this.navigationService.navigate(["home"])
|
|
}
|
|
|
|
processApplication(): void {
|
|
this.changeInProgress = true;
|
|
this.carnetService.processApplication(this.headerid).pipe(finalize(() => {
|
|
this.changeInProgress = false;
|
|
})).subscribe({
|
|
next: () => {
|
|
this.notificationService.showSuccess('Application processed successfully');
|
|
this.navigationService.navigate(["home"]);
|
|
},
|
|
error: (error) => {
|
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to submit application');
|
|
this.notificationService.showError(errorMessage);
|
|
console.error('Error submitting the application', error);
|
|
}
|
|
});
|
|
}
|
|
} |