service-provider-app/src/app/fees/cargo-rate/cargo-rate.component.ts
2025-12-05 07:46:40 -04:00

247 lines
7.9 KiB
TypeScript

import { Component, EventEmitter, inject, Input, OnInit, Output, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { CommonModule } from '@angular/common';
import { CustomPaginator } from '../../shared/custom-paginator';
import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { finalize } from 'rxjs';
import { CargoRate } from '../../core/models/fees/cargo-rate';
import { CargoRateService } from '../../core/services/fees/cargo-rate.service';
@Component({
selector: 'app-cargo-rate',
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule],
templateUrl: './cargo-rate.component.html',
styleUrl: './cargo-rate.component.scss',
providers: [{ provide: MatPaginatorIntl, useClass: CustomPaginator }],
})
export class CargoRateComponent implements OnInit {
@ViewChild(MatPaginator, { static: false })
set paginator(value: MatPaginator) {
this.dataSource.paginator = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'expiredDate', 'actions'];
dataSource = new MatTableDataSource<any>();
cargoRateForm: FormGroup;
isEditing = false;
currentCargoRateId: number | null = null;
isLoading = false;
changeInProgress = false;
showForm = false;
showExpiredRecords = false;
cargoRates: CargoRate[] = [];
readOnlyFields: any = {
lastChangedDate: null,
lastChangedBy: null
};
carnetTypes = [
{ label: 'Original', value: 'ORIGINAL' },
{ label: 'Re-order', value: 'REORDER' },
{ label: 'Replacement', value: 'REPLACE' }
];
@Input() isEditMode = false;
@Input() spid: number = 0;
@Input() userPreferences!: UserPreferences;
@Output() hasCargoRates = new EventEmitter<boolean>();
private fb = inject(FormBuilder);
private cargoRateService = inject(CargoRateService);
private notificationService = inject(NotificationService);
private errorHandler = inject(ApiErrorHandlerService);
constructor() {
this.cargoRateForm = this.fb.group({
carnetType: ['ORIGINAL', Validators.required],
startSets: ['', [
Validators.required,
Validators.pattern('^[0-9]*$'),
Validators.min(1)
]],
endSets: ['', [
Validators.required,
Validators.pattern('^[0-9]*$'),
Validators.min(1)
]],
rate: ['', [
Validators.required,
Validators.pattern(/^\d+\.?\d{0,4}$/),
Validators.min(0)
]],
effectiveDate: ['', Validators.required]
}, { validator: this.validateSetsRange });
}
ngOnInit(): void {
this.loadCargoRates();
}
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
private validateSetsRange(group: FormGroup): { [key: string]: any } | null {
const start = +group.get('startSets')?.value;
const end = +group.get('endSets')?.value;
return start && end && start >= end ? { invalidRange: true } : null;
}
loadCargoRates(): void {
this.isLoading = true;
this.cargoRateService.getCargoRates(this.spid).pipe(finalize(() => {
this.isLoading = false;
}))
.subscribe({
next: (
cargoRates: CargoRate[]) => {
this.cargoRates = cargoRates;
this.dataSource.data = this.cargoRates;
this.renderRecods();
},
error: (error: any) => {
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load cargo rates');
this.notificationService.showError(errorMessage);
console.error('Error loading cargo rates:', error);
}
});
}
toggleShowExpiredRecords(): void {
this.showExpiredRecords = !this.showExpiredRecords;
this.renderRecods();
}
renderRecods(): void {
if (this.showExpiredRecords) {
this.dataSource.data = this.cargoRates.filter(record => record.expired);
} else {
this.dataSource.data = this.cargoRates.filter(record => !record.expired);
}
}
// applyFilter(event: Event): void {
// const filterValue = (event.target as HTMLInputElement).value;
// this.dataSource.filter = filterValue.trim().toLowerCase();
// if (this.dataSource.paginator) {
// this.dataSource.paginator.firstPage();
// }
// }
addNewCargoRate(): void {
this.showForm = true;
this.isEditing = false;
this.currentCargoRateId = null;
this.cargoRateForm.reset({
carnetType: 'ORIGINAL'
});
this.cargoRateForm.get('carnetType')?.enable();
this.cargoRateForm.get('startSets')?.enable();
this.cargoRateForm.get('endSets')?.enable();
}
editCargoRate(cargoRate: any): void {
this.showForm = true;
this.isEditing = true;
this.currentCargoRateId = cargoRate.id;
this.cargoRateForm.patchValue({
carnetType: cargoRate.carnetType,
startSets: cargoRate.startSets,
endSets: cargoRate.endSets,
rate: cargoRate.rate,
effectiveDate: new Date(cargoRate.effectiveDate)
});
this.readOnlyFields.lastChangedDate = cargoRate.dateCreated;
this.readOnlyFields.lastChangedBy = cargoRate.createdBy;
this.cargoRateForm.get('carnetType')?.disable();
this.cargoRateForm.get('startSets')?.disable();
this.cargoRateForm.get('endSets')?.disable();
}
saveCargoRate(): void {
if (this.cargoRateForm.invalid) {
this.cargoRateForm.markAllAsTouched();
return;
}
const cargoRateData = {
...this.cargoRateForm.value,
spid: this.spid
};
const saveObservable = this.isEditing && this.currentCargoRateId
? this.cargoRateService.updateCargoRate(this.currentCargoRateId, cargoRateData)
: this.cargoRateService.addCargoRate(this.spid, cargoRateData);
this.changeInProgress = true;
saveObservable.pipe(finalize(() => {
this.changeInProgress = false;
})).subscribe({
next: () => {
this.notificationService.showSuccess(`Cargo Rate ${this.isEditing ? 'updated' : 'added'} successfully`);
this.loadCargoRates();
this.cancelEdit();
this.hasCargoRates.emit(true);
},
error: (error) => {
let errorMessage = this.errorHandler.handleApiError(error, `Failed to ${this.isEditing ? 'update' : 'add'} cargo rate`);
this.notificationService.showError(errorMessage);
console.error('Error saving cargo rate:', error);
}
});
}
// deleteCargoRate(cargoRateId: string): void {
// const dialogRef = this.dialog.open(ConfirmDialogComponent, {
// width: '350px',
// data: {
// title: 'Confirm Delete',
// message: 'Are you sure you want to delete this cargoRate setup?',
// confirmText: 'Delete',
// cancelText: 'Cancel'
// }
// });
// dialogRef.afterClosed().subscribe(result => {
// if (result) {
// this.cargoRateService.deleteCargoRate(cargoRateId).subscribe({
// next: () => {
// this.notificationService.showSuccess('CargoRate deleted successfully');
// this.loadCargoRates();
// },
// error: (error) => {
// this.notificationService.showError('Failed to delete cargoRate');
// }
// });
// }
// });
// }
cancelEdit(): void {
this.showForm = false;
this.isEditing = false;
this.currentCargoRateId = null;
this.cargoRateForm.reset({
carnetType: 'ORIGINAL'
});
}
getOptionLabel(options: any[], value: string): string {
return options.find(opt => opt.value === value)?.label || value;
}
}