import { Component, inject, ViewChild } from '@angular/core'; import { HomeService } from '../core/services/home.service'; import { AngularMaterialModule } from '../shared/module/angular-material.module'; import { ChartComponent } from './chart/chart.component'; import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { UserPreferences } from '../core/models/user-preference'; import { UserPreferencesService } from '../core/services/user-preference.service'; import { CommonModule } from '@angular/common'; import { CustomPaginator } from '../shared/custom-paginator'; import { CarnetStatus } from '../core/models/carnet-status'; import { ApiErrorHandlerService } from '../core/services/common/api-error-handler.service'; import { CommonService } from '../core/services/common/common.service'; import { NotificationService } from '../core/services/common/notification.service'; import { NavigationService } from '../core/services/common/navigation.service'; import { MatRadioChange } from '@angular/material/radio'; import * as XLSX from 'xlsx'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmDialogComponent } from '../shared/components/confirm-dialog/confirm-dialog.component'; import { CarnetDialogComponent } from './carnet-dialog.component'; import { BorDialogComponent } from './bor-dialog.component'; import { FormsModule } from '@angular/forms'; import { CarnetService } from '../core/services/carnet/carnet.service'; import { CopyCarnetDialogComponent } from './copy-carnet-dialog.component'; @Component({ selector: 'app-home', imports: [AngularMaterialModule, ChartComponent, CommonModule, FormsModule], templateUrl: './home.component.html', styleUrl: './home.component.scss', providers: [{ provide: MatPaginatorIntl, useClass: CustomPaginator }], }) export class HomeComponent { carnetData: any[] = []; isLoading = false; showTable = false; userPreferences: UserPreferences; carnetStatuses: CarnetStatus[] = []; dataSource = new MatTableDataSource(); @ViewChild(MatPaginator, { static: false }) set paginator(value: MatPaginator) { this.dataSource.paginator = value; } @ViewChild(MatSort, { static: false }) set sort(value: MatSort) { this.dataSource.sort = value; } displayedColumns: string[] = ['applicationName', 'holderName', 'carnetNumber', 'usSets', 'foreignSets', 'transitSets', 'carnetValue', 'issueDate', 'expiryDate', 'orderType', 'carnetStatus', 'actions']; private homeService = inject(HomeService); private carnetService = inject(CarnetService); private errorHandler = inject(ApiErrorHandlerService); private notificationService = inject(NotificationService); private commonService = inject(CommonService); private navigationService = inject(NavigationService); private dialog = inject(MatDialog); constructor(userPrefenceService: UserPreferencesService) { this.userPreferences = userPrefenceService.getPreferences(); } ngOnInit(): void { this.loadCarnetStatuses(); this.loadCarnetData(); } loadCarnetStatuses(): void { this.commonService.getCarnetStatuses().subscribe({ next: (carnetStatuses) => { this.carnetStatuses = carnetStatuses; }, error: (error) => { console.error('Error loading carnet status:', error); } }); } loadCarnetData(): void { this.isLoading = true; this.homeService.getCarnetSummaryData().subscribe({ next: (data) => { this.carnetData = data; this.isLoading = false; }, error: (error) => { console.error('Error loading carnet data:', error); this.isLoading = false; } }); } onCarnetStatusClick(event: any): void { this.isLoading = true; this.showTable = false; this.homeService.getCarnetDataByStatus(event.spid, event.carnetStatus).subscribe({ next: (carnetDetails) => { this.isLoading = false; this.showTable = true; this.dataSource.data = carnetDetails; this.dataSource.paginator = this.paginator; this.dataSource.sort = this.sort; }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load carnet data for the selected status'); this.notificationService.showError(errorMessage); this.isLoading = false; console.error('Error loading carnet data for the selected status:', error); } }); } exportData() { try { // Prepare worksheet data const worksheetData = this.prepareDownloadData(); // Create workbook and worksheet const workbook = XLSX.utils.book_new(); const worksheet = XLSX.utils.json_to_sheet(worksheetData); // Add worksheet to workbook XLSX.utils.book_append_sheet(workbook, worksheet, 'Carnet Data'); // Generate Excel file const fileName = `carnet_data_${new Date().toISOString()}.xlsx`; XLSX.writeFile(workbook, fileName); } catch (error) { console.error('Error downloading goods items:', error); this.notificationService.showError('Failed to download Excel file'); } } prepareDownloadData(): any[] { return this.dataSource.data.map(item => ({ 'Application Name': item.applicationName, 'Holder Name': item.holderName, 'Carnet Number': item.carnetNumber, 'US Sets': item.usSets, 'Foreign Sets': item.foreignSets, 'Transit Sets': item.transitSets, 'Carnet Value': item.carnetValue, 'Issue Date': item.issueDate ? new Date(item.issueDate).toLocaleDateString() : '', 'Expiry Date': item.expiryDate ? new Date(item.expiryDate).toLocaleDateString() : '', 'Order Type': item.orderType, 'Carnet Status': this.getCarnetStatusLabel(item.carnetStatus) })); } getCarnetStatusLabel(value: string): string { const carnetStatus = this.carnetStatuses.find(t => t.value === value); return carnetStatus ? carnetStatus.name : value; } newCarnet(event: MatRadioChange): void { if (event.value) { this.navigateTo(['add-carnet']); } } additionalSets(event: MatRadioChange): void { if (event.value) { const dialogRef = this.dialog.open(CarnetDialogComponent, { width: '500px', data: { carnetAction: 'additional' }, }); dialogRef.afterClosed().subscribe(carnetNumber => { if (carnetNumber) { this.carnetService.additionalSets(carnetNumber).subscribe({ next: (data) => { if (data && data.BORFLAG === 'Y') { this.showBorDialog('additional', data.HEADERID, data.APPLICATIONNAME); } else if (data) { this.navigateTo(['additional-sets', data.HEADERID], { queryParams: { applicationname: data.APPLICATIONNAME } }); } }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to add additional sets'); this.notificationService.showError(errorMessage); console.error('Error adding additional sets:', error); } }); } }); } } duplicateCarnet(event: MatRadioChange): void { if (event.value) { const dialogRef = this.dialog.open(CarnetDialogComponent, { width: '500px', data: { carnetAction: 'duplicate' }, }); dialogRef.afterClosed().subscribe(carnetNumber => { if (carnetNumber) { this.carnetService.duplicateCarnet(carnetNumber).subscribe({ next: (data) => { if (data && data.BORFLAG === 'Y') { this.showBorDialog('duplicate', data.HEADERID, data.APPLICATIONNAME); } else if (data) { this.navigateTo(['duplicate-carnet', data.HEADERID], { queryParams: { applicationname: data.APPLICATIONNAME } }); } }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to duplicate carnet'); this.notificationService.showError(errorMessage); console.error('Error duplicating carnet:', error); } }); } }); } } extendCarnet(event: MatRadioChange): void { if (event.value) { const dialogRef = this.dialog.open(CarnetDialogComponent, { width: '500px', data: { carnetAction: 'extend' }, }); dialogRef.afterClosed().subscribe(carnetNumber => { if (carnetNumber) { this.carnetService.extendCarnet(carnetNumber).subscribe({ next: (data) => { if (data && data.BORFLAG === 'Y') { this.showBorDialog('extend', data.HEADERID, data.APPLICATIONNAME); } else if (data) { this.navigateTo(['extend-carnet', data.HEADERID], { queryParams: { applicationname: data.APPLICATIONNAME } }); } }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to extend carnet'); this.notificationService.showError(errorMessage); console.error('Error extend carnet:', error); } }); } }); } } showBorDialog(carnetAction: string, headerid: number, applicationName: string): void { const dialogRef = this.dialog.open(BorDialogComponent, { width: '500px', data: { carnetAction: carnetAction }, }); dialogRef.afterClosed().subscribe(carnetAction => { if (carnetAction === 'delete') { this.carnetService.deleteCarnet(headerid).subscribe({ next: () => { }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to delete carnet'); this.notificationService.showError(errorMessage); console.error('Error deleting carnet:', error); } }); } else { let route: string = 'edit-carnet'; if (carnetAction === 'duplicate') { route = 'duplicate-carnet'; } else if (carnetAction === 'extend') { route = 'extend-carnet'; } else if (carnetAction === 'additional') { route = 'additional-sets'; } this.navigateTo([route, headerid], { queryParams: { applicationname: applicationName } }); } }); } editCarnet(item: any): void { if (item && item.headerid) { let route: string = 'edit-carnet'; if (item.orderType === 'DUPLICATE') { route = 'duplicate-carnet'; } else if (item.orderType === 'REPLACE') { route = 'extend-carnet'; } else if (item.orderType === 'ADDLSETS') { route = 'additional-sets'; } this.navigateTo([route, item.headerid], { queryParams: { applicationname: item.applicationName } }); } else { this.notificationService.showError('Invalid carnet data'); } } viewCarnet(item: any): void { if (item && item.headerid) { let route: string = 'view-carnet'; if (item.orderType === 'REPLACE') { route = 'view-extend-carnet'; } this.navigateTo([route, item.headerid], { queryParams: { applicationname: item.applicationName } }); } else { this.notificationService.showError('Invalid carnet data'); } } printGeneralList(headerid: number): void { if (headerid) { this.carnetService.printGeneralList(headerid).subscribe({ next: (blob: Blob) => { let filename = `${headerid}-GL.pdf`; // Initiate download this.saveFile(blob, filename); }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to print general list'); this.notificationService.showError(errorMessage); console.error('Error printing general list:', error); } }); } else { this.notificationService.showError('Invalid carnet data'); } } deleteCarnet(headerid: number): void { if (headerid) { const dialogRef = this.dialog.open(ConfirmDialogComponent, { width: '350px', data: { title: 'Delete Carnet', message: 'Are you sure you want to delete the carnet?', confirmText: 'Yes', cancelText: 'Cancel' } }); dialogRef.afterClosed().subscribe(result => { if (result) { this.carnetService.deleteCarnet(headerid).subscribe({ next: () => { this.notificationService.showSuccess('Carnet deleted successfully'); this.loadCarnetData(); }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to delete carnet'); this.notificationService.showError(errorMessage); console.error('Error deleting carnet:', error); } }); } }); } else { this.notificationService.showError('Invalid carnet data'); } } copyCarnet(headerid: number): void { if (headerid) { const dialogRef = this.dialog.open(CopyCarnetDialogComponent, { width: '500px', data: { headerid: headerid }, }); dialogRef.afterClosed().subscribe(data => { if (data) { this.carnetService.copyCarnet(data.headerid, data.applicationName).subscribe({ next: (applicationData: any) => { this.notificationService.showSuccess('Carnet copied successfully'); this.navigateTo(['edit-carnet', applicationData.HEADERID], { queryParams: { applicationname: applicationData.APPLICATIONNAME } }); }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to copy carnet'); this.notificationService.showError(errorMessage); console.error('Error copying carnet:', error); } }); } }); } } navigateTo(route: any[], extras?: any): void { this.navigationService.navigate(route, extras); } private saveFile(blob: Blob, filename: string): void { const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); // Append to body to make it clickable in some browsers a.click(); document.body.removeChild(a); // Clean up window.URL.revokeObjectURL(url); } }