manage fee and region updates

This commit is contained in:
Cyril Joseph 2025-11-06 22:40:36 -04:00
parent 164a3ba87a
commit a0f698c31f
52 changed files with 473 additions and 100 deletions

View File

@ -12,14 +12,16 @@ import { ParamTableComponent } from './param/table/param-table.component';
import { ManageTableRecordComponent } from './param/manage-table-record/manage-table-record.component'; import { ManageTableRecordComponent } from './param/manage-table-record/manage-table-record.component';
import { ManageParamRecordComponent } from './param/manage-param-record/manage-param-record.component'; import { ManageParamRecordComponent } from './param/manage-param-record/manage-param-record.component';
import { RegionComponent } from './region/region.component'; import { RegionComponent } from './region/region.component';
import { ManageFeeComponent } from './fees/manage/manage-fee.component';
export const routes: Routes = [ export const routes: Routes = [
{ path: 'login', component: LoginComponent }, { path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent }, { path: 'register', component: RegisterComponent },
{ path: 'forgot-password', component: ForgotPasswordComponent }, { path: 'forgot-password', component: ForgotPasswordComponent },
{ path: 'table-record', component: ManageTableRecordComponent }, { path: 'table-record', component: ManageTableRecordComponent, canActivate: [AuthGuard] },
{ path: 'param-record/:id', component: ManageParamRecordComponent }, { path: 'param-record/:id', component: ManageParamRecordComponent, canActivate: [AuthGuard] },
{ path: 'region', component: RegionComponent, canActivate: [AuthGuard] }, { path: 'region', component: RegionComponent, canActivate: [AuthGuard] },
{ path: 'fees', component: ManageFeeComponent, canActivate: [AuthGuard] },
{ path: 'usersettings', component: UserSettingsComponent, canActivate: [AuthGuard] }, { path: 'usersettings', component: UserSettingsComponent, canActivate: [AuthGuard] },
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] }, { path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
{ path: 'service-provider/:id', component: EditServiceProviderComponent, canActivate: [AuthGuard] }, { path: 'service-provider/:id', component: EditServiceProviderComponent, canActivate: [AuthGuard] },

View File

@ -10,6 +10,7 @@
<mat-menu #configurations="matMenu"> <mat-menu #configurations="matMenu">
<button mat-menu-item (click)="navigateTo('table-record')">Table Records</button> <button mat-menu-item (click)="navigateTo('table-record')">Table Records</button>
<button mat-menu-item (click)="navigateTo('region')">Manage Region</button> <button mat-menu-item (click)="navigateTo('region')">Manage Region</button>
<button mat-menu-item (click)="navigateTo('fees')">Manage Fees</button>
</mat-menu> </mat-menu>
<div class="profile-container"> <div class="profile-container">
<button mat-icon-button (click)="toggleProfileMenu()" class="profile-button"> <button mat-icon-button (click)="toggleProfileMenu()" class="profile-button">

View File

@ -3,7 +3,7 @@ import { environment } from '../../../../environments/environment';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { map, Observable } from 'rxjs'; import { map, Observable } from 'rxjs';
import { UserService } from '../common/user.service'; import { UserService } from '../common/user.service';
import { BasicFee } from '../../models/service-provider/basic-fee'; import { BasicFee } from '../../models/fees/basic-fee';
import { CommonService } from '../common/common.service'; import { CommonService } from '../common/common.service';
@Injectable({ @Injectable({

View File

@ -4,7 +4,7 @@ import { map, Observable } from 'rxjs';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
import { CommonService } from '../common/common.service'; import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service'; import { UserService } from '../common/user.service';
import { CargoRate } from '../../models/service-provider/cargo-rate'; import { CargoRate } from '../../models/fees/cargo-rate';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'

View File

@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { map, Observable } from 'rxjs'; import { map, Observable } from 'rxjs';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
import { CarnetFee } from '../../models/service-provider/carnet-fee'; import { CarnetFee } from '../../models/fees/carnet-fee';
import { CommonService } from '../common/common.service'; import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service'; import { UserService } from '../common/user.service';

View File

@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core';
import { map, Observable } from 'rxjs'; import { map, Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
import { ContinuationSheetFee } from '../../models/service-provider/continuation-sheet-fee'; import { ContinuationSheetFee } from '../../models/fees/continuation-sheet-fee';
import { CommonService } from '../common/common.service'; import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service'; import { UserService } from '../common/user.service';

View File

@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { map, Observable } from 'rxjs'; import { map, Observable } from 'rxjs';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
import { CounterfoilFee } from '../../models/service-provider/counterfoil-fee'; import { CounterfoilFee } from '../../models/fees/counterfoil-fee';
import { CommonService } from '../common/common.service'; import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service'; import { UserService } from '../common/user.service';

View File

@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core';
import { map, Observable } from 'rxjs'; import { map, Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
import { ExpeditedFee } from '../../models/service-provider/expedited-fee'; import { ExpeditedFee } from '../../models/fees/expedited-fee';
import { CommonService } from '../common/common.service'; import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service'; import { UserService } from '../common/user.service';

View File

@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core'; import { inject, Injectable } from '@angular/core';
import { map, Observable } from 'rxjs'; import { map, Observable } from 'rxjs';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
import { SecurityDeposit } from '../../models/service-provider/security-deposit'; import { SecurityDeposit } from '../../models/fees/security-deposit';
import { CommonService } from '../common/common.service'; import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service'; import { UserService } from '../common/user.service';

View File

@ -2,16 +2,16 @@ import { Component, EventEmitter, inject, Input, Output, ViewChild } from '@angu
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator'; import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table'; import { MatTableDataSource } from '@angular/material/table';
import { BasicFee } from '../../core/models/service-provider/basic-fee'; import { BasicFee } from '../../core/models/fees/basic-fee';
import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CustomPaginator } from '../../shared/custom-paginator'; import { CustomPaginator } from '../../shared/custom-paginator';
import { finalize, forkJoin } from 'rxjs'; import { concat, finalize } from 'rxjs';
import { UserPreferences } from '../../core/models/user-preference'; import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service'; import { NotificationService } from '../../core/services/common/notification.service';
import { BasicFeeService } from '../../core/services/service-provider/basic-fee.service'; import { BasicFeeService } from '../../core/services/fees/basic-fee.service';
@Component({ @Component({
selector: 'app-basic-fee', selector: 'app-basic-fee',
@ -26,10 +26,7 @@ export class BasicFeeComponent {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort, { static: false }) @ViewChild(MatSort) sort!: MatSort;
set sort(value: MatSort) {
this.dataSource.sort = value;
}
displayedColumns: string[] = ['startCarnetValue', 'endCarnetValue', 'fees', 'effectiveDate', 'actions']; displayedColumns: string[] = ['startCarnetValue', 'endCarnetValue', 'fees', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<BasicFee>(); dataSource = new MatTableDataSource<BasicFee>();
@ -128,11 +125,15 @@ export class BasicFeeComponent {
this.changeInProgress = true; this.changeInProgress = true;
// Execute all creations in parallel and wait for all to complete // Execute all creations in sequence
forkJoin(creationObservables).pipe(finalize(() => { concat(...creationObservables).pipe(
finalize(() => {
this.changeInProgress = false; this.changeInProgress = false;
})).subscribe({ })
).subscribe({
next: () => { next: () => {
},
complete: () => {
this.loadBasicFees(); // Refresh the list after all creations are done this.loadBasicFees(); // Refresh the list after all creations are done
}, },
error: (error) => { error: (error) => {

View File

@ -10,8 +10,8 @@ import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service'; import { NotificationService } from '../../core/services/common/notification.service';
import { finalize } from 'rxjs'; import { finalize } from 'rxjs';
import { CargoRate } from '../../core/models/service-provider/cargo-rate'; import { CargoRate } from '../../core/models/fees/cargo-rate';
import { CargoRateService } from '../../core/services/service-provider/cargo-rate.service'; import { CargoRateService } from '../../core/services/fees/cargo-rate.service';
@Component({ @Component({
selector: 'app-cargo-rate', selector: 'app-cargo-rate',
@ -26,10 +26,7 @@ export class CargoRateComponent implements OnInit {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort, { static: false }) @ViewChild(MatSort) sort!: MatSort;
set sort(value: MatSort) {
this.dataSource.sort = value;
}
displayedColumns: string[] = ['carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'actions']; displayedColumns: string[] = ['carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();
@ -101,7 +98,6 @@ export class CargoRateComponent implements OnInit {
} }
loadCargoRates(): void { loadCargoRates(): void {
if (!this.spid) return;
this.isLoading = true; this.isLoading = true;
this.cargoRateService.getCargoRates(this.spid).pipe(finalize(() => { this.cargoRateService.getCargoRates(this.spid).pipe(finalize(() => {

View File

@ -7,13 +7,13 @@ import { MatTableDataSource } from '@angular/material/table';
import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CustomPaginator } from '../../shared/custom-paginator'; import { CustomPaginator } from '../../shared/custom-paginator';
import { CarnetFee } from '../../core/models/service-provider/carnet-fee'; import { CarnetFee } from '../../core/models/fees/carnet-fee';
import { FeeType } from '../../core/models/fee-type'; import { FeeType } from '../../core/models/fee-type';
import { UserPreferences } from '../../core/models/user-preference'; import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { CommonService } from '../../core/services/common/common.service'; import { CommonService } from '../../core/services/common/common.service';
import { NotificationService } from '../../core/services/common/notification.service'; import { NotificationService } from '../../core/services/common/notification.service';
import { CarnetFeeService } from '../../core/services/service-provider/carnet-fee.service'; import { CarnetFeeService } from '../../core/services/fees/carnet-fee.service';
import { finalize } from 'rxjs'; import { finalize } from 'rxjs';
@Component({ @Component({
@ -29,10 +29,7 @@ export class CarnetFeeComponent implements OnInit {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort, { static: false }) @ViewChild(MatSort) sort!: MatSort;
set sort(value: MatSort) {
this.dataSource.sort = value;
}
displayedColumns: string[] = ['feeType', 'commissionRate', 'effectiveDate', 'actions']; displayedColumns: string[] = ['feeType', 'commissionRate', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<CarnetFee>(); dataSource = new MatTableDataSource<CarnetFee>();

View File

@ -10,7 +10,7 @@ import { CustomPaginator } from '../../shared/custom-paginator';
import { UserPreferences } from '../../core/models/user-preference'; import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service'; import { NotificationService } from '../../core/services/common/notification.service';
import { ContinuationSheetFeeService } from '../../core/services/service-provider/continuation-sheet-fee.service'; import { ContinuationSheetFeeService } from '../../core/services/fees/continuation-sheet-fee.service';
@Component({ @Component({
selector: 'app-continuation-sheet-fee', selector: 'app-continuation-sheet-fee',
@ -25,10 +25,7 @@ export class ContinuationSheetFeeComponent implements OnInit {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort, { static: false }) @ViewChild(MatSort) sort!: MatSort;
set sort(value: MatSort) {
this.dataSource.sort = value;
}
displayedColumns: string[] = ['customerType', 'carnetType', 'rate', 'effectiveDate', 'actions']; displayedColumns: string[] = ['customerType', 'carnetType', 'rate', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();
@ -91,8 +88,6 @@ export class ContinuationSheetFeeComponent implements OnInit {
} }
loadContinuationSheets(): void { loadContinuationSheets(): void {
if (!this.spid) return;
this.isLoading = true; this.isLoading = true;
this.continuationSheetFeeService.getContinuationSheets(this.spid).pipe(finalize(() => { this.continuationSheetFeeService.getContinuationSheets(this.spid).pipe(finalize(() => {
this.isLoading = false; this.isLoading = false;

View File

@ -5,12 +5,12 @@ import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table'; import { MatTableDataSource } from '@angular/material/table';
import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CounterfoilFee } from '../../core/models/service-provider/counterfoil-fee'; import { CounterfoilFee } from '../../core/models/fees/counterfoil-fee';
import { CustomPaginator } from '../../shared/custom-paginator'; import { CustomPaginator } from '../../shared/custom-paginator';
import { UserPreferences } from '../../core/models/user-preference'; import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service'; import { NotificationService } from '../../core/services/common/notification.service';
import { CounterfoilFeeService } from '../../core/services/service-provider/counterfoil-fee.service'; import { CounterfoilFeeService } from '../../core/services/fees/counterfoil-fee.service';
import { finalize } from 'rxjs'; import { finalize } from 'rxjs';
@Component({ @Component({
@ -26,10 +26,7 @@ export class CounterfoilFeeComponent implements OnInit {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort, { static: false }) @ViewChild(MatSort) sort!: MatSort;
set sort(value: MatSort) {
this.dataSource.sort = value;
}
displayedColumns: string[] = ['customerType', 'carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'actions']; displayedColumns: string[] = ['customerType', 'carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();
@ -108,8 +105,6 @@ export class CounterfoilFeeComponent implements OnInit {
} }
loadCounterfoils(): void { loadCounterfoils(): void {
if (!this.spid) return;
this.isLoading = true; this.isLoading = true;
this.counterfoilFeeService.getCounterfoils(this.spid).pipe(finalize(() => { this.counterfoilFeeService.getCounterfoils(this.spid).pipe(finalize(() => {
this.isLoading = false; this.isLoading = false;

View File

@ -6,7 +6,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CustomPaginator } from '../../shared/custom-paginator'; import { CustomPaginator } from '../../shared/custom-paginator';
import { ExpeditedFee } from '../../core/models/service-provider/expedited-fee'; import { ExpeditedFee } from '../../core/models/fees/expedited-fee';
import { DeliveryType } from '../../core/models/delivery-type'; import { DeliveryType } from '../../core/models/delivery-type';
import { TimeZone } from '../../core/models/timezone'; import { TimeZone } from '../../core/models/timezone';
import { finalize, Subject, takeUntil } from 'rxjs'; import { finalize, Subject, takeUntil } from 'rxjs';
@ -15,7 +15,7 @@ import { ApiErrorHandlerService } from '../../core/services/common/api-error-han
import { CommonService } from '../../core/services/common/common.service'; import { CommonService } from '../../core/services/common/common.service';
import { NotificationService } from '../../core/services/common/notification.service'; import { NotificationService } from '../../core/services/common/notification.service';
import { TimeFormatService } from '../../core/services/common/timeformat.service'; import { TimeFormatService } from '../../core/services/common/timeformat.service';
import { ExpeditedFeeService } from '../../core/services/service-provider/expedited-fee.service'; import { ExpeditedFeeService } from '../../core/services/fees/expedited-fee.service';
@Component({ @Component({
selector: 'app-expedited-fee', selector: 'app-expedited-fee',
@ -30,10 +30,7 @@ export class ExpeditedFeeComponent implements OnInit, OnDestroy {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort, { static: false }) @ViewChild(MatSort) sort!: MatSort;
set sort(value: MatSort) {
this.dataSource.sort = value;
}
displayedColumns: string[] = ['customerType', 'deliveryType', 'time', 'fee', 'effectiveDate', 'actions']; displayedColumns: string[] = ['customerType', 'deliveryType', 'time', 'fee', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();

View File

@ -0,0 +1,62 @@
<h2 class="page-header">Manage Fees</h2>
<div class="manage-fees-action-buttons">
<button mat-button (click)="accordion().openAll()">Expand All</button>
<button mat-button (click)="accordion().closeAll()">Collapse All</button>
</div>
<mat-accordion class="manage-fees-headers-align" multi>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Carnet Fee & Commission Setup </mat-panel-title>
</mat-expansion-panel-header>
<app-carnet-fee [spid]="spid" [isEditMode]="isEditMode" [userPreferences]="userPreferences"></app-carnet-fee>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Basic Fee Setup</mat-panel-title>
</mat-expansion-panel-header>
<app-basic-fee [spid]="spid" [isEditMode]="isEditMode" [userPreferences]="userPreferences"></app-basic-fee>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Counterfoil Setup</mat-panel-title>
</mat-expansion-panel-header>
<app-counterfoil-fee [spid]="spid" [isEditMode]="isEditMode"
[userPreferences]="userPreferences"></app-counterfoil-fee>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Continuation Sheet Fee Setup </mat-panel-title>
</mat-expansion-panel-header>
<app-continuation-sheet-fee [spid]="spid" [isEditMode]="isEditMode"
[userPreferences]="userPreferences"></app-continuation-sheet-fee>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Expedited Fee Setup</mat-panel-title>
</mat-expansion-panel-header>
<app-expedited-fee [spid]="spid" [isEditMode]="isEditMode"
[userPreferences]="userPreferences"></app-expedited-fee>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Security Deposit </mat-panel-title>
</mat-expansion-panel-header>
<app-security-deposit [spid]="spid" [isEditMode]="isEditMode"
[userPreferences]="userPreferences"></app-security-deposit>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Cargo Rate Setup </mat-panel-title>
</mat-expansion-panel-header>
<app-cargo-rate [spid]="spid" [isEditMode]="isEditMode" [userPreferences]="userPreferences">
</app-cargo-rate>
</mat-expansion-panel>
</mat-accordion>

View File

@ -0,0 +1,18 @@
.page-header {
margin: 0.5rem 0px;
color: var(--mat-sys-primary);
font-weight: 500;
}
.manage-fees-action-buttons {
padding-bottom: 20px;
}
.manage-fees-headers-align .mat-expansion-panel-header-description {
justify-content: space-between;
align-items: center;
}
.manage-fees-headers-align .mat-mdc-form-field+.mat-mdc-form-field {
margin-left: 8px;
}

View File

@ -0,0 +1,35 @@
import { afterNextRender, Component, viewChild } from '@angular/core';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { MatAccordion } from '@angular/material/expansion';
import { CarnetFeeComponent } from "../carnet-fee/carnet-fee.component";
import { BasicFeeComponent } from "../basic-fee/basic-fee.component";
import { CounterfoilFeeComponent } from "../counterfoil-fee/counterfoil-fee.component";
import { ContinuationSheetFeeComponent } from "../continuation-sheet-fee/continuation-sheet-fee.component";
import { ExpeditedFeeComponent } from "../expedited-fee/expedited-fee.component";
import { SecurityDepositComponent } from "../security-deposit/security-deposit.component";
import { UserPreferences } from '../../core/models/user-preference';
import { CommonModule } from '@angular/common';
import { UserPreferencesService } from '../../core/services/user-preference.service';
import { CargoRateComponent } from '../cargo-rate/cargo-rate.component';
@Component({
selector: 'app-manage-fee',
imports: [AngularMaterialModule, CarnetFeeComponent, BasicFeeComponent, CounterfoilFeeComponent, ContinuationSheetFeeComponent, ExpeditedFeeComponent, SecurityDepositComponent, CommonModule, CargoRateComponent],
templateUrl: './manage-fee.component.html',
styleUrl: './manage-fee.component.scss'
})
export class ManageFeeComponent {
accordion = viewChild.required(MatAccordion);
isEditMode = true;
spid = 0;
serviceProviderName: string | null = null;
userPreferences: UserPreferences;
constructor(userPrefenceService: UserPreferencesService) {
this.userPreferences = userPrefenceService.getPreferences();
afterNextRender(() => {
// Open all panels
this.accordion().openAll();
});
}
}

View File

@ -7,12 +7,12 @@ import { AngularMaterialModule } from '../../shared/module/angular-material.modu
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CustomPaginator } from '../../shared/custom-paginator'; import { CustomPaginator } from '../../shared/custom-paginator';
import { Country } from '../../core/models/country'; import { Country } from '../../core/models/country';
import { SecurityDeposit } from '../../core/models/service-provider/security-deposit'; import { SecurityDeposit } from '../../core/models/fees/security-deposit';
import { UserPreferences } from '../../core/models/user-preference'; import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { CommonService } from '../../core/services/common/common.service'; import { CommonService } from '../../core/services/common/common.service';
import { NotificationService } from '../../core/services/common/notification.service'; import { NotificationService } from '../../core/services/common/notification.service';
import { SecurityDepositService } from '../../core/services/service-provider/security-deposit.service'; import { SecurityDepositService } from '../../core/services/fees/security-deposit.service';
import { finalize } from 'rxjs'; import { finalize } from 'rxjs';
import { HolderType } from '../../core/models/holder-type'; import { HolderType } from '../../core/models/holder-type';
@ -29,10 +29,7 @@ export class SecurityDepositComponent implements OnInit {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort, { static: false }) @ViewChild(MatSort) sort!: MatSort;
set sort(value: MatSort) {
this.dataSource.sort = value;
}
displayedColumns: string[] = ['holderType', 'uscibMember', 'specialCommodity', 'specialCountry', 'rate', 'rateInPercentage', 'effectiveDate', 'actions']; displayedColumns: string[] = ['holderType', 'uscibMember', 'specialCommodity', 'specialCountry', 'rate', 'rateInPercentage', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();

View File

@ -1,4 +1,6 @@
<div class="region-container"> <div class="region-container">
<h2 class="page-header">Manage Regions</h2>
<div class="actions-bar"> <div class="actions-bar">
<!-- <mat-slide-toggle (change)="toggleShowExpiredRecords()"> <!-- <mat-slide-toggle (change)="toggleShowExpiredRecords()">
Show Expired Records Show Expired Records

View File

@ -4,6 +4,12 @@
flex-direction: column; flex-direction: column;
gap: 24px; gap: 24px;
.page-header {
margin: 0px;
color: var(--mat-sys-primary);
font-weight: 500;
}
.actions-bar { .actions-bar {
clear: both; clear: both;
margin-bottom: -16px; margin-bottom: -16px;

View File

@ -27,10 +27,7 @@ export class RegionComponent implements OnInit, AfterViewInit {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort, { static: false }) @ViewChild(MatSort) sort!: MatSort;
set sort(value: MatSort) {
this.dataSource.sort = value;
}
displayedColumns: string[] = ['value', 'name', 'actions']; displayedColumns: string[] = ['value', 'name', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();

View File

@ -23,8 +23,8 @@
<mat-step [completed]="regionCompleted" [editable]="!!serviceProviderId && basicDetailsCompleted"> <mat-step [completed]="regionCompleted" [editable]="!!serviceProviderId && basicDetailsCompleted">
<ng-template matStepLabel>Regions</ng-template> <ng-template matStepLabel>Regions</ng-template>
<app-region *ngIf="serviceProviderId" [spid]="serviceProviderId" (hasRegions)="onRegionsSaved($event)"> <app-sp-region *ngIf="serviceProviderId" [spid]="serviceProviderId" (hasRegions)="onRegionsSaved($event)">
</app-region> </app-sp-region>
</mat-step> </mat-step>
<!-- Carnet Sequence Step --> <!-- Carnet Sequence Step -->

View File

@ -5,16 +5,16 @@ import { AngularMaterialModule } from '../../shared/module/angular-material.modu
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ContactsComponent } from '../contacts/contacts.component'; import { ContactsComponent } from '../contacts/contacts.component';
import { CarnetSequenceComponent } from '../carnet-sequence/carnet-sequence.component'; import { CarnetSequenceComponent } from '../carnet-sequence/carnet-sequence.component';
import { CarnetFeeComponent } from '../carnet-fee/carnet-fee.component'; import { CarnetFeeComponent } from '../../fees/carnet-fee/carnet-fee.component';
import { BasicFeeComponent } from '../basic-fee/basic-fee.component'; import { BasicFeeComponent } from '../../fees/basic-fee/basic-fee.component';
import { CounterfoilFeeComponent } from '../counterfoil-fee/counterfoil-fee.component'; import { CounterfoilFeeComponent } from '../../fees/counterfoil-fee/counterfoil-fee.component';
import { ExpeditedFeeComponent } from '../expedited-fee/expedited-fee.component'; import { ExpeditedFeeComponent } from '../../fees/expedited-fee/expedited-fee.component';
import { SecurityDepositComponent } from '../security-deposit/security-deposit.component'; import { SecurityDepositComponent } from '../../fees/security-deposit/security-deposit.component';
import { ContinuationSheetFeeComponent } from "../continuation-sheet-fee/continuation-sheet-fee.component"; import { ContinuationSheetFeeComponent } from "../../fees/continuation-sheet-fee/continuation-sheet-fee.component";
import { UserPreferences } from '../../core/models/user-preference'; import { UserPreferences } from '../../core/models/user-preference';
import { UserPreferencesService } from '../../core/services/user-preference.service'; import { UserPreferencesService } from '../../core/services/user-preference.service';
import { CargoRateComponent } from '../cargo-rate/cargo-rate.component'; import { CargoRateComponent } from '../../fees/cargo-rate/cargo-rate.component';
import { RegionComponent } from '../../region/region.component'; import { RegionComponent } from '../region/region.component';
@Component({ @Component({
selector: 'app-add-service-provider', selector: 'app-add-service-provider',

View File

@ -28,10 +28,7 @@ export class CarnetSequenceComponent implements OnInit {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort, { static: false }) @ViewChild(MatSort) sort!: MatSort;
set sort(value: MatSort) {
this.dataSource.sort = value;
}
displayedColumns: string[] = ['carnetType', 'region', 'startNumber', 'endNumber', 'lastNumber']; displayedColumns: string[] = ['carnetType', 'region', 'startNumber', 'endNumber', 'lastNumber'];
dataSource = new MatTableDataSource<CarnetSequence>(); dataSource = new MatTableDataSource<CarnetSequence>();

View File

@ -30,10 +30,7 @@ export class ContactsComponent implements OnInit {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort, { static: false }) @ViewChild(MatSort) sort!: MatSort;
set sort(value: MatSort) {
this.dataSource.sort = value;
}
displayedColumns: string[] = ['firstName', 'lastName', 'title', 'phone', 'email', 'defaultContact', 'actions']; displayedColumns: string[] = ['firstName', 'lastName', 'title', 'phone', 'email', 'defaultContact', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();

View File

@ -24,7 +24,7 @@
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title> Regions </mat-panel-title> <mat-panel-title> Regions </mat-panel-title>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<app-region [spid]="spid"></app-region> <app-sp-region [spid]="spid"></app-sp-region>
</mat-expansion-panel> </mat-expansion-panel>
<mat-expansion-panel> <mat-expansion-panel>

View File

@ -5,17 +5,17 @@ import { BasicDetailsComponent } from '../basic-details/basic-details.component'
import { ContactsComponent } from '../contacts/contacts.component'; import { ContactsComponent } from '../contacts/contacts.component';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { CarnetSequenceComponent } from '../carnet-sequence/carnet-sequence.component'; import { CarnetSequenceComponent } from '../carnet-sequence/carnet-sequence.component';
import { CarnetFeeComponent } from "../carnet-fee/carnet-fee.component"; import { CarnetFeeComponent } from "../../fees/carnet-fee/carnet-fee.component";
import { BasicFeeComponent } from "../basic-fee/basic-fee.component"; import { BasicFeeComponent } from "../../fees/basic-fee/basic-fee.component";
import { CounterfoilFeeComponent } from "../counterfoil-fee/counterfoil-fee.component"; import { CounterfoilFeeComponent } from "../../fees/counterfoil-fee/counterfoil-fee.component";
import { ContinuationSheetFeeComponent } from "../continuation-sheet-fee/continuation-sheet-fee.component"; import { ContinuationSheetFeeComponent } from "../../fees/continuation-sheet-fee/continuation-sheet-fee.component";
import { ExpeditedFeeComponent } from "../expedited-fee/expedited-fee.component"; import { ExpeditedFeeComponent } from "../../fees/expedited-fee/expedited-fee.component";
import { SecurityDepositComponent } from "../security-deposit/security-deposit.component"; import { SecurityDepositComponent } from "../../fees/security-deposit/security-deposit.component";
import { UserPreferences } from '../../core/models/user-preference'; import { UserPreferences } from '../../core/models/user-preference';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { UserPreferencesService } from '../../core/services/user-preference.service'; import { UserPreferencesService } from '../../core/services/user-preference.service';
import { CargoRateComponent } from '../cargo-rate/cargo-rate.component'; import { CargoRateComponent } from '../../fees/cargo-rate/cargo-rate.component';
import { RegionComponent } from '../../region/region.component'; import { RegionComponent } from '../region/region.component';
@Component({ @Component({
selector: 'app-edit-service-provider', selector: 'app-edit-service-provider',

View File

@ -0,0 +1,55 @@
<div class="region-container">
<div class="loading-shade" *ngIf="isLoading">
<mat-spinner diameter="50"></mat-spinner>
</div>
<div class="region-selection-container">
<!-- Available Regions Listbox -->
<div class="available-regions">
<h3>Available Regions</h3>
<mat-selection-list [multiple]="false" hideSingleSelectionIndicator>
<mat-list-option *ngFor="let region of regions" [value]="region" [disabled]="isRegionSelected(region)"
(click)="onAvailableRegionSelection(availableoption)" #availableoption>
{{region.name}}
</mat-list-option>
</mat-selection-list>
</div>
<!-- Controls -->
<div class="controls">
<div class="action-buttons">
<button mat-raised-button color="primary" type="button" (click)="addRegion()" class="icon-end">
<mat-icon>keyboard_double_arrow_right</mat-icon>
<span> Add</span>
</button>
<button mat-raised-button type="button" (click)="removeRegion()">
<mat-icon>keyboard_double_arrow_left</mat-icon>
<span> Remove</span>
</button>
</div>
</div>
<!-- Selected Regions -->
<div class="selected-regions">
<div class="regions">
<h3>Selected Regions</h3>
<mat-selection-list [multiple]="false" hideSingleSelectionIndicator>
<mat-list-option *ngFor="let region of selectedRegions" [value]="region"
(click)="onRegionSelection(selectedoption)" #selectedoption>
{{region.name}}
</mat-list-option>
<mat-list-item *ngIf="selectedRegions.length === 0">
<span class="empty-message">No regions selected</span>
</mat-list-item>
</mat-selection-list>
</div>
</div>
</div>
<div class="form-actions">
<button mat-raised-button color="primary" type="submit" (click)="onSubmit()"
[disabled]="changeInProgress || selectedRegions.length === 0">
Save
</button>
</div>
</div>

View File

@ -0,0 +1,90 @@
.region-container {
padding: 0.75rem 0 0 0;
margin: 0 auto;
.region-selection-container {
display: flex;
gap: 24px;
margin-bottom: 12px;
// border: 1px solid;
// border-radius: 4px;
// padding: 20px;
@media (max-width: 768px) {
flex-direction: column;
}
}
.available-regions,
.selected-regions {
flex: 1;
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 16px;
overflow: hidden;
h3 {
margin: 0 0 16px 0;
font-size: 0.875rem;
font-weight: 500;
}
mat-selection-list {
height: 150px;
overflow-y: auto;
padding: 0;
mat-list-item {
.empty-message {
font-style: italic;
}
}
}
}
.controls {
display: flex;
flex-direction: column;
gap: 16px;
width: 150px;
padding: 16px;
.action-buttons {
display: flex;
flex-direction: column;
gap: 8px;
button {
width: 100%;
display: flex;
// gap: 8px;
align-items: center;
}
mat-icon {
margin: 0;
}
button.icon-end {
flex-direction: row-reverse;
}
}
}
.selected-regions {
display: flex;
flex-direction: column;
gap: 16px;
.regions {
flex: 1;
}
}
.form-actions {
display: flex;
justify-content: flex-end;
padding-top: 12px;
border-top: 1px solid #e0e0e0;
}
}

View File

@ -0,0 +1,133 @@
import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { finalize, Subject, takeUntil } from 'rxjs';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { CommonModule } from '@angular/common';
import { MatListModule } from '@angular/material/list';
import { RegionService } from '../../core/services/region/region.service';
import { Region } from '../../core/models/region/region';
@Component({
selector: 'app-sp-region',
imports: [AngularMaterialModule, ReactiveFormsModule, CommonModule, MatListModule],
templateUrl: './region.component.html',
styleUrl: './region.component.scss'
})
export class RegionComponent {
@Input() spid: number = 0;
@Input() isEditMode = false;
@Output() hasRegions = new EventEmitter<boolean>();
private destroy$ = new Subject<void>();
private notificationService = inject(NotificationService);
private errorHandler = inject(ApiErrorHandlerService);
private regionService = inject(RegionService);
isLoading = false;
changeInProgress = false;
regions: Region[] = [];
selectedRegions: Region[] = [];
// Currently selected region in the listbox
selectedAvailableRegion: Region | null = null;
selectedRegion: Region | null = null;
constructor() {
}
ngOnInit(): void {
this.loadRegions(0);
this.loadRegions(this.spid);
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
loadRegions(spid: number): void {
this.isLoading = true;
this.regionService.getRegions(spid)
.pipe(takeUntil(this.destroy$), finalize(() => {
this.isLoading = false;
}))
.subscribe({
next: (regions) => {
if (spid === 0) {
this.regions = regions;
} else {
this.selectedRegions = regions;
}
},
error: (error) => {
console.error('Failed to load regions', error);
}
});
}
onAvailableRegionSelection(event: any) {
this.selectedAvailableRegion = event.value;
}
onRegionSelection(event: any) {
this.selectedRegion = event.value;
}
// Add selected region
addRegion(): void {
if (!this.selectedAvailableRegion) return;
const existingIndex = this.selectedRegions.findIndex(
c => c.value === this.selectedAvailableRegion!.value
);
if (existingIndex === -1) {
this.selectedRegions.push({
...this.selectedAvailableRegion
});
}
}
// Remove region
removeRegion(): void {
if (!this.selectedRegion) return;
this.selectedRegions = this.selectedRegions.filter(
c => c.value !== this.selectedRegion!.value
);
}
// Check if a region is already selected
isRegionSelected(region: Region): boolean {
return this.selectedRegions.some(c => c.value === region.value)
}
onSubmit(): void {
const region: Region = {
id: 0,
value: this.selectedRegions.map(r => r.value).join(','),
name: this.selectedRegions.map(r => r.name).join(',')
};
this.changeInProgress = true;
this.regionService.createRegion(region, this.spid).pipe(finalize(() => {
this.changeInProgress = false;
})).subscribe({
next: () => {
this.notificationService.showSuccess('Regions saved successfully');
this.hasRegions.emit(true);
},
error: (error) => {
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save regions');
this.notificationService.showError(errorMessage);
console.error('Error saving region data : ', error);
}
});
}
}