Invoice and clearance seal approval

This commit is contained in:
hagiye
2026-06-27 00:39:48 +03:00
8 changed files with 64 additions and 0 deletions

View File

@@ -78,6 +78,7 @@ export class CreateWarehouseModule1790000000000 implements MigrationInterface {
weight NUMERIC(14,3) NOT NULL DEFAULT 0,
volume NUMERIC(12,3) NULL,
status VARCHAR(32) NOT NULL DEFAULT 'ARRIVED_AT_WAREHOUSE',
inspection_status VARCHAR(20) NULL,
arrived_at TIMESTAMPTZ NULL,
inspected_at TIMESTAMPTZ NULL,
ready_for_loading_at TIMESTAMPTZ NULL,

View File

@@ -0,0 +1,39 @@
import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm';
/**
* Catch-up for environments where AddWarehouseInspection ran before the
* warehouse module table existed. Production needs this column for unload and
* inspection flows because the WarehouseInventory entity maps inspectionStatus.
*/
export class EnsureWarehouseInventoryInspectionStatus1821000000001 implements MigrationInterface {
private readonly table = 'freight.warehouse_inventory';
public async up(queryRunner: QueryRunner): Promise<void> {
if (!(await queryRunner.hasColumn(this.table, 'inspection_status'))) {
await queryRunner.addColumn(
this.table,
new TableColumn({
name: 'inspection_status',
type: 'varchar',
length: '20',
isNullable: true,
}),
);
}
await queryRunner.query(`
CREATE INDEX IF NOT EXISTS idx_warehouse_inventory_inspection_status
ON freight.warehouse_inventory(inspection_status)
`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
DROP INDEX IF EXISTS freight.idx_warehouse_inventory_inspection_status
`);
if (await queryRunner.hasColumn(this.table, 'inspection_status')) {
await queryRunner.dropColumn(this.table, 'inspection_status');
}
}
}

View File

@@ -32,6 +32,7 @@ export class LastMileService {
private readonly logger = new Logger(LastMileService.name);
constructor(
private readonly lastMileRepository: LastMileRepository,
private readonly bookingsRepository: BookingsRepository,
private readonly vehiclesService: VehiclesService,

View File

@@ -37,6 +37,7 @@ export interface ImportTrainItemRow {
weight: number | null;
arrivalTime: string | null;
currentStatus: string | null;
inspectionStatus: string | null;
lastMileRequested: boolean;
pickupOption: string;
}
@@ -271,6 +272,7 @@ export class SchedulingReadFacade {
b.cargo_total_weight_vgm AS "weight",
COALESCE(ts.actual_arrival_at, ts.scheduled_arrival_date) AS "arrivalTime",
COALESCE(inv.status, b.status) AS "currentStatus",
inv.inspection_status AS "inspectionStatus",
(b.last_mile_delivery_address IS NOT NULL) AS "lastMileRequested",
CASE WHEN b.last_mile_delivery_address IS NOT NULL
THEN 'DOOR_DELIVERY' ELSE 'TERMINAL_PICKUP' END AS "pickupOption"

View File

@@ -687,6 +687,7 @@ function ImportTrainDetailTable({ scheduleId }: { scheduleId: string }) {
<Table.Th>Cargo Type</Table.Th>
<Table.Th>Weight</Table.Th>
<Table.Th>Arrival</Table.Th>
<Table.Th>Inspection</Table.Th>
<Table.Th>Current Status</Table.Th>
<Table.Th>Last Mile</Table.Th>
<Table.Th>Pickup Option</Table.Th>
@@ -709,6 +710,11 @@ function ImportTrainDetailTable({ scheduleId }: { scheduleId: string }) {
<Table.Td>{it.cargoType ?? '—'}</Table.Td>
<Table.Td>{formatNumber(Number(it.weight))}</Table.Td>
<Table.Td>{formatDate(it.arrivalTime)}</Table.Td>
<Table.Td>
<Badge size="xs" variant="light" color={it.inspectionStatus === 'PASSED' ? 'green' : 'gray'}>
{it.inspectionStatus ?? 'Not inspected'}
</Badge>
</Table.Td>
<Table.Td>
<Badge size="xs" variant="light" color="gray">{it.currentStatus ?? '—'}</Badge>
</Table.Td>

View File

@@ -1,2 +1,10 @@
export const API_BASE_URL =
<<<<<<< HEAD
import.meta.env.VITE_API_URL?.replace(/\/+$/, '') || 'https://edrfreightapi.triaplc.com';
=======
import.meta.env.VITE_BASE_API_URL ||
import.meta.env.VITE_API_URL ||
'https://edrfreightapi.triaplc.com';
//export const API_BASE_URL = 'http://localhost:3001';
>>>>>>> 2f06817e4811190cdc9ef8a2975aeca1e31c3484

View File

@@ -73,6 +73,7 @@ function ImportTrainDetailRows({ scheduleId }: { scheduleId: string }) {
<Table.Th>Weight</Table.Th>
<Table.Th>Arrival</Table.Th>
<Table.Th>Status</Table.Th>
<Table.Th>Inspection</Table.Th>
<Table.Th>Pickup</Table.Th>
</Table.Tr>
</Table.Thead>
@@ -94,6 +95,11 @@ function ImportTrainDetailRows({ scheduleId }: { scheduleId: string }) {
{item.currentStatus ?? 'PENDING'}
</Badge>
</Table.Td>
<Table.Td>
<Badge variant="light" color={item.inspectionStatus === 'PASSED' ? 'green' : 'gray'} size="sm">
{item.inspectionStatus ?? 'Not inspected'}
</Badge>
</Table.Td>
<Table.Td>{item.pickupOption.replace(/_/g, ' ')}</Table.Td>
</Table.Tr>
))}

View File

@@ -513,6 +513,7 @@ export interface ImportTrainItem {
weight: number | null;
arrivalTime: string | null;
currentStatus: string | null;
inspectionStatus: string | null;
lastMileRequested: boolean;
pickupOption: string;
}