Merge branch 'empty-return-requests-fix' into dev

This commit is contained in:
hager
2026-09-06 20:13:50 +00:00
2 changed files with 57 additions and 9 deletions

View File

@@ -54,6 +54,33 @@ export interface EmptyReturnQuote {
unavailableReason: string | null;
}
/** A queue row: the request plus the booking and payer names staff read it by. */
export type EmptyReturnRequestRow = Pick<
EmptyReturnRequest,
| 'id'
| 'bookingId'
| 'companyId'
| 'status'
| 'containerNumbers'
| 'containerCount'
| 'quotedUnitAmount'
| 'quotedTotalAmount'
| 'currency'
| 'invoiceId'
| 'paidAt'
| 'requestedReturnDate'
| 'truckPlateNumber'
| 'truckDriverName'
| 'truckType'
| 'scheduledAt'
| 'submittedByUserId'
| 'submittedAt'
| 'reviewedByStaffId'
| 'reviewedAt'
| 'rejectionReason'
| 'completedAt'
> & { bookingReference: string | null; companyName: string | null };
export interface EmptyReturnEligibility {
eligible: boolean;
/** Why the customer cannot request one, when `eligible` is false. */
@@ -82,13 +109,34 @@ export class EmptyReturnRequestsService {
async findAll(filter: {
status?: EmptyReturnRequestStatus;
bookingId?: string;
}): Promise<
Array<EmptyReturnRequest & { bookingReference: string | null; companyName: string | null }>
> {
}): Promise<EmptyReturnRequestRow[]> {
// Raw SQL bypasses the entity mapping, so every column is aliased to the
// property name the clients read — `r.*` would hand them snake_case.
return this.dataSource.query(
`SELECT r.*,
b.reference AS "bookingReference",
c.name AS "companyName"
`SELECT r.id,
r.booking_id AS "bookingId",
r.company_id AS "companyId",
r.status,
r.container_numbers AS "containerNumbers",
r.container_count AS "containerCount",
r.quoted_unit_amount::float8 AS "quotedUnitAmount",
r.quoted_total_amount::float8 AS "quotedTotalAmount",
r.currency,
r.invoice_id AS "invoiceId",
r.paid_at AS "paidAt",
r.requested_return_date AS "requestedReturnDate",
r.truck_plate_number AS "truckPlateNumber",
r.truck_driver_name AS "truckDriverName",
r.truck_type AS "truckType",
r.scheduled_at AS "scheduledAt",
r.submitted_by_user_id AS "submittedByUserId",
r.submitted_at AS "submittedAt",
r.reviewed_by_staff_id AS "reviewedByStaffId",
r.reviewed_at AS "reviewedAt",
r.rejection_reason AS "rejectionReason",
r.completed_at AS "completedAt",
b.reference AS "bookingReference",
c.name AS "companyName"
FROM freight.empty_return_requests r
LEFT JOIN freight.bookings b ON b.id = r.booking_id AND b.deleted_at IS NULL
LEFT JOIN freight.companies c ON c.id = r.company_id

View File

@@ -79,7 +79,7 @@ export default function EmptyReturnRequestsPage() {
const controls = useListControls(requests, {
dateKey: "submittedAt",
searchValue: (row) =>
`${row.bookingReference ?? ""} ${row.companyName ?? ""} ${row.containerNumbers.join(" ")}`,
`${row.bookingReference ?? ""} ${row.companyName ?? ""} ${(row.containerNumbers ?? []).join(" ")}`,
});
const invalidate = () => {
@@ -143,7 +143,7 @@ export default function EmptyReturnRequestsPage() {
<Stack gap={2}>
<Badge size="sm">{row.original.containerCount}</Badge>
<Text size="xs" c="dimmed" lineClamp={2}>
{row.original.containerNumbers.join(", ")}
{(row.original.containerNumbers ?? []).join(", ")}
</Text>
</Stack>
),
@@ -386,7 +386,7 @@ function ApproveModal({
Containers coming back
</Text>
<Text size="sm" c="dimmed">
{request.containerNumbers.join(", ")}
{(request.containerNumbers ?? []).join(", ")}
</Text>
</div>