feedback updates

This commit is contained in:
Cyril Joseph 2026-01-10 22:39:19 -04:00
parent cbe7a1e8b0
commit cf6fdb6489
11 changed files with 149 additions and 47 deletions

View File

@ -46,6 +46,9 @@
<button mat-raised-button color="primary" type="button" *ngIf="!isViewMode" (click)="addNewItem()"> <button mat-raised-button color="primary" type="button" *ngIf="!isViewMode" (click)="addNewItem()">
<mat-icon>add</mat-icon> Add Item <mat-icon>add</mat-icon> Add Item
</button> </button>
<button mat-raised-button color="primary" type="button" *ngIf="!isViewMode" (click)="deleteAllItems()">
<mat-icon>delete</mat-icon> Delete All
</button>
<div class="upload-section"> <div class="upload-section">
<input type="file" accept=".xlsx,.xls,.csv" (change)="fileUpload($event)" hidden #fileInput> <input type="file" accept=".xlsx,.xls,.csv" (change)="fileUpload($event)" hidden #fileInput>
<button mat-raised-button type="button" *ngIf="!isViewMode" (click)="fileInput.click()" <button mat-raised-button type="button" *ngIf="!isViewMode" (click)="fileInput.click()"

View File

@ -63,6 +63,7 @@ export class GoodsComponent {
// Data // Data
countries: Country[] = []; countries: Country[] = [];
unitsOfMeasures: UnitOfMeasure[] = []; unitsOfMeasures: UnitOfMeasure[] = [];
goodsItems: GoodsItem[] = [];
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
@ -135,7 +136,7 @@ export class GoodsComponent {
this.isLoading = false; this.isLoading = false;
})).subscribe({ })).subscribe({
next: (items: GoodsItem[]) => { next: (items: GoodsItem[]) => {
this.dataSource.data = items; this.dataSource.data = this.goodsItems = items;
this.completed.emit((this.goodsForm.valid || this.goodsForm.disabled) && this.dataSource.data.length > 0); this.completed.emit((this.goodsForm.valid || this.goodsForm.disabled) && this.dataSource.data.length > 0);
}, },
error: (error: any) => { error: (error: any) => {
@ -285,18 +286,56 @@ export class GoodsComponent {
}); });
} }
// Delete all items with confirmation
deleteAllItems(): void {
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
width: '350px',
data: {
title: 'Confirm Delete',
message: 'Are you sure you want to delete all the items?',
confirmText: 'Delete',
cancelText: 'Cancel'
}
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.changeInProgress = true;
this.goodsService.deleteAllGoodsItems(this.headerid, this.goodsItems).pipe(finalize(() => {
this.changeInProgress = false;
})).subscribe({
next: () => {
this.notificationService.showSuccess('All items deleted successfully');
this.loadGoodsItems();
this.cancelEdit();
},
error: (error) => {
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to delete all items');
this.notificationService.showError(errorMessage);
console.error('Error deleting all items:', error);
}
});
}
});
}
// Handle file selection for upload // Handle file selection for upload
fileUpload(event: any): void { fileUpload(event: any): void {
const file: File = event.target.files[0]; const fileInput = event.target as HTMLInputElement;
const file: File | null = fileInput?.files ? fileInput.files[0] : null;
if (!file) {
return;
}
this.processExcelFile(file) this.processExcelFile(file)
// .then(response => { .then(() => {
// // console.log('File uploaded successfully:', response); fileInput.value = '';
// // Handle success (e.g., update UI) })
// })
.catch(error => { .catch(error => {
console.error('Error processing file:', error); console.error('Error processing file:', error);
this.notificationService.showError('Failed to upload file'); this.notificationService.showError('Failed to upload file');
fileInput.value = '';
}); });
} }
@ -384,15 +423,20 @@ export class GoodsComponent {
// Parse Excel data into our format // Parse Excel data into our format
private parseExcelData(data: any[]): any[] { private parseExcelData(data: any[]): any[] {
return data.map(row => ({ return data.map(row => {
itemNumber: row['Item Number'] || row['itemNumber'] || '', // Convert row to array if it's not already
description: row['Description'] || row['description'] || '', const rowArray = Array.isArray(row) ? row : Object.values(row);
pieces: Number(row['Pieces'] || row['pieces'] || 0),
weight: Number(row['Weight'] || row['weight'] || 0), return {
unitOfMeasure: row['Unit of Measure'] || row['unit of measure'] || row['unitofmeasure'] || row['UnitOfMeasure'], itemNumber: rowArray[0]?.toString().trim() || '',
value: Number(row['Value'] || row['value'] || 0), description: rowArray[1]?.toString().trim() || '',
countryOfOrigin: row['Country Of Origin'] || row['Country of Origin'] || row['country of origin'] || row['countryoforigin'] || row['CountryOfOrigin'] || '' pieces: Number(rowArray[2]) || 0,
})).filter(item => weight: Number(rowArray[3]) || 0,
unitOfMeasure: rowArray[4]?.toString().trim() || '',
value: Number(rowArray[5]) || 0,
countryOfOrigin: rowArray[6]?.toString().trim() || ''
};
}).filter(item =>
item.itemNumber && item.itemNumber &&
item.description && item.description &&
item.pieces > 0 item.pieces > 0

View File

@ -16,24 +16,26 @@ import { NotificationService } from '../../core/services/common/notification.ser
<mat-dialog-content> <mat-dialog-content>
<p> The following fees apply:</p> <p> The following fees apply:</p>
<ul> <ul>
<li *ngIf="estimatedFees.basicFee">Basic fee: {{estimatedFees.basicFee | currency}}</li> <li *ngIf="estimatedFees.basicFee">Basic fee <span> {{estimatedFees.basicFee | currency}} </span></li>
<li *ngIf="estimatedFees.counterFoilFee">Counterfoil Fee: {{estimatedFees.counterFoilFee | currency}} <li *ngIf="estimatedFees.counterFoilFee">Counterfoil Fee <span> {{estimatedFees.counterFoilFee | currency}}
</li> </span></li>
<li *ngIf="estimatedFees.continuationSheetFee">Continuation sheet fee: <li *ngIf="estimatedFees.continuationSheetFee">Continuation sheet fee
{{estimatedFees.continuationSheetFee | currency}}</li> <span> {{estimatedFees.continuationSheetFee | currency}}</span></li>
<li *ngIf="estimatedFees.expeditedFee">Expedited fee: {{estimatedFees.expeditedFee | currency}}</li> <li *ngIf="estimatedFees.expeditedFee">Expedited fee <span> {{estimatedFees.expeditedFee | currency}}</span></li>
<li *ngIf="estimatedFees.shippingFee">Shipping fee: {{estimatedFees.shippingFee | currency}}</li> <li *ngIf="estimatedFees.shippingFee">Shipping fee <span> {{estimatedFees.shippingFee | currency}}</span></li>
<li *ngIf="estimatedFees.bondPremium">{{bondPremiumLabel}}: {{estimatedFees.bondPremium | currency}}</li> <li *ngIf="estimatedFees.bondPremium">{{bondPremiumLabel}} <span> {{estimatedFees.bondPremium | currency}}</span></li>
<li *ngIf="estimatedFees.cargoPremium">Cargo Premium: {{estimatedFees.cargoPremium | currency}}</li> <li *ngIf="estimatedFees.cargoPremium">Cargo Premium <span> {{estimatedFees.cargoPremium | currency}}</span></li>
<li *ngIf="estimatedFees.ldiPremium">LDI Premium: {{estimatedFees.ldiPremium | currency}}</li> <li *ngIf="estimatedFees.ldiPremium">LDI Premium <span> {{estimatedFees.ldiPremium | currency}}</span></li>
</ul> </ul>
<hr/> <hr/>
<ul> <ul>
<li *ngIf="estimatedFees.securityAmount">Security Amount: {{estimatedFees.securityAmount | currency}}</li> <li class="total">Total: <span>{{total | currency}}</span></li>
<li *ngIf="estimatedFees.insuredValue">Insured Value: {{estimatedFees.insuredValue | currency}}</li>
</ul> </ul>
<hr/> <hr/>
<p class="total">Total: {{total | currency}}</p> <ul>
<li *ngIf="estimatedFees.securityAmount">Security Amount <span>{{estimatedFees.securityAmount | currency}}</span></li>
<li *ngIf="estimatedFees.insuredValue">Insured Value <span>{{estimatedFees.insuredValue | currency}}</span></li>
</ul>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions> <mat-dialog-actions>
<button mat-raised-button color="primary" (click)="onClose()"> <button mat-raised-button color="primary" (click)="onClose()">
@ -44,6 +46,8 @@ import { NotificationService } from '../../core/services/common/notification.ser
styles: [` styles: [`
li { li {
margin-bottom: 8px; margin-bottom: 8px;
display: flex;
justify-content: space-between;
} }
.total { .total {

View File

@ -17,7 +17,7 @@
<mat-form-field appearance="outline" class="formofsecurity"> <mat-form-field appearance="outline" class="formofsecurity">
<mat-label>Form Of Security</mat-label> <mat-label>Form Of Security</mat-label>
<mat-select formControlName="formOfSecurity" required> <mat-select formControlName="formOfSecurity">
<mat-option *ngFor="let formOfSecurity of formOfSecurities" [value]="formOfSecurity.value"> <mat-option *ngFor="let formOfSecurity of formOfSecurities" [value]="formOfSecurity.value">
{{ formOfSecurity.name }} {{ formOfSecurity.name }}
</mat-option> </mat-option>

View File

@ -490,7 +490,11 @@ export class ShippingComponent {
if (this.applicationType === 'duplicate' || this.applicationType === 'additional' if (this.applicationType === 'duplicate' || this.applicationType === 'additional'
|| this.applicationType === 'extend') { || this.applicationType === 'extend') {
this.shippingForm.get('formOfSecurity')?.disable(); const formOfSecurityControl = this.shippingForm.get('formOfSecurity');
formOfSecurityControl?.disable();
formOfSecurityControl?.clearValidators();
formOfSecurityControl?.updateValueAndValidity();
this.shippingForm.get('needsLostDocProtection')?.disable(); this.shippingForm.get('needsLostDocProtection')?.disable();
} }

View File

@ -11,26 +11,35 @@
<h3>Fees and Charges</h3> <h3>Fees and Charges</h3>
<p> The following fees apply:</p> <p> The following fees apply:</p>
<ul> <ul>
<li *ngIf="estimatedFees.basicFee">Basic fee: {{estimatedFees.basicFee | currency}}</li> <li *ngIf="estimatedFees.basicFee">Basic fee <span> {{estimatedFees.basicFee | currency}} </span></li>
<li *ngIf="estimatedFees.counterFoilFee">Counterfoil Fee: {{estimatedFees.counterFoilFee | currency}} <li *ngIf="estimatedFees.counterFoilFee">Counterfoil Fee <span> {{estimatedFees.counterFoilFee |
currency}}
</span></li>
<li *ngIf="estimatedFees.continuationSheetFee">Continuation sheet fee
<span> {{estimatedFees.continuationSheetFee | currency}}</span>
</li> </li>
<li *ngIf="estimatedFees.continuationSheetFee">Continuation sheet fee: <li *ngIf="estimatedFees.expeditedFee">Expedited fee <span> {{estimatedFees.expeditedFee |
{{estimatedFees.continuationSheetFee | currency}}</li> currency}}</span></li>
<li *ngIf="estimatedFees.expeditedFee">Expedited fee: {{estimatedFees.expeditedFee | currency}}</li> <li *ngIf="estimatedFees.shippingFee">Shipping fee <span> {{estimatedFees.shippingFee |
<li *ngIf="estimatedFees.shippingFee">Shipping fee: {{estimatedFees.shippingFee | currency}}</li> currency}}</span></li>
<li *ngIf="estimatedFees.bondPremium">{{bondPremiumLabel}}: {{estimatedFees.bondPremium | currency}} <li *ngIf="estimatedFees.bondPremium">{{bondPremiumLabel}} <span> {{estimatedFees.bondPremium |
currency}}</span></li>
<li *ngIf="estimatedFees.cargoPremium">Cargo Premium <span> {{estimatedFees.cargoPremium |
currency}}</span></li>
<li *ngIf="estimatedFees.ldiPremium">LDI Premium <span> {{estimatedFees.ldiPremium | currency}}</span>
</li> </li>
<li *ngIf="estimatedFees.cargoPremium">Cargo Premium: {{estimatedFees.cargoPremium | currency}}</li>
<li *ngIf="estimatedFees.ldiPremium">LDI Premium: {{estimatedFees.ldiPremium | currency}}</li>
</ul> </ul>
<hr /> <hr />
<ul> <ul>
<li *ngIf="estimatedFees.securityAmount">Security Amount: {{estimatedFees.securityAmount | currency}} <li class="total">Total: <span>{{total | currency}}</span></li>
</li>
<li *ngIf="estimatedFees.insuredValue">Insured Value: {{estimatedFees.insuredValue | currency}}</li>
</ul> </ul>
<hr /> <hr />
<p class="total">Total: {{total | currency}}</p> <ul>
<li *ngIf="estimatedFees.securityAmount">Security Amount <span>{{estimatedFees.securityAmount |
currency}}</span></li>
<li *ngIf="estimatedFees.insuredValue">Insured Value <span>{{estimatedFees.insuredValue |
currency}}</span></li>
</ul>
<mat-checkbox [(ngModel)]="hasReadAllTerms" color="primary" class="read-checkbox"> <mat-checkbox [(ngModel)]="hasReadAllTerms" color="primary" class="read-checkbox">
I have read and agree to all terms and conditions above I have read and agree to all terms and conditions above
</mat-checkbox> </mat-checkbox>

View File

@ -38,6 +38,8 @@ mat-card-header {
li { li {
margin-bottom: 8px; margin-bottom: 8px;
display: flex;
justify-content: space-between;
} }
strong { strong {

View File

@ -3,7 +3,7 @@ import { environment } from '../../../../environments/environment';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { UserService } from '../common/user.service'; import { UserService } from '../common/user.service';
import { Goods, GoodsItem } from '../../models/carnet/goods'; import { Goods, GoodsItem } from '../../models/carnet/goods';
import { map, Observable } from 'rxjs'; import { catchError, from, map, mergeMap, Observable, of, toArray } from 'rxjs';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -117,4 +117,34 @@ export class GoodsService {
// delete request with body // delete request with body
return this.http.delete(`${this.apiUrl}/${this.apiDb}/DeleteGenerallistItems`, { body: goodsItemsObj }); return this.http.delete(`${this.apiUrl}/${this.apiDb}/DeleteGenerallistItems`, { body: goodsItemsObj });
} }
deleteAllGoodsItems(headerid: number, items: GoodsItem[]): Observable<any[]> {
return from(items).pipe(
mergeMap(item => {
const goodsItemsObj = {
P_HEADERID: headerid,
P_ITEMNO: item.itemNumber,
P_USERID: this.userService.getUser(),
};
return this.http.delete(
`${this.apiUrl}/${this.apiDb}/DeleteGenerallistItems`,
{ body: goodsItemsObj }
).pipe(
catchError(error => {
console.error(`Failed to delete item ${item.itemNumber}:`, error);
// Return error result instead of failing the whole stream
return of({
success: false,
item: item.itemNumber,
error: error.message
});
})
);
}, 5),
// Collect all results into an array
toArray()
);
}
} }

View File

@ -21,6 +21,12 @@ export class ParamService {
) )
} }
getValidParameters(P_PARAMTYPE: string): Observable<ParamProperties[]> {
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_SPID=${this.userService.getUserSpid()}&P_PARAMTYPE=${P_PARAMTYPE}`).pipe(
map(response => this.mapToParamValue(response))
)
}
private mapToParamValue(data: any[]): ParamProperties[] { private mapToParamValue(data: any[]): ParamProperties[] {
return data.map((paramValue: any) => ({ return data.map((paramValue: any) => ({
paramId: paramValue.PARAMID, paramId: paramValue.PARAMID,

View File

@ -180,7 +180,7 @@ export class HomeComponent {
} }
else if (item.orderType === 'REPLACE') { else if (item.orderType === 'REPLACE') {
route = 'process-extend-carnet'; route = 'process-extend-carnet';
} else if (item.orderType === 'ADDLSETS') { } else if (item.orderType === 'REORDER') {
route = 'process-additional-sets'; route = 'process-additional-sets';
} }

View File

@ -71,8 +71,8 @@ export class ManageCountryComponent {
this.isLoading = true; this.isLoading = true;
forkJoin({ forkJoin({
countries: this.paramService.getParameters('002'), countries: this.paramService.getValidParameters('002'),
countriesWithMessages: this.paramService.getParameters('014') countriesWithMessages: this.paramService.getValidParameters('014')
}).pipe(finalize(() => { }).pipe(finalize(() => {
this.isLoading = false; this.isLoading = false;
})).subscribe({ })).subscribe({