shipping contact updates
This commit is contained in:
parent
78f7b114fa
commit
1b6ceb6be7
61
src/app/carnet/shipping/contact-dialog.component.ts
Normal file
61
src/app/carnet/shipping/contact-dialog.component.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { Component, Inject } from '@angular/core';
|
||||||
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||||
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-contact-dialog',
|
||||||
|
imports: [AngularMaterialModule, CommonModule, FormsModule],
|
||||||
|
template: `
|
||||||
|
<h2 mat-dialog-title>Select Contact</h2>
|
||||||
|
<mat-dialog-content>
|
||||||
|
<mat-radio-group [(ngModel)]="selectedContact">
|
||||||
|
<mat-radio-button *ngFor="let contact of contacts" [value]="contact">
|
||||||
|
{{getContactLabel(contact)}}
|
||||||
|
</mat-radio-button>
|
||||||
|
</mat-radio-group>
|
||||||
|
</mat-dialog-content>
|
||||||
|
<mat-dialog-actions>
|
||||||
|
<button mat-button (click)="onCancel()">Cancel</button>
|
||||||
|
<button mat-raised-button color="primary" (click)="onSelect()" [disabled]="!selectedContact">
|
||||||
|
Select
|
||||||
|
</button>
|
||||||
|
</mat-dialog-actions>
|
||||||
|
`,
|
||||||
|
styles: [`
|
||||||
|
mat-radio-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
mat-radio-button {
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
`]
|
||||||
|
})
|
||||||
|
export class ContactDialogComponent {
|
||||||
|
selectedContact: any | null = null;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<ContactDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: { contacts: any[] }
|
||||||
|
) { }
|
||||||
|
|
||||||
|
get contacts() {
|
||||||
|
return this.data.contacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelect(): void {
|
||||||
|
this.dialogRef.close(this.selectedContact);
|
||||||
|
}
|
||||||
|
|
||||||
|
onCancel(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
getContactLabel(contact: any): string {
|
||||||
|
return `${contact.firstName} ${contact.middleInitial} ${contact.lastName},
|
||||||
|
${contact.email}, ${contact.phone}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -33,6 +33,10 @@
|
|||||||
<button mat-icon-button color="primary" (click)="editAddressForm()" matTooltip="Edit">
|
<button mat-icon-button color="primary" (click)="editAddressForm()" matTooltip="Edit">
|
||||||
<mat-icon>edit</mat-icon>
|
<mat-icon>edit</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-icon-button color="primary" (click)="selectContact()"
|
||||||
|
matTooltip="Change contact">
|
||||||
|
<mat-icon>compare_arrows</mat-icon>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
@ -249,7 +253,7 @@
|
|||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
<mat-label>Delivery Type</mat-label>
|
<mat-label>Delivery Type</mat-label>
|
||||||
<mat-select formControlName="deliveryType" required>
|
<mat-select formControlName="deliveryType" required (change)="onDeliveryTypeChange()">
|
||||||
<mat-option *ngFor="let deliveryType of deliveryTypes" [value]="deliveryType.value">
|
<mat-option *ngFor="let deliveryType of deliveryTypes" [value]="deliveryType.value">
|
||||||
{{ deliveryType.name }}
|
{{ deliveryType.name }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
@ -263,7 +267,8 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
<mat-label>Delivery Method</mat-label>
|
<mat-label>Delivery Method</mat-label>
|
||||||
<mat-select formControlName="deliveryMethod" required>
|
<mat-select formControlName="deliveryMethod" required
|
||||||
|
(selectionChange)="onDeliveryMethodChange($event.value)">
|
||||||
<mat-option *ngFor="let deliveryMethod of deliveryMethods" [value]="deliveryMethod.value">
|
<mat-option *ngFor="let deliveryMethod of deliveryMethods" [value]="deliveryMethod.value">
|
||||||
{{ deliveryMethod.name }}
|
{{ deliveryMethod.name }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
|
|||||||
@ -15,6 +15,10 @@ import { DeliveryType } from '../../core/models/delivery-type';
|
|||||||
import { DeliveryMethod } from '../../core/models/delivery-method';
|
import { DeliveryMethod } from '../../core/models/delivery-method';
|
||||||
import { PaymentType } from '../../core/models/payment-type';
|
import { PaymentType } from '../../core/models/payment-type';
|
||||||
import { format, addDays, isAfter, isWeekend } from 'date-fns';
|
import { format, addDays, isAfter, isWeekend } 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';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-shipping',
|
selector: 'app-shipping',
|
||||||
@ -28,6 +32,8 @@ export class ShippingComponent {
|
|||||||
@Output() completed = new EventEmitter<boolean>();
|
@Output() completed = new EventEmitter<boolean>();
|
||||||
|
|
||||||
private fb = inject(FormBuilder);
|
private fb = inject(FormBuilder);
|
||||||
|
private dialog = inject(MatDialog);
|
||||||
|
|
||||||
private shippingService = inject(ShippingService);
|
private shippingService = inject(ShippingService);
|
||||||
private notificationService = inject(NotificationService);
|
private notificationService = inject(NotificationService);
|
||||||
private errorHandler = inject(ApiErrorHandlerService);
|
private errorHandler = inject(ApiErrorHandlerService);
|
||||||
@ -49,16 +55,33 @@ export class ShippingComponent {
|
|||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
|
|
||||||
// preparer contact and address mock data
|
// preparer contact and address mock data
|
||||||
preparerContact = {
|
preparerContact: ShippingContact | null | undefined = null;
|
||||||
firstName: 'John',
|
|
||||||
lastName: 'Doe',
|
preparerContacts: ShippingContact[] = [
|
||||||
middleInitial: 'A',
|
{
|
||||||
title: 'Mr.',
|
contactid: 1,
|
||||||
phone: '1234567890',
|
firstName: 'John',
|
||||||
mobile: '0987654321',
|
lastName: 'Doe',
|
||||||
fax: '1234567890',
|
middleInitial: 'A',
|
||||||
email: 'j@doe.com',
|
title: 'Mr.',
|
||||||
}
|
phone: '1234567890',
|
||||||
|
mobile: '0987654321',
|
||||||
|
fax: '1234567890',
|
||||||
|
email: 'j@doe.com',
|
||||||
|
defaultContact: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contactid: 2,
|
||||||
|
firstName: 'Jane',
|
||||||
|
lastName: 'Smith',
|
||||||
|
middleInitial: 'B',
|
||||||
|
title: 'Ms.',
|
||||||
|
phone: '2345678901',
|
||||||
|
mobile: '1098765432',
|
||||||
|
fax: '2345678901',
|
||||||
|
email: 'jan@sm.cm',
|
||||||
|
defaultContact: false
|
||||||
|
}];
|
||||||
|
|
||||||
preparerAddress = {
|
preparerAddress = {
|
||||||
companyName: 'ABC Company',
|
companyName: 'ABC Company',
|
||||||
@ -80,16 +103,33 @@ export class ShippingComponent {
|
|||||||
country: 'US'
|
country: 'US'
|
||||||
};
|
};
|
||||||
|
|
||||||
holderContact = {
|
holderContact: ShippingContact | null | undefined = null;
|
||||||
firstName: 'Jane',
|
|
||||||
lastName: 'Smith',
|
holderContacts: ShippingContact[] = [
|
||||||
middleInitial: 'B',
|
{
|
||||||
title: 'Ms.',
|
contactid: 1,
|
||||||
phone: '2345678901',
|
firstName: 'John',
|
||||||
mobile: '1098765432',
|
lastName: 'Doe',
|
||||||
fax: '2345678901',
|
middleInitial: 'A',
|
||||||
email: 'jan@sm.cm'
|
title: 'Mr.',
|
||||||
};
|
phone: '1234567890',
|
||||||
|
mobile: '0987654321',
|
||||||
|
fax: '1234567890',
|
||||||
|
email: 'j@doe.com',
|
||||||
|
defaultContact: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contactid: 2,
|
||||||
|
firstName: 'Jane',
|
||||||
|
lastName: 'Smith',
|
||||||
|
middleInitial: 'B',
|
||||||
|
title: 'Ms.',
|
||||||
|
phone: '2345678901',
|
||||||
|
mobile: '1098765432',
|
||||||
|
fax: '2345678901',
|
||||||
|
email: 'jan@sm.cm',
|
||||||
|
defaultContact: true
|
||||||
|
}];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.shippingForm = this.fb.group({
|
this.shippingForm = this.fb.group({
|
||||||
@ -124,19 +164,8 @@ export class ShippingComponent {
|
|||||||
paymentNotes: ['']
|
paymentNotes: ['']
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update form validation based on selections
|
|
||||||
this.shippingForm.get('shipTo')?.valueChanges.subscribe(value => {
|
|
||||||
this.updateShippingValidation(value);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.shippingForm.get('deliveryMethod')?.valueChanges.subscribe(value => {
|
this.shippingForm.get('deliveryMethod')?.valueChanges.subscribe(value => {
|
||||||
const courierControl = this.shippingForm.get('courierAccount');
|
|
||||||
if (value === 'CLC') {
|
|
||||||
courierControl?.setValidators([Validators.required]);
|
|
||||||
} else {
|
|
||||||
courierControl?.clearValidators();
|
|
||||||
}
|
|
||||||
courierControl?.updateValueAndValidity();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.shippingForm.get('deliveryType')?.valueChanges.subscribe(() => {
|
this.shippingForm.get('deliveryType')?.valueChanges.subscribe(() => {
|
||||||
@ -156,6 +185,10 @@ export class ShippingComponent {
|
|||||||
|
|
||||||
if (this.headerid && this.isEditMode) {
|
if (this.headerid && this.isEditMode) {
|
||||||
this.loadShippingData();
|
this.loadShippingData();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
this.preparerContact = this.preparerContacts.find(pc => pc.defaultContact);
|
||||||
|
this.holderContact = this.holderContacts.find(hc => hc.defaultContact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +197,43 @@ export class ShippingComponent {
|
|||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSubmit(): void {
|
||||||
|
if (this.shippingForm.invalid) {
|
||||||
|
this.shippingForm.markAllAsTouched();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isLoading = true;
|
||||||
|
const shippingData = this.shippingForm.value;
|
||||||
|
|
||||||
|
this.shippingService.saveShippingDetails(this.headerid, shippingData).subscribe({
|
||||||
|
next: () => {
|
||||||
|
this.notificationService.showSuccess('Shipping & payments information saved successfully');
|
||||||
|
this.completed.emit(true);
|
||||||
|
this.isLoading = false;
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save shipping and payment information');
|
||||||
|
this.notificationService.showError(errorMessage);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
onCountryChange(country: string): void {
|
||||||
this.shippingForm.get('address.state')?.reset();
|
this.shippingForm.get('address.state')?.reset();
|
||||||
|
|
||||||
@ -174,6 +244,39 @@ export class ShippingComponent {
|
|||||||
this.shippingForm.get('address.zip')?.updateValueAndValidity();
|
this.shippingForm.get('address.zip')?.updateValueAndValidity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
editAddressForm(): void {
|
||||||
|
this.showAddressForm = true;
|
||||||
|
let shipTo = this.shippingForm.get('shipTo')?.value;
|
||||||
|
|
||||||
|
if (shipTo === 'preparer') {
|
||||||
|
this.shippingForm.get('address')?.patchValue(this.preparerAddress);
|
||||||
|
this.loadStates(this.preparerAddress.country);
|
||||||
|
} else if (shipTo === 'holder') {
|
||||||
|
this.shippingForm.get('address')?.patchValue(this.holderAddress);
|
||||||
|
this.loadStates(this.preparerAddress.country);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelEditAddressForm(): void {
|
||||||
|
this.showAddressForm = false;
|
||||||
|
this.shippingForm.get('address')?.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
onShipToChange(event: any): void {
|
||||||
|
const shipTo = event.value;
|
||||||
|
this.showAddressForm = false;
|
||||||
|
this.showContactForm = false;
|
||||||
|
|
||||||
|
this.updateShippingValidation(shipTo);
|
||||||
|
|
||||||
|
if (shipTo === 'thirdParty') {
|
||||||
|
this.shippingForm.get('contact')?.reset();
|
||||||
|
this.shippingForm.get('address')?.reset();
|
||||||
|
this.showAddressForm = true;
|
||||||
|
this.showContactForm = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loadCountries(): void {
|
loadCountries(): void {
|
||||||
this.commonService.getCountries(0)
|
this.commonService.getCountries(0)
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
@ -285,8 +388,14 @@ export class ShippingComponent {
|
|||||||
this.loadStates(shipping.address?.country);
|
this.loadStates(shipping.address?.country);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shipping.deliveryMethod === 'CLC') {
|
||||||
|
this.onDeliveryMethodChange(shipping.deliveryMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.calculateDeliveryEstimate();
|
||||||
|
this.updateShippingValidation(shipping.shipTo);
|
||||||
|
|
||||||
if (shipping.shipTo === 'thirdParty') {
|
if (shipping.shipTo === 'thirdParty') {
|
||||||
this.updateShippingValidation(shipping.shipTo);
|
|
||||||
this.showAddressForm = true;
|
this.showAddressForm = true;
|
||||||
this.showContactForm = true;
|
this.showContactForm = true;
|
||||||
|
|
||||||
@ -317,8 +426,64 @@ export class ShippingComponent {
|
|||||||
notes: shipping.contact?.notes,
|
notes: shipping.contact?.notes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.calculateDeliveryEstimate();
|
loadPreparerContacts(): void {
|
||||||
|
this.isLoading = true;
|
||||||
|
this.shippingService.getPreparerContactsById().subscribe({
|
||||||
|
next: (data: ShippingContact) => {
|
||||||
|
// this.preparerContacts = data;
|
||||||
|
this.preparerContact = this.preparerContacts.find(pc => pc.defaultContact);
|
||||||
|
},
|
||||||
|
error: (error: any) => {
|
||||||
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load preparer contacts data');
|
||||||
|
this.notificationService.showError(errorMessage);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadHolderContacts(): void {
|
||||||
|
this.isLoading = true;
|
||||||
|
this.shippingService.getHolderContactsById(0).subscribe({
|
||||||
|
next: (data: ShippingContact) => {
|
||||||
|
// this.holderContacts = data;
|
||||||
|
this.holderContact = this.holderContacts.find(hc => hc.defaultContact);
|
||||||
|
},
|
||||||
|
error: (error: any) => {
|
||||||
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load holder contacts data');
|
||||||
|
this.notificationService.showError(errorMessage);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadPreparerAddress(): void {
|
||||||
|
this.isLoading = true;
|
||||||
|
this.shippingService.getPreparerAddress().subscribe({
|
||||||
|
next: (data: ShippingAddress) => {
|
||||||
|
// this.preparerAddress = data;
|
||||||
|
},
|
||||||
|
error: (error: any) => {
|
||||||
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load preparer address data');
|
||||||
|
this.notificationService.showError(errorMessage);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadHolderAddress(): void {
|
||||||
|
this.isLoading = true;
|
||||||
|
this.shippingService.getHolderAddressById(0).subscribe({
|
||||||
|
next: (data: ShippingAddress) => {
|
||||||
|
// this.holderAddress = data;
|
||||||
|
},
|
||||||
|
error: (error: any) => {
|
||||||
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load holder address data');
|
||||||
|
this.notificationService.showError(errorMessage);
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateShippingValidation(shipTo: string): void {
|
updateShippingValidation(shipTo: string): void {
|
||||||
@ -340,60 +505,38 @@ export class ShippingComponent {
|
|||||||
} else if (key === 'zip') {
|
} else if (key === 'zip') {
|
||||||
addressGroup.get(key)?.setValidators([Validators.required, ZipCodeValidator('country')]);
|
addressGroup.get(key)?.setValidators([Validators.required, ZipCodeValidator('country')]);
|
||||||
}
|
}
|
||||||
|
addressGroup.get(key)?.updateValueAndValidity();
|
||||||
});
|
});
|
||||||
Object.keys(contactGroup.controls).forEach(key => {
|
Object.keys(contactGroup.controls).forEach(key => {
|
||||||
if (key === 'firstName') {
|
if (key === 'firstName') {
|
||||||
addressGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(50)]);
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(50)]);
|
||||||
} else if (key === 'lastName') {
|
} else if (key === 'lastName') {
|
||||||
addressGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(50)]);
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(50)]);
|
||||||
} else if (key === 'middleInitial') {
|
} else if (key === 'middleInitial') {
|
||||||
addressGroup.get(key)?.setValidators([Validators.maxLength(1)]);
|
contactGroup.get(key)?.setValidators([Validators.maxLength(1)]);
|
||||||
} else if (key === 'title') {
|
} else if (key === 'title') {
|
||||||
addressGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(100)]);
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(100)]);
|
||||||
} else if (key === 'phone') {
|
} else if (key === 'phone') {
|
||||||
addressGroup.get(key)?.setValidators([Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]);
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]);
|
||||||
} else if (key === 'mobile') {
|
} else if (key === 'mobile') {
|
||||||
addressGroup.get(key)?.setValidators([Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]);
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]);
|
||||||
} else if (key === 'fax') {
|
} else if (key === 'fax') {
|
||||||
addressGroup.get(key)?.setValidators([Validators.pattern(/^[0-9]{10,15}$/)]);
|
contactGroup.get(key)?.setValidators([Validators.pattern(/^[0-9]{10,15}$/)]);
|
||||||
} else if (key === 'email') {
|
} else if (key === 'email') {
|
||||||
addressGroup.get(key)?.setValidators([Validators.required, Validators.email, Validators.maxLength(100)]);
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.email, Validators.maxLength(100)]);
|
||||||
}
|
}
|
||||||
|
contactGroup.get(key)?.updateValueAndValidity();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Object.keys(addressGroup.controls).forEach(key => {
|
Object.keys(addressGroup.controls).forEach(key => {
|
||||||
addressGroup.get(key)?.clearValidators();
|
addressGroup.get(key)?.clearValidators();
|
||||||
|
addressGroup.get(key)?.updateValueAndValidity();
|
||||||
});
|
});
|
||||||
Object.keys(contactGroup.controls).forEach(key => {
|
Object.keys(contactGroup.controls).forEach(key => {
|
||||||
contactGroup.get(key)?.clearValidators();
|
contactGroup.get(key)?.clearValidators();
|
||||||
|
contactGroup.get(key)?.updateValueAndValidity();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// addressGroup.updateValueAndValidity();
|
|
||||||
// contactGroup.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit(): void {
|
|
||||||
if (this.shippingForm.invalid) {
|
|
||||||
this.shippingForm.markAllAsTouched();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isLoading = true;
|
|
||||||
const shippingData = this.shippingForm.value;
|
|
||||||
|
|
||||||
this.shippingService.saveShippingDetails(this.headerid, shippingData).subscribe({
|
|
||||||
next: () => {
|
|
||||||
this.notificationService.showSuccess('Shipping & payments information saved successfully');
|
|
||||||
this.completed.emit(true);
|
|
||||||
this.isLoading = false;
|
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save shipping and payment information');
|
|
||||||
this.notificationService.showError(errorMessage);
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getAddressLabel(): string {
|
getAddressLabel(): string {
|
||||||
@ -417,50 +560,19 @@ export class ShippingComponent {
|
|||||||
getContactLabel(): string {
|
getContactLabel(): string {
|
||||||
let shipTo = this.shippingForm.get('shipTo')?.value;
|
let shipTo = this.shippingForm.get('shipTo')?.value;
|
||||||
|
|
||||||
if (shipTo === 'preparer') {
|
if (shipTo === 'preparer' && this.preparerContact) {
|
||||||
return `${this.preparerContact.firstName} ${this.preparerContact.middleInitial} ${this.preparerContact.lastName},
|
return `${this.preparerContact.firstName} ${this.preparerContact.middleInitial} ${this.preparerContact.lastName},
|
||||||
${this.preparerContact.email}, ${this.preparerContact.phone}`;
|
${this.preparerContact.email}, ${this.preparerContact.phone}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shipTo === 'holder') {
|
if (shipTo === 'holder' && this.holderContact) {
|
||||||
return `${this.holderContact.firstName} ${this.holderContact.middleInitial} ${this.holderContact.lastName},
|
return `${this.holderContact.firstName} ${this.holderContact.middleInitial} ${this.holderContact.lastName},
|
||||||
${this.holderContact.email}, ${this.holderContact.phone}`;
|
${this.holderContact.email}, ${this.holderContact.phone}`;
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
editAddressForm(): void {
|
calculateDeliveryEstimate(): void {
|
||||||
this.showAddressForm = true;
|
|
||||||
let shipTo = this.shippingForm.get('shipTo')?.value;
|
|
||||||
|
|
||||||
if (shipTo === 'preparer') {
|
|
||||||
this.shippingForm.get('address')?.patchValue(this.preparerAddress);
|
|
||||||
this.loadStates(this.preparerAddress.country);
|
|
||||||
} else if (shipTo === 'holder') {
|
|
||||||
this.shippingForm.get('address')?.patchValue(this.holderAddress);
|
|
||||||
this.loadStates(this.preparerAddress.country);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelEditAddressForm(): void {
|
|
||||||
this.showAddressForm = false;
|
|
||||||
this.shippingForm.get('address')?.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
onShipToChange(event: any): void {
|
|
||||||
const shipTo = event.value;
|
|
||||||
this.showAddressForm = false;
|
|
||||||
this.showContactForm = false;
|
|
||||||
|
|
||||||
if (shipTo === 'thirdParty') {
|
|
||||||
this.shippingForm.get('contact')?.reset();
|
|
||||||
this.shippingForm.get('address')?.reset();
|
|
||||||
this.showAddressForm = true;
|
|
||||||
this.showContactForm = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private calculateDeliveryEstimate(): void {
|
|
||||||
const deliveryType = this.shippingForm.get('deliveryType')?.value;
|
const deliveryType = this.shippingForm.get('deliveryType')?.value;
|
||||||
const deliveryTypeObj = this.deliveryTypes.find(dt => dt.value === deliveryType);
|
const deliveryTypeObj = this.deliveryTypes.find(dt => dt.value === deliveryType);
|
||||||
const daysToDelivery: number = Number(deliveryTypeObj?.daysToDelivery) !== 0 ? Number(deliveryTypeObj?.daysToDelivery) : 3;
|
const daysToDelivery: number = Number(deliveryTypeObj?.daysToDelivery) !== 0 ? Number(deliveryTypeObj?.daysToDelivery) : 3;
|
||||||
@ -511,4 +623,32 @@ export class ShippingComponent {
|
|||||||
|
|
||||||
this.deliveryEstimate = message;
|
this.deliveryEstimate = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectContact(): void {
|
||||||
|
let shipTo = this.shippingForm.get('shipTo')?.value;
|
||||||
|
|
||||||
|
if (shipTo === 'preparer') {
|
||||||
|
this.preparerContact = this.preparerContacts.find(pc => pc.defaultContact);
|
||||||
|
} else if (shipTo === 'holder') {
|
||||||
|
this.holderContact = this.holderContacts.find(hc => hc.defaultContact);
|
||||||
|
}
|
||||||
|
|
||||||
|
const contacts = shipTo === 'preparer' ? this.preparerContacts : this.holderContacts;
|
||||||
|
|
||||||
|
const dialogRef = this.dialog.open(ContactDialogComponent, {
|
||||||
|
width: '500px',
|
||||||
|
data: { contacts }
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -10,4 +10,6 @@ export interface ShippingContact {
|
|||||||
email: string;
|
email: string;
|
||||||
refNumber?: string | null;
|
refNumber?: string | null;
|
||||||
notes?: string | null;
|
notes?: string | null;
|
||||||
|
defaultContact?: boolean;
|
||||||
|
isInactive?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import { HttpClient } from '@angular/common/http';
|
|||||||
import { filter, map, Observable } from 'rxjs';
|
import { filter, map, Observable } from 'rxjs';
|
||||||
import { UserService } from '../common/user.service';
|
import { UserService } from '../common/user.service';
|
||||||
import { Shipping } from '../../models/carnet/shipping';
|
import { Shipping } from '../../models/carnet/shipping';
|
||||||
|
import { ShippingContact } from '../../models/carnet/shipping-contact';
|
||||||
|
import { ShippingAddress } from '../../models/carnet/shipping-address';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -35,32 +37,28 @@ export class ShippingService {
|
|||||||
needsLostDocProtection: shippingDetails.LDIPROTECTION === 'Y'
|
needsLostDocProtection: shippingDetails.LDIPROTECTION === 'Y'
|
||||||
};
|
};
|
||||||
|
|
||||||
if (shippingDetails.address) {
|
shippingData.address = {
|
||||||
shippingData.address = {
|
addressid: shippingDetails.SHIPADDRESSID,
|
||||||
addressid: shippingDetails.SHIPADDRESSID,
|
address1: shippingDetails.ADDRESS1,
|
||||||
address1: shippingDetails.ADDRESS1,
|
address2: shippingDetails.ADDRESS2,
|
||||||
address2: shippingDetails.ADDRESS2,
|
city: shippingDetails.CITY,
|
||||||
city: shippingDetails.CITY,
|
state: shippingDetails.STATE,
|
||||||
state: shippingDetails.STATE,
|
zip: shippingDetails.ZIP,
|
||||||
zip: shippingDetails.ZIP,
|
country: shippingDetails.COUNTRY
|
||||||
country: shippingDetails.COUNTRY
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shippingDetails.contact) {
|
shippingData.contact = {
|
||||||
shippingData.contact = {
|
contactid: shippingDetails.SHIPCONTACTID,
|
||||||
contactid: shippingDetails.SHIPCONTACTID,
|
firstName: shippingDetails.FIRSTNAME,
|
||||||
firstName: shippingDetails.FIRSTNAME,
|
lastName: shippingDetails.LASTNAME,
|
||||||
lastName: shippingDetails.LASTNAME,
|
middleInitial: shippingDetails.MIDDLEINITIAL,
|
||||||
middleInitial: shippingDetails.MIDDLEINITIAL,
|
title: shippingDetails.TITLE,
|
||||||
title: shippingDetails.TITLE,
|
phone: shippingDetails.PHONENO,
|
||||||
phone: shippingDetails.PHONENO,
|
mobile: shippingDetails.MOBILENO,
|
||||||
mobile: shippingDetails.MOBILENO,
|
fax: shippingDetails.FAXNO,
|
||||||
fax: shippingDetails.FAXNO,
|
email: shippingDetails.EMAILADDRESS,
|
||||||
email: shippingDetails.EMAILADDRESS,
|
refNumber: shippingDetails.REFNO,
|
||||||
refNumber: shippingDetails.REFNO,
|
notes: shippingDetails.NOTES,
|
||||||
notes: shippingDetails.NOTES,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return shippingData;
|
return shippingData;
|
||||||
@ -104,4 +102,52 @@ export class ShippingService {
|
|||||||
|
|
||||||
return this.http.patch(`${this.apiUrl}/${this.apiDb}/UpdateShippingDetails`, shippingDetails);
|
return this.http.patch(`${this.apiUrl}/${this.apiDb}/UpdateShippingDetails`, shippingDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPreparerContactsById(): ShippingContact[] | any {
|
||||||
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetPreparerContactsByClientid/${this.userService.getUserSpid()}/${this.userService.getUserClientid()}`).pipe(
|
||||||
|
map(response => this.mapToContacts(response)));
|
||||||
|
}
|
||||||
|
|
||||||
|
getHolderContactsById(id: number): ShippingContact[] | any {
|
||||||
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetHolderContacts/${this.userService.getUserSpid()}/${id}`).pipe(
|
||||||
|
map(response => this.mapToContacts(response)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private mapToContacts(data: any[]): ShippingContact[] {
|
||||||
|
return data.map(contact => ({
|
||||||
|
contactid: contact.CLIENTCONTACTID,
|
||||||
|
defaultContact: contact.DEFCONTACTFLAG === 'Y',
|
||||||
|
firstName: contact.FIRSTNAME,
|
||||||
|
lastName: contact.LASTNAME,
|
||||||
|
title: contact.TITLE,
|
||||||
|
phone: contact.PHONENO,
|
||||||
|
mobile: contact.MOBILENO,
|
||||||
|
fax: contact.FAXNO || null,
|
||||||
|
email: contact.EMAILADDRESS,
|
||||||
|
middleInitial: contact.MIDDLEINITIAL || null,
|
||||||
|
isInactive: contact.INACTIVEFLAG === 'Y' || false
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
getPreparerAddress(): ShippingAddress[] | any {
|
||||||
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetPreparerLocByClientid/${this.userService.getUserSpid()}/${this.userService.getUserClientid()}`).pipe(
|
||||||
|
map(response => this.mapToAddress(response)));
|
||||||
|
}
|
||||||
|
|
||||||
|
getHolderAddressById(id: number): ShippingContact[] | any {
|
||||||
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetHolderRecord/${this.userService.getUserSpid()}/${id}`).pipe(
|
||||||
|
map(response => this.mapToAddress(response)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private mapToAddress(data: any[]): ShippingAddress[] {
|
||||||
|
return data.map(address => ({
|
||||||
|
addressid: address.SHIPADDRESSID,
|
||||||
|
address1: address.ADDRESS1,
|
||||||
|
address2: address.ADDRESS2,
|
||||||
|
city: address.CITY,
|
||||||
|
state: address.STATE,
|
||||||
|
zip: address.ZIP,
|
||||||
|
country: address.COUNTRY
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user