extend carnet and feedback updates
This commit is contained in:
parent
f484131cb7
commit
6a628b9dc7
@ -17,6 +17,7 @@ export const serverRoutes: ServerRoute[] = [
|
||||
{ path: ':appId/process-extend-carnet/:headerid', renderMode: RenderMode.Client },
|
||||
{ path: ':appId/process-additional-sets/:headerid', renderMode: RenderMode.Client },
|
||||
{ path: ':appId/view-carnet/:headerid', renderMode: RenderMode.Client },
|
||||
{ path: ':appId/view-extend-carnet/:headerid', renderMode: RenderMode.Client },
|
||||
{ path: ':appId/add-holder', renderMode: RenderMode.Client },
|
||||
{ path: ':appId/edit-holder/:holderid', renderMode: RenderMode.Client },
|
||||
{
|
||||
|
||||
@ -26,6 +26,7 @@ export const routes: Routes = [
|
||||
{ path: 'process-extend-carnet/:headerid', loadComponent: () => import('./carnet/edit/edit-carnet.component').then(m => m.EditCarnetComponent), canDeactivate: [CarnetCleanupGuard] },
|
||||
{ path: 'process-additional-sets/:headerid', loadComponent: () => import('./carnet/edit/edit-carnet.component').then(m => m.EditCarnetComponent), canDeactivate: [CarnetCleanupGuard] },
|
||||
{ path: 'view-carnet/:headerid', loadComponent: () => import('./carnet/view/view-carnet.component').then(m => m.ViewCarnetComponent), canDeactivate: [CarnetCleanupGuard] },
|
||||
{ path: 'view-extend-carnet/:headerid', loadComponent: () => import('./carnet/view/view-carnet.component').then(m => m.ViewCarnetComponent), canDeactivate: [CarnetCleanupGuard] },
|
||||
{ path: 'add-holder', loadComponent: () => import('./holder/add/add-holder.component').then(m => m.AddHolderComponent), canDeactivate: [CarnetCleanupGuard] },
|
||||
{ path: 'edit-holder/:holderid', loadComponent: () => import('./holder/edit/edit-holder.component').then(m => m.EditHolderComponent), canDeactivate: [CarnetCleanupGuard] },
|
||||
{ path: '', redirectTo: 'home', pathMatch: 'full' }
|
||||
|
||||
@ -1 +0,0 @@
|
||||
<p>additional-set works!</p>
|
||||
@ -1,11 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-additional-set',
|
||||
imports: [],
|
||||
templateUrl: './additional-set.component.html',
|
||||
styleUrl: './additional-set.component.scss'
|
||||
})
|
||||
export class AdditionalSetComponent {
|
||||
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
<p>duplicate works!</p>
|
||||
@ -1,11 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-duplicate',
|
||||
imports: [],
|
||||
templateUrl: './duplicate.component.html',
|
||||
styleUrl: './duplicate.component.scss'
|
||||
})
|
||||
export class DuplicateComponent {
|
||||
|
||||
}
|
||||
@ -3,6 +3,15 @@
|
||||
<mat-stepper orientation="vertical" [linear]="isLinear" (selectionChange)="onStepChange($event)"
|
||||
[selectedIndex]="currentStep">
|
||||
|
||||
<!-- Replacement Application Step -->
|
||||
<mat-step *ngIf="applicationType === 'extend'" [completed]="stepsCompleted.extension"
|
||||
[editable]="stepsCompleted.extension">
|
||||
<ng-template matStepLabel>Extension Application</ng-template>
|
||||
<app-replacement-set (completed)="onExtensionApplicationSaved($event)" [headerid]="headerid"
|
||||
[isEditMode]="isEditMode && applicationType === 'extend'">
|
||||
</app-replacement-set>
|
||||
</mat-step>
|
||||
|
||||
<!-- Application Name Step -->
|
||||
<mat-step [completed]="stepsCompleted.applicationDetail" [editable]="stepsCompleted.applicationDetail">
|
||||
<ng-template matStepLabel>Application Name</ng-template>
|
||||
|
||||
@ -11,11 +11,12 @@ import { ShippingComponent } from '../shipping/shipping.component';
|
||||
import { TravelPlanComponent } from '../travel-plan/travel-plan.component';
|
||||
import { UserPreferences } from '../../core/models/user-preference';
|
||||
import { UserPreferencesService } from '../../core/services/user-preference.service';
|
||||
import { ReplacementSetComponent } from '../replacement-set/replacement-set.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-edit-carnet',
|
||||
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule,
|
||||
ApplicationComponent, HolderComponent, GoodsComponent, TravelPlanComponent, ShippingComponent],
|
||||
ApplicationComponent, HolderComponent, GoodsComponent, TravelPlanComponent, ShippingComponent, ReplacementSetComponent],
|
||||
templateUrl: './edit-carnet.component.html',
|
||||
styleUrl: './edit-carnet.component.scss'
|
||||
})
|
||||
@ -38,7 +39,8 @@ export class EditCarnetComponent {
|
||||
holderSelection: false,
|
||||
goodsSection: false,
|
||||
travelPlan: false,
|
||||
shipping: false
|
||||
shipping: false,
|
||||
extension: false
|
||||
};
|
||||
|
||||
private route = inject(ActivatedRoute);
|
||||
@ -70,6 +72,8 @@ export class EditCarnetComponent {
|
||||
|
||||
if (returnTo === 'holder') {
|
||||
this.currentStep = 1;
|
||||
} else if (returnTo === 'shipping' && this.applicationType === 'extend') {
|
||||
this.currentStep = 5;
|
||||
} else if (returnTo === 'shipping') {
|
||||
this.currentStep = 4;
|
||||
} else if (this.applicationType === 'additional') {
|
||||
@ -115,9 +119,15 @@ export class EditCarnetComponent {
|
||||
this.shippingComponent?.refreshInsuranceData(data);
|
||||
}
|
||||
|
||||
onExtensionApplicationSaved(completed: boolean): void {
|
||||
this.stepsCompleted.extension = completed;
|
||||
this.isAllSectionsCompleted();
|
||||
}
|
||||
|
||||
isAllSectionsCompleted() {
|
||||
this.allSectionsCompleted = this.stepsCompleted.applicationDetail
|
||||
&& this.stepsCompleted.holderSelection && this.stepsCompleted.goodsSection
|
||||
&& this.stepsCompleted.shipping && this.stepsCompleted.travelPlan;
|
||||
&& this.stepsCompleted.shipping && this.stepsCompleted.travelPlan
|
||||
&& (this.applicationType !== 'extend' || this.stepsCompleted.extension);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,8 +33,15 @@ export class GoodsComponent {
|
||||
@Input() isEditMode: boolean = false;
|
||||
@Output() completed = new EventEmitter<boolean>();
|
||||
|
||||
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
@ViewChild(MatPaginator, { static: false })
|
||||
set paginator(value: MatPaginator) {
|
||||
this.dataSource.paginator = value;
|
||||
}
|
||||
|
||||
@ViewChild(MatSort, { static: false })
|
||||
set sort(value: MatSort) {
|
||||
this.dataSource.sort = value;
|
||||
}
|
||||
|
||||
// Table configuration
|
||||
displayedColumns: string[] = ['itemNumber', 'description', 'pieces', 'weight', 'unitOfMeasure', 'value', 'countryOfOrigin', 'actions'];
|
||||
|
||||
@ -1 +1,98 @@
|
||||
<p>replacement-set works!</p>
|
||||
<!-- extension-section.component.html -->
|
||||
<div class="extension-container">
|
||||
<div class="loading-shade" *ngIf="isLoading">
|
||||
<mat-spinner diameter="50"></mat-spinner>
|
||||
</div>
|
||||
|
||||
<!-- General Section -->
|
||||
<div class="general-section">
|
||||
<h3>General</h3>
|
||||
<div class="detail-row">
|
||||
<label>Carnet No:</label>
|
||||
<span>{{ replacementDetails?.replacementCarnetNumber || 'N/A' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-row">
|
||||
<label>Issue Date:</label>
|
||||
<span>{{ replacementDetails?.issueDate | date:'mediumDate':'UTC' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-row">
|
||||
<label>Preparer Name:</label>
|
||||
<span>{{ replacementDetails?.preparerName || 'N/A' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-row">
|
||||
<label>Address:</label>
|
||||
<span>{{ getAddressLabel() || 'N/A' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Extension Section -->
|
||||
<div class="extension-section">
|
||||
<h3>Extension</h3>
|
||||
|
||||
<form [formGroup]="extensionForm" (ngSubmit)="onSubmit()">
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline" class="current-port">
|
||||
<mat-label>Current port where the goods are located</mat-label>
|
||||
<input matInput formControlName="portName" required>
|
||||
<mat-error *ngIf="f['portName'].errors?.['required']">
|
||||
Port location is required
|
||||
</mat-error>
|
||||
<mat-error *ngIf="f['portName'].errors?.['maxlength']">
|
||||
Maximum 100 characters allowed
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="country">
|
||||
<mat-label>Country</mat-label>
|
||||
<mat-select formControlName="portCountry" required>
|
||||
<mat-option *ngFor="let country of countries" [value]="country.value">
|
||||
{{ country.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="f['portCountry'].errors?.['required']">
|
||||
Port Country is required
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline" class="reason">
|
||||
<mat-label>Reason for Extension</mat-label>
|
||||
<mat-select formControlName="reasonForExtension" required>
|
||||
<mat-option *ngFor="let reason of extensionReasons" [value]="reason.value">
|
||||
{{ reason.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="f['reasonForExtension'].errors?.['required']">
|
||||
Reason is required
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="duration">
|
||||
<mat-label>Duration</mat-label>
|
||||
<input matInput type="number" formControlName="duration" required>
|
||||
<span matTextSuffix>Month(s)</span>
|
||||
<mat-error *ngIf="f['duration'].errors?.['required']">
|
||||
Duration is required
|
||||
</mat-error>
|
||||
<mat-error *ngIf="f['duration'].errors?.['min']">
|
||||
Minimum 1 month required
|
||||
</mat-error>
|
||||
<mat-error *ngIf="f['duration'].errors?.['max']">
|
||||
Maximum 24 months allowed
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button mat-raised-button color="primary" type="submit" *ngIf="!isViewMode"
|
||||
[disabled]="extensionForm.invalid || changeInProgress">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,51 @@
|
||||
.extension-container {
|
||||
padding: 0.5rem;
|
||||
|
||||
.general-section,
|
||||
.extension-section {
|
||||
margin-bottom: 24px;
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--mat-sys-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
font-size: 0.875rem;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 16px;
|
||||
align-items: start;
|
||||
|
||||
mat-form-field {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.current-port {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,173 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||
import { finalize, Subject, takeUntil } from 'rxjs';
|
||||
import { Country } from '../../core/models/country';
|
||||
import { CommonService } from '../../core/services/common/common.service';
|
||||
import { Replacement } from '../../core/models/carnet/replacement';
|
||||
import { ReplacementService } from '../../core/services/carnet/replacement.service';
|
||||
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
||||
import { NotificationService } from '../../core/services/common/notification.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
||||
import { ExtensionReason } from '../../core/models/extension-reason';
|
||||
|
||||
@Component({
|
||||
selector: 'app-replacement-set',
|
||||
imports: [],
|
||||
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule],
|
||||
templateUrl: './replacement-set.component.html',
|
||||
styleUrl: './replacement-set.component.scss'
|
||||
})
|
||||
export class ReplacementSetComponent {
|
||||
@Input() headerid: number = 0;
|
||||
@Input() isViewMode = false;
|
||||
@Input() isEditMode: boolean = false;
|
||||
@Output() completed = new EventEmitter<boolean>();
|
||||
|
||||
}
|
||||
extensionForm: FormGroup;
|
||||
countries: Country[] = [];
|
||||
extensionReasons: ExtensionReason[] = [];
|
||||
replacementDetails: Replacement | undefined;
|
||||
|
||||
// UI state
|
||||
isEditing = false;
|
||||
isLoading = false;
|
||||
changeInProgress = false;
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
private fb = inject(FormBuilder);
|
||||
private commonService = inject(CommonService);
|
||||
private notificationService = inject(NotificationService);
|
||||
private replacementService = inject(ReplacementService);
|
||||
private errorHandler = inject(ApiErrorHandlerService);
|
||||
|
||||
constructor(
|
||||
) {
|
||||
this.extensionForm = this.createForm();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadCountries();
|
||||
this.loadExtensionReasons();
|
||||
|
||||
if (this.headerid > 0) {
|
||||
this.isLoading = true;
|
||||
this.replacementService.getExtensionData(this.headerid).pipe(finalize(() => {
|
||||
this.isLoading = false;
|
||||
})).subscribe({
|
||||
next: (replacementData: Replacement) => {
|
||||
if (replacementData) {
|
||||
this.patchFormData(replacementData);
|
||||
this.replacementDetails = replacementData;
|
||||
this.completed.emit(this.extensionForm.valid || this.extensionForm.disabled);
|
||||
this.completed.emit(true);
|
||||
}
|
||||
},
|
||||
error: (error: any) => {
|
||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load extension details');
|
||||
this.notificationService.showError(errorMessage);
|
||||
console.error('Error loading extension details:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
patchFormData(data: Replacement): void {
|
||||
this.extensionForm.patchValue({
|
||||
portName: data.portName,
|
||||
portCountry: data.portCountry,
|
||||
reasonForExtension: data.reasonForExtension,
|
||||
duration: data.duration
|
||||
});
|
||||
|
||||
if (this.isViewMode) {
|
||||
this.extensionForm.disable();
|
||||
}
|
||||
}
|
||||
|
||||
createForm(): FormGroup {
|
||||
return this.fb.group({
|
||||
portName: ['', [Validators.required, Validators.maxLength(100)]],
|
||||
portCountry: ['', Validators.required],
|
||||
reasonForExtension: ['', Validators.required],
|
||||
duration: [1, [Validators.required, Validators.min(1), Validators.max(24)]]
|
||||
});
|
||||
}
|
||||
|
||||
loadCountries(): void {
|
||||
this.commonService.getCountries()
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe({
|
||||
next: (countries) => {
|
||||
this.countries = countries;
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Failed to load countries', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadExtensionReasons(): void {
|
||||
this.commonService.getExtensionReasons()
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe({
|
||||
next: (extensionReasons) => {
|
||||
this.extensionReasons = extensionReasons;
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Failed to load extension reasons', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onSubmit(): void {
|
||||
if (this.extensionForm.invalid) {
|
||||
this.extensionForm.markAllAsTouched();
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = this.extensionForm.value;
|
||||
this.changeInProgress = true;
|
||||
|
||||
this.replacementService.saveExtensionDetails(this.headerid, formData).pipe(finalize(() => {
|
||||
this.changeInProgress = false;
|
||||
})).subscribe({
|
||||
next: () => {
|
||||
this.notificationService.showSuccess('Extension details saved successfully');
|
||||
this.completed.emit(this.extensionForm.valid);
|
||||
},
|
||||
error: (error) => {
|
||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save extension information');
|
||||
this.notificationService.showError(errorMessage);
|
||||
console.error('Error saving extension information:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get f() {
|
||||
return this.extensionForm.controls;
|
||||
}
|
||||
|
||||
getAddressLabel(): string {
|
||||
if (!this.replacementDetails) {
|
||||
return 'No contact information available';
|
||||
}
|
||||
|
||||
// Build name parts, filtering out null/undefined/empty strings
|
||||
const allParts = [
|
||||
this.replacementDetails.address1,
|
||||
this.replacementDetails.address2,
|
||||
this.replacementDetails.city,
|
||||
this.replacementDetails.state,
|
||||
this.replacementDetails.country,
|
||||
this.replacementDetails.zip
|
||||
].filter(part => part != null && part.trim() !== '');
|
||||
|
||||
return allParts.join(', ') || '';
|
||||
}
|
||||
}
|
||||
@ -180,6 +180,11 @@ export class ShippingComponent {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.applicationType === 'extend' && this.shippingFromDB) {
|
||||
shippingData.needsLostDocProtection = this.shippingFromDB.needsLostDocProtection;
|
||||
shippingData.formOfSecurity = this.shippingFromDB.formOfSecurity;
|
||||
}
|
||||
|
||||
this.shippingService.saveShippingDetails(this.headerid, shippingData).pipe(finalize(() => {
|
||||
this.changeInProgress = false;
|
||||
})).subscribe({
|
||||
@ -483,9 +488,13 @@ export class ShippingComponent {
|
||||
this.shippingForm.disable();
|
||||
}
|
||||
|
||||
if (this.applicationType === 'duplicate' || this.applicationType === 'additional') {
|
||||
if (this.applicationType === 'duplicate' || this.applicationType === 'additional'
|
||||
|| this.applicationType === 'extend') {
|
||||
this.shippingForm.get('formOfSecurity')?.disable();
|
||||
this.shippingForm.get('needsLostDocProtection')?.disable();
|
||||
}
|
||||
|
||||
if (this.applicationType === 'duplicate' || this.applicationType === 'additional') {
|
||||
this.shippingForm.get('needsInsurance')?.disable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,15 @@
|
||||
<button mat-button (click)="accordion().closeAll()">Collapse All</button>
|
||||
</div>
|
||||
<mat-accordion class="carnet-headers-align" multi>
|
||||
|
||||
<mat-expansion-panel *ngIf="applicationType==='extend'">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title> Extension Application </mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<app-replacement-set [headerid]=" headerid" [isViewMode]="isViewMode">
|
||||
</app-replacement-set>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title> Application Name </mat-panel-title>
|
||||
|
||||
@ -11,11 +11,12 @@ import { GoodsComponent } from '../goods/goods.component';
|
||||
import { HolderComponent } from '../holder/holder.component';
|
||||
import { ShippingComponent } from '../shipping/shipping.component';
|
||||
import { TravelPlanComponent } from '../travel-plan/travel-plan.component';
|
||||
import { ReplacementSetComponent } from '../replacement-set/replacement-set.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-view-carnet',
|
||||
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule,
|
||||
ApplicationComponent, HolderComponent, GoodsComponent, TravelPlanComponent, ShippingComponent],
|
||||
ApplicationComponent, HolderComponent, GoodsComponent, TravelPlanComponent, ShippingComponent, ReplacementSetComponent],
|
||||
templateUrl: './view-carnet.component.html',
|
||||
styleUrl: './view-carnet.component.scss'
|
||||
})
|
||||
@ -25,12 +26,20 @@ export class ViewCarnetComponent {
|
||||
headerid: number = 0;
|
||||
applicationName: string = '';
|
||||
userPreferences: UserPreferences;
|
||||
applicationType: 'new' | 'edit' | 'additional' | 'duplicate' | 'extend' | null = 'edit';
|
||||
|
||||
private route = inject(ActivatedRoute);
|
||||
|
||||
constructor(userPrefenceService: UserPreferencesService) {
|
||||
this.userPreferences = userPrefenceService.getPreferences();
|
||||
|
||||
// set application type based on the route url
|
||||
const urlSegments = this.route.snapshot.url.map(segment => segment.path);
|
||||
|
||||
if (urlSegments.includes('view-extend-carnet')) {
|
||||
this.applicationType = 'extend';
|
||||
}
|
||||
|
||||
afterNextRender(() => {
|
||||
// Open all panels
|
||||
this.accordion().openAll();
|
||||
|
||||
15
src/app/core/models/carnet/replacement.ts
Normal file
15
src/app/core/models/carnet/replacement.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export interface Replacement {
|
||||
replacementCarnetNumber: string;
|
||||
issueDate: Date;
|
||||
preparerName: string;
|
||||
address1: string;
|
||||
address2?: string | null;
|
||||
city: string;
|
||||
state: string;
|
||||
country: string;
|
||||
zip: string;
|
||||
portName: string;
|
||||
portCountry: string;
|
||||
reasonForExtension: string;
|
||||
duration: number;
|
||||
}
|
||||
5
src/app/core/models/extension-reason.ts
Normal file
5
src/app/core/models/extension-reason.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface ExtensionReason {
|
||||
name: string;
|
||||
id: string;
|
||||
value: string;
|
||||
}
|
||||
59
src/app/core/services/carnet/replacement.service.ts
Normal file
59
src/app/core/services/carnet/replacement.service.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { environment } from '../../../../environments/environment';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { map, Observable } from 'rxjs';
|
||||
import { UserService } from '../common/user.service';
|
||||
import { Replacement } from '../../models/carnet/replacement';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ReplacementService {
|
||||
private apiUrl = environment.apiUrl;
|
||||
private apiDb = environment.apiDb;
|
||||
|
||||
private http = inject(HttpClient);
|
||||
private userService = inject(UserService);
|
||||
|
||||
getExtensionData(headerid: number): Replacement | any {
|
||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetExtendedSection/${this.userService.getUserSpid()}/${headerid}`).pipe(
|
||||
map(response => this.mapToExtensionData(response)));
|
||||
}
|
||||
|
||||
private mapToExtensionData(extensionDataCollection: any): Replacement {
|
||||
let extensionData = extensionDataCollection?.[0];
|
||||
|
||||
let replacementData: Replacement = {
|
||||
replacementCarnetNumber: extensionData.REPLACECARNETNO,
|
||||
issueDate: extensionData.ISSUEDATE,
|
||||
preparerName: extensionData.PREPARERNAME,
|
||||
address1: extensionData.ADDRESS1,
|
||||
address2: extensionData.ADDRESS2,
|
||||
city: extensionData.CITY,
|
||||
state: extensionData.STATE,
|
||||
country: extensionData.COUNTRY,
|
||||
zip: extensionData.ZIP,
|
||||
portName: extensionData.GOODSPORT,
|
||||
portCountry: extensionData.GOODSCOUNTRY,
|
||||
reasonForExtension: extensionData.REASONCODE,
|
||||
duration: extensionData.EXTENSIONPERIOD,
|
||||
};
|
||||
|
||||
return replacementData;
|
||||
}
|
||||
|
||||
saveExtensionDetails(headerid: number, extensionData: Replacement): Observable<any> {
|
||||
|
||||
const extensionDetails = {
|
||||
P_HEADERID: headerid,
|
||||
P_GOODSPORT: extensionData.portName,
|
||||
P_GOODSCOUNTRY: extensionData.portCountry,
|
||||
P_REASONCODE: extensionData.reasonForExtension,
|
||||
P_EXTENSIONPERIOD: extensionData.duration,
|
||||
P_USERID: this.userService.getUser(),
|
||||
P_SPID: this.userService.getUserSpid()
|
||||
}
|
||||
|
||||
return this.http.patch(`${this.apiUrl}/${this.apiDb}/SaveExtensionApplication`, extensionDetails);
|
||||
}
|
||||
}
|
||||
@ -17,6 +17,7 @@ import { DeliveryMethod } from '../../models/delivery-method';
|
||||
import { FormOfSecurity } from '../../models/formofsecurity';
|
||||
import { PaymentType } from '../../models/payment-type';
|
||||
import { UnitOfMeasure } from '../../models/unitofmeasure';
|
||||
import { ExtensionReason } from '../../models/extension-reason';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -205,6 +206,18 @@ export class CommonService {
|
||||
);
|
||||
}
|
||||
|
||||
getExtensionReasons(): Observable<ExtensionReason[]> {
|
||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=008&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||
map((response) =>
|
||||
response.map((item) => ({
|
||||
name: item.PARAMDESC,
|
||||
id: item.PARAMID,
|
||||
value: item.PARAMVALUE,
|
||||
}))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
formatUSDate(datetime: Date): string {
|
||||
const date = new Date(datetime);
|
||||
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
||||
|
||||
@ -198,7 +198,13 @@ export class HomeComponent {
|
||||
this.storageService.set("carnet-clientid", item.clientid);
|
||||
this.storageService.set("carnet-locationid", item.locationid);
|
||||
|
||||
this.navigateTo(['view-carnet', 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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user