fix(freight): filter container returns by returned-by truck type

Top Returned Containers table ignored the EDR/Customer tab because
the backend never persisted which truck type performed the return.
Added returned_by column + DTO/entity field, wired create payload to
send it, and filtered the table by the active tab.
This commit is contained in:
Hagernesh
2026-08-04 06:54:52 +00:00
parent 5c33ea90bd
commit dfc7dfec5a
13 changed files with 198 additions and 578 deletions

View File

@@ -28,6 +28,7 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
import { DataSource, In } from 'typeorm';
import { deriveTradeDirection } from '../../common/derive-trade-direction.util';
import { assertExportReceivedWithGrn } from '../../common/export-received-gate';
import { Yard } from '../rule-engine/entities/yard.entity';
import { ServiceType } from '../rule-engine/entities/service-type.entity';
import { TrainSchedule } from '../train-schedules/entities/train-schedule.entity';
@@ -239,6 +240,10 @@ export class BookingsService {
*/
async carriageAcceptanceSheet(bookingId: string): Promise<{ filename: string; buffer: Buffer }> {
const booking = await this.findById(bookingId);
// The sheet attests that EDR has taken custody. For export that happens at
// cargo receipt (GRN), so the GRN is required even when wagons are already
// allocated — an allocation is a plan, not possession.
await assertExportReceivedWithGrn(this.dataSource, booking);
let wagons: CarriageAcceptanceWagonRow[] = await this.dataSource.query(
`SELECT tsw.sequence_no AS "sequenceNo",
COALESCE(wt.code, wt.name) AS "wagonType",
@@ -291,7 +296,10 @@ export class BookingsService {
LEFT JOIN freight.containers c
ON c.id = inv.container_id AND c.deleted_at IS NULL
WHERE inv.booking_id = $1 AND inv.deleted_at IS NULL
AND COALESCE(NULLIF(TRIM(inv.grn_number), ''), '') <> ''
AND COALESCE(
NULLIF(TRIM(inv.grn_number), ''),
substring(inv.notes FROM 'GRN Number: ([^\\n\\r]+)')
) IS NOT NULL
ORDER BY inv.created_at`,
[bookingId],
)