mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 12:58:13 +00:00
feat(bookings): two-level clearance charges (port + misc) billed to customer with invoices
This commit is contained in:
@@ -40,6 +40,7 @@ import {
|
||||
import type { Response } from "express";
|
||||
|
||||
import { BookingClearanceChargeService } from './booking-clearance-charge.service';
|
||||
import { ClearanceEventService } from './clearance-event.service';
|
||||
import { BillClearanceChargeDto } from './dto/clearance-charge.dto';
|
||||
import { BookingContractService } from './booking-contract.service';
|
||||
import { BookingPricingService } from './booking-pricing.service';
|
||||
@@ -174,6 +175,7 @@ export class BookingsController {
|
||||
private readonly wagonCancellationService: BookingWagonCancellationService,
|
||||
private readonly consolidationApprovalService: ConsolidationApprovalService,
|
||||
private readonly clearanceChargeService: BookingClearanceChargeService,
|
||||
private readonly clearanceEventService: ClearanceEventService,
|
||||
) {}
|
||||
|
||||
@Post()
|
||||
@@ -975,10 +977,12 @@ export class BookingsController {
|
||||
async submitClearanceDocuments(
|
||||
@Param("id", ParseUUIDPipe) id: string,
|
||||
@UploadedFiles() files: Express.Multer.File[],
|
||||
@CurrentUser() user: AuthUserPayload,
|
||||
) {
|
||||
const booking = await this.transitionService.submitClearanceDocuments(
|
||||
id,
|
||||
files ?? [],
|
||||
resolveAuthUserId(user),
|
||||
);
|
||||
return this.transitionService.enrichBookingResponse(booking);
|
||||
}
|
||||
@@ -995,11 +999,13 @@ export class BookingsController {
|
||||
async proceedToOperation(
|
||||
@Param("id", ParseUUIDPipe) id: string,
|
||||
@Body() dto: RequestOperationDto,
|
||||
@CurrentUser() user: AuthUserPayload,
|
||||
) {
|
||||
const booking = await this.transitionService.requestOperation(
|
||||
id,
|
||||
dto.scheduledDate,
|
||||
dto.trainScheduleId ?? null,
|
||||
{ userId: resolveAuthUserId(user) },
|
||||
);
|
||||
return this.transitionService.enrichBookingResponse(booking);
|
||||
}
|
||||
@@ -1077,6 +1083,19 @@ export class BookingsController {
|
||||
return this.transitionService.enrichBookingResponse(booking);
|
||||
}
|
||||
|
||||
@Get(":id/clearance/history")
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.contracts.clearanceEtActions,
|
||||
FREIGHT_PERMS.contracts.clearanceDjActions,
|
||||
])
|
||||
@ApiOperation({
|
||||
summary:
|
||||
"Clearance action history for the booking — reviews, workflow steps, charges (newest first)",
|
||||
})
|
||||
getClearanceHistory(@Param("id", ParseUUIDPipe) id: string) {
|
||||
return this.clearanceEventService.list(id);
|
||||
}
|
||||
|
||||
// ── Clearance charges (post-finalization customer billing) ────────────────
|
||||
|
||||
@Get(":id/clearance/charges")
|
||||
@@ -1140,8 +1159,13 @@ export class BookingsController {
|
||||
sendClearanceCharge(
|
||||
@Param("id", ParseUUIDPipe) id: string,
|
||||
@Param("chargeId", ParseUUIDPipe) chargeId: string,
|
||||
@CurrentUser() user: AuthUserPayload,
|
||||
) {
|
||||
return this.clearanceChargeService.sendCharge(id, chargeId);
|
||||
return this.clearanceChargeService.sendCharge(
|
||||
id,
|
||||
chargeId,
|
||||
resolveAuthUserId(user),
|
||||
);
|
||||
}
|
||||
|
||||
@Post(":id/clearance/charges/miscellaneous")
|
||||
@@ -1175,10 +1199,12 @@ export class BookingsController {
|
||||
async uploadClearanceOutput(
|
||||
@Param("id", ParseUUIDPipe) id: string,
|
||||
@UploadedFiles() files: Express.Multer.File[],
|
||||
@CurrentUser() user: AuthUserPayload,
|
||||
) {
|
||||
const booking = await this.transitionService.uploadClearanceOutputDocuments(
|
||||
id,
|
||||
files ?? [],
|
||||
resolveAuthUserId(user),
|
||||
);
|
||||
return this.transitionService.enrichBookingResponse(booking);
|
||||
}
|
||||
@@ -1189,8 +1215,14 @@ export class BookingsController {
|
||||
summary:
|
||||
"GL finalizes clearance (requires 100% approved) → CLEARANCE_READY",
|
||||
})
|
||||
async finalizeClearance(@Param("id", ParseUUIDPipe) id: string) {
|
||||
const booking = await this.transitionService.finalizeClearance(id);
|
||||
async finalizeClearance(
|
||||
@Param("id", ParseUUIDPipe) id: string,
|
||||
@CurrentUser() user: AuthUserPayload,
|
||||
) {
|
||||
const booking = await this.transitionService.finalizeClearance(
|
||||
id,
|
||||
resolveAuthUserId(user),
|
||||
);
|
||||
return this.transitionService.enrichBookingResponse(booking);
|
||||
}
|
||||
|
||||
@@ -1203,8 +1235,13 @@ export class BookingsController {
|
||||
async requestBookingTransitAssignee(
|
||||
@Param('id', ParseUUIDPipe) id: string,
|
||||
@Body('note') note: string | undefined,
|
||||
@CurrentUser() user: AuthUserPayload,
|
||||
) {
|
||||
const booking = await this.bookingClearanceService.requestTransitAssignee(id, note);
|
||||
const booking = await this.bookingClearanceService.requestTransitAssignee(
|
||||
id,
|
||||
note,
|
||||
resolveAuthUserId(user),
|
||||
);
|
||||
return this.transitionService.enrichBookingResponse(booking);
|
||||
}
|
||||
|
||||
@@ -1217,8 +1254,13 @@ export class BookingsController {
|
||||
async assignBookingTransitAssignee(
|
||||
@Param('id', ParseUUIDPipe) id: string,
|
||||
@Body('transitAgentId', ParseUUIDPipe) transitAgentId: string,
|
||||
@CurrentUser() user: AuthUserPayload,
|
||||
) {
|
||||
const booking = await this.bookingClearanceService.assignTransitAssignee(id, transitAgentId);
|
||||
const booking = await this.bookingClearanceService.assignTransitAssignee(
|
||||
id,
|
||||
transitAgentId,
|
||||
resolveAuthUserId(user),
|
||||
);
|
||||
return this.transitionService.enrichBookingResponse(booking);
|
||||
}
|
||||
|
||||
@@ -1302,8 +1344,14 @@ export class BookingsController {
|
||||
summary:
|
||||
'Customer accepts the draft customs declaration — unlocks the real customs declaration step for GL Ethiopia',
|
||||
})
|
||||
async acceptBookingDraftDeclaration(@Param('id', ParseUUIDPipe) id: string) {
|
||||
const booking = await this.bookingClearanceService.acceptDraftDeclaration(id);
|
||||
async acceptBookingDraftDeclaration(
|
||||
@Param('id', ParseUUIDPipe) id: string,
|
||||
@CurrentUser() user: AuthUserPayload,
|
||||
) {
|
||||
const booking = await this.bookingClearanceService.acceptDraftDeclaration(
|
||||
id,
|
||||
resolveAuthUserId(user),
|
||||
);
|
||||
return this.transitionService.enrichBookingResponse(booking);
|
||||
}
|
||||
|
||||
@@ -1329,8 +1377,14 @@ export class BookingsController {
|
||||
@Post(':id/clearance/finalize-pre-clearance')
|
||||
@BookingStaff(FREIGHT_PERMS.contracts.clearanceEtActions)
|
||||
@ApiOperation({ summary: 'GL ET finalizes import pre-clearance on booking' })
|
||||
async finalizeBookingPreClearance(@Param('id', ParseUUIDPipe) id: string) {
|
||||
const booking = await this.bookingClearanceService.finalizePreClearance(id);
|
||||
async finalizeBookingPreClearance(
|
||||
@Param('id', ParseUUIDPipe) id: string,
|
||||
@CurrentUser() user: AuthUserPayload,
|
||||
) {
|
||||
const booking = await this.bookingClearanceService.finalizePreClearance(
|
||||
id,
|
||||
resolveAuthUserId(user),
|
||||
);
|
||||
return this.transitionService.enrichBookingResponse(booking);
|
||||
}
|
||||
|
||||
@@ -1342,8 +1396,13 @@ export class BookingsController {
|
||||
async uploadBookingDutySlip(
|
||||
@Param('id', ParseUUIDPipe) id: string,
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@CurrentUser() user: AuthUserPayload,
|
||||
) {
|
||||
const booking = await this.bookingClearanceService.uploadDutySlip(id, file);
|
||||
const booking = await this.bookingClearanceService.uploadDutySlip(
|
||||
id,
|
||||
file,
|
||||
resolveAuthUserId(user),
|
||||
);
|
||||
return this.transitionService.enrichBookingResponse(booking);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user